16 static TQDataStream &operator>>( TQDataStream &s, RGB &rgb )
18 s >> rgb.r >> rgb.g >> rgb.b;
23 static TQDataStream &operator>>( TQDataStream &s, Palette &pal )
25 for (
int i=0; i<16; ++i )
31 static TQDataStream &operator>>( TQDataStream &s, PCXHEADER &ph )
37 s >> ph.XMin >> ph.YMin >> ph.XMax >> ph.YMax;
38 s >> ph.HDpi >> ph.YDpi;
49 while ( s.device()->at() < 128 )
55 static TQDataStream &operator<<( TQDataStream &s,
const RGB &rgb )
57 s << rgb.r << rgb.g << rgb.b;
62 static TQDataStream &operator<<( TQDataStream &s,
const Palette &pal )
64 for (
int i=0; i<16; ++i )
70 static TQDataStream &operator<<( TQDataStream &s,
const PCXHEADER &ph )
76 s << ph.XMin << ph.YMin << ph.XMax << ph.YMax;
77 s << ph.HDpi << ph.YDpi;
87 for (
int i=0; i<54; ++i )
93 PCXHEADER::PCXHEADER()
96 TQByteArray dummy( 128 );
98 TQDataStream s( dummy, IO_ReadOnly );
102 static void readLine( TQDataStream &s, TQByteArray &buf,
const PCXHEADER &header )
105 TQ_UINT32 size = buf.size();
106 TQ_UINT8 byte, count;
108 if ( header.isCompressed() )
120 while ( count-- && i < size )
135 static void readImage1( TQImage &img, TQDataStream &s,
const PCXHEADER &header )
137 TQByteArray buf( header.BytesPerLine );
139 if(!img.create( header.width(), header.height(), 1, 2, TQImage::BigEndian ))
142 for (
int y=0; y<header.height(); ++y )
150 readLine( s, buf, header );
151 uchar *p = img.scanLine( y );
152 unsigned int bpl = TQMIN((header.width()+7)/8, header.BytesPerLine);
153 for (
unsigned int x=0; x< bpl; ++x )
158 img.setColor( 0, tqRgb( 0, 0, 0 ) );
159 img.setColor( 1, tqRgb( 255, 255, 255 ) );
162 static void readImage4( TQImage &img, TQDataStream &s,
const PCXHEADER &header )
164 TQByteArray buf( header.BytesPerLine*4 );
165 TQByteArray pixbuf( header.width() );
167 if(!img.create( header.width(), header.height(), 8, 16 ))
170 for (
int y=0; y<header.height(); ++y )
179 readLine( s, buf, header );
181 for (
int i=0; i<4; i++ )
183 TQ_UINT32 offset = i*header.BytesPerLine;
184 for (
unsigned int x=0; x<header.width(); ++x )
185 if ( buf[ offset + ( x/8 ) ] & ( 128 >> ( x%8 ) ) )
186 pixbuf[ x ] =
static_cast<const char>(pixbuf.at(x)) + ( 1 << i );
189 uchar *p = img.scanLine( y );
190 for (
unsigned int x=0; x<header.width(); ++x )
191 p[ x ] = pixbuf[ x ];
195 for (
int i=0; i<16; ++i )
196 img.setColor( i, header.ColorMap.color( i ) );
199 static void readImage8( TQImage &img, TQDataStream &s,
const PCXHEADER &header )
201 TQByteArray buf( header.BytesPerLine );
203 if(!img.create( header.width(), header.height(), 8, 256 ))
206 for (
int y=0; y<header.height(); ++y )
214 readLine( s, buf, header );
216 uchar *p = img.scanLine( y );
217 unsigned int bpl = TQMIN(header.BytesPerLine, header.width());
218 for (
unsigned int x=0; x<bpl; ++x )
224 kdDebug( 399 ) <<
"Palette Flag: " << flag << endl;
226 if ( flag == 12 && ( header.Version == 5 || header.Version == 2 ) )
230 for (
int i=0; i<256; ++i )
233 img.setColor( i, tqRgb( r, g, b ) );
238 static void readImage24( TQImage &img, TQDataStream &s,
const PCXHEADER &header )
240 TQByteArray r_buf( header.BytesPerLine );
241 TQByteArray g_buf( header.BytesPerLine );
242 TQByteArray b_buf( header.BytesPerLine );
244 if(!img.create( header.width(), header.height(), 32 ))
247 for (
int y=0; y<header.height(); ++y )
255 readLine( s, r_buf, header );
256 readLine( s, g_buf, header );
257 readLine( s, b_buf, header );
259 uint *p = ( uint * )img.scanLine( y );
260 for (
unsigned int x=0; x<header.width(); ++x )
261 p[ x ] = tqRgb( r_buf[ x ], g_buf[ x ], b_buf[ x ] );
265 TDE_EXPORT
void kimgio_pcx_read( TQImageIO *io )
267 TQDataStream s( io->ioDevice() );
268 s.setByteOrder( TQDataStream::LittleEndian );
270 if ( s.device()->size() < 128 )
280 if ( header.Manufacturer != 10 || s.atEnd())
286 int w = header.width();
287 int h = header.height();
289 kdDebug( 399 ) <<
"Manufacturer: " << header.Manufacturer << endl;
290 kdDebug( 399 ) <<
"Version: " << header.Version << endl;
291 kdDebug( 399 ) <<
"Encoding: " << header.Encoding << endl;
292 kdDebug( 399 ) <<
"Bpp: " << header.Bpp << endl;
293 kdDebug( 399 ) <<
"Width: " << w << endl;
294 kdDebug( 399 ) <<
"Height: " << h << endl;
295 kdDebug( 399 ) <<
"Window: " << header.XMin <<
"," << header.XMax <<
","
296 << header.YMin <<
"," << header.YMax << endl;
297 kdDebug( 399 ) <<
"BytesPerLine: " << header.BytesPerLine << endl;
298 kdDebug( 399 ) <<
"NPlanes: " << header.NPlanes << endl;
302 if ( header.Bpp == 1 && header.NPlanes == 1 )
304 readImage1( img, s, header );
306 else if ( header.Bpp == 1 && header.NPlanes == 4 )
308 readImage4( img, s, header );
310 else if ( header.Bpp == 8 && header.NPlanes == 1 )
312 readImage8( img, s, header );
314 else if ( header.Bpp == 8 && header.NPlanes == 3 )
316 readImage24( img, s, header );
319 kdDebug( 399 ) <<
"Image Bytes: " << img.numBytes() << endl;
320 kdDebug( 399 ) <<
"Image Bytes Per Line: " << img.bytesPerLine() << endl;
321 kdDebug( 399 ) <<
"Image Depth: " << img.depth() << endl;
334 static void writeLine( TQDataStream &s, TQByteArray &buf )
337 TQ_UINT32 size = buf.size();
338 TQ_UINT8 count, data;
346 while ( ( i < size ) && ( TQChar(
byte) == buf.at(i) ) && ( count < 63 ) )
354 if ( count > 1 || data >= 0xc0 )
364 static void writeImage1( TQImage &img, TQDataStream &s, PCXHEADER &header )
366 img = img.convertBitOrder( TQImage::BigEndian );
370 header.BytesPerLine = img.bytesPerLine();
374 TQByteArray buf( header.BytesPerLine );
376 for (
int y=0; y<header.height(); ++y )
378 TQ_UINT8 *p = img.scanLine( y );
381 for (
int i=0; i<header.BytesPerLine; ++i )
388 static void writeImage4( TQImage &img, TQDataStream &s, PCXHEADER &header )
392 header.BytesPerLine = header.width()/8;
394 for (
int i=0; i<16; ++i )
395 header.ColorMap.setColor( i, img.color( i ) );
399 TQByteArray buf[ 4 ];
401 for (
int i=0; i<4; ++i )
402 buf[ i ].resize( header.BytesPerLine );
404 for (
int y=0; y<header.height(); ++y )
406 TQ_UINT8 *p = img.scanLine( y );
408 for (
int i=0; i<4; ++i )
411 for (
unsigned int x=0; x<header.width(); ++x )
413 for (
int i=0; i<4; ++i )
414 if ( *( p+x ) & ( 1 << i ) )
415 buf[ i ][ x/8 ] = buf[ i ].at(x/8) | 1 << ( 7-x%8 );
418 for (
int i=0; i<4; ++i )
419 writeLine( s, buf[ i ] );
423 static void writeImage8( TQImage &img, TQDataStream &s, PCXHEADER &header )
427 header.BytesPerLine = img.bytesPerLine();
431 TQByteArray buf( header.BytesPerLine );
433 for (
int y=0; y<header.height(); ++y )
435 TQ_UINT8 *p = img.scanLine( y );
437 for (
int i=0; i<header.BytesPerLine; ++i )
448 for (
int i=0; i<256; ++i )
449 s << RGB( img.color( i ) );
452 static void writeImage24( TQImage &img, TQDataStream &s, PCXHEADER &header )
456 header.BytesPerLine = header.width();
460 TQByteArray r_buf( header.width() );
461 TQByteArray g_buf( header.width() );
462 TQByteArray b_buf( header.width() );
464 for (
int y=0; y<header.height(); ++y )
466 uint *p = ( uint * )img.scanLine( y );
468 for (
unsigned int x=0; x<header.width(); ++x )
471 r_buf[ x ] = tqRed( rgb );
472 g_buf[ x ] = tqGreen( rgb );
473 b_buf[ x ] = tqBlue( rgb );
476 writeLine( s, r_buf );
477 writeLine( s, g_buf );
478 writeLine( s, b_buf );
482 TDE_EXPORT
void kimgio_pcx_write( TQImageIO *io )
484 TQDataStream s( io->ioDevice() );
485 s.setByteOrder( TQDataStream::LittleEndian );
487 TQImage img = io->image();
490 int h = img.height();
492 kdDebug( 399 ) <<
"Width: " << w << endl;
493 kdDebug( 399 ) <<
"Height: " << h << endl;
494 kdDebug( 399 ) <<
"Depth: " << img.depth() << endl;
495 kdDebug( 399 ) <<
"BytesPerLine: " << img.bytesPerLine() << endl;
496 kdDebug( 399 ) <<
"Num Colors: " << img.numColors() << endl;
500 header.Manufacturer = 10;
510 header.PaletteInfo =1;
512 if ( img.depth() == 1 )
514 writeImage1( img, s, header );
516 else if ( img.depth() == 8 && img.numColors() <= 16 )
518 writeImage4( img, s, header );
520 else if ( img.depth() == 8 )
522 writeImage8( img, s, header );
524 else if ( img.depth() == 32 )
526 writeImage24( img, s, header );