//#include "qptrlist.h"
//#include "qasyncimageio.h"
//#include "qpngio.h"
-//#include "qmngio.h"
-//#include "qjpegio.h"
//#include "qmap.h"
//#include <private/qpluginmanager_p.h>
//#include "qimageformatinterface_p.h"
load( fileName, format );
}
-#ifndef QT_NO_IMAGEIO_XPM
-// helper
-static void read_xpm_image_or_array( QImageIO *, const char * const *, QImage & );
-#endif
/*!
Constructs an image from \a xpm, which must be a valid XPM image.
QImage::QImage( const char * const xpm[] )
{
init();
-#ifndef QT_NO_IMAGEIO_XPM
- read_xpm_image_or_array( 0, xpm, *this );
-#else
// We use a qFatal rather than disabling the whole function, as this
// constructor may be ambiguous.
qFatal("XPM not supported");
-#endif
}
/*!
#endif
/*****************************************************************************
- Standard image io handlers (defined below)
- *****************************************************************************/
-
-// standard image io handlers (defined below)
-#ifndef QT_NO_IMAGEIO_BMP
-static void read_bmp_image( QImageIO * );
-static void write_bmp_image( QImageIO * );
-#endif
-#ifndef QT_NO_IMAGEIO_PPM
-static void read_pbm_image( QImageIO * );
-static void write_pbm_image( QImageIO * );
-#endif
-#ifndef QT_NO_IMAGEIO_XBM
-static void read_xbm_image( QImageIO * );
-static void write_xbm_image( QImageIO * );
-#endif
-#ifndef QT_NO_IMAGEIO_XPM
-static void read_xpm_image( QImageIO * );
-static void write_xpm_image( QImageIO * );
-#endif
-
-#ifndef QT_NO_ASYNC_IMAGE_IO
-static void read_async_image( QImageIO * ); // Not in table of handlers
-#endif
-
-/*****************************************************************************
- Misc. utility functions
- *****************************************************************************/
-#if !defined(QT_NO_IMAGEIO_XPM) || !defined(QT_NO_IMAGEIO_XBM)
-static QString fbname( const QString &fileName ) // get file basename (sort of)
-{
- QString s = fileName;
- if ( !s.isEmpty() ) {
- int i;
- if ( (i = s.findRev('/')) >= 0 )
- s = s.mid( i );
- if ( (i = s.findRev('\\')) >= 0 )
- s = s.mid( i );
- QRegExp r( QString::fromLatin1("[a-zA-Z][a-zA-Z0-9_]*") );
- int p = r.search( s );
- if ( p == -1 )
- s.truncate( 0 );
- else
- s = s.mid( p, r.matchedLength() );
- }
- if ( s.isEmpty() )
- s = QString::fromLatin1( "dummy" );
- return s;
-}
-#endif
-
-#ifndef QT_NO_IMAGEIO_BMP
-static void swapPixel01( QImage *image ) // 1-bpp: swap 0 and 1 pixels
-{
- int i;
- if ( image->depth() == 1 && image->numColors() == 2 ) {
- uint *p = (uint *)image->bits();
- int nbytes = image->byteCount();
- for ( i=0; i<nbytes/4; i++ ) {
- *p = ~*p;
- p++;
- }
- uchar *p2 = (uchar *)p;
- for ( i=0; i<(nbytes&3); i++ ) {
- *p2 = ~*p2;
- p2++;
- }
- QRgb t = image->color(0); // swap color 0 and 1
- image->setColor( 0, image->color(1) );
- image->setColor( 1, t );
- }
-}
-#endif
-
-
-/*****************************************************************************
QImageIO member functions
*****************************************************************************/
Q_CHECK_PTR( imageHandlers );
imageHandlers->setAutoDelete( true );
qAddPostRoutine( cleanup );
-#ifndef QT_NO_IMAGEIO_BMP
- QImageIO::defineIOHandler( "BMP", "^BM", 0,
- read_bmp_image, write_bmp_image );
-#endif
-#ifndef QT_NO_IMAGEIO_PPM
- QImageIO::defineIOHandler( "PBM", "^P1", "t",
- read_pbm_image, write_pbm_image );
- QImageIO::defineIOHandler( "PBMRAW", "^P4", "O",
- read_pbm_image, write_pbm_image );
- QImageIO::defineIOHandler( "PGM", "^P2", "t",
- read_pbm_image, write_pbm_image );
- QImageIO::defineIOHandler( "PGMRAW", "^P5", "O",
- read_pbm_image, write_pbm_image );
- QImageIO::defineIOHandler( "PPM", "^P3", "t",
- read_pbm_image, write_pbm_image );
- QImageIO::defineIOHandler( "PPMRAW", "^P6", "O",
- read_pbm_image, write_pbm_image );
-#endif
-#ifndef QT_NO_IMAGEIO_XBM
- QImageIO::defineIOHandler( "XBM", "^#define", "T",
- read_xbm_image, write_xbm_image );
-#endif
-#ifndef QT_NO_IMAGEIO_XPM
- QImageIO::defineIOHandler( "XPM", "/\\*.XPM.\\*/", "T",
- read_xpm_image, write_xpm_image );
-#endif
-#ifndef QT_NO_IMAGEIO_MNG
- qInitMngIO();
-#endif
#ifndef QT_NO_IMAGEIO_PNG
qInitPngIO();
#endif
-#ifndef QT_NO_IMAGEIO_JPEG
- qInitJpegIO();
-#endif
}
}
}
}
d->at( pos ); // restore position
-#ifndef QT_NO_ASYNC_IMAGE_IO
- if ( !format )
- format = QImageDecoder::formatName( (uchar*)buf2, rdlen );
-#endif
return format;
}
qt_init_image_handlers();
qt_init_image_plugins();
-#ifndef QT_NO_ASYNC_IMAGE_IO
- // Include asynchronous loaders first.
- result = QImageDecoder::inputFormats();
-#endif
-
QImageHandler *p = imageHandlers->first();
while ( p ) {
if ( p->read_image
if ( h && h->read_image ) {
(*h->read_image)( this );
}
-#ifndef QT_NO_ASYNC_IMAGE_IO
- else {
- // Format name, but no handler - must be an asychronous reader
- read_async_image( this );
- }
-#endif
if ( file.isOpen() ) { // image was read using file
file.close();
}
#endif //QT_NO_IMAGEIO
-#ifndef QT_NO_IMAGEIO_BMP
-
-/*****************************************************************************
- BMP (DIB) image read/write functions
- *****************************************************************************/
-
-const int BMP_FILEHDR_SIZE = 14; // size of BMP_FILEHDR data
-
-struct BMP_FILEHDR { // BMP file header
- char bfType[2]; // "BM"
- Q_INT32 bfSize; // size of file
- Q_INT16 bfReserved1;
- Q_INT16 bfReserved2;
- Q_INT32 bfOffBits; // pointer to the pixmap bits
-};
-
-QDataStream &operator>>( QDataStream &s, BMP_FILEHDR &bf )
-{ // read file header
- s.readRawBytes( bf.bfType, 2 );
- s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
- return s;
-}
-
-QDataStream &operator<<( QDataStream &s, const BMP_FILEHDR &bf )
-{ // write file header
- s.writeRawBytes( bf.bfType, 2 );
- s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
- return s;
-}
-
-
-const int BMP_OLD = 12; // old Windows/OS2 BMP size
-const int BMP_WIN = 40; // new Windows BMP size
-const int BMP_OS2 = 64; // new OS/2 BMP size
-
-const int BMP_RGB = 0; // no compression
-const int BMP_RLE8 = 1; // run-length encoded, 8 bits
-const int BMP_RLE4 = 2; // run-length encoded, 4 bits
-const int BMP_BITFIELDS = 3; // RGB values encoded in data as bit-fields
-
-struct BMP_INFOHDR { // BMP information header
- Q_INT32 biSize; // size of this struct
- Q_INT32 biWidth; // pixmap width
- Q_INT32 biHeight; // pixmap height
- Q_INT16 biPlanes; // should be 1
- Q_INT16 biBitCount; // number of bits per pixel
- Q_INT32 biCompression; // compression method
- Q_INT32 biSizeImage; // size of image
- Q_INT32 biXPelsPerMeter; // horizontal resolution
- Q_INT32 biYPelsPerMeter; // vertical resolution
- Q_INT32 biClrUsed; // number of colors used
- Q_INT32 biClrImportant; // number of important colors
-};
-
-
-QDataStream &operator>>( QDataStream &s, BMP_INFOHDR &bi )
-{
- s >> bi.biSize;
- if ( bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 ) {
- s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
- s >> bi.biCompression >> bi.biSizeImage;
- s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
- s >> bi.biClrUsed >> bi.biClrImportant;
- }
- else { // probably old Windows format
- Q_INT16 w, h;
- s >> w >> h >> bi.biPlanes >> bi.biBitCount;
- bi.biWidth = w;
- bi.biHeight = h;
- bi.biCompression = BMP_RGB; // no compression
- bi.biSizeImage = 0;
- bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;
- bi.biClrUsed = bi.biClrImportant = 0;
- }
- return s;
-}
-
-QDataStream &operator<<( QDataStream &s, const BMP_INFOHDR &bi )
-{
- s << bi.biSize;
- s << bi.biWidth << bi.biHeight;
- s << bi.biPlanes;
- s << bi.biBitCount;
- s << bi.biCompression;
- s << bi.biSizeImage;
- s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
- s << bi.biClrUsed << bi.biClrImportant;
- return s;
-}
-
-static
-int calc_shift(int mask)
-{
- int result = 0;
- while (!(mask & 1)) {
- result++;
- mask >>= 1;
- }
- return result;
-}
-
-static
-bool read_dib( QDataStream& s, int offset, int startpos, QImage& image )
-{
- BMP_INFOHDR bi;
- QIODevice* d = s.device();
-
- s >> bi; // read BMP info header
- if ( d->atEnd() ) // end of stream/file
- return false;
-#if 0
- qDebug( "offset...........%d", offset );
- qDebug( "startpos.........%d", startpos );
- qDebug( "biSize...........%d", bi.biSize );
- qDebug( "biWidth..........%d", bi.biWidth );
- qDebug( "biHeight.........%d", bi.biHeight );
- qDebug( "biPlanes.........%d", bi.biPlanes );
- qDebug( "biBitCount.......%d", bi.biBitCount );
- qDebug( "biCompression....%d", bi.biCompression );
- qDebug( "biSizeImage......%d", bi.biSizeImage );
- qDebug( "biXPelsPerMeter..%d", bi.biXPelsPerMeter );
- qDebug( "biYPelsPerMeter..%d", bi.biYPelsPerMeter );
- qDebug( "biClrUsed........%d", bi.biClrUsed );
- qDebug( "biClrImportant...%d", bi.biClrImportant );
-#endif
- int w = bi.biWidth, h = bi.biHeight, nbits = bi.biBitCount;
- int t = bi.biSize, comp = bi.biCompression;
- int red_mask, green_mask, blue_mask;
- int red_shift = 0;
- int green_shift = 0;
- int blue_shift = 0;
- int red_scale = 0;
- int green_scale = 0;
- int blue_scale = 0;
-
- if ( !(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||
- bi.biPlanes != 1 || comp > BMP_BITFIELDS )
- return false; // weird BMP image
- if ( !(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
- (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)) )
- return false; // weird compression type
-
- int ncols;
- int depth;
- switch ( nbits ) {
- case 32:
- case 24:
- case 16:
- depth = 32;
- break;
- case 8:
- case 4:
- depth = 8;
- break;
- default:
- depth = 1;
- }
- if ( depth == 32 ) // there's no colormap
- ncols = 0;
- else // # colors used
- ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
-
- image.create( w, h, depth, ncols, nbits == 1 ?
- QImage::BigEndian : QImage::IgnoreEndian );
- if ( image.isNull() ) // could not create image
- return false;
-
- image.setDotsPerMeterX( bi.biXPelsPerMeter );
- image.setDotsPerMeterY( bi.biYPelsPerMeter );
-
- d->at( startpos + BMP_FILEHDR_SIZE + bi.biSize ); // goto start of colormap
-
- if ( ncols > 0 ) { // read color table
- uchar rgb[4];
- int rgb_len = t == BMP_OLD ? 3 : 4;
- for ( int i=0; i<ncols; i++ ) {
- if ( d->readBlock( (char *)rgb, rgb_len ) != rgb_len )
- return false;
- image.setColor( i, qRgb(rgb[2],rgb[1],rgb[0]) );
- if ( d->atEnd() ) // truncated file
- return false;
- }
- } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
- if ( (Q_ULONG)d->readBlock( (char *)&red_mask, sizeof(red_mask) ) != sizeof(red_mask) )
- return false;
- if ( (Q_ULONG)d->readBlock( (char *)&green_mask, sizeof(green_mask) ) != sizeof(green_mask) )
- return false;
- if ( (Q_ULONG)d->readBlock( (char *)&blue_mask, sizeof(blue_mask) ) != sizeof(blue_mask) )
- return false;
- red_shift = calc_shift(red_mask);
- red_scale = 256 / ((red_mask >> red_shift) + 1);
- green_shift = calc_shift(green_mask);
- green_scale = 256 / ((green_mask >> green_shift) + 1);
- blue_shift = calc_shift(blue_mask);
- blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
- } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
- blue_mask = 0x000000ff;
- green_mask = 0x0000ff00;
- red_mask = 0x00ff0000;
- blue_shift = 0;
- green_shift = 8;
- red_shift = 16;
- blue_scale = green_scale = red_scale = 1;
- } else if (comp == BMP_RGB && nbits == 16) // don't support RGB values for 15/16 bpp
- return false;
-
- // offset can be bogus, be careful
- if (offset>=0 && startpos + offset > (Q_LONG)d->at() )
- d->at( startpos + offset ); // start of image data
-
- int bpl = image.bytesPerLine();
-#ifdef Q_WS_QWS
- //
- // Guess the number of bytes-per-line if we don't know how much
- // image data is in the file (bogus image ?).
- //
- int bmpbpl = bi.biSizeImage > 0 ?
- bi.biSizeImage / bi.biHeight :
- (d->size() - offset) / bi.biHeight;
- int pad = bmpbpl-bpl;
-#endif
- uchar **line = image.jumpTable();
-
- if ( nbits == 1 ) { // 1 bit BMP image
- while ( --h >= 0 ) {
- if ( d->readBlock((char*)line[h],bpl) != bpl )
- break;
-#ifdef Q_WS_QWS
- if ( pad > 0 )
- d->at(d->at()+pad);
-#endif
- }
- if ( ncols == 2 && qGray(image.color(0)) < qGray(image.color(1)) )
- swapPixel01( &image ); // pixel 0 is white!
- }
-
- else if ( nbits == 4 ) { // 4 bit BMP image
- int buflen = ((w+7)/8)*4;
- uchar *buf = new uchar[buflen];
- Q_CHECK_PTR( buf );
- if ( comp == BMP_RLE4 ) { // run length compression
- int x=0, y=0, b, c, i;
- uchar *p = line[h-1];
- uchar *endp = line[h-1]+w;
- while ( y < h ) {
- if ( (b=d->getch()) == EOF )
- break;
- if ( b == 0 ) { // escape code
- switch ( (b=d->getch()) ) {
- case 0: // end of line
- x = 0;
- y++;
- p = line[h-y-1];
- break;
- case 1: // end of image
- case EOF: // end of file
- y = h; // exit loop
- break;
- case 2: // delta (jump)
- x += d->getch();
- y += d->getch();
-
- // Protection
- if ( (uint)x >= (uint)w )
- x = w-1;
- if ( (uint)y >= (uint)h )
- y = h-1;
-
- p = line[h-y-1] + x;
- break;
- default: // absolute mode
- // Protection
- if ( p + b > endp )
- b = endp-p;
-
- i = (c = b)/2;
- while ( i-- ) {
- b = d->getch();
- *p++ = b >> 4;
- *p++ = b & 0x0f;
- }
- if ( c & 1 )
- *p++ = d->getch() >> 4;
- if ( (((c & 3) + 1) & 2) == 2 )
- d->getch(); // align on word boundary
- x += c;
- }
- } else { // encoded mode
- // Protection
- if ( p + b > endp )
- b = endp-p;
-
- i = (c = b)/2;
- b = d->getch(); // 2 pixels to be repeated
- while ( i-- ) {
- *p++ = b >> 4;
- *p++ = b & 0x0f;
- }
- if ( c & 1 )
- *p++ = b >> 4;
- x += c;
- }
- }
- } else if ( comp == BMP_RGB ) { // no compression
- while ( --h >= 0 ) {
- if ( d->readBlock((char*)buf,buflen) != buflen )
- break;
- uchar *p = line[h];
- uchar *b = buf;
- for ( int i=0; i<w/2; i++ ) { // convert nibbles to bytes
- *p++ = *b >> 4;
- *p++ = *b++ & 0x0f;
- }
- if ( w & 1 ) // the last nibble
- *p = *b >> 4;
- }
- }
- delete [] buf;
- }
-
- else if ( nbits == 8 ) { // 8 bit BMP image
- if ( comp == BMP_RLE8 ) { // run length compression
- int x=0, y=0, b;
- uchar *p = line[h-1];
- const uchar *endp = line[h-1]+w;
- while ( y < h ) {
- if ( (b=d->getch()) == EOF )
- break;
- if ( b == 0 ) { // escape code
- switch ( (b=d->getch()) ) {
- case 0: // end of line
- x = 0;
- y++;
- p = line[h-y-1];
- break;
- case 1: // end of image
- case EOF: // end of file
- y = h; // exit loop
- break;
- case 2: // delta (jump)
- x += d->getch();
- y += d->getch();
-
- // Protection
- if ( (uint)x >= (uint)w )
- x = w-1;
- if ( (uint)y >= (uint)h )
- y = h-1;
-
- p = line[h-y-1] + x;
- break;
- default: // absolute mode
- // Protection
- if ( p + b > endp )
- b = endp-p;
-
- if ( d->readBlock( (char *)p, b ) != b )
- return false;
- if ( (b & 1) == 1 )
- d->getch(); // align on word boundary
- x += b;
- p += b;
- }
- } else { // encoded mode
- // Protection
- if ( p + b > endp )
- b = endp-p;
-
- memset( p, d->getch(), b ); // repeat pixel
- x += b;
- p += b;
- }
- }
- } else if ( comp == BMP_RGB ) { // uncompressed
- while ( --h >= 0 ) {
- if ( d->readBlock((char *)line[h],bpl) != bpl )
- break;
-#ifdef Q_WS_QWS
- if ( pad > 0 )
- d->at(d->at()+pad);
-#endif
- }
- }
- }
-
- else if ( nbits == 16 || nbits == 24 || nbits == 32 ) { // 16,24,32 bit BMP image
- QRgb *p;
- QRgb *end;
- uchar *buf24 = new uchar[bpl];
- int bpl24 = ((w*nbits+31)/32)*4;
- uchar *b;
- int c;
-
- while ( --h >= 0 ) {
- p = (QRgb *)line[h];
- end = p + w;
- if ( d->readBlock( (char *)buf24,bpl24) != bpl24 )
- break;
- b = buf24;
- while ( p < end ) {
- c = *(uchar*)b | (*(uchar*)(b+1)<<8);
- if (nbits != 16)
- c |= *(uchar*)(b+2)<<16;
- *p++ = qRgb(((c & red_mask) >> red_shift) * red_scale,
- ((c & green_mask) >> green_shift) * green_scale,
- ((c & blue_mask) >> blue_shift) * blue_scale);
- b += nbits/8;
- }
- }
- delete[] buf24;
- }
-
- return true;
-}
-
-bool qt_read_dib( QDataStream& s, QImage& image )
-{
- return read_dib(s,-1,-BMP_FILEHDR_SIZE,image);
-}
-
-
-static void read_bmp_image( QImageIO *iio )
-{
- QIODevice *d = iio->ioDevice();
- QDataStream s( d );
- BMP_FILEHDR bf;
- int startpos = d->at();
-
- s.setByteOrder( QDataStream::LittleEndian );// Intel byte order
- s >> bf; // read BMP file header
-
- if ( qstrncmp(bf.bfType,"BM",2) != 0 ) // not a BMP image
- return;
-
- QImage image;
- if (read_dib( s, bf.bfOffBits, startpos, image )) {
- iio->setImage( image );
- iio->setStatus( 0 ); // image ok
- }
-}
-
-bool qt_write_dib( QDataStream& s, QImage image )
-{
- int nbits;
- int bpl_bmp;
- int bpl = image.bytesPerLine();
-
- QIODevice* d = s.device();
-
- if ( image.depth() == 8 && image.numColors() <= 16 ) {
- bpl_bmp = (((bpl+1)/2+3)/4)*4;
- nbits = 4;
- } else if ( image.depth() == 32 ) {
- bpl_bmp = ((image.width()*24+31)/32)*4;
- nbits = 24;
-#ifdef Q_WS_QWS
- } else if ( image.depth() == 1 || image.depth() == 8 ) {
- // Qt/E doesn't word align.
- bpl_bmp = ((image.width()*image.depth()+31)/32)*4;
- nbits = image.depth();
-#endif
- } else {
- bpl_bmp = bpl;
- nbits = image.depth();
- }
-
- BMP_INFOHDR bi;
- bi.biSize = BMP_WIN; // build info header
- bi.biWidth = image.width();
- bi.biHeight = image.height();
- bi.biPlanes = 1;
- bi.biBitCount = nbits;
- bi.biCompression = BMP_RGB;
- bi.biSizeImage = bpl_bmp*image.height();
- bi.biXPelsPerMeter = image.dotsPerMeterX() ? image.dotsPerMeterX()
- : 2834; // 72 dpi default
- bi.biYPelsPerMeter = image.dotsPerMeterY() ? image.dotsPerMeterY() : 2834;
- bi.biClrUsed = image.numColors();
- bi.biClrImportant = image.numColors();
- s << bi; // write info header
-
- if ( image.depth() != 32 ) { // write color table
- uchar *color_table = new uchar[4*image.numColors()];
- uchar *rgb = color_table;
- QRgb *c = image.colorTable();
- for ( int i=0; i<image.numColors(); i++ ) {
- *rgb++ = qBlue ( c[i] );
- *rgb++ = qGreen( c[i] );
- *rgb++ = qRed ( c[i] );
- *rgb++ = 0;
- }
- d->writeBlock( (char *)color_table, 4*image.numColors() );
- delete [] color_table;
- }
-
- if ( image.depth() == 1 && image.bitOrder() != QImage::BigEndian )
- image = image.convertBitOrder( QImage::BigEndian );
-
- int y;
-
- if ( nbits == 1 || nbits == 8 ) { // direct output
-#ifdef Q_WS_QWS
- // Qt/E doesn't word align.
- int pad = bpl_bmp - bpl;
- char padding[4];
-#endif
- for ( y=image.height()-1; y>=0; y-- ) {
- d->writeBlock( (char*)image.scanLine(y), bpl );
-#ifdef Q_WS_QWS
- d->writeBlock( padding, pad );
-#endif
- }
- return true;
- }
-
- uchar *buf = new uchar[bpl_bmp];
- uchar *b, *end;
- uchar *p;
-
- memset( buf, 0, bpl_bmp );
- for ( y=image.height()-1; y>=0; y-- ) { // write the image bits
- if ( nbits == 4 ) { // convert 8 -> 4 bits
- p = image.scanLine(y);
- b = buf;
- end = b + image.width()/2;
- while ( b < end ) {
- *b++ = (*p << 4) | (*(p+1) & 0x0f);
- p += 2;
- }
- if ( image.width() & 1 )
- *b = *p << 4;
- } else { // 32 bits
- QRgb *p = (QRgb *)image.scanLine( y );
- QRgb *end = p + image.width();
- b = buf;
- while ( p < end ) {
- *b++ = qBlue(*p);
- *b++ = qGreen(*p);
- *b++ = qRed(*p);
- p++;
- }
- }
- if ( bpl_bmp != d->writeBlock( (char*)buf, bpl_bmp ) ) {
- delete[] buf;
- return false;
- }
- }
- delete[] buf;
- return true;
-}
-
-
-static void write_bmp_image( QImageIO *iio )
-{
- QIODevice *d = iio->ioDevice();
- QImage image = iio->image();
- QDataStream s( d );
- BMP_FILEHDR bf;
- int bpl_bmp;
- int bpl = image.bytesPerLine();
-
- // Code partially repeated in qt_write_dib
- if ( image.depth() == 8 && image.numColors() <= 16 ) {
- bpl_bmp = (((bpl+1)/2+3)/4)*4;
- } else if ( image.depth() == 32 ) {
- bpl_bmp = ((image.width()*24+31)/32)*4;
- } else {
- bpl_bmp = bpl;
- }
-
- iio->setStatus( 0 );
- s.setByteOrder( QDataStream::LittleEndian );// Intel byte order
- strncpy( bf.bfType, "BM", 2 ); // build file header
- bf.bfReserved1 = bf.bfReserved2 = 0; // reserved, should be zero
- bf.bfOffBits = BMP_FILEHDR_SIZE + BMP_WIN + image.numColors()*4;
- bf.bfSize = bf.bfOffBits + bpl_bmp*image.height();
- s << bf; // write file header
-
- if ( !qt_write_dib( s, image ) )
- iio->setStatus( 1 );
-
-}
-
-#endif // QT_NO_IMAGEIO_BMP
-
-#ifndef QT_NO_IMAGEIO_PPM
-
-/*****************************************************************************
- PBM/PGM/PPM (ASCII and RAW) image read/write functions
- *****************************************************************************/
-
-static int read_pbm_int( QIODevice *d )
-{
- int c;
- int val = -1;
- bool digit;
- const int buflen = 100;
- char buf[buflen];
- for ( ;; ) {
- if ( (c=d->getch()) == EOF ) // end of file
- break;
- digit = isdigit( (uchar) c );
- if ( val != -1 ) {
- if ( digit ) {
- val = 10*val + c - '0';
- continue;
- } else {
- if ( c == '#' ) // comment
- d->readLine( buf, buflen );
- break;
- }
- }
- if ( digit ) // first digit
- val = c - '0';
- else if ( isspace((uchar) c) )
- continue;
- else if ( c == '#' )
- d->readLine( buf, buflen );
- else
- break;
- }
- return val;
-}
-
-static void read_pbm_image( QImageIO *iio ) // read PBM image data
-{
- const int buflen = 300;
- char buf[buflen];
- QIODevice *d = iio->ioDevice();
- int w, h, nbits, mcc, y;
- int pbm_bpl;
- char type;
- bool raw;
- QImage image;
-
- if ( d->readBlock( buf, 3 ) != 3 ) // read P[1-6]<white-space>
- return;
- if ( !(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2])) )
- return;
- switch ( (type=buf[1]) ) {
- case '1': // ascii PBM
- case '4': // raw PBM
- nbits = 1;
- break;
- case '2': // ascii PGM
- case '5': // raw PGM
- nbits = 8;
- break;
- case '3': // ascii PPM
- case '6': // raw PPM
- nbits = 32;
- break;
- default:
- return;
- }
- raw = type >= '4';
- w = read_pbm_int( d ); // get image width
- h = read_pbm_int( d ); // get image height
- if ( nbits == 1 )
- mcc = 1; // ignore max color component
- else
- mcc = read_pbm_int( d ); // get max color component
- if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 )
- return; // weird P.M image
-
- int maxc = mcc;
- if ( maxc > 255 )
- maxc = 255;
- image.create( w, h, nbits, 0,
- nbits == 1 ? QImage::BigEndian : QImage::IgnoreEndian );
- if ( image.isNull() )
- return;
-
- pbm_bpl = (nbits*w+7)/8; // bytes per scanline in PBM
-
- if ( raw ) { // read raw data
- if ( nbits == 32 ) { // type 6
- pbm_bpl = 3*w;
- uchar *buf24 = new uchar[pbm_bpl], *b;
- QRgb *p;
- QRgb *end;
- for ( y=0; y<h; y++ ) {
- if ( d->readBlock( (char *)buf24, pbm_bpl ) != pbm_bpl ) {
- delete[] buf24;
- return;
- }
- p = (QRgb *)image.scanLine( y );
- end = p + w;
- b = buf24;
- while ( p < end ) {
- *p++ = qRgb(b[0],b[1],b[2]);
- b += 3;
- }
- }
- delete[] buf24;
- } else { // type 4,5
- for ( y=0; y<h; y++ ) {
- if ( d->readBlock( (char *)image.scanLine(y), pbm_bpl )
- != pbm_bpl )
- return;
- }
- }
- } else { // read ascii data
- uchar *p;
- int n;
- for ( y=0; y<h; y++ ) {
- p = image.scanLine( y );
- n = pbm_bpl;
- if ( nbits == 1 ) {
- int b;
- while ( n-- ) {
- b = 0;
- for ( int i=0; i<8; i++ )
- b = (b << 1) | (read_pbm_int(d) & 1);
- *p++ = b;
- }
- } else if ( nbits == 8 ) {
- if ( mcc == maxc ) {
- while ( n-- ) {
- *p++ = read_pbm_int( d );
- }
- } else {
- while ( n-- ) {
- *p++ = read_pbm_int( d ) * maxc / mcc;
- }
- }
- } else { // 32 bits
- n /= 4;
- int r, g, b;
- if ( mcc == maxc ) {
- while ( n-- ) {
- r = read_pbm_int( d );
- g = read_pbm_int( d );
- b = read_pbm_int( d );
- *((QRgb*)p) = qRgb( r, g, b );
- p += 4;
- }
- } else {
- while ( n-- ) {
- r = read_pbm_int( d ) * maxc / mcc;
- g = read_pbm_int( d ) * maxc / mcc;
- b = read_pbm_int( d ) * maxc / mcc;
- *((QRgb*)p) = qRgb( r, g, b );
- p += 4;
- }
- }
- }
- }
- }
-
- if ( nbits == 1 ) { // bitmap
- image.setNumColors( 2 );
- image.setColor( 0, qRgb(255,255,255) ); // white
- image.setColor( 1, qRgb(0,0,0) ); // black
- } else if ( nbits == 8 ) { // graymap
- image.setNumColors( maxc+1 );
- for ( int i=0; i<=maxc; i++ )
- image.setColor( i, qRgb(i*255/maxc,i*255/maxc,i*255/maxc) );
- }
-
- iio->setImage( image );
- iio->setStatus( 0 ); // image ok
-}
-
-
-static void write_pbm_image( QImageIO *iio )
-{
- QIODevice* out = iio->ioDevice();
- QCString str;
-
- QImage image = iio->image();
- QCString format = iio->format();
- format = format.left(3); // ignore RAW part
- bool gray = format == "PGM";
-
- if ( format == "PBM" ) {
- image = image.convertDepth(1);
- } else if ( image.depth() == 1 ) {
- image = image.convertDepth(8);
- }
-
- if ( image.depth() == 1 && image.numColors() == 2 ) {
- if ( qGray(image.color(0)) < qGray(image.color(1)) ) {
- // 0=dark/black, 1=light/white - invert
- image.detach();
- for ( int y=0; y<image.height(); y++ ) {
- uchar *p = image.scanLine(y);
- uchar *end = p + image.bytesPerLine();
- while ( p < end )
- *p++ ^= 0xff;
- }
- }
- }
-
- uint w = image.width();
- uint h = image.height();
-
- str.sprintf("P\n%d %d\n", w, h);
-
- switch (image.depth()) {
- case 1: {
- str.insert(1, '4');
- if ((uint)out->writeBlock(str, str.length()) != str.length()) {
- iio->setStatus(1);
- return;
- }
- w = (w+7)/8;
- for (uint y=0; y<h; y++) {
- uchar* line = image.scanLine(y);
- if ( w != (uint)out->writeBlock((char*)line, w) ) {
- iio->setStatus(1);
- return;
- }
- }
- }
- break;
-
- case 8: {
- str.insert(1, gray ? '5' : '6');
- str.append("255\n");
- if ((uint)out->writeBlock(str, str.length()) != str.length()) {
- iio->setStatus(1);
- return;
- }
- QRgb *color = image.colorTable();
- uint bpl = w*(gray ? 1 : 3);
- uchar *buf = new uchar[bpl];
- for (uint y=0; y<h; y++) {
- uchar *b = image.scanLine(y);
- uchar *p = buf;
- uchar *end = buf+bpl;
- if ( gray ) {
- while ( p < end ) {
- uchar g = (uchar)qGray(color[*b++]);
- *p++ = g;
- }
- } else {
- while ( p < end ) {
- QRgb rgb = color[*b++];
- *p++ = qRed(rgb);
- *p++ = qGreen(rgb);
- *p++ = qBlue(rgb);
- }
- }
- if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
- iio->setStatus(1);
- return;
- }
- }
- delete [] buf;
- }
- break;
-
- case 32: {
- str.insert(1, gray ? '5' : '6');
- str.append("255\n");
- if ((uint)out->writeBlock(str, str.length()) != str.length()) {
- iio->setStatus(1);
- return;
- }
- uint bpl = w*(gray ? 1 : 3);
- uchar *buf = new uchar[bpl];
- for (uint y=0; y<h; y++) {
- QRgb *b = (QRgb*)image.scanLine(y);
- uchar *p = buf;
- uchar *end = buf+bpl;
- if ( gray ) {
- while ( p < end ) {
- uchar g = (uchar)qGray(*b++);
- *p++ = g;
- }
- } else {
- while ( p < end ) {
- QRgb rgb = *b++;
- *p++ = qRed(rgb);
- *p++ = qGreen(rgb);
- *p++ = qBlue(rgb);
- }
- }
- if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
- iio->setStatus(1);
- return;
- }
- }
- delete [] buf;
- }
- }
-
- iio->setStatus(0);
-}
-
-#endif // QT_NO_IMAGEIO_PPM
-
-#ifndef QT_NO_ASYNC_IMAGE_IO
-
-class QImageIOFrameGrabber : public QImageConsumer {
-public:
- QImageIOFrameGrabber() : framecount(0) { }
-
- QImageDecoder *decoder;
- int framecount;
-
- void changed(const QRect&) { }
- void end() { }
- void frameDone(const QPoint&, const QRect&) { framecount++; }
- void frameDone() { framecount++; }
- void setLooping(int) { }
- void setFramePeriod(int) { }
- void setSize(int, int) { }
-};
-
-static void read_async_image( QImageIO *iio )
-{
- const int buf_len = 2048;
- uchar buffer[buf_len];
- QIODevice *d = iio->ioDevice();
- QImageIOFrameGrabber* consumer = new QImageIOFrameGrabber();
- QImageDecoder *decoder = new QImageDecoder(consumer);
- consumer->decoder = decoder;
- int startAt = d->at();
- int totLen = 0;
-
- for (;;) {
- int length = d->readBlock((char*)buffer, buf_len);
- if ( length <= 0 ) {
- iio->setStatus(length);
- break;
- }
- uchar* b = buffer;
- int r = -1;
- while (length > 0 && consumer->framecount==0) {
- r = decoder->decode(b, length);
- if ( r <= 0 ) break;
- b += r;
- totLen += r;
- length -= r;
- }
- if ( consumer->framecount ) {
- // Stopped after first frame
- if ( d->isDirectAccess() )
- d->at( startAt + totLen );
- else {
- // ### We have (probably) read too much from the stream into
- // the buffer, and there is no way to put it back!
- }
- iio->setImage(decoder->image());
- iio->setStatus(0);
- break;
- }
- if ( r <= 0 ) {
- iio->setStatus(r);
- break;
- }
- }
-
- consumer->decoder = 0;
- delete decoder;
- delete consumer;
-}
-
-#endif // QT_NO_ASYNC_IMAGE_IO
-
-#ifndef QT_NO_IMAGEIO_XBM
-
-/*****************************************************************************
- X bitmap image read/write functions
- *****************************************************************************/
-
-static inline int hex2byte( char *p )
-{
- return ( (isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4 ) |
- ( isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10 );
-}
-
-static void read_xbm_image( QImageIO *iio )
-{
- const int buflen = 300;
- char buf[buflen];
- QRegExp r1, r2;
- QIODevice *d = iio->ioDevice();
- int w=-1, h=-1;
- QImage image;
-
- r1 = QString::fromLatin1("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+");
- r2 = QString::fromLatin1("[0-9]+");
- d->readLine( buf, buflen ); // "#define .._width <num>"
- QString sbuf;
- sbuf = QString::fromLatin1(buf);
-
- if ( r1.search(sbuf) == 0 &&
- r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
- w = atoi( &buf[r1.matchedLength()] );
-
- d->readLine( buf, buflen ); // "#define .._height <num>"
- sbuf = QString::fromLatin1(buf);
-
- if ( r1.search(sbuf) == 0 &&
- r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
- h = atoi( &buf[r1.matchedLength()] );
-
- if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 )
- return; // format error
-
- for ( ;; ) { // scan for data
- if ( d->readLine(buf, buflen) <= 0 ) // end of file
- return;
- if ( strstr(buf,"0x") != 0 ) // does line contain data?
- break;
- }
-
- image.create( w, h, 1, 2, QImage::LittleEndian );
- if ( image.isNull() )
- return;
-
- image.setColor( 0, qRgb(255,255,255) ); // white
- image.setColor( 1, qRgb(0,0,0) ); // black
-
- int x = 0, y = 0;
- uchar *b = image.scanLine(0);
- char *p = strstr( buf, "0x" );
- w = (w+7)/8; // byte width
-
- while ( y < h ) { // for all encoded bytes...
- if ( p ) { // p = "0x.."
- *b++ = hex2byte(p+2);
- p += 2;
- if ( ++x == w && ++y < h ) {
- b = image.scanLine(y);
- x = 0;
- }
- p = strstr( p, "0x" );
- } else { // read another line
- if ( d->readLine(buf,buflen) <= 0 ) // EOF ==> truncated image
- break;
- p = strstr( buf, "0x" );
- }
- }
-
- iio->setImage( image );
- iio->setStatus( 0 ); // image ok
-}
-
-
-static void write_xbm_image( QImageIO *iio )
-{
- QIODevice *d = iio->ioDevice();
- QImage image = iio->image();
- int w = image.width();
- int h = image.height();
- int i;
- QString s = fbname(iio->fileName()); // get file base name
- char buf[100];
-
- sprintf( buf, "#define %s_width %d\n", s.ascii(), w );
- d->writeBlock( buf, qstrlen(buf) );
- sprintf( buf, "#define %s_height %d\n", s.ascii(), h );
- d->writeBlock( buf, qstrlen(buf) );
- sprintf( buf, "static char %s_bits[] = {\n ", s.ascii() );
- d->writeBlock( buf, qstrlen(buf) );
-
- iio->setStatus( 0 );
-
- if ( image.depth() != 1 )
- image = image.convertDepth( 1 ); // dither
- if ( image.bitOrder() != QImage::LittleEndian )
- image = image.convertBitOrder( QImage::LittleEndian );
-
- bool invert = qGray(image.color(0)) < qGray(image.color(1));
- char hexrep[16];
- for ( i=0; i<10; i++ )
- hexrep[i] = '0' + i;
- for ( i=10; i<16; i++ )
- hexrep[i] = 'a' -10 + i;
- if ( invert ) {
- char t;
- for ( i=0; i<8; i++ ) {
- t = hexrep[15-i];
- hexrep[15-i] = hexrep[i];
- hexrep[i] = t;
- }
- }
- int bcnt = 0;
- char *p = buf;
- uchar *b = image.scanLine(0);
- int x=0, y=0;
- int nbytes = image.byteCount();
- w = (w+7)/8;
- while ( nbytes-- ) { // write all bytes
- *p++ = '0'; *p++ = 'x';
- *p++ = hexrep[*b >> 4];
- *p++ = hexrep[*b++ & 0xf];
- if ( ++x == w && y < h-1 ) {
- b = image.scanLine(++y);
- x = 0;
- }
- if ( nbytes > 0 ) {
- *p++ = ',';
- if ( ++bcnt > 14 ) {
- *p++ = '\n';
- *p++ = ' ';
- *p = '\0';
- if ( (int)qstrlen(buf) != d->writeBlock( buf, qstrlen(buf) ) ) {
- iio->setStatus( 1 );
- return;
- }
- p = buf;
- bcnt = 0;
- }
- }
- }
- strcpy( p, " };\n" );
- if ( (int)qstrlen(buf) != d->writeBlock( buf, qstrlen(buf) ) )
- iio->setStatus( 1 );
-}
-
-#endif // QT_NO_IMAGEIO_XBM
-
-
-#ifndef QT_NO_IMAGEIO_XPM
-
-/*****************************************************************************
- XPM image read/write functions
- *****************************************************************************/
-
-
-// Skip until ", read until the next ", return the rest in *buf
-// Returns FALSE on error, TRUE on success
-
-static bool read_xpm_string( QCString &buf, QIODevice *d,
- const char * const *source, int &index )
-{
- if ( source ) {
- buf = source[index++];
- return true;
- }
-
- if ( buf.size() < 69 ) //# just an approximation
- buf.resize( 123 );
-
- buf[0] = '\0';
- int c;
- int i;
- while ( (c=d->getch()) != EOF && c != '"' ) { }
- if ( c == EOF ) {
- return false;
- }
- i = 0;
- while ( (c=d->getch()) != EOF && c != '"' ) {
- if ( i == (int)buf.size() )
- buf.resize( i*2+42 );
- buf[i++] = c;
- }
- if ( c == EOF ) {
- return false;
- }
-
- if ( i == (int)buf.size() ) // always use a 0 terminator
- buf.resize( i+1 );
- buf[i] = '\0';
- return true;
-}
-
-
-
-static int nextColorSpec(const QCString & buf)
-{
- int i = buf.find(" c ");
- if (i < 0)
- i = buf.find(" g ");
- if (i < 0)
- i = buf.find(" g4 ");
- if (i < 0)
- i = buf.find(" m ");
- if (i < 0)
- i = buf.find(" s ");
- return i;
-}
-
-//
-// INTERNAL
-//
-// Reads an .xpm from either the QImageIO or from the QString *.
-// One of the two HAS to be 0, the other one is used.
-//
-
-static void read_xpm_image_or_array( QImageIO * iio, const char * const * source,
- QImage & image)
-{
- QCString buf;
- QIODevice *d = 0;
- buf.resize( 200 );
-
- int i, cpp, ncols, w, h, index = 0;
-
- if ( iio ) {
- iio->setStatus( 1 );
- d = iio ? iio->ioDevice() : 0;
- d->readLine( buf.data(), buf.size() ); // "/* XPM */"
- QRegExp r( QString::fromLatin1("/\\*.XPM.\\*/") );
- if ( buf.find(r) == -1 )
- return; // bad magic
- } else if ( !source ) {
- return;
- }
-
- if ( !read_xpm_string( buf, d, source, index ) )
- return;
-
- if ( sscanf( buf, "%d %d %d %d", &w, &h, &ncols, &cpp ) < 4 )
- return; // < 4 numbers parsed
-
- if ( cpp > 15 )
- return;
-
- if ( ncols > 256 ) {
- image.create( w, h, 32 );
- } else {
- image.create( w, h, 8, ncols );
- }
-
- QMap<QString, int> colorMap;
- int currentColor;
-
- for( currentColor=0; currentColor < ncols; ++currentColor ) {
- if ( !read_xpm_string( buf, d, source, index ) ) {
-#if defined(QT_CHECK_RANGE)
- qWarning( "QImage: XPM color specification missing");
-#endif
- return;
- }
- QString index;
- index = buf.left( cpp );
- buf = buf.mid( cpp ).simplifyWhiteSpace().lower();
- buf.prepend( " " );
- i = nextColorSpec(buf);
- if ( i < 0 ) {
-#if defined(QT_CHECK_RANGE)
- qWarning( "QImage: XPM color specification is missing: %s", buf.data());
-#endif
- return; // no c/g/g4/m/s specification at all
- }
- buf = buf.mid( i+3 );
- // Strip any other colorspec
- int end = nextColorSpec(buf);
- if (end != -1)
- buf.truncate(end);
- buf = buf.stripWhiteSpace();
- if ( buf == "none" ) {
- image.setAlphaBuffer( true );
- int transparentColor = currentColor;
- if ( image.depth() == 8 ) {
- image.setColor( transparentColor,
- RGB_MASK & qRgb(198,198,198) );
- colorMap.insert( index, transparentColor );
- } else {
- QRgb rgb = RGB_MASK & qRgb(198,198,198);
- colorMap.insert( index, rgb );
- }
- } else {
- if ( ((buf.length()-1) % 3) && (buf[0] == '#') ) {
- buf.truncate (((buf.length()-1) / 4 * 3) + 1); // remove alpha channel left by imagemagick
- }
- QColor c( buf.data() );
- if ( image.depth() == 8 ) {
- image.setColor( currentColor, 0xff000000 | c.rgb() );
- colorMap.insert( index, currentColor );
- } else {
- QRgb rgb = 0xff000000 | c.rgb();
- colorMap.insert( index, rgb );
- }
- }
- }
-
- // Read pixels
- for( int y=0; y<h; y++ ) {
- if ( !read_xpm_string( buf, d, source, index ) ) {
-#if defined(QT_CHECK_RANGE)
- qWarning( "QImage: XPM pixels missing on image line %d", y);
-#endif
- return;
- }
- if ( image.depth() == 8 ) {
- uchar *p = image.scanLine(y);
- uchar *d = (uchar *)buf.data();
- uchar *end = d + buf.length();
- int x;
- if ( cpp == 1 ) {
- char b[2];
- b[1] = '\0';
- for ( x=0; x<w && d<end; x++ ) {
- b[0] = *d++;
- *p++ = (uchar)colorMap[b];
- }
- } else {
- char b[16];
- b[cpp] = '\0';
- for ( x=0; x<w && d<end; x++ ) {
- strncpy( b, (char *)d, cpp );
- *p++ = (uchar)colorMap[b];
- d += cpp;
- }
- }
- } else {
- QRgb *p = (QRgb*)image.scanLine(y);
- uchar *d = (uchar *)buf.data();
- uchar *end = d + buf.length();
- int x;
- char b[16];
- b[cpp] = '\0';
- for ( x=0; x<w && d<end; x++ ) {
- strncpy( b, (char *)d, cpp );
- *p++ = (QRgb)colorMap[b];
- d += cpp;
- }
- }
- }
- if ( iio ) {
- iio->setImage( image );
- iio->setStatus( 0 ); // image ok
- }
-}
-
-
-static void read_xpm_image( QImageIO * iio )
-{
- QImage i;
- (void)read_xpm_image_or_array( iio, 0, i );
- return;
-}
-
-
-static const char* xpm_color_name( int cpp, int index )
-{
- static char returnable[5];
- static const char code[] = ".#abcdefghijklmnopqrstuvwxyzABCD"
- "EFGHIJKLMNOPQRSTUVWXYZ0123456789";
- // cpp is limited to 4 and index is limited to 64^cpp
- if ( cpp > 1 ) {
- if ( cpp > 2 ) {
- if ( cpp > 3 ) {
- returnable[3] = code[index % 64];
- index /= 64;
- } else
- returnable[3] = '\0';
- returnable[2] = code[index % 64];
- index /= 64;
- } else
- returnable[2] = '\0';
- // the following 4 lines are a joke!
- if ( index == 0 )
- index = 64*44+21;
- else if ( index == 64*44+21 )
- index = 0;
- returnable[1] = code[index % 64];
- index /= 64;
- } else
- returnable[1] = '\0';
- returnable[0] = code[index];
-
- return returnable;
-}
-
-
-// write XPM image data
-static void write_xpm_image( QImageIO * iio )
-{
- if ( iio )
- iio->setStatus( 1 );
- else
- return;
-
- // ### 8-bit case could be made faster
- QImage image;
- if ( iio->image().depth() != 32 )
- image = iio->image().convertDepth( 32 );
- else
- image = iio->image();
-
- QMap<QRgb, int> colorMap;
-
- int w = image.width(), h = image.height(), ncolors = 0;
- int x, y;
-
- // build color table
- for( y=0; y<h; y++ ) {
- QRgb * yp = (QRgb *)image.scanLine( y );
- for( x=0; x<w; x++ ) {
- QRgb color = *(yp + x);
- if ( !colorMap.contains(color) )
- colorMap.insert( color, ncolors++ );
- }
- }
-
- // number of 64-bit characters per pixel needed to encode all colors
- int cpp = 1;
- for ( int k = 64; ncolors > k; k *= 64 ) {
- ++cpp;
- // limit to 4 characters per pixel
- // 64^4 colors is enough for a 4096x4096 image
- if ( cpp > 4)
- break;
- }
-
- QString line;
-
- // write header
- QTextStream s( iio->ioDevice() );
- s << "/* XPM */" << endl
- << "static char *" << fbname(iio->fileName()) << "[]={" << endl
- << "\"" << w << " " << h << " " << ncolors << " " << cpp << "\"";
-
- // write palette
- QMap<QRgb, int>::Iterator c = colorMap.begin();
- while ( c != colorMap.end() ) {
- QRgb color = c.key();
- if ( image.hasAlphaBuffer() && color == (color & RGB_MASK) )
- line.sprintf( "\"%s c None\"",
- xpm_color_name(cpp, *c) );
- else
- line.sprintf( "\"%s c #%02x%02x%02x\"",
- xpm_color_name(cpp, *c),
- qRed(color),
- qGreen(color),
- qBlue(color) );
- ++c;
- s << "," << endl << line;
- }
-
- // write pixels, limit to 4 characters per pixel
- line.truncate( cpp*w );
- for( y=0; y<h; y++ ) {
- QRgb * yp = (QRgb *) image.scanLine( y );
- int cc = 0;
- for( x=0; x<w; x++ ) {
- int color = (int)(*(yp + x));
- QCString chars = xpm_color_name( cpp, colorMap[color] );
- line[cc++] = chars[0];
- if ( cpp > 1 ) {
- line[cc++] = chars[1];
- if ( cpp > 2 ) {
- line[cc++] = chars[2];
- if ( cpp > 3 ) {
- line[cc++] = chars[3];
- }
- }
- }
- }
- s << "," << endl << "\"" << line << "\"";
- }
- s << "};" << endl;
-
- iio->setStatus( 0 );
-}
-
-#endif // QT_NO_IMAGEIO_XPM
-
/*!
Returns an image with depth \a d, using the \a palette_count
colors pointed to by \a palette. If \a d is 1 or 8, the returned