GenerateRLE16.cpp
Go to the documentation of this file.00001 //*** GenerateRLE16.h *** 00002 00003 #include "GenerateRLE16.h" 00004 #include "Image.h" 00005 #include "ColorHelper.h" 00006 #include "StandardLibrary.h" 00007 #include "Bitmap_RLE16.h" 00008 #include "FloydSteinbergDither.h" 00009 #include "Debug.h" 00010 00011 //*** Constructor *** 00012 00013 GenerateRLE16::GenerateRLE16(const Image& image, Bitmap_RLE16* bitmap, bool dither): 00014 opaqueSize_(0), 00015 opaqueData_(0), 00016 alphaSize_(0), 00017 alphaData_(0), 00018 hPitch_(0), 00019 vPitch_(0), 00020 hOffset_(0), 00021 vOffset_(0) 00022 { 00023 CreateFromImage(&image, dither); 00024 00025 bitmap->opaqueSize_=opaqueSize_; 00026 bitmap->opaqueData_=opaqueData_; 00027 bitmap->alphaSize_=alphaSize_; 00028 bitmap->alphaData_=alphaData_; 00029 bitmap->hPitch_=hPitch_; 00030 bitmap->vPitch_=vPitch_; 00031 bitmap->hOffset_=hOffset_; 00032 bitmap->vOffset_=vOffset_; 00033 00034 opaqueSize_=0; 00035 opaqueData_=0; 00036 alphaSize_=0; 00037 alphaData_=0; 00038 hPitch_=0; 00039 vPitch_=0; 00040 hOffset_=0; 00041 vOffset_=0; 00042 } 00043 00044 00045 00046 00047 //*** Crop *** 00048 00049 void GenerateRLE16::Crop(const Image* image, int* minX, int* minY, int* maxX, int* maxY) 00050 { 00051 *minX=image->GetWidth(); 00052 *minY=image->GetHeight(); 00053 *maxX=0; 00054 *maxY=0; 00055 for (int y=0; y<image->GetHeight(); y++) 00056 { 00057 for (int x=0; x<image->GetWidth(); x++) 00058 { 00059 unsigned int color=image->GetPixel(x,y); 00060 if (color>>24) 00061 { 00062 if (y<*minY) 00063 *minY=y; 00064 if (x<*minX) 00065 *minX=x; 00066 if (y>*maxY) 00067 *maxY=y; 00068 if (x>*maxX) 00069 *maxX=x; 00070 } 00071 } 00072 } 00073 } 00074 00075 00076 //*** CreateFromImage *** 00077 00078 void GenerateRLE16::CreateFromImage(const Image* image, bool dither) 00079 { 00080 int minX=0; 00081 int minY=0; 00082 int maxX=0; 00083 int maxY=0; 00084 00085 // Crop image 00086 Crop(image,&minX,&minY,&maxX,&maxY); 00087 if (maxX<minX || maxY<minY) 00088 { 00089 return; 00090 } 00091 00092 hPitch_=(unsigned short)(maxX-minX+1); 00093 vPitch_=(unsigned short)(maxY-minY+1); 00094 00095 hOffset_=(unsigned short)minX; 00096 vOffset_=(unsigned short)minY; 00097 00098 // First, create 16-bit version 00099 unsigned short* data=0; 00100 unsigned char* mask=0; 00101 Palettize(image,&data,&mask,dither); 00102 00103 // Create RLE data 00104 opaqueSize_=GetRLESize(data,mask); 00105 if (opaqueSize_>0) 00106 { 00107 opaqueData_=static_cast<unsigned char*>(Malloc(opaqueSize_)); 00108 CreateRLE(data,mask,opaqueData_); 00109 } 00110 00111 // Create RLE mask 00112 alphaSize_=GetRLESize_Alpha(data,mask); 00113 if (alphaSize_>0) 00114 { 00115 alphaData_=static_cast<unsigned char*>(Malloc(alphaSize_)); 00116 CreateRLE_Alpha(data,mask,alphaData_); 00117 } 00118 00119 00120 // Release temp stuff 00121 if (data) 00122 { 00123 Free(data); 00124 } 00125 if (mask) 00126 { 00127 Free(mask); 00128 } 00129 } 00130 00131 00132 00133 //*** Palettize *** 00134 00135 void GenerateRLE16::Palettize(const Image* image,unsigned short** data, unsigned char** mask, bool dither) 00136 { 00137 *data=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*hPitch_*vPitch_)); 00138 *mask=static_cast<unsigned char*>(Malloc(sizeof(unsigned char)*hPitch_*vPitch_)); 00139 unsigned short* img=*data; 00140 unsigned char* maskimg=*mask; 00141 unsigned short* dithered=0; 00142 00143 if (dither) 00144 { 00145 dithered=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*image->GetWidth()*image->GetHeight())); 00146 FloydSteinbergDither::DitherImage(image->GetPointer(),image->GetWidth(), image->GetHeight(),dithered); 00147 } 00148 00149 00150 for (int y=0; y<vPitch_; y++) 00151 { 00152 for (int x=0; x<hPitch_; x++) 00153 { 00154 unsigned int color=image->GetPixel(hOffset_+x,vOffset_+y); 00155 unsigned short color16=RGB32TO16(color); 00156 if (dithered) 00157 { 00158 color16=dithered[(x+hOffset_)+(y+vOffset_)*image->GetWidth()]; 00159 } 00160 *img=color16; 00161 img++; 00162 00163 unsigned char a=((unsigned char)((color&0xff000000)>>24)); 00164 *maskimg=a; 00165 maskimg++; 00166 } 00167 } 00168 00169 if (dithered) 00170 { 00171 Free(dithered); 00172 } 00173 } 00174 00175 00176 //*** GetRLESize *** 00177 00178 int GenerateRLE16::GetRLESize(unsigned short* data,unsigned char* mask) 00179 { 00180 return CreateRLE(data,mask,0); 00181 } 00182 00183 00184 //*** CreateRLE *** 00185 00186 int GenerateRLE16::CreateRLE(unsigned short* source, unsigned char* mask, unsigned char* destination) 00187 { 00188 int result=0; 00189 int size=hPitch_*vPitch_; 00190 while (size>0) 00191 { 00192 unsigned int blank=0; 00193 while (size>0 && *mask<255) 00194 { 00195 blank++; 00196 size--; 00197 source++; 00198 mask++; 00199 } 00200 00201 if (destination) 00202 { 00203 Assert(blank<=0xffff,"RLE run is too long - need code here to break it up"); 00204 *reinterpret_cast<unsigned short*>(destination)=(unsigned short)blank; 00205 destination+=2; 00206 } 00207 result+=2; 00208 00209 unsigned short* nonblankptr=reinterpret_cast<unsigned short*>(destination); 00210 if (destination) 00211 { 00212 destination+=2; 00213 } 00214 result+=2; 00215 00216 unsigned int nonblank=0; 00217 while (size>0 && *mask==255) 00218 { 00219 if (destination) 00220 { 00221 *reinterpret_cast<unsigned short*>(destination)=*source; 00222 destination+=2; 00223 } 00224 result+=2; 00225 nonblank++; 00226 size--; 00227 source++; 00228 mask++; 00229 } 00230 00231 if (destination) 00232 { 00233 Assert(nonblank<=0xffff,"RLE run is too long - need code here to break it up"); 00234 *nonblankptr=(unsigned short)nonblank; 00235 } 00236 } 00237 00238 return result; 00239 } 00240 00241 00242 //*** GetRLESize_Alpha *** 00243 00244 int GenerateRLE16::GetRLESize_Alpha(unsigned short* data,unsigned char* mask) 00245 { 00246 return CreateRLE_Alpha(data,mask,0); 00247 } 00248 00249 00250 //*** CreateRLE_Alpha *** 00251 00252 int GenerateRLE16::CreateRLE_Alpha(unsigned short* source, unsigned char* mask, unsigned char* destination) 00253 { 00254 int result=0; 00255 int size=hPitch_*vPitch_; 00256 while (size>0) 00257 { 00258 unsigned int blank=0; 00259 while (size>0 && (*mask==0 || *mask==255)) 00260 { 00261 blank++; 00262 size--; 00263 source++; 00264 mask++; 00265 } 00266 00267 if (destination) 00268 { 00269 Assert(blank<=0xffff,"RLE run is too long - need code here to break it up"); 00270 *reinterpret_cast<unsigned short*>(destination)=(unsigned short)blank; 00271 destination+=2; 00272 } 00273 result+=2; 00274 00275 unsigned short* nonblankptr=reinterpret_cast<unsigned short*>(destination); 00276 if (destination) 00277 { 00278 destination+=2; 00279 } 00280 result+=2; 00281 unsigned int nonblank=0; 00282 while (size>0 && *mask>0 && *mask<255) 00283 { 00284 if (destination) 00285 { 00286 *reinterpret_cast<unsigned short*>(destination)=*static_cast<unsigned short*>(source); 00287 destination+=2; 00288 *static_cast<unsigned char*>(destination)=*static_cast<unsigned char*>(mask); 00289 destination+=1; 00290 } 00291 result+=3; 00292 nonblank++; 00293 size--; 00294 source++; 00295 mask++; 00296 } 00297 00298 if (destination) 00299 { 00300 Assert(nonblank<=0xffff,"RLE run is too long - need code here to break it up"); 00301 *nonblankptr=(unsigned short)nonblank; 00302 } 00303 } 00304 00305 return result; 00306 } 00307 00308
Reproduction/republishing of any material on this site without permission is strictly prohibited.
