/////////////////////////////////////////////////////////////////////////////
-// Name: imagbmp.cpp
+// Name: src/common/imagbmp.cpp
// Purpose: wxImage BMP,ICO and CUR handlers
// Author: Robert Roebling, Chris Elliott
// RCS-ID: $Id$
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-#pragma implementation "imagbmp.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
-#include "wx/defs.h"
-
#if wxUSE_IMAGE
#include "wx/imagbmp.h"
-#include "wx/bitmap.h"
-#include "wx/debug.h"
-#include "wx/log.h"
-#include "wx/app.h"
+
+#ifndef WX_PRECOMP
+ #ifdef __WXMSW__
+ #include "wx/msw/wrapwin.h"
+ #endif
+ #include "wx/log.h"
+ #include "wx/app.h"
+ #include "wx/bitmap.h"
+ #include "wx/palette.h"
+ #include "wx/intl.h"
+#endif
+
#include "wx/filefn.h"
#include "wx/wfstream.h"
-#include "wx/intl.h"
-#include "wx/module.h"
#include "wx/quantize.h"
+#include "wx/anidecod.h"
// For memcpy
#include <string.h>
#endif
#endif
-#ifdef __WXMSW__
-#include "wx/msw/wrapwin.h"
-#endif
-
//-----------------------------------------------------------------------------
// wxBMPHandler
//-----------------------------------------------------------------------------
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++)
+ for ( int 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;
+ // if 1BPP_BW then the value should be either 0 or 255
+ wxUint8 c = (wxUint8)((i > 0) && (format == wxBMP_1BPP_BW) ? 255 : i);
+
+ rgbquad[i*4] =
+ rgbquad[i*4+1] =
+ rgbquad[i*4+2] = c;
rgbquad[i*4+3] = 0;
}
}
{
pixel = 3*(y*width + x);
#if wxUSE_PALETTE
- buffer[x] = palette->GetPixel( data[pixel],
- data[pixel+1],
- data[pixel+2] );
+ buffer[x] = (wxUint8)palette->GetPixel( data[pixel],
+ data[pixel+1],
+ data[pixel+2] );
#else
// FIXME: what should this be? use some std palette maybe?
buffer[x] = 0;
// fill buffer, ignore if > width
#if wxUSE_PALETTE
- buffer[x/2] =
+ buffer[x/2] = (wxUint8)(
((wxUint8)palette->GetPixel(data[pixel],
data[pixel+1],
data[pixel+2]) << 4) |
? 0
: ((wxUint8)palette->GetPixel(data[pixel+3],
data[pixel+4],
- data[pixel+5]) ));
+ data[pixel+5]) )) );
#else
// FIXME: what should this be? use some std palette maybe?
buffer[x/2] = 0;
pixel = 3*(y*width + x);
#if wxUSE_PALETTE
- buffer[x/8] = ((wxUint8)palette->GetPixel(data[pixel], data[pixel+1], data[pixel+2]) << 7) |
+ buffer[x/8] = (wxUint8)(
+ ((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]) ));
+ (((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;
{
pixel = 3*(y*width + x);
- buffer[x/8] =
+ buffer[x/8] = (wxUint8)(
(((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+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.)) ));
+ (((x+7) > width) ? 0 : (((wxUint8)(data[pixel+21]/128.)) )) );
}
}
bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
int bpp, int ncolors, int comp,
- off_t bmpOffset, wxInputStream& stream,
+ wxFileOffset bmpOffset, wxInputStream& stream,
bool verbose, bool IsBmp, bool hasPalette)
{
wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0;
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;
+ r[j] = cmap[j].r =
+ g[j] = cmap[j].g =
+ b[j] = cmap[j].b = ( j ? 255 : 0 );
}
}
{
++readBytes ;
aByte = stream.GetC();
- nibble[0] = ( (aByte & 0xF0) >> 4 ) ;
- nibble[1] = ( aByte & 0x0F ) ;
+ nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ;
+ nibble[1] = (wxUint8)( aByte & 0x0F ) ;
}
ptr[poffset ] = cmap[nibble[k%2]].r;
ptr[poffset + 1] = cmap[nibble[k%2]].g;
else
{
wxUint8 nibble[2] ;
- nibble[0] = ( (aByte & 0xF0) >> 4 ) ;
- nibble[1] = ( aByte & 0x0F ) ;
+ nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ;
+ nibble[1] = (wxUint8)( aByte & 0x0F ) ;
for ( int l = 0; l < first && column < width; l++ )
{
to retrieve the color data out of the word. Then
shift it left by (8 - number of bits) such that
the image has the proper dynamic range */
- temp = (aWord & rmask) >> rshift << (8-rbits);
+ temp = (unsigned char)((aWord & rmask) >> rshift << (8-rbits));
ptr[poffset] = temp;
- temp = (aWord & gmask) >> gshift << (8-gbits);
+ temp = (unsigned char)((aWord & gmask) >> gshift << (8-gbits));
ptr[poffset + 1] = temp;
- temp = (aWord & bmask) >> bshift << (8-bbits);
+ temp = (unsigned char)((aWord & bmask) >> bshift << (8-bbits));
ptr[poffset + 2] = temp;
column++;
}
stream.Read(&aDword, 4);
aDword = wxINT32_SWAP_ON_BE(aDword);
linepos += 4;
- temp = (aDword & rmask) >> rshift;
+ temp = (unsigned char)((aDword & rmask) >> rshift);
ptr[poffset] = temp;
- temp = (aDword & gmask) >> gshift;
+ temp = (unsigned char)((aDword & gmask) >> gshift);
ptr[poffset + 1] = temp;
- temp = (aDword & bmask) >> bshift;
+ temp = (unsigned char)((aDword & bmask) >> bshift);
ptr[poffset + 2] = temp;
column++;
}
wxUint16 aWord;
wxInt32 dbuf[4];
wxInt8 bbuf[4];
- off_t offset;
- offset = 0; // keep gcc quiet
+ wxFileOffset offset = 0; // keep gcc quiet
if ( IsBmp )
{
// read the header off the .BMP format file
offset = stream.TellI();
- if (offset == wxInvalidOffset) offset = 0;
+ if (offset == wxInvalidOffset)
+ offset = 0;
stream.Read(bbuf, 2);
stream.Read(dbuf, 16);
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]);
+ int width = wxINT32_SWAP_ON_BE((int)dbuf[0]);
+ int height = wxINT32_SWAP_ON_BE((int)dbuf[1]);
if ( !IsBmp)height = height / 2; // for icons divide by 2
if ( width > 32767 )
int planes = (int)wxUINT16_SWAP_ON_BE( aWord );
*/
stream.Read(&aWord, 2);
- int bpp = (int)wxUINT16_SWAP_ON_BE(aWord);
+ int bpp = wxUINT16_SWAP_ON_BE((int)aWord);
if ( bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32 )
{
if (verbose)
}
stream.Read(dbuf, 4 * 4);
- int comp = (int)wxINT32_SWAP_ON_BE(dbuf[0]);
+ int comp = wxINT32_SWAP_ON_BE((int)dbuf[0]);
if ( comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 &&
comp != BI_BITFIELDS )
{
}
stream.Read(dbuf, 4 * 2);
- int ncolors = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
+ int ncolors = wxINT32_SWAP_ON_BE( (int)dbuf[0] );
if (ncolors == 0)
ncolors = 1 << bpp;
/* some more sanity checks */
verbose, IsBmp, true) )
{
if (verbose)
- wxLogError( _("Error in reading image DIB .") );
+ wxLogError( _("Error in reading image DIB.") );
return false;
}
return false;
}
- int images = 1; // only generate one image
+ const int images = 1; // only generate one image
// VS: This is a hack of sort - since ICO and CUR files are almost
// identical, we have all the meat in wxICOHandler and check for
ICONDIR IconDir;
IconDir.idReserved = 0;
- IconDir.idType = wxUINT16_SWAP_ON_BE(type);
- IconDir.idCount = wxUINT16_SWAP_ON_BE(images);
+ IconDir.idType = wxUINT16_SWAP_ON_BE((wxUint16)type);
+ IconDir.idCount = wxUINT16_SWAP_ON_BE((wxUint16)images);
stream.Write(&IconDir.idReserved, sizeof(IconDir.idReserved));
stream.Write(&IconDir.idType, sizeof(IconDir.idType));
stream.Write(&IconDir.idCount, sizeof(IconDir.idCount));
// for each iamage write a description ICONDIRENTRY:
ICONDIRENTRY icondirentry;
- for (int i = 0; i < images; i++)
+ for (int img = 0; img < images; img++)
{
wxImage mask;
}
wxUint32 Size = cStream.GetSize();
- // wxCountingOutputStream::Ok() always returns true for now and this
+ // wxCountingOutputStream::IsOk() always returns true for now and this
// "if" provokes VC++ warnings in optimized build
#if 0
if ( !cStream.Ok() )
offset = offset + sizeof(ICONDIRENTRY);
- icondirentry.bWidth = image->GetWidth();
- icondirentry.bHeight = 2 * image->GetHeight();
+ icondirentry.bWidth = (wxUint8)image->GetWidth();
+ icondirentry.bHeight = (wxUint8)(2 * image->GetHeight());
icondirentry.bColorCount = 0;
icondirentry.bReserved = 0;
icondirentry.wPlanes = wxUINT16_SWAP_ON_BE(1);
ICONDIR IconDir;
- off_t iPos = stream.TellI();
+ wxFileOffset iPos = stream.TellI();
stream.Read(&IconDir, sizeof(IconDir));
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
// nType is 1 for Icons, 2 for Cursors:
int wxICOHandler::GetImageCount(wxInputStream& stream)
{
ICONDIR IconDir;
- off_t iPos = stream.TellI();
+ wxFileOffset iPos = stream.TellI();
stream.SeekI(0);
stream.Read(&IconDir, sizeof(IconDir));
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
#if wxUSE_STREAMS
bool wxANIHandler::LoadFile(wxImage *image, wxInputStream& stream,
- bool verbose, int index)
+ bool WXUNUSED(verbose), int index)
{
- wxInt32 FCC1, FCC2;
- wxUint32 datalen;
-
- wxInt32 riff32;
- memcpy( &riff32, "RIFF", 4 );
- wxInt32 list32;
- memcpy( &list32, "LIST", 4 );
- wxInt32 ico32;
- memcpy( &ico32, "icon", 4 );
- int iIcon = 0;
-
- stream.SeekI(0);
- stream.Read(&FCC1, 4);
- if ( FCC1 != riff32 )
+ wxANIDecoder decoder;
+ if (!decoder.Load(stream))
return false;
- // we have a riff file:
- while (stream.IsOk())
- {
- // we always have a data size
- stream.Read(&datalen, 4);
- datalen = wxINT32_SWAP_ON_BE(datalen) ;
- //data should be padded to make even number of bytes
- if (datalen % 2 == 1) datalen ++ ;
- //now either data or a FCC
- if ( (FCC1 == riff32) || (FCC1 == list32) )
- {
- stream.Read(&FCC2, 4);
- }
- else
- {
- if (FCC1 == ico32 && iIcon >= index)
- {
- return DoLoadFile(image, stream, verbose, -1);
- }
- else
- {
- stream.SeekI(stream.TellI() + datalen);
- if ( FCC1 == ico32 )
- iIcon ++;
- }
- }
-
- // try to read next data chunk:
- stream.Read(&FCC1, 4);
- }
- return false;
+ return decoder.ConvertToImage(index != -1 ? (size_t)index : 0, image);
}
bool wxANIHandler::DoCanRead(wxInputStream& stream)
{
- wxInt32 FCC1, FCC2;
- wxUint32 datalen ;
-
- wxInt32 riff32;
- memcpy( &riff32, "RIFF", 4 );
- wxInt32 list32;
- memcpy( &list32, "LIST", 4 );
- wxInt32 ico32;
- memcpy( &ico32, "icon", 4 );
- wxInt32 anih32;
- memcpy( &anih32, "anih", 4 );
-
- stream.SeekI(0);
- if ( !stream.Read(&FCC1, 4) )
- return false;
-
- if ( FCC1 != riff32 )
- return false;
-
- // we have a riff file:
- while ( stream.IsOk() )
- {
- if ( FCC1 == anih32 )
- return true;
- // we always have a data size:
- stream.Read(&datalen, 4);
- datalen = wxINT32_SWAP_ON_BE(datalen) ;
- //data should be padded to make even number of bytes
- if (datalen % 2 == 1) datalen ++ ;
- // now either data or a FCC:
- if ( (FCC1 == riff32) || (FCC1 == list32) )
- {
- stream.Read(&FCC2, 4);
- }
- else
- {
- stream.SeekI(stream.TellI() + datalen);
- }
-
- // try to read next data chunk:
- if ( !stream.Read(&FCC1, 4) )
- {
- // reading failed -- either EOF or IO error, bail out anyhow
- return false;
- }
- }
-
- return false;
+ wxANIDecoder decod;
+ return decod.CanRead(stream);
}
int wxANIHandler::GetImageCount(wxInputStream& stream)
{
- wxInt32 FCC1, FCC2;
- wxUint32 datalen ;
-
- wxInt32 riff32;
- memcpy( &riff32, "RIFF", 4 );
- wxInt32 list32;
- memcpy( &list32, "LIST", 4 );
- wxInt32 ico32;
- memcpy( &ico32, "icon", 4 );
- wxInt32 anih32;
- memcpy( &anih32, "anih", 4 );
-
- stream.SeekI(0);
- stream.Read(&FCC1, 4);
- if ( FCC1 != riff32 )
+ wxANIDecoder decoder;
+ if (!decoder.Load(stream))
return wxNOT_FOUND;
- // we have a riff file:
- while ( stream.IsOk() )
- {
- // we always have a data size:
- stream.Read(&datalen, 4);
- datalen = wxINT32_SWAP_ON_BE(datalen) ;
- //data should be padded to make even number of bytes
- if (datalen % 2 == 1) datalen ++ ;
- // now either data or a FCC:
- if ( (FCC1 == riff32) || (FCC1 == list32) )
- {
- stream.Read(&FCC2, 4);
- }
- else
- {
- if ( FCC1 == anih32 )
- {
- wxUint32 *pData = new wxUint32[datalen/4];
- stream.Read(pData, datalen);
- int nIcons = wxINT32_SWAP_ON_BE(*(pData + 1));
- delete[] pData;
- return nIcons;
- }
- else
- stream.SeekI(stream.TellI() + datalen);
- }
-
- // try to read next data chunk:
- stream.Read(&FCC1, 4);
- }
-
- return wxNOT_FOUND;
+ return decoder.GetFrameCount();
}
#endif // wxUSE_STREAMS