   Problem with 8 bit bitmaps
  Hi,I've been developing my own Bitmap class, following the code an tutorial on How to load bitmaps. For 24 bit bitmaps, I have no problems, but for 8 bit bitmaps (ie. with a color table), the colors are strange. Here's my convert8 code:boolBitmap :: convert8 (char * tmpData){int offset;int diff;int i, j;diff = width * height * RGB_BYTES;if ((pixelData = (char *) malloc (diff * sizeof (char))) == NULL) {fprintf (stderr, "Error: out of memory\n");exit (EXIT_FAILURE);}offset = padWidth - byteWidth;if (height > 0) {j = 0;for (i = 0; i < dataSize * RGB_BYTES; i = i + 3) {if ((i + 1) % padWidth == 0) {i = i + offset;}pixelData = colors[tmpData[j]].rgbRed;pixelData = colors[tmpData[j]].rgbGreen;pixelData = colors[tmpData[j]].rgbBlue;j++;}} <span class="cpp-keyword">else</span> {j = dataSize - <span class="cpp-number">1</span>;<span class="cpp-keyword">for</span> (i = <span class="cpp-number">0</span>; i &lt; dataSize * RGB_BYTES; i = i + <span class="cpp-number">3</span>) {<span class="cpp-keyword">if</span> ((i + <span class="cpp-number">1</span>) % padWidth == <span class="cpp-number">0</span>) {i = i + offset;}pixelData<span style="font-weight:bold;"> = colors[tmpData[j]].rgbRed;pixelData = colors[tmpData[j]].rgbGreen;pixelData = colors[tmpData[j]].rgbBlue;j–;}}<span class="cpp-keyword">return</span> (<span class="cpp-keyword">true</span>);}</pre></div><!–ENDSCRIPT–>and here's where I load the color table:<!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre><span class="cpp-keyword">if</span> (bmih.biBitCount == <span class="cpp-number">8</span>) {<span class="cpp-keyword">if</span> ((colors = (RGBQuad *)malloc (numColors * <span class="cpp-keyword">sizeof</span> (RGBQuad))) == NULL) {fprintf (stderr, <span class="cpp-literal">"Error: out of memory\n"</span>);fclose (bmp);exit (EXIT_FAILURE);}<span class="cpp-comment">// Read in the color table, and check for validity</span><span class="cpp-keyword">if</span> (fread (colors, <span class="cpp-keyword">sizeof</span> (RGBQuad), numColors, bmp) != numColors) {fprintf (stderr, invalidBMPError);fclose (bmp);<span class="cpp-keyword">return</span> (<span class="cpp-keyword">false</span>);}}</pre></div><!–ENDSCRIPT–>Any ideas? Please note that the code supplied with the tutorial gives me exactly the same result…Cheers!- Joseph Paterson<!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - jpaterso on May 27, 2006 6:59:08 AM]<!–EDIT–></span><!–/EDIT–>
  what does your RGBQuad structure or class look like? does it match the Windows format of Blue comes b4 Green comes b4 Red? or is that just a typo and u really are using RGBQUAD instead? otherwise looks ok to me.   ;  It's the same I believe:typedef struct {charrgbBlue;charrgbGreen;charrgbRed;charrgbReserved;} RGBQuad;But it just won't work... :(   ;  i didn't look at your convert8 function earlier, but shouldn'tpixelData = colors[tmpData[j]].rgbRed;pixelData = colors[tmpData[j]].rgbGreen;<br>pixelData = colors[tmpData[j]].rgbBlue;<br><br>be<br><br>pixelData<span style="font-weight:bold;"> = colors[tmpData[j]].rgbBlue;<br>pixelData = colors[tmpData[j]].rgbGreen;<br>pixelData = colors[tmpData[j]].rgbRed;<br><br>instead since 24 bit bitmaps are store BRG? i'm still thinking<br>your image is just inverted, but this time in the conversion.;  Mmm I tried BGR and RGB, but no luck... :(   ;  another thing i see wrong is you use j++ to increment your index to your 8-bit bitmap. after each row, you do have to skip some bytes if the width isn't divisible by 8. your conversion loop is really strange and not efficient especially with that modulus having to be called every iteration. something like the following code should work... if it doesn't then the only thing i can think of is that you started reading the bitmap data in the wrong spot.bool Bitmap :: convert8(char* tmpData){ // number of bytes per row int pitch_bytes_08 = (( 8*width + 31) & (~31))/8; int pitch_bytes_24 = ((24*width + 31) & (~31))/8; // number of bytes in image int total_bytes_08 = pitch_bytes_08*height; int total_bytes_24 = pitch_bytes_24*height; // allocate your 24-bit data right? if((pixelData = (char*)malloc(total_bytes_24)) == NULL) {    fprintf (stderr, "Error: out of memory\n");    exit(EXIT_FAILURE);   } // beginning of row variables int begin_08 = 0; int begin_24 = 0; for(int y = 0; y < height; y++)    {// updated as we go down the row...int offset_08 = begin_08;int offset_24 = begin_24;for(int x = 0; x < width; x++)   {    RGBQuad color = colors[tmpData[offset_08++]];    pixelData[offset_24++] = color.rgbBlue;    pixelData[offset_24++] = color.rgbGreen;    pixelData[offset_24++] = color.rgbRed;   }// move indeces to next rowbegin_08 += pitch_bytes_08;begin_24 += pitch_bytes_24;    } return (true);};  Aha I cracked it!It was simply due to the fact that the indices were being treated as a signed char, and instead should have been unsigned.so tmpData is a pointer to unsigned char, instead of a pointer to char.Thanks for all your help!Cheers,- Joseph Paterson   ;  if ((pixelData = (char *) malloc (diff * sizeof (char))) == NULL) {if ((colors = (RGBQuad *)malloc (numColors * sizeof (RGBQuad))) == NULL) The above two lines need to be changed, they are a NO NO in C++.I would also change the struct to the following:#pragma pack(push,1)typedef struct {unsigned charrgbBlue;unsigned charrgbGreen;unsigned charrgbRed;unsigned charrgbReserved;} RGBQuad, *p_RGBQuad;#pragma pack(pop)   ;  Maybe I should say why there a NO NO lol. Casting the return value from malloc is valid C but not C++. :)   