I'm (again) experiencing troubles uncompressing bitmaps. My app is opening bitmaps that have been created on another device. It gets them in a database. They can be compressed in multiple formats (i.e. scanline, RLE, packbits).
On a 3.5 ROM with an RLE compressed bitmap it works great.
On a 4.0 ROM with an RLE compressed bitmap I get a memory error reading memory manager data structures. What is interesting is that for the same bitmap BmpBitsSize() returns different values on 3.5 and 4.0. The 4.0 size returned is always 2 less than the 3.5 size. I understand that the first two bytes of the compressed data is the number of compressed bits and that matches the 4.0 return value (the one that doesn't work).
Example:
3.5 BmpBitsSize() = 192 : uncompresses fine 4.0 BmpBitsSize() = 190 : memory error First two bytes of data is 190.
Why would BmpBitsSize return different values depending upon the ROM version? Perhaps the 3.5 version includes the 2 bytes that contain the number of bytes but in any case this is not documented as far as I can tell.
Is there a work-around or better way to uncompress bitmaps? (I tried looking in the OS source code but the bitmap routines aren't in there)
Here is the code: (I realize some of this code will break on the next SDK release due to direct access to bitmap internals but I haven't found any other way to do what I'm trying to do)
BitmapType *Bmp_UncompressBitmap( BitmapType *bmP )
{
BitmapCompressionType CT;
BitmapTypeV2 *pUncomprBitmapV2;
BitmapType *pUncomprBitmap;
Int16 width, height;
UInt16 rowBytes;
UInt8 pixelSize;
UInt16 createErr;
UInt8 *destDataBitsP, *srcDataBitsP;
Err err;
ColorTableType *clrTblP;
UInt16 heapID;
Boolean bIsDynamic; // uses glue function
Bmp_GetCompressionType( bmP, &CT );
if( CT == BitmapCompressionTypeNone )
{
{
return bmP;
} // is it in the dynamic heap?
heapID = MemPtrHeapID( bmP );
bIsDynamic = MemHeapDynamic( heapID ); if( !bIsDynamic )
{
// create heap space for bitmap
// get dimensions using glue functions
Bmp_GetDimensions( bmP, &width, &height, &rowBytes, &pixelSize ); // BmpSize returns size of compressed bitmap; I need room for uncompressed
bitmap
clrTblP = Bmp_GetColortable( bmP ); // this creates a version 2 bitmap
pUncomprBitmap = BmpCreate( width, height, pixelSize, clrTblP, &createErr );
if( pUncomprBitmap )
{
UInt16 bitsSize; // color table copied in (if there) but need the flags from
// the header so the BmpCompress call knows it is compressed.
// first 10 bytes always the same and that has the flags in it
// (yuck...but what choice do I have. there is no BmpGetFlags call)
MemMove( pUncomprBitmap, bmP, 10 ); // yuck again, but I need a way to set the compression type so BmpCompress
works.
pUncomprBitmapV2 = (BitmapTypeV2 *)pUncomprBitmap;
pUncomprBitmapV2->compressionType = CT; // copy the compressed bits in and uncompress it
destDataBitsP = (UInt8 *)BmpGetBits( pUncomprBitmap );
srcDataBitsP = (UInt8 *)BmpGetBits( bmP );// returns different values on different OS's. Ugh.
MemMove( destDataBitsP, srcDataBitsP, bitsSize );
}
}
else
{
pUncomprBitmap = bmP;
} if( pUncomprBitmap )
{
err = BmpCompress( pUncomprBitmap, BitmapCompressionTypeNone );
} // might be same as bitmap passed in
return pUncomprBitmap;} // end Bmp_UncompressBitmap
-- For information on using the Palm Developer Forums, or to unsubscribe, please see http://www.palmos.com/dev/support/forums/
