+ }
+
+ wxPalette *palette = NULL; // entries for quantized images
+ wxUint8 *rgbquad = NULL; // for the RGBQUAD bytes for the colormap
+ wxImage *q_image = NULL; // destination for quantized image
+
+ // if <24bpp use quantization to reduce colors for *some* of the formats
+ if ( (format == wxBMP_1BPP) || (format == wxBMP_4BPP) ||
+ (format == wxBMP_8BPP) || (format == wxBMP_8BPP_PALETTE))
+ {
+ // make a new palette and quantize the image
+ if (format != wxBMP_8BPP_PALETTE)
+ {
+ q_image = new wxImage();
+
+ // I get a delete error using Quantize when desired colors > 236
+ int quantize = ((palette_size > 236) ? 236 : palette_size);
+ // fill the destination too, it gives much nicer 4bpp images
+ wxQuantize::Quantize( *image, *q_image, &palette, quantize, 0,
+ wxQUANTIZE_FILL_DESTINATION_IMAGE );
+ }
+ else
+ {
+#if wxUSE_PALETTE
+ palette = new wxPalette(image->GetPalette());
+#endif // wxUSE_PALETTE
+ }
+
+ int i;
+ unsigned char r, g, b;
+ rgbquad = new wxUint8 [palette_size*4];
+
+ for (i=0; i<palette_size; i++)
+ {
+#if wxUSE_PALETTE
+ if (!palette->GetRGB( i, &r, &g, &b ))
+#endif // wxUSE_PALETTE
+ r = g = b = 0;
+
+ rgbquad[i*4] = b;
+ rgbquad[i*4+1] = g;
+ rgbquad[i*4+2] = r;
+ rgbquad[i*4+3] = 0;
+ }
+ }
+ // make a 256 entry greyscale colormap or 2 entry black & white
+ else if ((format == wxBMP_8BPP_GREY) || (format == wxBMP_8BPP_RED) ||
+ (format == wxBMP_1BPP_BW))
+ {
+ int i;
+ rgbquad = new wxUint8 [palette_size*4];
+
+ for (i=0; i<palette_size; i++)
+ {
+ // if 1BPP_BW then just 0 and 255 then exit
+ if (( i > 0) && (format == wxBMP_1BPP_BW)) i = 255;
+ rgbquad[i*4] = i;
+ rgbquad[i*4+1] = i;
+ rgbquad[i*4+2] = i;
+ rgbquad[i*4+3] = 0;
+ }
+ }
+
+ // if the colormap was made, then it needs to be written
+ if (rgbquad)
+ {
+ if (!IsMask)
+ {
+ if (!stream.Write(rgbquad, palette_size*4))
+ {
+ if (verbose)
+ wxLogError(_("BMP: Couldn't write RGB color map."));
+ delete [] rgbquad;
+#if wxUSE_PALETTE
+ delete palette;
+#endif // wxUSE_PALETTE
+ delete q_image;
+ return FALSE;
+ }
+ }
+ delete []rgbquad;
+ }
+
+ // pointer to the image data, use quantized if available
+ wxUint8 *data = (wxUint8*) image->GetData();
+ if (q_image) if (q_image->Ok()) data = (wxUint8*) q_image->GetData();
+
+ wxUint8 *buffer = new wxUint8[row_width];
+ memset(buffer, 0, row_width);
+ int y; unsigned x;
+ long int pixel;
+
+ for (y = image->GetHeight() -1 ; y >= 0; y--)
+ {
+ if (format == wxBMP_24BPP) // 3 bytes per pixel red,green,blue
+ {
+ for (x = 0; x < width; x++)
+ {
+ pixel = 3*(y*width + x);
+
+ buffer[3*x ] = data[pixel+2];
+ buffer[3*x + 1] = data[pixel+1];
+ buffer[3*x + 2] = data[pixel];
+ }
+ }
+ else if ((format == wxBMP_8BPP) || // 1 byte per pixel in color
+ (format == wxBMP_8BPP_PALETTE))
+ {
+ for (x = 0; x < width; x++)
+ {
+ pixel = 3*(y*width + x);
+#if wxUSE_PALETTE
+ buffer[x] = palette->GetPixel( data[pixel],
+ data[pixel+1],
+ data[pixel+2] );
+#else
+ // FIXME: what should this be? use some std palette maybe?
+ buffer[x] = 0;
+#endif // wxUSE_PALETTE
+ }
+ }
+ else if (format == wxBMP_8BPP_GREY) // 1 byte per pix, rgb ave to grey
+ {
+ for (x = 0; x < width; x++)
+ {
+ pixel = 3*(y*width + x);
+ buffer[x] = (wxUint8)(.299*data[pixel] +
+ .587*data[pixel+1] +
+ .114*data[pixel+2]);
+ }
+ }
+ else if (format == wxBMP_8BPP_RED) // 1 byte per pixel, red as greys
+ {
+ for (x = 0; x < width; x++)
+ {
+ buffer[x] = (wxUint8)data[3*(y*width + x)];
+ }
+ }
+ else if (format == wxBMP_4BPP) // 4 bpp in color
+ {
+ for (x = 0; x < width; x+=2)
+ {
+ pixel = 3*(y*width + x);
+
+ // fill buffer, ignore if > width
+#if wxUSE_PALETTE
+ buffer[x/2] =
+ ((wxUint8)palette->GetPixel(data[pixel],
+ data[pixel+1],
+ data[pixel+2]) << 4) |
+ (((x+1) > width)
+ ? 0
+ : ((wxUint8)palette->GetPixel(data[pixel+3],
+ data[pixel+4],
+ data[pixel+5]) ));
+#else
+ // FIXME: what should this be? use some std palette maybe?
+ buffer[x/2] = 0;
+#endif // wxUSE_PALETTE
+ }
+ }
+ else if (format == wxBMP_1BPP) // 1 bpp in "color"
+ {
+ for (x = 0; x < width; x+=8)
+ {
+ pixel = 3*(y*width + x);
+
+#if wxUSE_PALETTE
+ buffer[x/8] = ((wxUint8)palette->GetPixel(data[pixel], data[pixel+1], data[pixel+2]) << 7) |
+ (((x+1) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+3], data[pixel+4], data[pixel+5]) << 6)) |
+ (((x+2) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+6], data[pixel+7], data[pixel+8]) << 5)) |
+ (((x+3) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+9], data[pixel+10], data[pixel+11]) << 4)) |
+ (((x+4) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+12], data[pixel+13], data[pixel+14]) << 3)) |
+ (((x+5) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+15], data[pixel+16], data[pixel+17]) << 2)) |
+ (((x+6) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+18], data[pixel+19], data[pixel+20]) << 1)) |
+ (((x+7) > width) ? 0 : ((wxUint8)palette->GetPixel(data[pixel+21], data[pixel+22], data[pixel+23]) ));
+#else
+ // FIXME: what should this be? use some std palette maybe?
+ buffer[x/8] = 0;
+#endif // wxUSE_PALETTE
+ }
+ }
+ else if (format == wxBMP_1BPP_BW) // 1 bpp B&W colormap from red color ONLY
+ {
+ for (x = 0; x < width; x+=8)
+ {
+ pixel = 3*(y*width + x);
+
+ buffer[x/8] =
+ (((wxUint8)(data[pixel] /128.)) << 7) |
+ ( ((x+1) > width) ? 0 : (((wxUint8)(data[pixel+3] /128.)) << 6)) |
+ ( ((x+2) > width) ? 0 : (((wxUint8)(data[pixel+6] /128.)) << 5)) |
+ ( ((x+3) > width) ? 0 : (((wxUint8)(data[pixel+9] /128.)) << 4)) |
+ ( ((x+4) > width) ? 0 : (((wxUint8)(data[pixel+12]/128.)) << 3)) |
+ ( ((x+5) > width) ? 0 : (((wxUint8)(data[pixel+15]/128.)) << 2)) |
+ ( ((x+6) > width) ? 0 : (((wxUint8)(data[pixel+18]/128.)) << 1)) |
+ ( ((x+7) > width) ? 0 : (((wxUint8)(data[pixel+21]/128.)) ));
+ }
+ }
+
+ if (!stream.Write(buffer, row_width))
+ {
+ if (verbose)
+ wxLogError(_("BMP: Couldn't write data."));
+ delete[] buffer;
+#if wxUSE_PALETTE
+ delete palette;
+#endif // wxUSE_PALETTE
+ delete q_image;
+ return FALSE;
+ }
+ }
+ delete[] buffer;
+#if wxUSE_PALETTE
+ delete palette;
+#endif // wxUSE_PALETTE
+ delete q_image;
+
+ return TRUE;
+}
+
+
+
+
+bool wxBMPHandler::DoLoadDib (wxImage * image, int width, int height, int bpp, int ncolors, int comp,
+ off_t bmpOffset, wxInputStream& stream,
+ bool verbose, bool IsBmp, bool hasPalette )
+ {
+
+ wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0;
+ int rshift = 0, gshift = 0, bshift = 0;
+ wxInt32 dbuf[4];
+ wxInt8 bbuf[4];
+ wxUint8 aByte;
+ wxUint16 aWord;
+
+
+ // allocate space for palette if needed
+ struct _cmap
+ {
+ unsigned char r, g, b;
+ }
+ *cmap = NULL;
+