(format == wxBMP_8BPP_RED) || (format == wxBMP_8BPP_PALETTE))
{
// need to set a wxPalette to use this, HOW TO CHECK IF VALID, SIZE?
- if ((format == wxBMP_8BPP_PALETTE) && !image->HasPalette())
+ if ((format == wxBMP_8BPP_PALETTE)
+#if wxUSE_PALETTE
+ && !image->HasPalette()
+#endif // wxUSE_PALETTE
+ )
{
if (verbose)
wxLogError(_("BMP: wImage doesn't have own wxPalette."));
}
else
{
+#if wxUSE_PALETTE
palette = new wxPalette(image->GetPalette());
+#endif // wxUSE_PALETTE
}
int i;
for (i=0; i<palette_size; i++)
{
- if (!palette->GetRGB( i, &r, &g, &b )) r = g = b = 0;
+#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;
{
if (!stream.Write(rgbquad, palette_size*4))
{
- if (verbose) wxLogError(_("BMP: Couldn't write RGB color map."));
- delete []rgbquad;
- if (palette) delete palette;
- if (q_image) delete q_image;
+ 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;
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
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]) ));
+ ((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"
{
pixel = 3*(y*width + x);
- buffer[x/8] =
- ((wxUint8)palette->GetPixel(data[pixel], data[pixel+1], data[pixel+2]) << 7) |
+#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+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
if (verbose)
wxLogError(_("BMP: Couldn't write data."));
delete[] buffer;
- if (palette) delete palette;
- if (q_image) delete q_image;
+#if wxUSE_PALETTE
+ delete palette;
+#endif // wxUSE_PALETTE
+ delete q_image;
return FALSE;
}
}
delete[] buffer;
- if (palette) delete palette;
- if (q_image) delete q_image;
+#if wxUSE_PALETTE
+ delete palette;
+#endif // wxUSE_PALETTE
+ delete q_image;
return TRUE;
}
#define poffset (line * width * 3 + column * 3)
-bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
-{
- int rshift = 0, gshift = 0, bshift = 0;
- wxUint8 aByte;
- wxUint16 aWord;
- wxInt32 dbuf[4];
- wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0;
- wxInt8 bbuf[4];
- struct _cmap {
- unsigned char r, g, b;
- } *cmap = NULL;
-
- off_t start_offset = stream.TellI();
- if (start_offset == wxInvalidOffset) start_offset = 0;
-
- image->Destroy();
- /*
- * Read the BMP header
- */
- stream.Read( bbuf, 2 );
- stream.Read( dbuf, 4 * 4 );
+struct ICONDIRENTRY
+ {
+ wxUint8 bWidth; // Width of the image
+ wxUint8 bHeight; // Height of the image (times 2)
+ wxUint8 bColorCount; // Number of colors in image (0 if >=8bpp)
+ wxUint8 bReserved; // Reserved
+ wxUint16 wPlanes; // Color Planes
+ wxUint16 wBitCount; // Bits per pixel
+ wxUint32 dwBytesInRes; // how many bytes in this resource?
+ wxUint32 dwImageOffset; // where in the file is this image
+} ;
+
+
+struct ICONDIR
+{
+ wxUint16 idReserved; // Reserved
+ wxUint16 idType; // resource type (1 for icons)
+ wxUint16 idCount; // how many images?
+} ;
-#if 0 // unused
- wxInt32 size = wxINT32_SWAP_ON_BE( dbuf[0] );
-#endif
- wxInt32 offset = wxINT32_SWAP_ON_BE( dbuf[2] );
- stream.Read(dbuf, 4 * 2);
- int width = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
- int height = (int)wxINT32_SWAP_ON_BE( dbuf[1] );
- if (width > 32767)
+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 )
{
- if (verbose)
- wxLogError( _("BMP: Image width > 32767 pixels for file.") );
- return FALSE;
- }
- if (height > 32767)
- {
- if (verbose)
- wxLogError( _("BMP: Image height > 32767 pixels for file.") );
- return FALSE;
- }
- stream.Read( &aWord, 2 );
-/*
- TODO
- int planes = (int)wxUINT16_SWAP_ON_BE( aWord );
-*/
- stream.Read( &aWord, 2 );
- int bpp = (int)wxUINT16_SWAP_ON_BE( aWord );
- if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32)
- {
- if (verbose)
- wxLogError( _("BMP: Unknown bitdepth in file.") );
- return FALSE;
- }
+ 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;
- stream.Read( dbuf, 4 * 4 );
- int comp = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
- if (comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 && comp != BI_BITFIELDS)
- {
- if (verbose)
- wxLogError( _("BMP: Unknown encoding in file.") );
- return FALSE;
- }
- stream.Read( dbuf, 4 * 2 );
- int ncolors = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
- if (ncolors == 0)
- ncolors = 1 << bpp;
- /* some more sanity checks */
- if (((comp == BI_RLE4) && (bpp != 4)) ||
- ((comp == BI_RLE8) && (bpp != 8)) ||
- ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
+ // allocate space for palette if needed
+ struct _cmap
{
- if (verbose)
- wxLogError( _("BMP: Encoding doesn't match bitdepth.") );
- return FALSE;
+ unsigned char r, g, b;
}
+ *cmap = NULL;
+
if (bpp < 16)
{
cmap = (struct _cmap *)malloc(sizeof(struct _cmap) * ncolors);
if (!cmap)
{
if (verbose)
- wxLogError( _("BMP: Couldn't allocate memory.") );
+ wxLogError( _("Loading DIB : Couldn't allocate memory.") );
return FALSE;
}
}
else
cmap = NULL;
+ // destroy existing here instead of
+ image->Destroy();
image->Create( width, height );
unsigned char *ptr = image->GetData();
if (!ptr)
{
if (verbose)
- wxLogError( _("BMP: Couldn't allocate memory.") );
+ wxLogError( _("Loading DIB : Couldn't allocate memory.") );
if (cmap)
free(cmap);
return FALSE;
}
-
/*
* Reading the palette, if it exists.
*/
unsigned char* b = new unsigned char[ncolors];
for (int j = 0; j < ncolors; j++)
{
+ if (hasPalette)
+ {
stream.Read( bbuf, 4 );
cmap[j].b = bbuf[0];
cmap[j].g = bbuf[1];
g[j] = cmap[j].g;
b[j] = cmap[j].b;
}
+ else
+ {
+ //used in reading .ico file mask
+ r[j] = cmap[j].r = j * 255;
+ g[j] = cmap[j].g = j * 255;
+ b[j] = cmap[j].b = j * 255;
+ }
+ }
+
+#if wxUSE_PALETTE
// Set the palette for the wxImage
image->SetPalette(wxPalette(ncolors, r, g, b));
+#endif // wxUSE_PALETTE
delete[] r;
delete[] g;
/*
* Reading the image data
*/
- stream.SeekI( start_offset + offset );
+ if ( IsBmp ) stream.SeekI( bmpOffset ); // else icon, just carry on
+
unsigned char *data = ptr;
/* set the whole image to the background color */
if (comp == BI_RLE4)
{
if (verbose)
- wxLogError( _("BMP: Cannot deal with 4bit encoded yet.") );
+ wxLogError( _("DIB Header: Cannot deal with 4bit encoded yet.") );
image->Destroy();
free(cmap);
return FALSE;
image->SetMask( FALSE );
+ return stream.IsOk();
+}
+
+
+bool wxBMPHandler::LoadDib( wxImage *image, wxInputStream& stream, bool verbose, bool IsBmp )
+{
+ wxUint16 aWord;
+ wxInt32 dbuf[4];
+ wxInt8 bbuf[4];
+ off_t offset;
+
+ offset = 0; // keep gcc quiet
+ if ( IsBmp )
+ {
+ // read the header off the .BMP format file
+
+ offset = stream.TellI();
+ if (offset == wxInvalidOffset) offset = 0;
+
+ stream.Read( bbuf, 2 );
+
+ stream.Read( dbuf, 16 );
+ }
+ else
+ {
+ stream.Read( dbuf, 4 );
+ }
+ #if 0 // unused
+ wxInt32 size = wxINT32_SWAP_ON_BE( dbuf[0] );
+ #endif
+ offset = offset + wxINT32_SWAP_ON_BE( dbuf[2] );
+
+ stream.Read(dbuf, 4 * 2);
+ int width = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
+ int height = (int)wxINT32_SWAP_ON_BE( dbuf[1] );
+ if ( !IsBmp ) height = height / 2; // for icons divide by 2
+
+ if (width > 32767)
+ {
+ if (verbose)
+ wxLogError( _("DIB Header: Image width > 32767 pixels for file.") );
+ return FALSE;
+ }
+ if (height > 32767)
+ {
+ if (verbose)
+ wxLogError( _("DIB Header: Image height > 32767 pixels for file.") );
+ return FALSE;
+ }
+
+ stream.Read( &aWord, 2 );
+ /*
+ TODO
+ int planes = (int)wxUINT16_SWAP_ON_BE( aWord );
+ */
+ stream.Read( &aWord, 2 );
+ int bpp = (int)wxUINT16_SWAP_ON_BE( aWord );
+ if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32)
+ {
+ if (verbose)
+ wxLogError( _("DIB Header: Unknown bitdepth in file.") );
+ return FALSE;
+ }
+
+ stream.Read( dbuf, 4 * 4 );
+ int comp = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
+ if (comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 && comp != BI_BITFIELDS)
+ {
+ if (verbose)
+ wxLogError( _("DIB Header: Unknown encoding in file.") );
+ return FALSE;
+ }
+
+ stream.Read( dbuf, 4 * 2 );
+ int ncolors = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
+ if (ncolors == 0)
+ ncolors = 1 << bpp;
+ /* some more sanity checks */
+ if (((comp == BI_RLE4) && (bpp != 4)) ||
+ ((comp == BI_RLE8) && (bpp != 8)) ||
+ ((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
+ {
+ if (verbose)
+ wxLogError( _("DIB Header: Encoding doesn't match bitdepth.") );
+ return FALSE;
+ }
+
+ //read DIB; this is the BMP image or the XOR part of an icon image
+ if (!DoLoadDib (image, width, height, bpp, ncolors, comp, offset, stream,
+ verbose, IsBmp, TRUE ) )
+ {
+ if (verbose)
+ wxLogError( _("Error in reading image DIB .") );
+ return FALSE;
+ }
+
+ if ( !IsBmp )
+ {
+ //read Icon mask which is monochrome
+ //there is no palette, so we will create one
+ wxImage mask;
+ if (!DoLoadDib (&mask, width, height, 1, 2, BI_RGB, offset, stream,
+ verbose, IsBmp, FALSE ) )
+ {
+ if (verbose)
+ wxLogError( _("ICO: Error in reading mask DIB.") );
+ return FALSE;
+ }
+ image->SetMaskFromImage(mask, 255, 255, 255);
+
+ }
return TRUE;
}
+
+bool wxBMPHandler::LoadFile ( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
+{
+ bool IsBmp = TRUE;
+ //Read a single DIB fom the file
+ return LoadDib ( image, stream, verbose, IsBmp ) ;
+}
+
+
+
+bool wxICOHandler::LoadFile ( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
+{
+ bool bResult = FALSE ;
+ bool IsBmp = FALSE;
+
+ ICONDIR m_IconDir ;
+ stream.Read (&m_IconDir, sizeof(m_IconDir));
+ wxUint16 nIcons = wxUINT16_SWAP_ON_BE ( m_IconDir.idCount ) ;
+
+ //loop round the icons and choose the best one
+ ICONDIRENTRY * pIconDirEntry = new ICONDIRENTRY [nIcons];
+ ICONDIRENTRY * pCurrentEntry = pIconDirEntry ;
+ int i ;
+ int wMax = 0 ;
+ int colmax = 0 ;
+ int iSel = wxNOT_FOUND ;
+ for (i=0; i < nIcons ; i++ )
+ {
+ stream.Read(pCurrentEntry, sizeof(ICONDIRENTRY));
+ //bHeight and bColorCount are wxUint8
+ if (pCurrentEntry->bWidth >= wMax )
+ {
+ // see if we have more colors, ==0 indicates > 8bpp
+ if (pCurrentEntry->bColorCount == 0 ) pCurrentEntry->bColorCount = 255 ;
+ if (pCurrentEntry->bColorCount >= colmax)
+ {
+ iSel = i ;
+ wMax = pCurrentEntry->bWidth ;
+ colmax = pCurrentEntry->bColorCount ;
+ }
+ }
+ pCurrentEntry ++ ;
+ }
+ if (iSel == wxNOT_FOUND)
+ {
+ bResult = FALSE;
+ }
+ else
+ {
+ //seek to selected icon
+ pCurrentEntry = pIconDirEntry + iSel ;
+ stream.SeekI (wxUINT32_SWAP_ON_BE ( pCurrentEntry -> dwImageOffset ), wxFromStart ) ;
+ bResult = LoadDib ( image, stream, TRUE, IsBmp );
+ }
+ delete [] pIconDirEntry ;
+ return bResult
+ ;
+}
+
+bool wxICOHandler::SaveFile(wxImage *image,
+ wxOutputStream& stream,
+ bool verbose)
+{
+ return FALSE ;
+}
+
bool wxBMPHandler::DoCanRead( wxInputStream& stream )
{
unsigned char hdr[2];
return (hdr[0] == 'B' && hdr[1] == 'M');
}
+bool wxICOHandler::DoCanRead( wxInputStream& stream )
+{
+ unsigned char hdr[4];
+
+ stream.Read(hdr, 4);
+ stream.SeekI(-4, wxFromCurrent);
+ return (hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\1' && hdr[3] == '\0');
+}
+
#endif // wxUSE_STREAMS
#endif // wxUSE_IMAGE