GP32 Problem reading bitmaps...


generalnmx

Playful/Fascist Mod
Joined
Apr 18, 2003
Messages
2,128
Age
42
Location
Maryland, USA
Website
www.matts-hosting.com
I'm having trouble reading bitmaps. The headers are read correctly, but it seems the image data either isn't being converted properly, or I need to do something with palletes. Right now, I'm using the GP32 SDK for simplicy (I'll optimize later as everything is wrapped).

Here's my code:

Code:
#define CORRECT_BITMAP_TYPE 19778

/* File information header
 * provides general information about the file */
typedef struct tagBITMAPFILEHEADER { 
  uword16    bfType;  /* 00h: if this is not 19778, then it is not a bitmap (represents the 'BM') */
  udword32   bfSize;  /* 02h: total size of the file, including the headers */
  uword16    bfReserved1;	/* 06h: should contain all zeros */
  uword16    bfReserved2;	/* 08h: "  "  "	"  */
  udword32   bfOffBits;  /* 0Ah: offset to the image data, varies depending on if a pallete exists */
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

/* Bitmap information header
 * provides information specific to the image data */
typedef struct tagBITMAPINFOHEADER{
  uword16   biSize;    /* 0Eh: size of remaining header. Should be 40 (size of BITMAPINFOHEADER). */
  udword32  biWidth;  	/* 12h: width of the image in pixels */
  udword32  biHeight;  	/* 16h: height of the image in pixels */
  uword16   biPlanes;  	/* 1Ah: number of bit planes, should be 1 */
  uword16   biBitCount;  	/* 1Ch: number of bits per pixel for colours */
  udword32  biCompression;  /* 1Eh: 0 for no compression */
  udword32  biSizeImage;  /* 22h: size of the image data (could be 0) */
  udword32  biXPelsPerMeter;	/* 26h: horizontal resolution in pixels per meter */
  udword32  biYPelsPerMeter;	/* 2Ah: vertical resolution in pixels per meter */
  udword32  biClrUsed;  	/* 2Eh: number of colours used from the pallete (24-bit has this as 0)*/
  udword32  biClrImportant;  /* 32h: number of colour indexes that are important (0 means all are important) */
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

/* Colour palette */
typedef struct tagRGBQUAD {
  ubyte8    rgbBlue;  /* number in blue range */ 
  ubyte8    rgbGreen;  /* number in green range */
  ubyte8    rgbRed;  	/* number in red range */
  ubyte8    rgbReserved;	/* reserved byte (should be 0) */
} RGBQUAD;

Code:
void* IGraphicsBitmapLoad(const_char8* filename, ubyte8 bbp, uint32* bitmap_width, uint32* bitmap_height)
{
	/* open file with read access */
	if ( ISystemFileOpen(filename, FILE_READ) )	/* check to make sure we could open the file */
	{
  BITMAPFILEHEADER bmfh;  /* see igraphics.h */
  BITMAPINFOHEADER bmih;
  RGBQUAD* pallete = NULL;	/* colour table */
  uint32 numColours;  	/* number of colours in pallete */
  void* pixelArray = NULL;	/* new pixel array to return */
  uint32 bytesRead = 0;
  uint32 byteWidth = 0, padWidth = 0;	/* to counteract byte padding */
  int32 j, i;	/* used in for loop below */

  /* read in the bitmap piece by piece (for crossplatform compatability) */
  /* bitmap header */
  bytesRead += ISystemFileRead(&bmfh.bfType, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmfh.bfSize, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmfh.bfReserved1, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmfh.bfReserved2, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmfh.bfOffBits, sizeof(udword32) );

  if (bmfh.bfType != CORRECT_BITMAP_TYPE)
  	return(NULL);

  /* image data (rest of header) */
  bytesRead = 0;
  bytesRead += ISystemFileRead(&bmih.biSize, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmfh.bfReserved1, sizeof(uword16) );	/* throw this away */
  bytesRead += ISystemFileRead(&bmih.biWidth, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biHeight, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biPlanes, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmih.biBitCount, sizeof(uword16) );
  bytesRead += ISystemFileRead(&bmih.biCompression, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biSizeImage, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biXPelsPerMeter, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biYPelsPerMeter, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biClrUsed, sizeof(udword32) );
  bytesRead += ISystemFileRead(&bmih.biClrImportant, sizeof(udword32) );

  /* given bit-per-pixel should equal the bit count */
  if (bbp != bmih.biBitCount)
  {
  	return(NULL);	
  }

  /* set the number of colours */
  numColours= 1 << bmih.biBitCount;

  /* load for 8 bits per pixel */
  if (bmih.biBitCount == 8)
  {
  	pallete = (RGBQUAD*)ISystemMemoryAllocate( sizeof(RGBQUAD) * numColours ); /* array of size numColours */
  	bytesRead = ISystemFileReadByBytes(pallete, sizeof(RGBQUAD), numColours);
  	if (bytesRead < numColours )
  	{
    ISystemMemoryFree(pallete);
    return(NULL);
  	}
  }

  ISystemMemoryFree(pallete);

  /* and here we would load up the pixel array */
  if (bbp == 8)
  {
  	ubyte8* tempPixelArray = NULL; /* temporary array, need to fix padding */
  	tempPixelArray = (ubyte8*)ISystemMemoryAllocate( sizeof(ubyte8) * (bmfh.bfSize-bmfh.bfOffBits) );
  	bytesRead = ISystemFileReadByBytes(tempPixelArray, sizeof(ubyte8), bmfh.bfSize-bmfh.bfOffBits);
  	if (bytesRead < bmfh.bfSize-bmfh.bfOffBits)
  	{
    ISystemMemoryFree(pallete);
    ISystemMemoryFree(tempPixelArray);
  	}

  	/* get actual width of bitmap */
  	byteWidth=padWidth=(udword32)((float)bmih.biWidth*(float)bmih.biBitCount/8.0f);

  	/* skip through padding */
  	while( (padWidth % 4) != 0 ) {
    padWidth++;
  	}

  	/* new array should be actual size (no padding) */
  	pixelArray = (ubyte8*)ISystemMemoryAllocate( sizeof(ubyte8) * (bmih.biHeight*byteWidth) );

  	/* to fix padding problems */
  	if (pixelArray && tempPixelArray && bmih.biHeight > 0) 
  	{
    j = (bmfh.bfSize-bmfh.bfOffBits)-3;
    for(i = 0; i < (bmfh.bfSize-bmfh.bfOffBits); i+=3) 
    {
    	if( ((i+1) % padWidth) == 0 ) {
      i += padWidth-byteWidth;
    	}

    *((ubyte8*)pixelArray+j+2)	= *(tempPixelArray+i);
    *((ubyte8*)pixelArray+j+1)	= *(tempPixelArray+i+1);
    *((ubyte8*)pixelArray+j)	= *(tempPixelArray+i+2);
     j++;
    } /* end of for loop */
  	} /* end of height check */
  } /* end of bbp == 8 check */

  /* assign bitmap size */
  if (bitmap_width) *bitmap_width = bmih.biWidth;
  if (bitmap_height) *bitmap_height = bmih.biHeight;

  return(pixelArray);
	}

	return(NULL);	/* could not open file! */
}
 
sorry, I can't help you. I just wonder why you guys favor BMPs instead ov PCXs. they seem to be the right solution for bitmapbased grafics...
 
I'm hoping to support more then just BMP, but I think it's best to start with a lossless encoding first.

Thanks for the link Woogal, I did a search, but I must have forgotten to reset the dates to check :)
 
Are you using the Debian Cross Toolchain?
I had a problem compiling the tonedial program where only half the screen was rendered and the colours were all funny. when I converted to use 8 bit bitmaps, I could get the correct picture.
 
I still can't get 16bit colour images to work! I have tried a load of different methods and it just dosent work! Apparently it is exactly the same as 8bit images but with 16 on the end of all the graphical functions. Has any body got any info on using 16 bit images and palletes?
 
Back
Top