]>
git.saurik.com Git - wxWidgets.git/blob - src/common/imagpcx.cpp
0ba41da2f227bf58c4a5169b740c856f2a0b1b7c
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxImage PCX handler 
   4 // Author:      Guillermo Rodriguez Garcia <guille@iies.es> 
   7 // Copyright:   (c) 1999 Guillermo Rodriguez Garcia 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  12    We don't put pragma implement in this file because it is already present in 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  27 #if wxUSE_STREAMS && wxUSE_PCX 
  30 #include "wx/wfstream.h" 
  31 #include "wx/module.h" 
  35 //----------------------------------------------------------------------------- 
  37 //----------------------------------------------------------------------------- 
  39 void RLEencode(unsigned char *WXUNUSED(p
), unsigned int WXUNUSED(size
), wxOutputStream
& WXUNUSED(s
)) 
  43 void RLEdecode(unsigned char *p
, unsigned int size
, wxInputStream
& s
) 
  45     unsigned int i
, data
, cont
; 
  47     // Read 'size' bytes. The PCX official specs say there will be 
  48     // a decoding break at the end of each scanline (but not at the 
  49     // end of each plane inside a scanline). Only use this function 
  50     // to read one or more _complete_ scanlines. Else, more than 
  51     // 'size' bytes might be read and the buffer might overflow. 
  55         data 
= (unsigned char)s
.GetC(); 
  57         // If ((data & 0xC0) != 0xC0), then the value read is a data 
  58         // byte. Else, it is a counter (cont = val & 0x3F) and the 
  59         // next byte is the data byte. 
  61         if ((data 
& 0xC0) != 0xC0) 
  69             data 
= (unsigned char)s
.GetC(); 
  70             for (i 
= 1; i 
<= cont
; i
++) 
  80 #define HDR_ENCODING        2 
  81 #define HDR_BITSPERPIXEL    3 
  86 #define HDR_NPLANES         65 
  87 #define HDR_BYTESPERLINE    66 
  90 #define IMAGE_8BIT  0       // 8 bpp, 1 plane (8 bit) 
  91 #define IMAGE_24BIT 1       // 8 bpp, 3 planes (24 bit) 
  94 #define E_OK        0       // everything was OK 
  95 #define E_FORMATO   1       // error in pcx file format 
  96 #define E_MEMORIA   2       // error allocating memory 
  97 #define E_VERSION   3       // error in pcx version number 
 101 //  Loads a PCX file into the wxImage object pointed by image. 
 102 //  Returns E_OK on success, or an error code otherwise (see 
 103 //  above for error codes) 
 105 int ReadPCX(wxImage 
*image
, wxInputStream
& stream
) 
 107     unsigned char hdr
[128];         // PCX header 
 108     unsigned char pal
[768];         // palette for 8 bit images 
 109     unsigned char *p
;               // space to store one scanline 
 110     unsigned char *dst
;             // pointer into wxImage data 
 111     unsigned int width
, height
;     // size of the image 
 112     unsigned int bytesperline
;      // bytes per line (each plane) 
 113     int bitsperpixel
;               // bits per pixel (each plane) 
 114     int nplanes
;                    // number of planes 
 115     int encoding
;                   // is the image RLE encoded? 
 116     int format
;                     // image format (8 bit, 24 bit) 
 120     // Read PCX header and check the version number (it must 
 121     // be at least 5 or higher for 8 bit and 24 bit images). 
 123     stream
.Read(hdr
, 128); 
 125     if (hdr
[HDR_VERSION
] < 5) return E_VERSION
; 
 127     // Extract all image info from the PCX header. 
 129     encoding     
= hdr
[HDR_ENCODING
]; 
 130     nplanes      
= hdr
[HDR_NPLANES
]; 
 131     bitsperpixel 
= hdr
[HDR_BITSPERPIXEL
]; 
 132     bytesperline 
= hdr
[HDR_BYTESPERLINE
] + 256 * hdr
[HDR_BYTESPERLINE 
+ 1]; 
 133     width        
