Bitmap_RLE8.cpp
Go to the documentation of this file.00001 //*** Bitmap_RLE8.cpp *** 00002 00003 #include "Bitmap_RLE8.h" 00004 #include "Image.h" 00005 #include "Asset.h" 00006 #include "Bitmap_16bit.h" 00007 #include "Bitmap_16bitAlpha.h" 00008 #include "ColorHelper.h" 00009 #include "GenerateRLE8.h" 00010 #include "BlitterRLE8.h" 00011 #include "CopperRLE8.h" 00012 00013 00014 const char* Pixie_Rle_Header="PIXRLE8B"; 00015 00016 //*** GetType *** 00017 00018 StringId Bitmap_RLE8::GetType() 00019 { 00020 static StringId idBitmap_RLE8("Bitmap_RLE8"); 00021 return idBitmap_RLE8; 00022 } 00023 00024 00025 //*** Constructor *** 00026 00027 Bitmap_RLE8::Bitmap_RLE8(): 00028 usesMask_(0), 00029 xOffset_(0), 00030 yOffset_(0), 00031 activeWidth_(0), 00032 activeHeight_(0), 00033 width_(0), 00034 height_(0), 00035 opaqueSize_(0), 00036 opaqueData_(0), 00037 alphaSize_(0), 00038 alphaData_(0), 00039 colorCount_(0), 00040 palette_(0), 00041 modulatedPalette_(0), 00042 currentPalette_(0) 00043 { 00044 } 00045 00046 00047 //*** Constructor *** 00048 00049 Bitmap_RLE8::Bitmap_RLE8(const Image& image, bool dither): 00050 usesMask_(0), 00051 xOffset_(0), 00052 yOffset_(0), 00053 activeWidth_(0), 00054 activeHeight_(0), 00055 width_(0), 00056 height_(0), 00057 opaqueSize_(0), 00058 opaqueData_(0), 00059 alphaSize_(0), 00060 alphaData_(0), 00061 colorCount_(0), 00062 palette_(0), 00063 modulatedPalette_(0), 00064 currentPalette_(0) 00065 { 00066 GenerateRLE8 generate(image,this,dither); 00067 } 00068 00069 00070 //*** Constructor *** 00071 00072 Bitmap_RLE8::Bitmap_RLE8(const Asset& asset): 00073 usesMask_(0), 00074 xOffset_(0), 00075 yOffset_(0), 00076 activeWidth_(0), 00077 activeHeight_(0), 00078 width_(0), 00079 height_(0), 00080 opaqueSize_(0), 00081 opaqueData_(0), 00082 alphaSize_(0), 00083 alphaData_(0), 00084 colorCount_(0), 00085 palette_(0), 00086 modulatedPalette_(0), 00087 currentPalette_(0) 00088 { 00089 Load(asset); 00090 } 00091 00092 00093 //*** Destructor *** 00094 00095 Bitmap_RLE8::~Bitmap_RLE8() 00096 { 00097 if (opaqueData_) 00098 { 00099 Free(opaqueData_); 00100 } 00101 00102 if (alphaData_) 00103 { 00104 Free(alphaData_); 00105 } 00106 00107 if (palette_) 00108 { 00109 Free(palette_); 00110 } 00111 00112 if (modulatedPalette_) 00113 { 00114 Free(modulatedPalette_); 00115 } 00116 } 00117 00118 00119 //*** GetWidth *** 00120 00121 int Bitmap_RLE8::GetWidth(Transformation transformation) const 00122 { 00123 switch (transformation) 00124 { 00125 case NoTransformation: 00126 case Rotate_180: 00127 case Mirror_X: 00128 case Mirror_Y: 00129 { 00130 return width_; 00131 } break; 00132 00133 case Rotate_90: 00134 case Rotate_270: 00135 { 00136 return height_; 00137 } break; 00138 } 00139 00140 return width_; 00141 } 00142 00143 00144 //*** GetHeight *** 00145 00146 int Bitmap_RLE8::GetHeight(Transformation transformation) const 00147 { 00148 switch (transformation) 00149 { 00150 case NoTransformation: 00151 case Rotate_180: 00152 case Mirror_X: 00153 case Mirror_Y: 00154 { 00155 return height_; 00156 } break; 00157 00158 case Rotate_90: 00159 case Rotate_270: 00160 { 00161 return width_; 00162 } break; 00163 } 00164 00165 return height_; 00166 } 00167 00168 00169 //*** GetColorData *** 00170 00171 unsigned short* Bitmap_RLE8::GetColorData() 00172 { 00173 return 0; 00174 } 00175 00176 00177 //*** GetAlphaData *** 00178 00179 unsigned char* Bitmap_RLE8::GetAlphaData() 00180 { 00181 return 0; 00182 } 00183 00184 00185 //*** Clear *** 00186 00187 void Bitmap_RLE8::Clear() 00188 { 00189 } 00190 00191 00192 //*** Fill *** 00193 00194 void Bitmap_RLE8::Fill(int x1, int y1, int x2, int y2, unsigned short color, unsigned char alpha) 00195 { 00196 } 00197 00198 00199 //*** Fill *** 00200 00201 void Bitmap_RLE8::Fill(unsigned short color, unsigned char alpha) 00202 { 00203 } 00204 00205 00206 00207 //*** SetPixelColor *** 00208 00209 void Bitmap_RLE8::SetPixelColor(int x, int y,unsigned short color, Transformation transformation) 00210 { 00211 } 00212 00213 00214 //*** GetPixelColor *** 00215 00216 unsigned short Bitmap_RLE8::GetPixelColor(int x, int y, Transformation transformation) const 00217 { 00218 if (x>=0 && x<GetWidth(transformation) && y>=0 && y<GetHeight(transformation)) 00219 { 00220 TransformCoordinates(x,y,transformation); 00221 return RLEGetPixelColor(x,y); 00222 } 00223 00224 return 0; 00225 } 00226 00227 00228 //*** SetPixelAlpha *** 00229 00230 void Bitmap_RLE8::SetPixelAlpha(int x, int y,unsigned char alpha, Transformation transformation) 00231 { 00232 } 00233 00234 00235 //*** GetPixelAlpha *** 00236 00237 unsigned char Bitmap_RLE8::GetPixelAlpha(int x, int y, Transformation transformation) const 00238 { 00239 if (x>=0 && x<GetWidth(transformation) && y>=0 && y<GetHeight(transformation)) 00240 { 00241 TransformCoordinates(x,y,transformation); 00242 return RLEGetPixelAlpha(x,y); 00243 } 00244 00245 return 0; 00246 } 00247 00248 00249 //*** BlendPixel *** 00250 00251 void Bitmap_RLE8::BlendPixel(int x, int y,unsigned short color, unsigned char alpha, Transformation transformation) 00252 { 00253 } 00254 00255 00256 //*** Blit *** 00257 00258 void Bitmap_RLE8::Blit(Bitmap& target, int x, int y, unsigned short modulate, unsigned char alpha, Transformation transformation) const 00259 { 00260 Blit(0, 0, width_-1, height_-1, target, x, y, modulate, alpha, transformation); 00261 } 00262 00263 00264 //*** Blit *** 00265 00266 void Bitmap_RLE8::Blit(int x1, int y1, int x2, int y2, Bitmap& target, int x, int y, unsigned short modulate, unsigned char alpha, Transformation transformation) const 00267 { 00268 BlitRLE(x1,y1,x2,y2,static_cast<Bitmap_16bit*>(&target),x,y,modulate,alpha); 00269 } 00270 00271 00272 //*** Copy *** 00273 00274 void Bitmap_RLE8::Copy(Bitmap& target, int x, int y, unsigned short modulate, Transformation transformation) const 00275 { 00276 Copy(0, 0, width_-1, height_-1, target, x, y, modulate, transformation); 00277 } 00278 00279 00280 //*** Copy *** 00281 00282 void Bitmap_RLE8::Copy(int x1, int y1, int x2, int y2, Bitmap& target, int x, int y, unsigned short modulate, Transformation transformation) const 00283 { 00284 BlitRLE(x1,y1,x2,y2,static_cast<Bitmap_16bitAlpha*>(&target),x,y,modulate); 00285 } 00286 00287 00288 //*** ReadFromAsset *** 00289 00290 void Bitmap_RLE8::ReadFromAsset(const Asset* asset) 00291 { 00292 asset->Read(&width_); 00293 asset->Read(&height_); 00294 asset->Read(&activeWidth_); 00295 asset->Read(&activeHeight_); 00296 asset->Read(&colorCount_); 00297 palette_=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*colorCount_)); 00298 asset->Read(palette_,colorCount_); 00299 asset->Read(&usesMask_); 00300 asset->Read(&opaqueSize_); 00301 if (opaqueSize_>0) 00302 { 00303 opaqueData_=static_cast<unsigned char*>(Malloc(opaqueSize_)); 00304 asset->Read(opaqueData_,opaqueSize_); 00305 } 00306 asset->Read(&alphaSize_); 00307 if (alphaSize_>0) 00308 { 00309 alphaData_=static_cast<unsigned char*>(Malloc(alphaSize_)); 00310 asset->Read(alphaData_,alphaSize_); 00311 } 00312 asset->Read(&xOffset_,1); 00313 asset->Read(&yOffset_,1); 00314 } 00315 00316 00317 //*** WriteToAsset *** 00318 00319 void Bitmap_RLE8::WriteToAsset(Asset* asset) const 00320 { 00321 asset->Write(&width_); 00322 asset->Write(&height_); 00323 asset->Write(&activeWidth_); 00324 asset->Write(&activeHeight_); 00325 asset->Write(&colorCount_); 00326 asset->Write(palette_,colorCount_); 00327 asset->Write(&usesMask_); 00328 asset->Write(&opaqueSize_); 00329 if (opaqueSize_>0 && opaqueData_) 00330 { 00331 asset->Write(opaqueData_,opaqueSize_); 00332 } 00333 asset->Write(&alphaSize_); 00334 if (alphaSize_>0 && alphaData_) 00335 { 00336 asset->Write(alphaData_,alphaSize_); 00337 } 00338 asset->Write(&xOffset_); 00339 asset->Write(&yOffset_); 00340 } 00341 00342 00343 //*** BlitRLE *** 00344 00345 void Bitmap_RLE8::BlitRLE(Bitmap_16bit* target,int x, int y,unsigned short modulate, unsigned char alpha) const 00346 { 00347 Blit(0,0,activeWidth_-1,activeHeight_-1,*target,x,y,modulate,alpha); 00348 } 00349 00350 00351 //*** Blit *** 00352 00353 void Bitmap_RLE8::BlitRLE(int x1, int y1, int x2, int y2, Bitmap_16bit* target,int x, int y, unsigned short modulate, unsigned char alpha) const 00354 { 00355 // Check for empty bitmap 00356 if (!opaqueData_ && !alphaData_) 00357 { 00358 return; 00359 } 00360 00361 if (alpha==0) 00362 { 00363 return; 00364 } 00365 00366 00367 int clipX1=x+xOffset_; 00368 int clipY1=y+yOffset_; 00369 int clipX2=x+xOffset_+(x2-x1); 00370 int clipY2=y+yOffset_+(y2-y1); 00371 00372 x-=x1; 00373 y-=y1; 00374 00375 if (clipX1<0) 00376 clipX1=0; 00377 if (clipY1<0) 00378 clipY1=0; 00379 if (clipX2>=target->GetWidth()) 00380 clipX2=target->GetWidth()-1; 00381 if (clipY2>=target->GetHeight()) 00382 clipY2=target->GetHeight()-1; 00383 00384 // Set up palette 00385 currentPalette_=palette_; 00386 if (modulate!=0xffff) 00387 { 00388 if (!modulatedPalette_) 00389 { 00390 modulatedPalette_=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*colorCount_)); 00391 } 00392 for (int i=0; i<colorCount_; i++) 00393 { 00394 int c=palette_[i]; 00395 unsigned int r=(c & 0xf800)>>11; 00396 unsigned int g=(c & 0x7e0)>>5; 00397 unsigned int b=(c & 0x1f); 00398 unsigned int mr=(modulate & 0xf800)>>11; 00399 unsigned int mg=(modulate & 0x7e0)>>5; 00400 unsigned int mb=(modulate & 0x1f); 00401 r*=mr; 00402 g*=mg; 00403 b*=mb; 00404 r>>=5; 00405 g>>=6; 00406 b>>=5; 00407 modulatedPalette_[i]=(unsigned short)((r<<11)|(g<<5)|(b)); 00408 } 00409 currentPalette_=modulatedPalette_; 00410 } 00411 int targetDelta=target->GetWidth()-activeWidth_; 00412 int tx1=x+xOffset_; 00413 int ty1=y+yOffset_; 00414 int tx2=tx1+activeWidth_-1; 00415 int ty2=ty1+activeHeight_-1; 00416 unsigned short* data=&(target->GetColorData())[tx1+ty1*target->GetWidth()]; 00417 00418 // Do we need to clip? 00419 if (tx1>=clipX1 && ty1>=clipY1 && tx2<=clipX2 && ty2<=clipY2) 00420 { 00421 // Render opaque part 00422 if (opaqueData_) 00423 { 00424 if (usesMask_) 00425 { 00426 if (alpha==255) 00427 { 00428 BlitterRLE8::Opaque_Unclipped_Masked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1); 00429 } 00430 else 00431 { 00432 BlitterRLE8::Opaque_Unclipped_Masked_Transparent(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,alpha); 00433 } 00434 } 00435 else 00436 { 00437 if (alpha==255) 00438 { 00439 BlitterRLE8::Opaque_Unclipped_Unmasked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1); 00440 } 00441 else 00442 { 00443 BlitterRLE8::Opaque_Unclipped_Unmasked_Transparent(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,alpha); 00444 } 00445 } 00446 } 00447 00448 // Render alpha part 00449 if (alphaData_) 00450 { 00451 if (alpha==255) 00452 { 00453 BlitterRLE8::Alpha_Unclipped(alphaData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1); 00454 } 00455 else 00456 { 00457 BlitterRLE8::Alpha_Unclipped_Transparent(alphaData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,alpha); 00458 } 00459 } 00460 } 00461 else // Yes, clipping required 00462 { 00463 // Trivial rejection test 00464 if (tx2<clipX1 || ty2<clipY1 || tx1>clipX2 || ty1>clipY2) 00465 return; 00466 00467 // Calculate visible part 00468 int xStart=0; 00469 int yStart=0; 00470 int xEnd=0; 00471 int yEnd=0; 00472 00473 if (tx1<clipX1) 00474 { 00475 xStart=clipX1-tx1; 00476 } 00477 if (ty1<clipY1) 00478 { 00479 yStart=clipY1-ty1; 00480 } 00481 if (tx2>clipX2) 00482 { 00483 xEnd=tx2-clipX2+1; 00484 } 00485 if (ty2>clipY2) 00486 { 00487 yEnd=ty2-clipY2+1; 00488 } 00489 00490 // Render opaque part 00491 if (opaqueData_) 00492 { 00493 if (usesMask_) 00494 { 00495 if (alpha==255) 00496 { 00497 BlitterRLE8::Opaque_Clipped_Masked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd); 00498 } 00499 else 00500 { 00501 BlitterRLE8::Opaque_Clipped_Masked_Transparent(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd,alpha); 00502 } 00503 } 00504 else 00505 { 00506 if (alpha==255) 00507 { 00508 BlitterRLE8::Opaque_Clipped_Unmasked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd); 00509 } 00510 else 00511 { 00512 BlitterRLE8::Opaque_Clipped_Unmasked_Transparent(opaqueData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd,alpha); 00513 } 00514 } 00515 } 00516 00517 // Render alpha part 00518 if (alphaData_) 00519 { 00520 if (alpha==255) 00521 { 00522 BlitterRLE8::Alpha_Clipped(alphaData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd); 00523 } 00524 else 00525 { 00526 BlitterRLE8::Alpha_Clipped_Transparent(alphaData_,activeWidth_,activeHeight_,currentPalette_,data,targetDelta,tx1,ty1,xStart,yStart,xEnd,yEnd,alpha); 00527 } 00528 } 00529 } 00530 } 00531 00532 00533 //*** Blit *** 00534 00535 void Bitmap_RLE8::BlitRLE(Bitmap_16bitAlpha* target,int x, int y, unsigned short modulate) const 00536 { 00537 Blit(0,0,activeWidth_-1,activeHeight_-1,*target,x,y,modulate); 00538 } 00539 00540 00541 //*** Blit *** 00542 00543 void Bitmap_RLE8::BlitRLE(int x1, int y1, int x2, int y2, Bitmap_16bitAlpha* target, int x, int y, unsigned short modulate) const 00544 { 00545 // Check for empty bitmap 00546 if (!opaqueData_ && !alphaData_) 00547 { 00548 return; 00549 } 00550 00551 x-=x1; 00552 y-=y1; 00553 00554 00555 int clipX1=x+xOffset_; 00556 int clipY1=y+yOffset_; 00557 int clipX2=x+xOffset_+(x2-x1); 00558 int clipY2=y+yOffset_+(y2-y1); 00559 00560 00561 if (clipX1<0) 00562 clipX1=0; 00563 if (clipY1<0) 00564 clipY1=0; 00565 if (clipX2>=target->GetWidth()) 00566 clipX2=target->GetWidth()-1; 00567 if (clipY2>=target->GetHeight()) 00568 clipY2=target->GetHeight()-1; 00569 00570 // Set up palette 00571 currentPalette_=palette_; 00572 if (modulate!=0xffff) 00573 { 00574 if (!modulatedPalette_) 00575 { 00576 modulatedPalette_=static_cast<unsigned short*>(Malloc(sizeof(unsigned short)*colorCount_)); 00577 } 00578 for (int i=0; i<colorCount_; i++) 00579 { 00580 int c=palette_[i]; 00581 unsigned int r=(c & 0xf800)>>11; 00582 unsigned int g=(c & 0x7e0)>>5; 00583 unsigned int b=(c & 0x1f); 00584 unsigned int mr=(modulate & 0xf800)>>11; 00585 unsigned int mg=(modulate & 0x7e0)>>5; 00586 unsigned int mb=(modulate & 0x1f); 00587 r*=mr; 00588 g*=mg; 00589 b*=mb; 00590 r>>=5; 00591 g>>=6; 00592 b>>=5; 00593 modulatedPalette_[i]=(unsigned short)((r<<11)|(g<<5)|(b)); 00594 } 00595 currentPalette_=modulatedPalette_; 00596 } 00597 00598 int targetDelta=target->GetWidth()-activeWidth_; 00599 int tx1=x+xOffset_; 00600 int ty1=y+yOffset_; 00601 int tx2=tx1+activeWidth_-1; 00602 int ty2=ty1+activeHeight_-1; 00603 unsigned short* colorData=&(target->GetColorData())[tx1+ty1*target->GetWidth()]; 00604 unsigned char* alphaData=&(target->GetAlphaData())[tx1+ty1*target->GetWidth()]; 00605 00606 // Do we need to clip? 00607 if (tx1>=clipX1 && ty1>=clipY1 && tx2<=clipX2 && ty2<=clipY2) 00608 { 00609 // Render alpha part 00610 if (alphaData_) 00611 { 00612 CopperRLE8::Alpha_Unclipped(alphaData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1); 00613 } 00614 00615 // Render opaque part 00616 if (opaqueData_) 00617 { 00618 if (usesMask_) 00619 { 00620 CopperRLE8::Opaque_Unclipped_Masked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1); 00621 } 00622 else 00623 { 00624 CopperRLE8::Opaque_Unclipped_Unmasked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1); 00625 } 00626 } 00627 00628 } 00629 else // Yes, clipping required 00630 { 00631 // Trivial rejection test 00632 if (tx2<clipX1 || ty2<clipY1 || tx1>clipX2 || ty1>clipY2) 00633 return; 00634 00635 // Calculate visible part 00636 int xStart=0; 00637 int yStart=0; 00638 int xEnd=0; 00639 int yEnd=0; 00640 00641 if (tx1<clipX1) 00642 { 00643 xStart=clipX1-tx1; 00644 } 00645 if (ty1<clipY1) 00646 { 00647 yStart=clipY1-ty1; 00648 } 00649 if (tx2>clipX2) 00650 { 00651 xEnd=tx2-clipX2+1; 00652 } 00653 if (ty2>clipY2) 00654 { 00655 yEnd=ty2-clipY2+1; 00656 } 00657 00658 // Render opaque part 00659 if (opaqueData_) 00660 { 00661 if (usesMask_) 00662 { 00663 CopperRLE8::Opaque_Clipped_Masked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1, xStart, yStart, xEnd, yEnd); 00664 } 00665 else 00666 { 00667 CopperRLE8::Opaque_Clipped_Unmasked(opaqueData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1, xStart, yStart, xEnd, yEnd); 00668 } 00669 } 00670 00671 // Render alpha part 00672 if (alphaData_) 00673 { 00674 CopperRLE8::Alpha_Clipped(alphaData_,activeWidth_,activeHeight_,currentPalette_,colorData, alphaData, targetDelta, tx1, ty1, xStart, yStart, xEnd, yEnd); 00675 } 00676 } 00677 } 00678 00679 00680 //*** IgnoreOpaque *** 00681 00682 void IgnoreOpaque(int len, unsigned char** source) 00683 { 00684 unsigned char* dataRLE=*source; 00685 if (len&0x80) 00686 { 00687 len&=0x7f; 00688 dataRLE+=len; 00689 } 00690 else 00691 { 00692 ++dataRLE; 00693 } 00694 *source=dataRLE; 00695 } 00696 00697 00698 //*** IgnoreAlpha *** 00699 00700 void IgnoreAlpha(int len, unsigned char** source) 00701 { 00702 unsigned char* dataRLE=*source; 00703 if (len&0x80) 00704 { 00705 len&=0x7f; 00706 dataRLE+=len*2; 00707 } 00708 else 00709 { 00710 dataRLE+=2; 00711 } 00712 *source=dataRLE; 00713 } 00714 00715 00716 //*** RLEGetPixelAlpha *** 00717 00718 unsigned char Bitmap_RLE8::RLEGetPixelAlpha(int x, int y) const 00719 { 00720 if (x<xOffset_ || x>=xOffset_+activeWidth_ || y<yOffset_ || y>=yOffset_+activeHeight_) 00721 { 00722 return 0; 00723 } 00724 00725 // First, test opaque part 00726 unsigned char* dataRLE=opaqueData_; 00727 00728 // Skip clipped rows 00729 for (int i=0; i<y-yOffset_; i++) 00730 { 00731 int xi=0; 00732 while (xi<activeWidth_) 00733 { 00734 // Get run length 00735 int len=*dataRLE; 00736 ++dataRLE; 00737 00738 IgnoreOpaque(len,&dataRLE); 00739 len&=0x7f; 00740 00741 xi+=len; 00742 } 00743 } 00744 00745 int xi=0; 00746 while (xi<=x-xOffset_) 00747 { 00748 00749 // Get run length 00750 int len=*dataRLE; 00751 ++dataRLE; 00752 if (len&0x80) 00753 { 00754 len&=0x7f; 00755 // Unique values 00756 for (int i=0; i<len; ++i) 00757 { 00758 int c=*dataRLE; 00759 if (xi==x-xOffset_) 00760 { 00761 if (c==255) 00762 return 0; 00763 return 255; 00764 } 00765 ++dataRLE; 00766 xi++; 00767 } 00768 } 00769 else 00770 { 00771 int c=*dataRLE; 00772 if (xi==x-xOffset_ || (xi+len)>=x-xOffset_) 00773 { 00774 if (c==255) 00775 return 0; 00776 return 255; 00777 } 00778 00779 ++dataRLE; 00780 xi+=len; 00781 } 00782 } 00783 00784 00785 // Test alpha part 00786 dataRLE=alphaData_; 00787 00788 // Skip clipped rows 00789 for (int i=0; i<y-yOffset_; i++) 00790 { 00791 int xi=0; 00792 while (xi<activeWidth_) 00793 { 00794 // Get run length 00795 int len=*dataRLE; 00796 ++dataRLE; 00797 00798 IgnoreAlpha(len,&dataRLE); 00799 len&=0x7f; 00800 00801 xi+=len; 00802 } 00803 } 00804 00805 xi=0; 00806 while (xi<=x-xOffset_) 00807 { 00808 00809 // Get run length 00810 int len=*dataRLE; 00811 ++dataRLE; 00812 if (len&0x80) 00813 { 00814 len&=0x7f; 00815 // Unique values 00816 for (int i=0; i<len; ++i) 00817 { 00818 int alpha=*dataRLE; 00819 if (xi==x-xOffset_) 00820 return (unsigned char)alpha; 00821 ++dataRLE; 00822 ++dataRLE; 00823 xi++; 00824 } 00825 } 00826 else 00827 { 00828 int alpha=*dataRLE; 00829 if (xi==x-xOffset_ || (xi+len)>=x-xOffset_) 00830 return (unsigned char)alpha; 00831 00832 ++dataRLE; 00833 ++dataRLE; 00834 xi+=len; 00835 } 00836 } 00837 return 0; 00838 } 00839 00840 00841 //*** RLEGetPixelColor *** 00842 00843 unsigned short Bitmap_RLE8::RLEGetPixelColor(int x, int y) const 00844 { 00845 return 0; 00846 } 00847 00848 00849 00850 //*** Save *** 00851 00852 void Bitmap_RLE8::Save(Asset& asset) const 00853 { 00854 if (asset.Create()) 00855 { 00856 asset.Write(Pixie_Rle_Header,StrLen(Pixie_Rle_Header)); 00857 int version=0; 00858 asset.Write(&version); 00859 int celCount=1; 00860 asset.Write(&celCount); 00861 WriteToAsset(&asset); 00862 asset.Close(); 00863 } 00864 } 00865 00866 00867 //*** Load *** 00868 00869 void Bitmap_RLE8::Load(const Asset& asset) 00870 { 00871 if (asset.Open()) 00872 { 00873 char header[8]; 00874 asset.Read(header,8); 00875 00876 if (StrNCmp(header,"PIXRLE8B",8)==0) 00877 { 00878 int version=0; 00879 asset.Read(&version); 00880 if (version==0) 00881 { 00882 int celCount=0; 00883 asset.Read(&celCount); 00884 if (celCount>=1) 00885 { 00886 ReadFromAsset(&asset); 00887 } 00888 } 00889 } 00890 00891 else if (StrNCmp(header,"PIXIE_RL",8)==0) 00892 { 00893 char c; 00894 asset.Read(&c); 00895 int version=0; 00896 asset.Read(&version); 00897 if (version==0) 00898 { 00899 int celCount=0; 00900 asset.Read(&celCount); 00901 if (celCount>=1) 00902 { 00903 ReadFromAsset(&asset); 00904 } 00905 } 00906 } 00907 else 00908 { 00909 Assert(false,"Invalid RLE header"); 00910 } 00911 } 00912 // Report missing file 00913 #ifdef _DEBUG 00914 else 00915 { 00916 const char* filename=asset.GetFilename().GetString(); 00917 if (filename) 00918 { 00919 char errorMessage[1024]; 00920 SNPrintF(errorMessage,1024,"File not found: %s",filename); 00921 Assert(false,errorMessage); 00922 } 00923 else 00924 { 00925 Assert(false,"An asset could not be accessed."); 00926 } 00927 } 00928 #endif 00929 } 00930 00931 00932 //*** GetX1 *** 00933 00934 int Bitmap_RLE8::GetX1() const 00935 { 00936 return xOffset_; 00937 } 00938 00939 00940 //*** GetY1 *** 00941 00942 int Bitmap_RLE8::GetY1() const 00943 { 00944 return yOffset_; 00945 } 00946 00947 00948 //*** GetX2 *** 00949 00950 int Bitmap_RLE8::GetX2() const 00951 { 00952 return xOffset_+activeWidth_; 00953 } 00954 00955 00956 //*** GetY2 *** 00957 00958 int Bitmap_RLE8::GetY2() const 00959 { 00960 return yOffset_+activeHeight_; 00961 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
