1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicstools/gdi_tools/bmconv/PBMCOMP.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1271 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "BMCONV.H"
1.20 +#include <stdlib.h>
1.21 +#include <ctype.h>
1.22 +#include <sys/stat.h>
1.23 +
1.24 +extern TRgb* color256Palette;
1.25 +extern char* color256InversePalette;
1.26 +
1.27 +static inline bool CanCopy16bppData(const char* aDest, const char* aDestEnd, int aDataSize)
1.28 + {
1.29 + const char* aDestNew = aDest + (aDataSize / 128) * (256 + 1) + //(2 * 128) bytes data + 1 leading byte
1.30 + (aDataSize % 128 ? (aDataSize % 128) * 2 + 1 : 0);
1.31 + return aDestNew <= aDestEnd;
1.32 + }
1.33 +
1.34 +static inline bool CanWrite16bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
1.35 + {
1.36 + const char* aDestNew = aDest + (aDataSize / 128) * (2 + 1) + //2 bytes data + 1 leading byte
1.37 + (aDataSize % 128 ? 2 + 1 : 0);
1.38 + return aDestNew <= aDestEnd;
1.39 + }
1.40 +
1.41 +static inline bool CanCopy8bppData(const char* aDest, const char* aDestEnd, int aDataSize)
1.42 + {
1.43 + const char* aDestNew = aDest + (aDataSize / 128) * (128 + 1) + //128 bytes data + 1 leading byte
1.44 + (aDataSize % 128 ? (aDataSize % 128) + 1 : 0);
1.45 + return aDestNew <= aDestEnd;
1.46 + }
1.47 +
1.48 +static inline bool CanWrite8bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
1.49 + {
1.50 + const char* aDestNew = aDest + (aDataSize / 128) * (1 + 1) + //1 byte data + 1 leading byte
1.51 + (aDataSize % 128 ? 1 + 1 : 0);
1.52 + return aDestNew <= aDestEnd;
1.53 + }
1.54 +
1.55 +static inline bool CanCopy24bppData(const char* aDest, const char* aDestEnd, int aDataSize)
1.56 + {
1.57 + const char* aDestNew = aDest + (aDataSize / 128) * (384 + 1) + //(128 * 3) bytes data + 1 leading byte
1.58 + (aDataSize % 128 ? (aDataSize % 128) * 3 + 1 : 0);
1.59 + return aDestNew <= aDestEnd;
1.60 + }
1.61 +
1.62 +static inline bool CanWrite24bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
1.63 + {
1.64 + const char* aDestNew = aDest + (aDataSize / 128) * (3 + 1) + //3 bytes data + 1 leading byte
1.65 + (aDataSize % 128 ? 3 + 1 : 0);
1.66 + return aDestNew <= aDestEnd;
1.67 + }
1.68 +
1.69 +static inline bool CanCopy32bppData(const char* aDest, const char* aDestEnd, int aDataSize)
1.70 + {
1.71 + const char* aDestNew = aDest + (aDataSize / 128) * (512 + 1) + //(128 * 4) bytes data + 1 leading byte
1.72 + (aDataSize % 128 ? (aDataSize % 128) * 4 + 1 : 0);
1.73 + return aDestNew <= aDestEnd;
1.74 + }
1.75 +
1.76 +static inline bool CanWrite32bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
1.77 + {
1.78 + const char* aDestNew = aDest + (aDataSize / 128) * (4 + 1) + //4 bytes data + 1 leading byte
1.79 + (aDataSize % 128 ? 4 + 1 : 0);
1.80 + return aDestNew <= aDestEnd;
1.81 + }
1.82 +
1.83 +BitmapCompiler::BitmapCompiler(char* aSourcefilenames[],int aNumSources):
1.84 + iSourcefilenames(aSourcefilenames),
1.85 + iPbmSources(NULL),
1.86 + iNumSources(aNumSources)
1.87 + {}
1.88 +
1.89 +BitmapCompiler::~BitmapCompiler()
1.90 + {
1.91 + iDestFile.close();
1.92 + if(iPbmSources)
1.93 + for(int count=0;count<iNumSources;count++)
1.94 + delete iPbmSources[count];
1.95 + delete [] iPbmSources;
1.96 + iPbmSources = NULL;
1.97 + }
1.98 +
1.99 +int BitmapCompiler::Compile(TStoreType aSt,int aCompress,char* aDestfilename,char* aHeaderFilename,char* aPaletteFilename)
1.100 + {
1.101 + int ret = LoadPalette(aPaletteFilename);
1.102 + if (ret)
1.103 + return ret;
1.104 +
1.105 + iDestFile.open(aDestfilename, ios::out | ios::binary);
1.106 + if(iDestFile.is_open()==0)
1.107 + return DestFile;
1.108 + if (iNumSources < 1)
1.109 + return SourceFile;
1.110 +
1.111 + if (iNumSources==1 && ((iSourcefilenames[0][0]==OPTCHAR || iSourcefilenames[0][0]==ALTERNATE_OPTCHAR)) && iSourcefilenames[0][1]=='m')
1.112 + {
1.113 + // Source is an existing MBM file, presumably because we want to convert
1.114 + // a filestore into a ROM image.
1.115 + if (aHeaderFilename)
1.116 + {
1.117 + cout << "Header file generation is not permitted with /m or -m\n";
1.118 + aHeaderFilename = NULL;
1.119 + }
1.120 + iSourcefilenames[0]+=2;
1.121 + EpocLoader pl;
1.122 + int romFormat;
1.123 + ret = pl.EpocBitmapCount(iSourcefilenames[0], iNumSources, romFormat);
1.124 + if (!ret)
1.125 + ret = LoadPbmFile(iSourcefilenames[0]);
1.126 + }
1.127 + else
1.128 + {
1.129 + // Read the usual list of [OPT]bmp_n source bitmaps.
1.130 + ret = LoadSourcefiles();
1.131 + }
1.132 + if (ret)
1.133 + return ret;
1.134 +
1.135 + ret = CreateHeader(aHeaderFilename);
1.136 + if (ret)
1.137 + return ret;
1.138 +
1.139 + if (aSt == ERomStore || aSt == ECompressedRomStore)
1.140 + ret = RomImage(aSt == ECompressedRomStore);
1.141 + else
1.142 + ret = FileImage(aCompress);
1.143 + return ret;
1.144 + };
1.145 +
1.146 +int BitmapCompiler::AllocatePbmSourcesArray()
1.147 + {
1.148 + iPbmSources = new SEpocBitmapHeader*[iNumSources];
1.149 + if(iPbmSources == NULL)
1.150 + return NoMemory;
1.151 +
1.152 + memset(iPbmSources,0xff,sizeof(SEpocBitmapHeader*)*iNumSources);
1.153 + int count;
1.154 + for(count=0;count<iNumSources;count++)
1.155 + iPbmSources[count]=NULL;
1.156 + return NoError;
1.157 + }
1.158 +
1.159 +int BitmapCompiler::LoadSourcefiles()
1.160 + {
1.161 + int ret = AllocatePbmSourcesArray();
1.162 + if (ret)
1.163 + return ret;
1.164 + for(int count=0;count<iNumSources;count++)
1.165 + {
1.166 + bool useAlpha = false;
1.167 + int bpp = 2;
1.168 + TBitmapColor color = EMonochromeBitmap;
1.169 + BitmapLoader bmpload;
1.170 + if(iSourcefilenames[count][0]==OPTCHAR || iSourcefilenames[count][0]==ALTERNATE_OPTCHAR)
1.171 + {
1.172 + iSourcefilenames[count]++;
1.173 + if(iSourcefilenames[count][0]=='c')
1.174 + {
1.175 + color = EColorBitmap;
1.176 + iSourcefilenames[count]++;
1.177 + }
1.178 + bpp=iSourcefilenames[count][0]-'0';
1.179 + iSourcefilenames[count]++;
1.180 + int next=iSourcefilenames[count][0]-'0';
1.181 + if(next==2 || next==6 || next==4)
1.182 + {
1.183 + bpp=bpp*10+next;
1.184 + iSourcefilenames[count]++;
1.185 + }
1.186 + if(iSourcefilenames[count][0]=='a')
1.187 + {
1.188 + useAlpha = true;
1.189 + iSourcefilenames[count]++;
1.190 + if (color!=EColorBitmap || bpp!=32)
1.191 + return Bpp;
1.192 + }
1.193 + if (color == EColorBitmap && bpp!=4 && bpp!=8 && bpp!=12 && bpp!=16 && bpp!=24 && bpp!=32)
1.194 + return Bpp;
1.195 + if (color == EMonochromeBitmap && bpp!=1 && bpp!=2 && bpp!=4 && bpp!=8)
1.196 + return Bpp;
1.197 + }
1.198 + if (color == EColorBitmap && useAlpha)
1.199 + color = EColorBitmapAlpha;
1.200 + ret = bmpload.LoadBitmap(iSourcefilenames[count],bpp,color,iPbmSources[count]);
1.201 + if (ret)
1.202 + return ret;
1.203 + }
1.204 + return NoError;
1.205 + }
1.206 +
1.207 +int BitmapCompiler::LoadPbmFile(char* aPbmFilename)
1.208 + {
1.209 + int ret = AllocatePbmSourcesArray();
1.210 + if (ret)
1.211 + return ret;
1.212 + for(int count=0;count<iNumSources;count++)
1.213 + {
1.214 + EpocLoader pl;
1.215 + ret = pl.LoadEpocBitmap(aPbmFilename,count);
1.216 + if (!ret)
1.217 + ret = pl.DupBitmap(iPbmSources[count]);
1.218 + if (ret)
1.219 + return ret;
1.220 + }
1.221 + return NoError;
1.222 + }
1.223 +
1.224 +int BitmapCompiler::RomImage(bool aCompress)
1.225 + {
1.226 + int count=0;
1.227 +
1.228 + if (aCompress)
1.229 + {
1.230 + for(; count<iNumSources; count++)
1.231 + {
1.232 + int ret = CompressBitmap(iPbmSources[count]);
1.233 + if (ret)
1.234 + return ret;
1.235 + }
1.236 + }
1.237 +
1.238 + int ret = WriteRomheader();
1.239 + if (ret)
1.240 + return ret;
1.241 +
1.242 + for(count=0;count<iNumSources;count++)
1.243 + {
1.244 + ret = WriteRombitmap(iPbmSources[count]);
1.245 + if (ret)
1.246 + return ret;
1.247 + }
1.248 + return NoError;
1.249 + }
1.250 +
1.251 +int BitmapCompiler::FileImage(int aCompress)
1.252 + {
1.253 + int count = 0;
1.254 + if(aCompress)
1.255 + {
1.256 + for(;count<iNumSources;count++)
1.257 + {
1.258 + int ret = CompressBitmap(iPbmSources[count]);
1.259 + if(ret)
1.260 + return ret;
1.261 + }
1.262 + }
1.263 + int ret = WriteFileheader();
1.264 + if (ret)
1.265 + return ret;
1.266 + for (count=0;count<iNumSources;count++)
1.267 + {
1.268 + ret = WriteFilebitmap(iPbmSources[count]);
1.269 + if (ret)
1.270 + return ret;
1.271 + }
1.272 + ret = WriteHeadStream();
1.273 + return ret;
1.274 + }
1.275 +
1.276 +int BitmapCompiler::WriteRomheader()
1.277 + {
1.278 + iDestFile.write((char*)&KMultiBitmapRomImageUid,4);
1.279 + iDestFile.write((char*)&iNumSources,4);
1.280 + int byteswritten=8+(iNumSources*4);
1.281 + for (int count=0;count<iNumSources;count++)
1.282 + {
1.283 + iDestFile.write((char*)&byteswritten,4);
1.284 + byteswritten+=(((iPbmSources[count]->iBitmapSize)+3)/4*4)-sizeof(SEpocBitmapHeader)+sizeof(Bitmap);
1.285 + }
1.286 + return NoError;
1.287 + }
1.288 +
1.289 +int BitmapCompiler::WriteRombitmap(SEpocBitmapHeader* aPbm)
1.290 + {
1.291 + if (aPbm->iPaletteEntries != 0)
1.292 + return PaletteSupportNotImplemented;
1.293 +
1.294 + int bitmapsize = aPbm->iBitmapSize-sizeof(SEpocBitmapHeader)+sizeof(Bitmap);
1.295 + bitmapsize = ((bitmapsize+3)/4)*4;
1.296 +
1.297 + char* buffer = new char[bitmapsize];
1.298 + if (buffer == NULL)
1.299 + return NoMemory;
1.300 + memset(buffer,0xff,bitmapsize);
1.301 +
1.302 + Bitmap* bmp = (Bitmap*)buffer;
1.303 + bmp->iUid=KCBitwiseBitmapUid;
1.304 + TBitmapColor color = aPbm->iColor;
1.305 +
1.306 + switch(aPbm->iBitsPerPixel)
1.307 + { // for corresponding enums, see TDisplayMode in <gdi.h>
1.308 + case 1:
1.309 + bmp->iDispMode=1;
1.310 + break;
1.311 + case 2:
1.312 + bmp->iDispMode=2;
1.313 + break;
1.314 + case 4:
1.315 + if (color == EMonochromeBitmap)
1.316 + bmp->iDispMode=3;
1.317 + else
1.318 + bmp->iDispMode=5;
1.319 + break;
1.320 + case 8:
1.321 + if (color == EMonochromeBitmap)
1.322 + bmp->iDispMode=4;
1.323 + else
1.324 + bmp->iDispMode=6;
1.325 + break;
1.326 + case 12:
1.327 + bmp->iDispMode=10;
1.328 + break;
1.329 + case 16:
1.330 + bmp->iDispMode=7;
1.331 + break;
1.332 + case 24:
1.333 + bmp->iDispMode=8;
1.334 + break;
1.335 + case 32:
1.336 + if (color == EColorBitmapAlpha)
1.337 + bmp->iDispMode=12; // Color16MA
1.338 + else
1.339 + bmp->iDispMode=11; // Color16MU
1.340 + break;
1.341 + default:
1.342 + delete [] buffer;
1.343 + return SourceFile;
1.344 + }
1.345 +
1.346 + bmp->iHeap = NULL;
1.347 + bmp->iPile = NULL;
1.348 + bmp->iHeader = *aPbm;
1.349 + bmp->iByteWidth = BitmapUtils::ByteWidth(bmp->iHeader.iWidthInPixels,bmp->iHeader.iBitsPerPixel);
1.350 + bmp->iDataOffset = sizeof(Bitmap);
1.351 +
1.352 + CopyTail(buffer + sizeof(Bitmap), aPbm, aPbm->iBitmapSize, sizeof(SEpocBitmapHeader));
1.353 + iDestFile.write(buffer,bitmapsize);
1.354 +
1.355 + delete [] buffer;
1.356 +
1.357 + return NoError;
1.358 + }
1.359 +
1.360 +int BitmapCompiler::WriteFileheader()
1.361 + {
1.362 + int zero=0;
1.363 + iDestFile.write((char*)&KWriteOnceFileStoreUid,4);
1.364 + iDestFile.write((char*)&KMultiBitmapFileImageUid,4);
1.365 + iDestFile.write((char*)&zero,4);
1.366 + iDestFile.write((char*)&KMultiBitmapFileImageChecksum,4);
1.367 + int byteswritten=16;
1.368 + for(int count=0;count<iNumSources;count++)
1.369 + {
1.370 + byteswritten+=iPbmSources[count]->iBitmapSize;
1.371 + }
1.372 + byteswritten+=4;
1.373 + iDestFile.write((char*)&byteswritten,4);
1.374 + return NoError;
1.375 + }
1.376 +
1.377 +int BitmapCompiler::WriteHeadStream()
1.378 + {
1.379 + iDestFile.write((char*)&iNumSources,4);
1.380 + int byteswritten=20;
1.381 + for(int count=0;count<iNumSources;count++)
1.382 + {
1.383 + iDestFile.write((char*)&byteswritten,4);
1.384 + byteswritten+=iPbmSources[count]->iBitmapSize;
1.385 + }
1.386 + return NoError;
1.387 + }
1.388 +
1.389 +int BitmapCompiler::WriteFilebitmap(SEpocBitmapHeader* aPbm)
1.390 + {
1.391 + if (aPbm->iPaletteEntries != 0)
1.392 + return PaletteSupportNotImplemented;
1.393 +
1.394 + int dataSize = aPbm->iBitmapSize - sizeof(SEpocBitmapHeader);
1.395 +
1.396 + iDestFile.write((char*)(aPbm),sizeof(SEpocBitmapHeader));
1.397 + // WritePalette()
1.398 + iDestFile.write(((char*)(aPbm)) + sizeof(SEpocBitmapHeader),dataSize);
1.399 +
1.400 + return NoError;
1.401 + }
1.402 +
1.403 +void BitmapCompiler::WritePalette()
1.404 + {
1.405 + for (int index = 0; index < 256; index++)
1.406 + {
1.407 + iDestFile.write((char*)(&iPalette[index]),3);
1.408 + }
1.409 + }
1.410 +
1.411 +int BitmapCompiler::LoadPalette(char* aPaletteFilename)
1.412 + {
1.413 + if (!aPaletteFilename)
1.414 + {
1.415 + iDefaultPalette = 1;
1.416 + return NoError;
1.417 + }
1.418 +
1.419 + iDefaultPalette = 0;
1.420 + color256Palette = iPalette;
1.421 + color256InversePalette = iInversePalette;
1.422 +
1.423 + struct stat fileinfo;
1.424 + if (stat(aPaletteFilename,&fileinfo)==-1)
1.425 + return CommandFile;
1.426 +
1.427 + int filesize = fileinfo.st_size;
1.428 + if (filesize == 0)
1.429 + return PaletteFile;
1.430 +
1.431 +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
1.432 + fstream paletteFile(aPaletteFilename, ios::in | ios::binary);
1.433 +#else
1.434 + fstream paletteFile(aPaletteFilename, ios::in | ios::binary | ios::nocreate);
1.435 +#endif
1.436 +
1.437 + if(!paletteFile.is_open())
1.438 + return PaletteFile;
1.439 +
1.440 + char* paletteData = new char[filesize];
1.441 + if (!paletteData)
1.442 + return NoMemory;
1.443 +
1.444 + memset(paletteData,0,filesize);
1.445 + paletteFile.read(paletteData,filesize);
1.446 + paletteFile.close();
1.447 +
1.448 + char* dataPtr = (char*)paletteData;
1.449 + char* dataPtrLimit = dataPtr + filesize;
1.450 +
1.451 + for (int index = 0; index < 256; index++)
1.452 + {
1.453 + char hexBuf[10];
1.454 + int ret = ReadHexString(hexBuf,dataPtr,dataPtrLimit);
1.455 + if (ret)
1.456 + {
1.457 + delete paletteData;
1.458 + return ret;
1.459 + }
1.460 +
1.461 + int red = HexToInt(hexBuf[8],hexBuf[9]);
1.462 + int green = HexToInt(hexBuf[6],hexBuf[7]);
1.463 + int blue = HexToInt(hexBuf[4],hexBuf[5]);
1.464 +
1.465 + iPalette[index] = TRgb(red,green,blue);
1.466 + }
1.467 +
1.468 + delete paletteData;
1.469 + CalculateInversePalette();
1.470 + return NoError;
1.471 + }
1.472 +
1.473 +void BitmapCompiler::CalculateInversePalette()
1.474 + {
1.475 + for (int index = 0; index < 4096; index++)
1.476 + {
1.477 + TRgb color = TRgb((index & 0x00f) * 17,((index & 0x0f0) >> 4) * 17,((index & 0xf00) >> 8) * 17);
1.478 +
1.479 + int nearest = 0;
1.480 + int distance = iPalette[0].Difference(color);
1.481 +
1.482 + for (int paletteIndex = 0; paletteIndex < 256; paletteIndex++)
1.483 + {
1.484 + TRgb paletteColor = iPalette[paletteIndex];
1.485 +
1.486 + if (paletteColor == color)
1.487 + {
1.488 + nearest = paletteIndex;
1.489 + break;
1.490 + }
1.491 +
1.492 + int paletteDistance = paletteColor.Difference(color);
1.493 + if (paletteDistance < distance)
1.494 + {
1.495 + nearest = paletteIndex;
1.496 + distance = paletteDistance;
1.497 + }
1.498 + }
1.499 +
1.500 + iInversePalette[index] = (char)nearest;
1.501 + TRgb palColor = iPalette[nearest];
1.502 + color = palColor;
1.503 + }
1.504 + }
1.505 +
1.506 +int BitmapCompiler::CreateHeader(char* aHeaderFilename)
1.507 + {
1.508 + if (!aHeaderFilename)
1.509 + return NoError;
1.510 +
1.511 + fstream hf(aHeaderFilename,ios::out);
1.512 + if(!hf.is_open())
1.513 + return DestFile;
1.514 +
1.515 + char* basename = strrchr(aHeaderFilename,'\\');
1.516 + if (basename==0)
1.517 + basename = aHeaderFilename;
1.518 + else
1.519 + basename++; // skip directory separator
1.520 +
1.521 + char unadornedFile[256];
1.522 + strcpy(unadornedFile, UnadornedName(aHeaderFilename));
1.523 +
1.524 + hf << "// " << basename << "\n";
1.525 + hf << "// Generated by BitmapCompiler\n";
1.526 + hf << "// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).\n";
1.527 + hf << "//\n\n";
1.528 + hf << "enum TMbm" << unadornedFile << "\n";
1.529 + hf << "\t{\n";
1.530 +
1.531 + for (int count=0;count<iNumSources;count++)
1.532 + {
1.533 + hf << "\tEMbm" << unadornedFile << UnadornedName(iSourcefilenames[count]);
1.534 + if(count<iNumSources-1)
1.535 + hf << ',';
1.536 + hf << '\n';
1.537 + }
1.538 + hf << "\t};\n";
1.539 + hf.close();
1.540 + return NoError;
1.541 + }
1.542 +
1.543 +char* BitmapCompiler::UnadornedName(char* aName)
1.544 + {
1.545 + int len = strlen(aName);
1.546 +
1.547 + char* foundDir = strrchr(aName,'\\');
1.548 + char* foundUrl = strrchr(aName,'/');
1.549 + char* foundExt = strrchr(aName,'.');
1.550 +
1.551 + char* foundPath = (foundDir > foundUrl) ? foundDir : foundUrl;
1.552 + char* firstchar = (foundPath > 0) ? foundPath + 1 : aName;
1.553 + char* lastchar = (foundExt > firstchar) ? foundExt : aName+len;
1.554 +
1.555 + static char result[256];
1.556 + if (lastchar-firstchar > 255)
1.557 + {
1.558 + strcpy(result,"NameTooLong");
1.559 + return result;
1.560 + }
1.561 + int i=0;
1.562 + result[0] = (char)toupper(*firstchar);
1.563 + firstchar+=1;
1.564 + for (i=1; firstchar<lastchar; i++,firstchar++)
1.565 + {
1.566 + result[i] = (char)tolower(*firstchar);
1.567 + }
1.568 + result[i] = '\0';
1.569 + return result;
1.570 + }
1.571 +
1.572 +int BitmapCompiler::CompressBitmap(SEpocBitmapHeader*& aPbm)
1.573 + {
1.574 + int originalsize = aPbm->iBitmapSize-sizeof(SEpocBitmapHeader);
1.575 + char* newbits=new char[originalsize+sizeof(SEpocBitmapHeader)];
1.576 + if(!newbits)
1.577 + return NoMemory;
1.578 +
1.579 + memset(newbits,0xff,sizeof(SEpocBitmapHeader)+originalsize);
1.580 + memcpy(newbits,aPbm,sizeof(SEpocBitmapHeader));
1.581 + char* newbitsptr=newbits+sizeof(SEpocBitmapHeader);
1.582 + char* oldbits=((char*)(aPbm))+sizeof(SEpocBitmapHeader);
1.583 +
1.584 + TBitmapfileCompression compression = ENoBitmapCompression;
1.585 + int ret = NoCompression;
1.586 +
1.587 + if (aPbm->iBitsPerPixel <= 8)
1.588 + {
1.589 + compression = EByteRLECompression;
1.590 + ret = CompressByteData(newbitsptr,oldbits,originalsize);
1.591 + }
1.592 + else if (aPbm->iBitsPerPixel == 12)
1.593 + {
1.594 + compression = ETwelveBitRLECompression;
1.595 + ret = CompressTwelveBitData(newbitsptr,oldbits,originalsize);
1.596 + }
1.597 + else if (aPbm->iBitsPerPixel == 16)
1.598 + {
1.599 + compression = ESixteenBitRLECompression;
1.600 + ret = CompressSixteenBitData(newbitsptr,oldbits,originalsize);
1.601 + }
1.602 + else if (aPbm->iBitsPerPixel == 24)
1.603 + {
1.604 + compression = ETwentyFourBitRLECompression;
1.605 + ret = CompressTwentyFourBitData(newbitsptr,oldbits,originalsize);
1.606 + }
1.607 + else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmap))
1.608 + {
1.609 + compression = EThirtyTwoUBitRLECompression;
1.610 + ret = CompressThirtyTwoUBitData(newbitsptr,oldbits,originalsize);
1.611 + }
1.612 + else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmapAlpha))
1.613 + {
1.614 + compression = EThirtyTwoABitRLECompression;
1.615 + ret = CompressThirtyTwoABitData(newbitsptr,oldbits,originalsize);
1.616 + }
1.617 +
1.618 + if(ret)
1.619 + {
1.620 + delete [] newbits;
1.621 + if(ret>0)
1.622 + return ret;
1.623 + return NoError;
1.624 + }
1.625 +
1.626 + delete aPbm;
1.627 + aPbm = (SEpocBitmapHeader*)newbits;
1.628 + aPbm->iBitmapSize = newbitsptr-(newbits+sizeof(SEpocBitmapHeader))+sizeof(SEpocBitmapHeader);
1.629 + aPbm->iCompression = compression;
1.630 + return NoError;
1.631 + }
1.632 +
1.633 +int BitmapCompiler::CompressByteData(char*& aDest,char* aSrce,int aSize)
1.634 + {
1.635 + const char* destEnd = aDest + aSize;
1.636 + char* bytepointer=aSrce;
1.637 + char* limitpointer=bytepointer+aSize;
1.638 + int margin = (aSize>>6);
1.639 + char* limitmargin = limitpointer - ((margin > 4) ? margin : 4);
1.640 + char* cutoffpointer=aDest+(aSize>>1)+(aSize>>2);
1.641 + int ret=NoError;
1.642 + char* oldbytepointer=NULL;
1.643 + while(bytepointer<limitmargin)
1.644 + {
1.645 + char value=*bytepointer;
1.646 + if(*(bytepointer+1)==value && *(bytepointer+2)==value)
1.647 + {
1.648 + oldbytepointer=bytepointer;
1.649 + bytepointer+=3;
1.650 + while ( ( bytepointer < limitmargin ) && ( *bytepointer == value ) )
1.651 + bytepointer++;
1.652 + ret = WriteCompressedByteValues(aDest,value,bytepointer-oldbytepointer, destEnd);
1.653 + if(ret) return ret;
1.654 + }
1.655 + else
1.656 + {
1.657 + oldbytepointer=bytepointer;
1.658 + while((bytepointer<limitmargin) && (*(bytepointer+1)!=value || *(bytepointer+2)!=value))
1.659 + {
1.660 + bytepointer++;
1.661 + value=*bytepointer;
1.662 + }
1.663 + ret = WriteCompressedByteData(aDest,oldbytepointer,bytepointer-oldbytepointer, destEnd);
1.664 + if(ret) return ret;
1.665 + }
1.666 + if(aDest>cutoffpointer)
1.667 + return NoCompression;
1.668 + }
1.669 +
1.670 + int remaining = limitpointer-bytepointer;
1.671 + if(remaining > 0)
1.672 + {
1.673 + if (aDest + remaining > cutoffpointer)
1.674 + return NoCompression;
1.675 + ret=WriteCompressedByteData(aDest,bytepointer,remaining, destEnd);
1.676 + if(ret) return ret;
1.677 + }
1.678 + return NoError;
1.679 + }
1.680 +
1.681 +int BitmapCompiler::WriteCompressedByteData(char*& aDest,char* aData,int aLength, const char* aDestEnd)
1.682 + {
1.683 + if(!CanCopy8bppData(aDest, aDestEnd, aLength))
1.684 + return NoCompression;
1.685 + while(aLength>128)
1.686 + {
1.687 + *aDest++=-128;
1.688 + for(int count=0;count<128;count++)
1.689 + *aDest++=*aData++;
1.690 + aLength-=128;
1.691 + }
1.692 + if(aLength>128 || aLength<1) return CompressionError;
1.693 + *aDest++=char(-aLength);
1.694 + for(int count=0;count<aLength;count++)
1.695 + *aDest++=*aData++;
1.696 + return NoError;
1.697 + }
1.698 +
1.699 +int BitmapCompiler::WriteCompressedByteValues(char*& aDest,char aValue,int aLength, const char* aDestEnd)
1.700 + {
1.701 + if (aLength < 1)
1.702 + return CompressionError;
1.703 +
1.704 + if(!CanWrite8bppValue(aDest, aDestEnd, aLength))
1.705 + return NoCompression;
1.706 +
1.707 + while (aLength > 128)
1.708 + {
1.709 + *aDest++ = 127;
1.710 + *aDest++ = aValue;
1.711 + aLength -= 128;
1.712 + }
1.713 +
1.714 + *aDest++ = char(aLength-1);
1.715 + *aDest++ = aValue;
1.716 +
1.717 + return NoError;
1.718 + }
1.719 +
1.720 +int BitmapCompiler::CompressTwelveBitData(char*& aDest,char* aSrce,int aSizeInBytes)
1.721 + {
1.722 + unsigned short* srcePtr = (unsigned short*)aSrce;
1.723 + unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2);
1.724 + unsigned short* dest = (unsigned short*)aDest;
1.725 +
1.726 + while (srcePtr < srceLimitPtr)
1.727 + {
1.728 + unsigned short* runStartPtr = srcePtr;
1.729 + unsigned short value = *srcePtr;
1.730 + do
1.731 + srcePtr++;
1.732 + while (srcePtr < srceLimitPtr && *srcePtr == value);
1.733 + WriteCompressedTwelveBitData(dest,*runStartPtr,srcePtr - runStartPtr); // Ignore error return as 12bpp compression never fails
1.734 + }
1.735 +
1.736 + aDest = (char*)dest;
1.737 + return NoError;
1.738 + }
1.739 +
1.740 +int BitmapCompiler::WriteCompressedTwelveBitData(unsigned short*& aDest,unsigned short aData,int aLength)
1.741 + {
1.742 + // The run length l is stored as l-1 in the top 4 bits of each 16-bit word (between 1 and 16)
1.743 + aData &= 0x0fff;
1.744 + unsigned short maxLengthData = (unsigned short)(aData | 0xf000);
1.745 +
1.746 + while(aLength>16)
1.747 + {
1.748 + *aDest++ = maxLengthData;
1.749 + aLength -= 16;
1.750 + }
1.751 +
1.752 + if (aLength > 0)
1.753 + *aDest++ = (unsigned short)(aData | ((aLength - 1) << 12));
1.754 +
1.755 + return NoError;
1.756 + }
1.757 +
1.758 +int BitmapCompiler::CompressSixteenBitData(char*& aDest,char* aSrce,int aSizeInBytes)
1.759 + {
1.760 + char* destEnd = aDest + aSizeInBytes;
1.761 + unsigned short* srcePtr = (unsigned short*)aSrce;
1.762 + unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2);
1.763 + unsigned short* srceLimitPtrMinusOne = srceLimitPtr - 1;
1.764 + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
1.765 + int ret = NoError;
1.766 +
1.767 + while (srcePtr < srceLimitPtrMinusOne)
1.768 + {
1.769 + unsigned short value = *srcePtr;
1.770 + unsigned short* runStartPtr = srcePtr++;
1.771 +
1.772 + if(*srcePtr == value)
1.773 + {
1.774 + do
1.775 + srcePtr++;
1.776 + while ( ( srcePtr < srceLimitPtr ) && ( *srcePtr == value ) );
1.777 +
1.778 + ret = WriteCompressedSixteenBitValues(aDest,value,srcePtr-runStartPtr, destEnd);
1.779 + if (ret)
1.780 + return ret;
1.781 + }
1.782 + else
1.783 + {
1.784 + value = *srcePtr;
1.785 + while (srcePtr < srceLimitPtrMinusOne && *(srcePtr + 1) != value)
1.786 + {
1.787 + srcePtr++;
1.788 + value = *srcePtr;
1.789 + }
1.790 +
1.791 + ret = WriteCompressedSixteenBitData(aDest,runStartPtr,srcePtr - runStartPtr, destEnd);
1.792 + if (ret)
1.793 + return ret;
1.794 + }
1.795 + if (aDest > destCompressedLimitPtr)
1.796 + return NoCompression;
1.797 + }
1.798 +
1.799 + if (srcePtr < srceLimitPtr)
1.800 + {
1.801 + ret = WriteCompressedSixteenBitData(aDest,srcePtr,srceLimitPtr - srcePtr, destEnd);
1.802 + if (ret)
1.803 + return ret;
1.804 + }
1.805 +
1.806 + if (aDest > destCompressedLimitPtr)
1.807 + return NoCompression;
1.808 + return NoError;
1.809 + }
1.810 +
1.811 +int BitmapCompiler::WriteCompressedSixteenBitData(char*& aDest,unsigned short* aData,
1.812 + int aLength, const char* aDestEnd)
1.813 + {
1.814 + if (aLength < 1)
1.815 + return CompressionError;
1.816 +
1.817 + if(!CanCopy16bppData(aDest, aDestEnd, aLength))
1.818 + return NoCompression;
1.819 +
1.820 + char* srcePtr = (char*)aData;
1.821 +
1.822 + while (aLength > 128)
1.823 + {
1.824 + *aDest++ = -128;
1.825 + memcpy(aDest,srcePtr,256);
1.826 + aDest += 256;
1.827 + srcePtr += 256;
1.828 + aLength -= 128;
1.829 + }
1.830 +
1.831 + *aDest++ = char(-aLength);
1.832 +
1.833 + int remainingBytes = aLength * 2;
1.834 + memcpy(aDest,srcePtr,remainingBytes);
1.835 + aDest += remainingBytes;
1.836 +
1.837 + return NoError;
1.838 + }
1.839 +
1.840 +int BitmapCompiler::WriteCompressedSixteenBitValues(char*& aDest,unsigned short aValue,
1.841 + int aLength, const char* aDestEnd)
1.842 + {
1.843 + if (aLength < 1)
1.844 + return CompressionError;
1.845 +
1.846 + if(!CanWrite16bppValue(aDest, aDestEnd, aLength))
1.847 + return NoCompression;
1.848 +
1.849 + char lowByte = char(aValue);
1.850 + char highByte = char(aValue >> 8);
1.851 +
1.852 + while (aLength > 128)
1.853 + {
1.854 + *aDest++ = 127;
1.855 + *aDest++ = lowByte;
1.856 + *aDest++ = highByte;
1.857 + aLength -= 128;
1.858 + }
1.859 +
1.860 + *aDest++ = char(aLength-1);
1.861 + *aDest++ = lowByte;
1.862 + *aDest++ = highByte;
1.863 +
1.864 + return NoError;
1.865 + }
1.866 +
1.867 +int BitmapCompiler::CompressTwentyFourBitData(char*& aDest,char* aSrce,int aSizeInBytes)
1.868 + {
1.869 + const char* destEnd = aDest + aSizeInBytes;
1.870 + char* srceLimitPtr = aSrce + aSizeInBytes;
1.871 + char* srceLimitPtrMinusThree = srceLimitPtr - 3; // three bytes == one pixel
1.872 + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
1.873 + int ret = NoError;
1.874 +
1.875 + while (aSrce < srceLimitPtrMinusThree)
1.876 + {
1.877 + char* runStartPtr = aSrce;
1.878 + char component1 = *aSrce++;
1.879 + char component2 = *aSrce++;
1.880 + char component3 = *aSrce++;
1.881 +
1.882 + if (TrueColorPointerCompare(aSrce,component1,component2,component3))
1.883 + {
1.884 + do
1.885 + aSrce += 3;
1.886 + while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3));
1.887 +
1.888 + ret = WriteCompressedTwentyFourBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 3, destEnd);
1.889 + if (ret)
1.890 + return ret;
1.891 + }
1.892 + else
1.893 + {
1.894 + bool more = true;
1.895 + bool eqRun = false;
1.896 + do
1.897 + {
1.898 + component1 = *aSrce++;
1.899 + component2 = *aSrce++;
1.900 + component3 = *aSrce++;
1.901 + more = (aSrce < srceLimitPtr);
1.902 + eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3);
1.903 + }
1.904 + while (more && !eqRun);
1.905 + if (eqRun)
1.906 + aSrce -= 3;
1.907 + int pixelLength = (aSrce - runStartPtr) / 3;
1.908 + ret = WriteCompressedTwentyFourBitData(aDest,runStartPtr,pixelLength,destEnd);
1.909 + if (ret)
1.910 + return ret;
1.911 + }
1.912 + if (aDest > destCompressedLimitPtr)
1.913 + return NoCompression;
1.914 + }
1.915 +
1.916 + if (aSrce < srceLimitPtr)
1.917 + {
1.918 + ret = WriteCompressedTwentyFourBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 3, destEnd);
1.919 + if (ret)
1.920 + return ret;
1.921 + }
1.922 +
1.923 + if (aDest > destCompressedLimitPtr)
1.924 + return NoCompression;
1.925 + return NoError;
1.926 + }
1.927 +
1.928 +int BitmapCompiler::WriteCompressedTwentyFourBitData(char*& aDest,char* aData,
1.929 + int aLength, const char* aDestEnd)
1.930 + {
1.931 + if (aLength < 1)
1.932 + return CompressionError;
1.933 +
1.934 + if(!CanCopy24bppData(aDest, aDestEnd, aLength))
1.935 + return NoCompression;
1.936 +
1.937 + while (aLength > 128)
1.938 + {
1.939 + *aDest++ = -128;
1.940 + memcpy(aDest,aData,384);
1.941 + aDest += 384;
1.942 + aData += 384;
1.943 + aLength -= 128;
1.944 + }
1.945 +
1.946 + *aDest++ = char(-aLength);
1.947 +
1.948 + int remainingBytes = aLength * 3;
1.949 + memcpy(aDest,aData,remainingBytes);
1.950 + aDest += remainingBytes;
1.951 +
1.952 + return NoError;
1.953 + }
1.954 +
1.955 +int BitmapCompiler::WriteCompressedTwentyFourBitValues(char*& aDest,char aComponent1,
1.956 + char aComponent2,char aComponent3,
1.957 + int aLength, const char* aDestEnd)
1.958 + {
1.959 + if (aLength < 1)
1.960 + return CompressionError;
1.961 +
1.962 + if(!CanWrite24bppValue(aDest, aDestEnd, aLength))
1.963 + return NoCompression;
1.964 +
1.965 + while (aLength > 128)
1.966 + {
1.967 + *aDest++ = 127;
1.968 + *aDest++ = aComponent1;
1.969 + *aDest++ = aComponent2;
1.970 + *aDest++ = aComponent3;
1.971 + aLength -= 128;
1.972 + }
1.973 +
1.974 + *aDest++ = char(aLength-1);
1.975 + *aDest++ = aComponent1;
1.976 + *aDest++ = aComponent2;
1.977 + *aDest++ = aComponent3;
1.978 +
1.979 + return NoError;
1.980 + }
1.981 +
1.982 +/** The function encodes 32-bit buffer into 24-bit stream by using RLE compression algorithm*/
1.983 +int BitmapCompiler::CompressThirtyTwoUBitData(char*& aDest,char* aSrce,int aSizeInBytes)
1.984 + {
1.985 + const char* destEnd = aDest + aSizeInBytes;
1.986 + char* srceLimitPtr = aSrce + aSizeInBytes;
1.987 + char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel
1.988 + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
1.989 + int ret = NoError;
1.990 +
1.991 + while (aSrce < srceLimitPtrMinusFour)
1.992 + {
1.993 + char* runStartPtr = aSrce;
1.994 + char component1 = *aSrce++;
1.995 + char component2 = *aSrce++;
1.996 + char component3 = *aSrce++;
1.997 + aSrce++;
1.998 +
1.999 + if (TrueColorPointerCompare(aSrce,component1,component2,component3))
1.1000 + {
1.1001 + do
1.1002 + aSrce += 4;
1.1003 + while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3));
1.1004 +
1.1005 + ret = WriteCompressedThirtyTwoUBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 4, destEnd);
1.1006 + if (ret)
1.1007 + return ret;
1.1008 + }
1.1009 + else //non repeating pixel buffer
1.1010 + {
1.1011 + bool more = true;
1.1012 + bool eqRun = false;
1.1013 + do {
1.1014 + component1 = *aSrce++;
1.1015 + component2 = *aSrce++;
1.1016 + component3 = *aSrce++;
1.1017 + aSrce++; //last byte is unused (no alpha component)
1.1018 + more = (aSrce < srceLimitPtr);
1.1019 + eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3);
1.1020 + } while (more && !eqRun);
1.1021 + if (eqRun)
1.1022 + aSrce -= 4;
1.1023 + int pixelLength = (aSrce - runStartPtr) / 4;
1.1024 + ret = WriteCompressedThirtyTwoUBitData(aDest,runStartPtr,pixelLength,destEnd);
1.1025 + if (ret)
1.1026 + return ret;
1.1027 + }
1.1028 + if (aDest > destCompressedLimitPtr)
1.1029 + return NoCompression;
1.1030 + }
1.1031 +
1.1032 + if (aSrce < srceLimitPtr)
1.1033 + {
1.1034 + ret = WriteCompressedThirtyTwoUBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd);
1.1035 + if (ret)
1.1036 + return ret;
1.1037 + }
1.1038 +
1.1039 + if (aDest > destCompressedLimitPtr)
1.1040 + return NoCompression;
1.1041 + return NoError;
1.1042 + }
1.1043 +
1.1044 +/** The function copies non repeating 32-bit buffer to 24-bit compressed buffer*/
1.1045 +int BitmapCompiler::WriteCompressedThirtyTwoUBitData(char*& aDest,char* aData,
1.1046 + int aLength, const char* aDestEnd)
1.1047 + {
1.1048 + if (aLength < 1)
1.1049 + return CompressionError;
1.1050 +
1.1051 + if(!CanCopy24bppData(aDest, aDestEnd, aLength))
1.1052 + return NoCompression;
1.1053 +
1.1054 + while (aLength > 128)
1.1055 + {
1.1056 + *aDest++ = -128;
1.1057 + for(int ii = 0; ii < 128; ii++)
1.1058 + {
1.1059 + memcpy(aDest,aData, 3);
1.1060 + aDest += 3;
1.1061 + aData += 4;
1.1062 + }
1.1063 + aLength -= 128;
1.1064 + }
1.1065 +
1.1066 + *aDest++ = char(-aLength);
1.1067 +
1.1068 + while(aLength--)
1.1069 + {
1.1070 + memcpy(aDest,aData, 3);
1.1071 + aDest += 3;
1.1072 + aData += 4;
1.1073 + }
1.1074 +
1.1075 + return NoError;
1.1076 + }
1.1077 +
1.1078 +/** The function copies repeating colour to the 24-bit compressed buffer */
1.1079 +int BitmapCompiler::WriteCompressedThirtyTwoUBitValues(char*& aDest,char aComponent1,
1.1080 + char aComponent2,char aComponent3,
1.1081 + int aLength, const char* aDestEnd)
1.1082 + {
1.1083 + if (aLength < 1)
1.1084 + return CompressionError;
1.1085 +
1.1086 + if(!CanWrite24bppValue(aDest, aDestEnd, aLength))
1.1087 + return NoCompression;
1.1088 + while (aLength > 128)
1.1089 + {
1.1090 + *aDest++ = 127;
1.1091 + *aDest++ = aComponent1;
1.1092 + *aDest++ = aComponent2;
1.1093 + *aDest++ = aComponent3;
1.1094 + aLength -= 128;
1.1095 + }
1.1096 +
1.1097 + *aDest++ = char(aLength-1);
1.1098 + *aDest++ = aComponent1;
1.1099 + *aDest++ = aComponent2;
1.1100 + *aDest++ = aComponent3;
1.1101 +
1.1102 + return NoError;
1.1103 + }
1.1104 +
1.1105 +int BitmapCompiler::TrueColorPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3)
1.1106 + {
1.1107 + return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3);
1.1108 + }
1.1109 +
1.1110 +/** The function encodes 32-bit buffer into 32-bit stream by using RLE compression algorithm*/
1.1111 +int BitmapCompiler::CompressThirtyTwoABitData(char*& aDest,char* aSrce,int aSizeInBytes)
1.1112 + {
1.1113 + const char* destEnd = aDest + aSizeInBytes;
1.1114 + char* srceLimitPtr = aSrce + aSizeInBytes;
1.1115 + char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel
1.1116 + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
1.1117 + int ret = NoError;
1.1118 +
1.1119 + while (aSrce < srceLimitPtrMinusFour)
1.1120 + {
1.1121 + char* runStartPtr = aSrce;
1.1122 + char component1 = *aSrce++;
1.1123 + char component2 = *aSrce++;
1.1124 + char component3 = *aSrce++;
1.1125 + char component4 = *aSrce++;
1.1126 +
1.1127 + if (ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4))
1.1128 + {
1.1129 + do
1.1130 + aSrce += 4;
1.1131 + while (aSrce < srceLimitPtr && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4));
1.1132 + int eqPixelLength = (aSrce - runStartPtr) / 4;
1.1133 + ret = WriteCompressedThirtyTwoABitValues(aDest,component1,component2,component3,component4,eqPixelLength,destEnd);
1.1134 + if (ret)
1.1135 + return ret;
1.1136 + }
1.1137 + else //non repeating pixel buffer
1.1138 + {
1.1139 + bool more = true;
1.1140 + bool eqRun = false;
1.1141 + do {
1.1142 + component1 = *aSrce++;
1.1143 + component2 = *aSrce++;
1.1144 + component3 = *aSrce++;
1.1145 + component4 = *aSrce++;
1.1146 + more = (aSrce < srceLimitPtr);
1.1147 + eqRun = more && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4);
1.1148 + } while (more && !eqRun);
1.1149 + if (eqRun)
1.1150 + aSrce -= 4;
1.1151 + int nePixelLength = (aSrce - runStartPtr) / 4;
1.1152 + ret = WriteCompressedThirtyTwoABitData(aDest,runStartPtr,nePixelLength,destEnd);
1.1153 + if (ret)
1.1154 + return ret;
1.1155 + }
1.1156 + if (aDest > destCompressedLimitPtr)
1.1157 + return NoCompression;
1.1158 + }
1.1159 +
1.1160 + if (aSrce < srceLimitPtr)
1.1161 + {
1.1162 + ret = WriteCompressedThirtyTwoABitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd);
1.1163 + if (ret)
1.1164 + return ret;
1.1165 + }
1.1166 +
1.1167 + if (aDest > destCompressedLimitPtr)
1.1168 + return NoCompression;
1.1169 + return NoError;
1.1170 + }
1.1171 +
1.1172 +/** The function copies non repeating 32-bit buffer to 32-bit compressed buffer*/
1.1173 +int BitmapCompiler::WriteCompressedThirtyTwoABitData(char*& aDest,char* aData,
1.1174 + int aLength, const char* aDestEnd)
1.1175 + {
1.1176 + if (aLength < 1)
1.1177 + return CompressionError;
1.1178 +
1.1179 + if(!CanCopy32bppData(aDest, aDestEnd, aLength))
1.1180 + return NoCompression;
1.1181 +
1.1182 + while (aLength > 128)
1.1183 + {
1.1184 + *aDest++ = -128;
1.1185 + memcpy(aDest,aData,512);
1.1186 + aDest += 512;
1.1187 + aData += 512;
1.1188 + aLength -= 128;
1.1189 + }
1.1190 +
1.1191 + *aDest++ = char(-aLength);
1.1192 + memcpy(aDest,aData, aLength*4);
1.1193 + aDest += aLength*4;
1.1194 + return NoError;
1.1195 + }
1.1196 +
1.1197 +/** The function copies repeating pixels including alpha to a 32-bit compressed buffer */
1.1198 +int BitmapCompiler::WriteCompressedThirtyTwoABitValues(char*& aDest,char aComponent1,
1.1199 + char aComponent2,char aComponent3,
1.1200 + char aComponent4,int aLength,
1.1201 + const char* aDestEnd)
1.1202 +
1.1203 + {
1.1204 + if (aLength < 1)
1.1205 + return CompressionError;
1.1206 +
1.1207 + if(!CanWrite32bppValue(aDest, aDestEnd, aLength))
1.1208 + return NoCompression;
1.1209 + while (aLength > 128)
1.1210 + {
1.1211 + *aDest++ = 127;
1.1212 + *aDest++ = aComponent1;
1.1213 + *aDest++ = aComponent2;
1.1214 + *aDest++ = aComponent3;
1.1215 + *aDest++ = aComponent4;
1.1216 + aLength -= 128;
1.1217 + }
1.1218 +
1.1219 + *aDest++ = char(aLength-1);
1.1220 + *aDest++ = aComponent1;
1.1221 + *aDest++ = aComponent2;
1.1222 + *aDest++ = aComponent3;
1.1223 + *aDest++ = aComponent4;
1.1224 +
1.1225 + return NoError;
1.1226 + }
1.1227 +
1.1228 +int BitmapCompiler::ColorAlphaPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3,char aComponent4)
1.1229 + {
1.1230 + return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3 && *(aColorPointer + 3) == aComponent4);
1.1231 + }
1.1232 +
1.1233 +int BitmapCompiler::ReadHexString(char aHexBuf[10],char*& aDataPtr,char* aDataPtrLimit)
1.1234 + {
1.1235 + while (aDataPtr < aDataPtrLimit)
1.1236 + {
1.1237 + if (aDataPtr[0] == '0')
1.1238 + {
1.1239 + if (aDataPtr[1] == 'x' || aDataPtr[1] == 'X')
1.1240 + {
1.1241 + memcpy(aHexBuf,aDataPtr,10);
1.1242 + aDataPtr += 10;
1.1243 + return NoError;
1.1244 + }
1.1245 + }
1.1246 + aDataPtr++;
1.1247 + }
1.1248 +
1.1249 + return PaletteFile;
1.1250 + }
1.1251 +
1.1252 +int BitmapCompiler::HexToInt(char aHighNibble,char aLowNibble)
1.1253 + {
1.1254 + return (HexToInt(aHighNibble) << 4) + HexToInt(aLowNibble);
1.1255 + }
1.1256 +
1.1257 +int BitmapCompiler::HexToInt(char aNibble)
1.1258 + {
1.1259 + int value = 0;
1.1260 +
1.1261 + if (aNibble >= '0' && aNibble <= '9')
1.1262 + value = aNibble - '0';
1.1263 + else if (aNibble >= 'a' && aNibble <= 'f')
1.1264 + value = aNibble - 'a' + 10;
1.1265 + else if (aNibble >= 'A' && aNibble <= 'F')
1.1266 + value = aNibble - 'A' + 10;
1.1267 +
1.1268 + return value;
1.1269 + }
1.1270 +
1.1271 +void BitmapCompiler::CopyTail(void* aDst, void* aSrc, int aFullSize, int aSkipped)
1.1272 + {
1.1273 + memcpy(aDst, ((char*)aSrc)+aSkipped, aFullSize-aSkipped);
1.1274 + }