Bitmap_16bitAlphaCrop.cpp
Go to the documentation of this file.00001 //*** Bitmap_16bitAlphaCrop.cpp *** 00002 00003 #include "Bitmap_16bitAlphaCrop.h" 00004 #include "ColorHelper.h" 00005 #include "Image.h" 00006 #include "Asset.h" 00007 #include "FloydSteinbergDither.h" 00008 00009 00010 //*** GetType *** 00011 00012 StringId Bitmap_16bitAlphaCrop::GetType() 00013 { 00014 static StringId idBitmap_16bitAlphaCrop("Bitmap_16bitAlphaCrop"); 00015 return idBitmap_16bitAlphaCrop; 00016 } 00017 00018 00019 //*** Constructor *** 00020 00021 Bitmap_16bitAlphaCrop::Bitmap_16bitAlphaCrop() 00022 { 00023 } 00024 00025 00026 //*** Constructor *** 00027 00028 Bitmap_16bitAlphaCrop::Bitmap_16bitAlphaCrop(const Asset& asset) 00029 { 00030 Load(asset); 00031 } 00032 00033 00034 //*** Constructor *** 00035 00036 Bitmap_16bitAlphaCrop::Bitmap_16bitAlphaCrop(const Image& image, bool dither) 00037 { 00038 width_=image.GetWidth(); 00039 height_=image.GetHeight(); 00040 00041 int minX=image.GetWidth(); 00042 int minY=image.GetHeight(); 00043 int maxX=0; 00044 int maxY=0; 00045 for (int y=0; y<image.GetHeight(); y++) 00046 { 00047 for (int x=0; x<image.GetWidth(); x++) 00048 { 00049 unsigned int color=image.GetPixel(x,y); 00050 if (color>>24) 00051 { 00052 if (y<minY) 00053 minY=y; 00054 if (x<minX) 00055 minX=x; 00056 if (y>maxY) 00057 maxY=y; 00058 if (x>maxX) 00059 maxX=x; 00060 } 00061 } 00062 } 00063 if (maxX<minX || maxY<minY) 00064 { 00065 return; 00066 } 00067 00068 hOffset_=(unsigned short)minX; 00069 vOffset_=(unsigned short)minY; 00070 hPitch_=(unsigned short)(maxX-minX+1); 00071 vPitch_=(unsigned short)(maxY-minY+1); 00072 00073 00074 color_=static_cast<unsigned short*>(Malloc(hPitch_*vPitch_*sizeof(unsigned short))); 00075 alpha_=static_cast<unsigned char*>(Malloc(hPitch_*vPitch_*sizeof(unsigned char))); 00076 00078 if (dither) 00079 { 00080 unsigned short* dithered=static_cast<unsigned short*>(Malloc(image.GetWidth()*image.GetHeight()*sizeof(unsigned short))); 00081 FloydSteinbergDither::DitherImage(image.GetPointer(),image.GetWidth(),image.GetHeight(),dithered); 00082 for (int y=0; y<vPitch_; y++) 00083 { 00084 for (int x=0; x<hPitch_; x++) 00085 { 00086 unsigned int color=image.GetPixel(x+hOffset_,y+vOffset_); 00087 color_[x+y*hPitch_]=dithered[x+hOffset_+(y+vOffset_)*image.GetWidth()]; 00088 alpha_[x+y*hPitch_]=static_cast<unsigned char>(color>>24); 00089 } 00090 } 00091 Free(dithered); 00092 return; 00093 } 00094 00095 for (int y=0; y<vPitch_; y++) 00096 { 00097 for (int x=0; x<hPitch_; x++) 00098 { 00099 unsigned int color=image.GetPixel(x+hOffset_,y+vOffset_); 00100 color_[x+y*hPitch_]=RGB32TO16(color); 00101 alpha_[x+y*hPitch_]=static_cast<unsigned char>(color>>24); 00102 } 00103 } 00104 } 00105 00106 00107 //*** Constructor *** 00108 00109 Bitmap_16bitAlphaCrop::Bitmap_16bitAlphaCrop(const Image& color, const Image& alpha, bool dither) 00110 { 00111 Assert(color.GetWidth()==alpha.GetWidth() && color.GetHeight()==alpha.GetHeight(),"The size of color and alpha doesn't match"); 00112 if (color.GetWidth()!=alpha.GetWidth() || color.GetHeight()!=alpha.GetHeight()) 00113 { 00114 return; 00115 } 00116 00117 width_=color.GetWidth(); 00118 height_=color.GetHeight(); 00119 int minX=alpha.GetWidth(); 00120 int minY=alpha.GetHeight(); 00121 int maxX=0; 00122 int maxY=0; 00123 for (int y=0; y<alpha.GetHeight(); y++) 00124 { 00125 for (int x=0; x<alpha.GetWidth(); x++) 00126 { 00127 unsigned int color=alpha.GetPixel(x,y); 00128 if (color&0xff) 00129 { 00130 if (y<minY) 00131 minY=y; 00132 if (x<minX) 00133 minX=x; 00134 if (y>maxY) 00135 maxY=y; 00136 if (x>maxX) 00137 maxX=x; 00138 } 00139 } 00140 } 00141 00142 if (maxX<minX || maxY<minY) 00143 { 00144 return; 00145 } 00146 00147 hOffset_=(unsigned short)minX; 00148 vOffset_=(unsigned short)minY; 00149 hPitch_=(unsigned short)(maxX-minX+1); 00150 vPitch_=(unsigned short)(maxY-minY+1); 00151 00152 color_=static_cast<unsigned short*>(Malloc(hPitch_*vPitch_*sizeof(unsigned short))); 00153 alpha_=static_cast<unsigned char*>(Malloc(hPitch_*vPitch_*sizeof(unsigned char))); 00154 00155 //**** FIX THIS SECTION - NO NEED TO DITHER ENTIRE color *** 00156 if (dither) 00157 { 00158 unsigned short* dithered=static_cast<unsigned short*>(Malloc(color.GetWidth()*color.GetHeight()*sizeof(unsigned short))); 00159 FloydSteinbergDither::DitherImage(color.GetPointer(),color.GetWidth(),color.GetHeight(),dithered); 00160 for (int y=0; y<vPitch_; y++) 00161 { 00162 for (int x=0; x<hPitch_; x++) 00163 { 00164 color_[x+y*hPitch_]=dithered[x+hOffset_+(y+hOffset_)*color.GetWidth()]; 00165 int a=(alpha.GetPixel(x+hOffset_,y+vOffset_)&0xff); 00166 alpha_[x+y*hPitch_]=static_cast<unsigned char>(a); 00167 } 00168 } 00169 Free(dithered); 00170 return; 00171 } 00172 00173 for (int y=0; y<vPitch_; y++) 00174 { 00175 for (int x=0; x<hPitch_; x++) 00176 { 00177 color_[x+y*hPitch_]=RGB32TO16(color.GetPixel(x+hOffset_,y+vOffset_)); 00178 int a=(alpha.GetPixel(x+hOffset_,y+vOffset_)&0xff); 00179 alpha_[x+y*hPitch_]=static_cast<unsigned char>(a); 00180 } 00181 } 00182 } 00183 00184 00185 //*** Destructor *** 00186 00187 Bitmap_16bitAlphaCrop::~Bitmap_16bitAlphaCrop() 00188 { 00189 if (color_) 00190 { 00191 Free(color_); 00192 } 00193 if (alpha_) 00194 { 00195 Free(alpha_); 00196 } 00197 } 00198 00199 00200 //*** Save *** 00201 00202 void Bitmap_16bitAlphaCrop::Save(Asset& asset) const 00203 { 00204 if (asset.Create()) 00205 { 00206 asset.Write("PIX16BAC",8); 00207 int version=0; 00208 asset.Write(&version); 00209 int celCount=0; 00210 asset.Write(&celCount); 00211 WriteToAsset(&asset); 00212 asset.Close(); 00213 } 00214 } 00215 00216 00217 //*** Load *** 00218 00219 void Bitmap_16bitAlphaCrop::Load(const Asset& asset) 00220 { 00221 if (asset.Open()) 00222 { 00223 char header[8]; 00224 asset.Read(header,8); 00225 00226 if (StrNCmp(header,"PIX16BAC",8)==0) 00227 { 00228 int version=0; 00229 asset.Read(&version); 00230 int celCount=0; 00231 asset.Read(&celCount); 00232 if (version==0) 00233 { 00234 ReadFromAsset(&asset); 00235 } 00236 } 00237 00238 // Check for old format too 00239 else if (StrNCmp(header,"PIXIE_CA",8)==0) 00240 { 00241 // Read the extra header bytes (BM) 00242 char c[2]; 00243 asset.Read(c,2); 00244 Assert(StrNCmp(c,"BM",2)==0,"Invalid header"); 00245 if (StrNCmp(c,"BM",2)!=0) 00246 { 00247 asset.Close(); 00248 return; 00249 } 00250 00251 int version=0; 00252 asset.Read(&version); 00253 if (version==0) 00254 { 00255 ReadFromAsset_Old(&asset); 00256 } 00257 } 00258 00259 else 00260 { 00261 Assert(false,"Invalid header"); 00262 } 00263 00264 asset.Close(); 00265 } 00266 // Report missing file 00267 #ifdef _DEBUG 00268 else 00269 { 00270 const char* filename=asset.GetFilename().GetString(); 00271 if (filename) 00272 { 00273 char errorMessage[1024]; 00274 SNPrintF(errorMessage,1024,"File not found: %s",filename); 00275 Assert(false,errorMessage); 00276 } 00277 else 00278 { 00279 Assert(false,"An asset could not be accessed."); 00280 } 00281 } 00282 #endif 00283 } 00284 00285 00286 //*** ReadFromAsset *** 00287 00288 void Bitmap_16bitAlphaCrop::ReadFromAsset(const Asset* asset) 00289 { 00290 if (color_) 00291 { 00292 Free(color_); 00293 color_=0; 00294 } 00295 if (alpha_) 00296 { 00297 Free(alpha_); 00298 alpha_=0; 00299 } 00300 00301 asset->Read(&width_); 00302 asset->Read(&height_); 00303 asset->Read(&hOffset_); 00304 asset->Read(&vOffset_); 00305 asset->Read(&hPitch_); 00306 asset->Read(&vPitch_); 00307 00308 if (hPitch_*vPitch_>0) 00309 { 00310 color_=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*hPitch_*vPitch_)); 00311 asset->Read(color_,hPitch_*vPitch_); 00312 alpha_=static_cast<unsigned char*>(Malloc(sizeof(unsigned char)*hPitch_*vPitch_)); 00313 asset->Read(alpha_,hPitch_*vPitch_); 00314 } 00315 } 00316 00317 00318 //*** ReadFromAsset_Old *** 00319 00320 void Bitmap_16bitAlphaCrop::ReadFromAsset_Old(const Asset* asset) 00321 { 00322 if (color_) 00323 { 00324 Free(color_); 00325 color_=0; 00326 } 00327 if (alpha_) 00328 { 00329 Free(alpha_); 00330 alpha_=0; 00331 } 00332 00333 asset->Read(&width_); 00334 asset->Read(&height_); 00335 00336 unsigned short xOffset; 00337 unsigned short yOffset; 00338 unsigned short activeWidth; 00339 unsigned short activeHeight; 00340 asset->Read(&xOffset); 00341 asset->Read(&yOffset); 00342 asset->Read(&activeWidth); 00343 asset->Read(&activeHeight); 00344 hOffset_=xOffset; 00345 vOffset_=yOffset; 00346 hPitch_=activeWidth; 00347 vPitch_=activeHeight; 00348 00349 if (hPitch_*vPitch_>0) 00350 { 00351 color_=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*hPitch_*vPitch_)); 00352 asset->Read(color_,hPitch_*vPitch_); 00353 alpha_=static_cast<unsigned char*>(Malloc(sizeof(unsigned char)*hPitch_*vPitch_)); 00354 asset->Read(alpha_,hPitch_*vPitch_); 00355 } 00356 } 00357 00358 00359 //*** WriteToAsset *** 00360 00361 void Bitmap_16bitAlphaCrop::WriteToAsset(Asset* asset) const 00362 { 00363 asset->Write(&width_); 00364 asset->Write(&height_); 00365 asset->Write(&hOffset_); 00366 asset->Write(&vOffset_); 00367 asset->Write(&hPitch_); 00368 asset->Write(&vPitch_); 00369 if (hPitch_*vPitch_>0) 00370 { 00371 asset->Write(color_,hPitch_*vPitch_); 00372 asset->Write(alpha_,hPitch_*vPitch_); 00373 } 00374 } 00375
Reproduction/republishing of any material on this site without permission is strictly prohibited.
