00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "LampBasic.h"
00044 #include "Core/Codec/Tga/TargaLoader.h"
00045 #include "Core/InputOutput/BinaryFileReader.h"
00046
00047 namespace Lamp{
00048
00049
00050
00051 TargaLoader::TargaLoader(BinaryReader* reader) : reader_(reader),
00052 size_(0, 0), hasAlpha_(false), allocateReader_(false){
00053 }
00054
00055
00056 TargaLoader::TargaLoader(const String& fileName) : reader_(NULL),
00057 size_(0, 0), hasAlpha_(false), allocateReader_(true){
00058 reader_ = new BinaryFileReader(fileName);
00059 }
00060
00061
00062 TargaLoader::~TargaLoader(){
00063 if(allocateReader_){ delete reader_; }
00064 }
00065
00066
00067 bool TargaLoader::loadHeader(){
00068
00069 u_char imageID = reader_->readUChar();
00070 Assert(imageID == 0);
00071
00072 u_char colorMapFlag = reader_->readUChar();
00073 if(colorMapFlag == 1){
00074 ErrorOut("TargaLoader::loadHeader() Unsupported colorMap");
00075 return false;
00076 }
00077
00078 u_char imageType = reader_->readUChar();
00079 if((imageType != 2) && (imageType != 10)){
00080 ErrorOut("TargaLoader::loadHeader() Unknown imageType %d", imageType);
00081 return false;
00082 }
00083
00084 if(imageType == 10){
00085 ErrorOut("TargaLoader::loadHeader() Unsupported compress image");
00086 return false;
00087 }
00088
00089 reader_->readShort();
00090 reader_->readShort();
00091 reader_->readUChar();
00092
00093 int xOrigin = reader_->readShort();
00094 if(xOrigin != 0){
00095 ErrorOut("TargaLoader::loadHeader() Unsupported xOrigin %d", xOrigin);
00096 return false;
00097 }
00098
00099 int yOrigin = reader_->readShort();
00100 if(yOrigin != 0){
00101 ErrorOut("TargaLoader::loadHeader() Unsupported yOrigin %d", yOrigin);
00102 return false;
00103 }
00104
00105 size_.width = reader_->readShort();
00106 if(size_.width < 1){
00107 ErrorOut("TargaLoader::loadHeader() Invalid width %d", size_.width);
00108 return false;
00109 }
00110
00111 size_.height = reader_->readShort();
00112 if(size_.height < 1){
00113 ErrorOut("TargaLoader::loadHeader() Invalid height %d", size_.height);
00114 return false;
00115 }
00116
00117 u_char pixelSize = reader_->readUChar();
00118 if((pixelSize != 24) && (pixelSize != 32)){
00119 ErrorOut("TargaLoader::loadHeader() Unsupported pixelSize %d",
00120 pixelSize);
00121 return false;
00122 }
00123 hasAlpha_ = (pixelSize == 32);
00124
00125 u_char imageDescriptor = reader_->readUChar();
00126 int alphaDepth = (imageDescriptor & 0xf);
00127
00128 if(hasAlpha_){
00129 if(alphaDepth != 8){
00130 ErrorOut("TargaLoader::loadHeader() Invalid alphaDepth %d",
00131 alphaDepth);
00132 return false;
00133 }
00134 }else{
00135 if(alphaDepth != 0){
00136 ErrorOut("TargaLoader::loadHeader() Invalid alphaDepth %d",
00137 alphaDepth);
00138 return false;
00139 }
00140 }
00141 if((imageDescriptor & 0xf0) != 0){
00142 ErrorOut("TargaLoader::loadHeader() Invalid imageDescriptor %d",
00143 imageDescriptor);
00144 return false;
00145 }
00146 return true;
00147 }
00148
00149
00150 void TargaLoader::loadImage(Color3c* output){
00151
00152 int bufferSize;
00153 if(hasAlpha_){ bufferSize = size_.width * size_.height * sizeof(Color4c); }
00154 else{ bufferSize = size_.width * size_.height * sizeof(Color3c); }
00155 u_char* buffer = new u_char[bufferSize];
00156 u_char* readAddress = buffer;
00157 reader_->readBytes(buffer, bufferSize);
00158 if(hasAlpha_){
00159 for(int i = size_.height - 1; i >= 0; i--){
00160 int offset = i * size_.width;
00161 for(int j = 0; j < size_.width; j++){
00162 u_char b = *readAddress;
00163 readAddress++;
00164 u_char g = *readAddress;
00165 readAddress++;
00166 u_char r = *readAddress;
00167 readAddress++;
00168 readAddress++;
00169 output[offset + j].set(r, g, b);
00170 }
00171 }
00172 }else{
00173 for(int i = size_.height - 1; i >= 0; i--){
00174 int offset = i * size_.width;
00175 for(int j = 0; j < size_.width; j++){
00176 u_char b = *readAddress;
00177 readAddress++;
00178 u_char g = *readAddress;
00179 readAddress++;
00180 u_char r = *readAddress;
00181 readAddress++;
00182 output[offset + j].set(r, g, b);
00183 }
00184 }
00185 }
00186 delete[] buffer;
00187 }
00188
00189
00190 void TargaLoader::loadImage(Color4c* output){
00191
00192 int bufferSize;
00193 if(hasAlpha_){ bufferSize = size_.width * size_.height * sizeof(Color4c); }
00194 else{ bufferSize = size_.width * size_.height * sizeof(Color3c); }
00195 u_char* buffer = new u_char[bufferSize];
00196 u_char* readAddress = buffer;
00197 reader_->readBytes(buffer, bufferSize);
00198 if(hasAlpha_){
00199 for(int i = size_.height - 1; i >= 0; i--){
00200 int offset = i * size_.width;
00201 for(int j = 0; j < size_.width; j++){
00202 u_char b = *readAddress;
00203 readAddress++;
00204 u_char g = *readAddress;
00205 readAddress++;
00206 u_char r = *readAddress;
00207 readAddress++;
00208 u_char a = *readAddress;
00209 readAddress++;
00210 output[offset + j].set(r, g, b, a);
00211 }
00212 }
00213 }else{
00214 for(int i = size_.height - 1; i >= 0; i--){
00215 int offset = i * size_.width;
00216 for(int j = 0; j < size_.width; j++){
00217 u_char b = *readAddress;
00218 readAddress++;
00219 u_char g = *readAddress;
00220 readAddress++;
00221 u_char r = *readAddress;
00222 readAddress++;
00223 output[offset + j].set(r, g, b, 255);
00224 }
00225 }
00226 }
00227 delete[] buffer;
00228 }
00229
00230 }
00231