= (hdr
[HDR_XMAX
] + 256 * hdr
[HDR_XMAX 
+ 1]) - 
 134                    (hdr
[HDR_XMIN
] + 256 * hdr
[HDR_XMIN 
+ 1]) + 1; 
 135     height       
= (hdr
[HDR_YMAX
] + 256 * hdr
[HDR_YMAX 
+ 1]) - 
 136                    (hdr
[HDR_YMIN
] + 256 * hdr
[HDR_YMIN 
+ 1]) + 1; 
 138     // Check image format. Currently supported formats are 
 139     // 8 bits (8 bpp, 1 plane) and 24 bits (8 bpp, 3 planes). 
 141     if ((nplanes 
== 3) && (bitsperpixel 
== 8)) 
 142         format 
= IMAGE_24BIT
; 
 143     else if ((nplanes 
== 1) && (bitsperpixel 
== 8)) 
 148     // If the image is of type IMAGE_8BIT, then there is a 
 149     // palette at the end of the file. Read it now before 
 152     if (format 
== IMAGE_8BIT
) 
 154         pos 
= stream
.TellI(); 
 155         stream
.SeekI(-769, wxFromEnd
); 
 157         if (stream
.GetC() != 12) 
 160         stream
.Read(pal
, 768); 
 161         stream
.SeekI(pos
, wxFromStart
); 
 164     // Allocate memory for a scanline and resize the image. 
 166     image
->Create(width
, height
); 
 171     if ((p 
= (unsigned char *) malloc(bytesperline 
* nplanes
)) == NULL
) 
 174     // Now start reading the file, line by line, and store 
 175     // the data in the format required by wxImage. 
 177     dst 
= image
->GetData(); 
 179     for (; height
; height
--) 
 182             RLEdecode(p
, bytesperline 
* nplanes
, stream
); 
 184             stream
.Read(p
, bytesperline 
* nplanes
); 
 190                 for (i 
= 0; i 
< width
; i
++) 
 192                     *(dst
++) = pal
[ 3 * (p
[i
]) ]; 
 193                     *(dst
++) = pal
[ 3 * (p
[i
]) + 1]; 
 194                     *(dst
++) = pal
[ 3 * (p
[i
]) + 2]; 
 200                 for (i 
= 0; i 
< width
; i
++) 
 203                     *(dst
++) = p
[i 
+ bytesperline
]; 
 204                     *(dst
++) = p
[i 
+ 2 * bytesperline
]; 
 217 //----------------------------------------------------------------------------- 
 219 //----------------------------------------------------------------------------- 
 221 #if !USE_SHARED_LIBRARIES 
 222 IMPLEMENT_DYNAMIC_CLASS(wxPCXHandler
,wxImageHandler
) 
 225 bool wxPCXHandler::LoadFile( wxImage 
*image
, wxInputStream
& stream
, bool verbose
, int WXUNUSED(index
) ) 
 229     if (!CanRead(stream
)) 
 232             wxLogError(wxT("wxPCXHandler: this is not a PCX file")); 
 239     if ((error 
= ReadPCX(image
, stream
)) != E_OK
) 
 245                 case E_FORMATO
: wxLogError(wxT("wxPCXHandler: image format unsupported")); break; 
 246                 case E_MEMORIA
: wxLogError(wxT("wxPCXHandler: couldn't allocate memory")); break; 
 247                 case E_VERSION
: wxLogError(wxT("wxPCXHandler: version number too low")); break; 
 248                 default:        wxLogError(wxT("wxPCXHandler: unknown error !!!")); 
 258 bool wxPCXHandler::SaveFile( wxImage 
*WXUNUSED(image
), wxOutputStream
& WXUNUSED(stream
), bool verbose 
) 
 261         wxLogError(wxT("wxPCXHandler::SaveFile still not implemented")); 
 266 bool wxPCXHandler::DoCanRead( wxInputStream
& stream 
) 
 271     stream
.SeekI(-1, wxFromCurrent
); 
 273     // not very safe, but this is all we can get from PCX header :-( 
 277 #endif // wxUSE_STREAMS && wxUSE_PCX