X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0bddb3cc6fbe51996d0cab95f8ce46017a8d0311..eea4d01c65f9b29baa1193db762b4c6b8144af24:/src/common/imagpcx.cpp?ds=sidebyside diff --git a/src/common/imagpcx.cpp b/src/common/imagpcx.cpp index 3b806c35f4..fdbb60c16d 100644 --- a/src/common/imagpcx.cpp +++ b/src/common/imagpcx.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: imagpcx.cpp +// Name: src/common/imagpcx.cpp // Purpose: wxImage PCX handler // Author: Guillermo Rodriguez Garcia // Version: 1.1 @@ -8,32 +8,35 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "imagpcx.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_IMAGE && wxUSE_PCX + #ifndef WX_PRECOMP -# include "wx/defs.h" + #include "wx/object.h" + #include "wx/list.h" + #include "wx/log.h" + #include "wx/intl.h" + #include "wx/palette.h" + #include "wx/hash.h" + #include "wx/module.h" #endif -#if wxUSE_STREAMS && wxUSE_PCX - #include "wx/imagpcx.h" #include "wx/wfstream.h" -#include "wx/module.h" -#include "wx/log.h" -#include "wx/intl.h" -#include "wx/hash.h" -#include "wx/list.h" -#include "wx/object.h" +//----------------------------------------------------------------------------- +// wxPCXHandler +//----------------------------------------------------------------------------- + +IMPLEMENT_DYNAMIC_CLASS(wxPCXHandler,wxImageHandler) + +#if wxUSE_STREAMS //----------------------------------------------------------------------------- // RLE encoding and decoding @@ -84,33 +87,33 @@ void RLEencode(unsigned char *p, unsigned int size, wxOutputStream& s) void RLEdecode(unsigned char *p, unsigned int size, wxInputStream& s) { - unsigned int i, data, cont; - // Read 'size' bytes. The PCX official specs say there will be // a decoding break at the end of each scanline (but not at the // end of each plane inside a scanline). Only use this function // to read one or more _complete_ scanlines. Else, more than // 'size' bytes might be read and the buffer might overflow. - while (size > 0) + while (size != 0) { - data = (unsigned char)s.GetC(); + unsigned int data = (unsigned char)s.GetC(); // If ((data & 0xC0) != 0xC0), then the value read is a data // byte. Else, it is a counter (cont = val & 0x3F) and the // next byte is the data byte. - // + if ((data & 0xC0) != 0xC0) { - *(p++) = data; + *(p++) = (unsigned char)data; size--; } else { - cont = data & 0x3F; + unsigned int cont = data & 0x3F; + if (cont > size) // can happen only if the file is malformed + break; data = (unsigned char)s.GetC(); - for (i = 1; i <= cont; i++) - *(p++) = data; + for (unsigned int i = 1; i <= cont; i++) + *(p++) = (unsigned char)data; size -= cont; } } @@ -211,7 +214,7 @@ int ReadPCX(wxImage *image, wxInputStream& stream) image->Create(width, height); - if (!image->Ok()) + if (!image->IsOk()) return wxPCX_MEMERR; if ((p = (unsigned char *) malloc(bytesperline * nplanes)) == NULL) @@ -276,6 +279,19 @@ int ReadPCX(wxImage *image, wxInputStream& stream) *(p++) = pal[3 * index + 1]; *(p++) = pal[3 * index + 2]; } + +#if wxUSE_PALETTE + unsigned char r[256]; + unsigned char g[256]; + unsigned char b[256]; + for (i = 0; i < 256; i++) + { + r[i] = pal[3*i + 0]; + g[i] = pal[3*i + 1]; + b[i] = pal[3*i + 2]; + } + image->SetPalette(wxPalette(256, r, g, b)); +#endif // wxUSE_PALETTE } return wxPCX_OK; @@ -296,9 +312,9 @@ int SavePCX(wxImage *image, wxOutputStream& stream) unsigned char *src; // pointer into wxImage data unsigned int width, height; // size of the image unsigned int bytesperline; // bytes per line (each plane) - int nplanes = 3; // number of planes + unsigned char nplanes = 3; // number of planes int format = wxPCX_24BIT; // image format (8 bit, 24 bit) - wxHashTable h(wxKEY_INTEGER); // image histogram + wxImageHistogram histogram; // image histogram unsigned long key; // key in the hashtable unsigned int i; @@ -306,7 +322,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) if (image->CountColours(256) <= 256) { - image->ComputeHistogram(h); + image->ComputeHistogram(histogram); format = wxPCX_8BIT; nplanes = 1; } @@ -315,7 +331,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) // according to PCX specs) and allocate space for one complete // scanline. - if (!image->Ok()) + if (!image->IsOk()) return wxPCX_INVFORMAT; width = image->GetWidth(); @@ -337,12 +353,12 @@ int SavePCX(wxImage *image, wxOutputStream& stream) hdr[HDR_ENCODING] = 1; hdr[HDR_NPLANES] = nplanes; hdr[HDR_BITSPERPIXEL] = 8; - hdr[HDR_BYTESPERLINE] = bytesperline % 256; - hdr[HDR_BYTESPERLINE + 1] = bytesperline / 256; - hdr[HDR_XMAX] = (width - 1) % 256; - hdr[HDR_XMAX + 1] = (width - 1) / 256; - hdr[HDR_YMAX] = (height - 1) % 256; - hdr[HDR_YMAX + 1] = (height - 1) / 256; + hdr[HDR_BYTESPERLINE] = (unsigned char)(bytesperline % 256); + hdr[HDR_BYTESPERLINE + 1] = (unsigned char)(bytesperline / 256); + hdr[HDR_XMAX] = (unsigned char)((width - 1) % 256); + hdr[HDR_XMAX + 1] = (unsigned char)((width - 1) / 256); + hdr[HDR_YMAX] = (unsigned char)((height - 1) % 256); + hdr[HDR_YMAX + 1] = (unsigned char)((height - 1) / 256); hdr[HDR_PALETTEINFO] = 1; stream.Write(hdr, 128); @@ -358,7 +374,6 @@ int SavePCX(wxImage *image, wxOutputStream& stream) case wxPCX_8BIT: { unsigned char r, g, b; - wxHNode *hnode; for (i = 0; i < width; i++) { @@ -367,8 +382,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) b = *(src++); key = (r << 16) | (g << 8) | b; - hnode = (wxHNode *) h.Get(key); - p[i] = (unsigned char)hnode->index; + p[i] = (unsigned char)histogram[key].index; } break; } @@ -389,26 +403,22 @@ int SavePCX(wxImage *image, wxOutputStream& stream) free(p); - // For 8 bit images, build the palette and write it to the stream - + // For 8 bit images, build the palette and write it to the stream: if (format == wxPCX_8BIT) { - wxNode *node; - wxHNode *hnode; - // zero unused colours memset(pal, 0, sizeof(pal)); - h.BeginFind(); - while ((node = h.Next()) != NULL) - { - key = node->GetKeyInteger(); - hnode = (wxHNode *) node->GetData(); + unsigned long index; - pal[3 * hnode->index] = (unsigned char)(key >> 16); - pal[3 * hnode->index + 1] = (unsigned char)(key >> 8); - pal[3 * hnode->index + 2] = (unsigned char)(key); - delete hnode; + for (wxImageHistogram::iterator entry = histogram.begin(); + entry != histogram.end(); ++entry ) + { + key = entry->first; + index = entry->second.index; + pal[3 * index] = (unsigned char)(key >> 16); + pal[3 * index + 1] = (unsigned char)(key >> 8); + pal[3 * index + 2] = (unsigned char)(key); } stream.PutC(12); @@ -422,8 +432,6 @@ int SavePCX(wxImage *image, wxOutputStream& stream) // wxPCXHandler //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxPCXHandler,wxImageHandler) - bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) ) { int error; @@ -431,9 +439,11 @@ bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose if (!CanRead(stream)) { if (verbose) + { wxLogError(_("PCX: this is not a PCX file.")); + } - return FALSE; + return false; } image->Destroy(); @@ -444,17 +454,17 @@ bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose { switch (error) { - case wxPCX_INVFORMAT: wxLogError(_("wxPCXHandler: image format unsupported")); break; - case wxPCX_MEMERR: wxLogError(_("wxPCXHandler: couldn't allocate memory")); break; - case wxPCX_VERERR: wxLogError(_("wxPCXHandler: version number too low")); break; - default: wxLogError(_("wxPCXHandler: unknown error !!!")); + case wxPCX_INVFORMAT: wxLogError(_("PCX: image format unsupported")); break; + case wxPCX_MEMERR: wxLogError(_("PCX: couldn't allocate memory")); break; + case wxPCX_VERERR: wxLogError(_("PCX: version number too low")); break; + default: wxLogError(_("PCX: unknown error !!!")); } } image->Destroy(); - return FALSE; + return false; } - return TRUE; + return true; } bool wxPCXHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose ) @@ -467,9 +477,9 @@ bool wxPCXHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos { switch (error) { - case wxPCX_INVFORMAT: wxLogError(_("wxPCXHandler: invalid image")); break; - case wxPCX_MEMERR: wxLogError(_("wxPCXHandler: couldn't allocate memory")); break; - default: wxLogError(_("wxPCXHandler: unknown error !!!")); + case wxPCX_INVFORMAT: wxLogError(_("PCX: invalid image")); break; + case wxPCX_MEMERR: wxLogError(_("PCX: couldn't allocate memory")); break; + default: wxLogError(_("PCX: unknown error !!!")); } } } @@ -479,14 +489,14 @@ bool wxPCXHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos bool wxPCXHandler::DoCanRead( wxInputStream& stream ) { - unsigned char c; - - c = stream.GetC(); - stream.SeekI(-1, wxFromCurrent); + unsigned char c = stream.GetC(); // it's ok to modify the stream position here + if ( !stream ) + return false; // not very safe, but this is all we can get from PCX header :-( - return (c == 10); + return c == 10; } -#endif // wxUSE_STREAMS && wxUSE_PCX +#endif // wxUSE_STREAMS +#endif // wxUSE_IMAGE && wxUSE_PCX