static QPixmap makeOffline(unsigned flags, const QPixmap &p) { unsigned swapColor = flags & ICON_COLOR_MASK; QImage image = p.convertToImage(); unsigned int *data = (image.depth() > 8) ? (unsigned int *)image.bits() : (unsigned int *)image.colorTable(); int pixels = (image.depth() > 8) ? image.width()*image.height() : image.numColors(); for (int i = 0; i < pixels; i++){ QColor c(qRed(data[i]), qGreen(data[i]), qBlue(data[i])); int a = qAlpha(data[i]); int h, s, v; c.hsv(&h, &s, &v); if (swapColor){ h = (swapColor * 2 - h) & 0xFF; c.setHsv(h, s, v); }else{ c.setHsv(h, 0, v * 3 / 4); } data[i] = qRgba(c.red(), c.green(), c.blue(), a); } QPixmap pict; pict.convertFromImage(image); return pict; }
UI_EXPORT QPixmap& intensity(QPixmap &pict, float percent) { QImage image = pict.convertToImage(); int i, tmp, r, g, b; int segColors = image.depth() > 8 ? 256 : image.numColors(); unsigned char *segTbl = new unsigned char[segColors]; int pixels = image.depth() > 8 ? image.width()*image.height() : image.numColors(); unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : (unsigned int *)image.colorTable(); bool brighten = (percent >= 0); if(percent < 0) percent = -percent; if(brighten){ // keep overflow check out of loops for(i=0; i < segColors; ++i){ tmp = (int)(i*percent); if(tmp > 255) tmp = 255; segTbl[i] = (unsigned char)tmp; } } else{ for(i=0; i < segColors; ++i){ tmp = (int)(i*percent); if(tmp < 0) tmp = 0; segTbl[i] = (unsigned char)tmp; } } if(brighten){ // same here for(i=0; i < pixels; ++i){ r = qRed(data[i]); g = qGreen(data[i]); b = qBlue(data[i]); r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; data[i] = qRgb(r, g, b); } } else{ for(i=0; i < pixels; ++i){ r = qRed(data[i]); g = qGreen(data[i]); b = qBlue(data[i]); r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; data[i] = qRgb(r, g, b); } } delete [] segTbl; pict.convertFromImage(image); return pict; }
template< int operation( int, int ) > static QImage changeImage( const QImage& image, int value ) { QImage im = image; im.detach(); if( im.colorCount() == 0 ) /* truecolor */ { if( im.format() != QImage::Format_RGB32 ) /* just in case */ im = im.convertToFormat( QImage::Format_RGB32 ); int table[ 256 ]; for( int i = 0; i < 256; ++i ) table[ i ] = operation( i, value ); if( im.hasAlphaChannel() ) { for( int y = 0; y < im.height(); ++y ) { QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y )); for( int x = 0; x < im.width(); ++x ) line[ x ] = qRgba( changeUsingTable( qRed( line[ x ] ), table ), changeUsingTable( qGreen( line[ x ] ), table ), changeUsingTable( qBlue( line[ x ] ), table ), changeUsingTable( qAlpha( line[ x ] ), table )); } } else { for( int y = 0; y < im.height(); ++y ) { QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y )); for( int x = 0; x < im.width(); ++x ) line[ x ] = qRgb( changeUsingTable( qRed( line[ x ] ), table ), changeUsingTable( qGreen( line[ x ] ), table ), changeUsingTable( qBlue( line[ x ] ), table )); } } } else { QVector<QRgb> colors = im.colorTable(); for( int i = 0; i < im.colorCount(); ++i ) colors[ i ] = qRgb( operation( qRed( colors[ i ] ), value ), operation( qGreen( colors[ i ] ), value ), operation( qBlue( colors[ i ] ), value )); } return im; }
/*! * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed. */ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no) { if (img.isNull()) return -1; int object = imageCache.value(serial_no); if(object) return object; QImage image = img; QImage::Format format = image.format(); if (image.depth() == 1 && *bitmap && img.colorTable().size() == 2 && img.colorTable().at(0) == QColor(Qt::black).rgba() && img.colorTable().at(1) == QColor(Qt::white).rgba()) { if (format == QImage::Format_MonoLSB) image = image.convertToFormat(QImage::Format_Mono); format = QImage::Format_Mono; } else { *bitmap = false; if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); format = QImage::Format_ARGB32; } } int w = image.width(); int h = image.height(); int d = image.depth(); if (format == QImage::Format_Mono) { int bytesPerLine = (w + 7) >> 3; QByteArray data; data.resize(bytesPerLine * h); char *rawdata = data.data(); for (int y = 0; y < h; ++y) { memcpy(rawdata, image.scanLine(y), bytesPerLine); rawdata += bytesPerLine; } object = writeImage(data, w, h, d, 0, 0); } else {
static QPixmap swapRG(const QPixmap &p) { QImage image = p.convertToImage(); unsigned int *data = (image.depth() > 8) ? (unsigned int *)image.bits() : (unsigned int *)image.colorTable(); int pixels = (image.depth() > 8) ? image.width()*image.height() : image.numColors(); for (int i = 0; i < pixels; i++){ int r = qRed(data[i]); int g = qGreen(data[i]); int b = qBlue(data[i]); int a = qAlpha(data[i]); data[i] = qRgba(g, r, b, a); } QPixmap pict; pict.convertFromImage(image); return pict; }
static QPixmap makeInactive(const QPixmap &p) { QImage image = p.convertToImage(); unsigned int *data = (image.depth() > 8) ? (unsigned int *)image.bits() : (unsigned int *)image.colorTable(); int pixels = (image.depth() > 8) ? image.width()*image.height() : image.numColors(); for (int i = 0; i < pixels; i++){ QColor c(qRed(data[i]), qGreen(data[i]), qBlue(data[i])); int a = qAlpha(data[i]); int h, s, v; c.hsv(&h, &s, &v); c.setHsv(h, s / 8, v); data[i] = qRgba(c.red(), c.green(), c.blue(), a); } QPixmap pict; pict.convertFromImage(image); return pict; }
void ImageTransforms::toGrayscale(QImage& in, QImage& out) { if (in.isNull()) return; int w = in.width(), h = in.height(); if (in.format()!=QImage::Format_ARGB32 && in.format()!=QImage::Format_RGB32 && in.format() != QImage::Format_RGB888 ) { std::cout << "ImageTransforms::toGrayscale : Error - accepted input format is ARGB32 o RGB888." << std::endl; return; } if(out.format() == QImage::Format_Indexed8) { QImage gout = toGrayscale(in); memcpy(out.bits(), gout.bits(), h*out.bytesPerLine()); out.setColorTable(gout.colorTable()); } else if( out.format() == QImage::Format_ARGB32 || out.format() == QImage::Format_RGB32 || out.format() == QImage::Format_RGB888 ) { //Color output image int i, j, k, g, cind1, cind2, bplin = in.bytesPerLine(), bplout = out.bytesPerLine(), step1 = (in.format() == QImage::Format_RGB888) ? 3 : 4, step2 = (out.format() == QImage::Format_RGB888) ? 3 : 4, wstep = w*step1; uchar *pin = in.bits(), *pout = out.bits(); for(i=0; i<h; i++) for(j=0,k=0; j<wstep; j+=step1,k+=step2) { cind1 = i*bplin + j; cind2 = i*bplout + k; g = qGray(pin[cind1+2],pin[cind1+1],pin[cind1]); pout[cind2+2] = pout[cind2+1] = pout[cind2] = g; } } }
void Uic::embed( QTextStream& out, const char* project, const QStringList& images ) { QString cProject = convertToCIdentifier( project ); QStringList::ConstIterator it; out << "/****************************************************************************\n"; out << "** Image collection for project '" << project << "'.\n"; out << "**\n"; out << "** Generated from reading image files: \n"; for ( it = images.begin(); it != images.end(); ++it ) out << "** " << *it << "\n"; out << "**\n"; out << "** Created: " << QDateTime::currentDateTime().toString() << "\n"; out << "** by: The User Interface Compiler ($Id: embed.cpp 2 2005-11-16 15:49:26Z dmik $)\n"; out << "**\n"; out << "** WARNING! All changes made in this file will be lost!\n"; out << "****************************************************************************/\n"; out << "\n"; out << "#include <qimage.h>\n"; out << "#include <qdict.h>\n"; out << "#include <qmime.h>\n"; out << "#include <qdragobject.h>\n"; out << "\n"; QPtrList<EmbedImage> list_image; list_image.setAutoDelete( TRUE ); int image_count = 0; for ( it = images.begin(); it != images.end(); ++it ) { QImage img; if ( !img.load( *it ) ) { fprintf( stderr, "uic: cannot load image file %s\n", (*it).latin1() ); continue; } EmbedImage *e = new EmbedImage; e->width = img.width(); e->height = img.height(); e->depth = img.depth(); e->numColors = img.numColors(); e->colorTable = new QRgb[e->numColors]; e->alpha = img.hasAlphaBuffer(); memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); QFileInfo fi( *it ); e->name = fi.fileName(); e->cname = QString("image_%1").arg( image_count++); list_image.append( e ); out << "// " << *it << "\n"; QString s; if ( e->depth == 1 ) img = img.convertBitOrder(QImage::BigEndian); out << s.sprintf( "static const unsigned char %s_data[] = {", (const char *)e->cname ); #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION e->compressed = #endif embedData( out, img.bits(), img.numBytes() ); out << "\n};\n\n"; if ( e->numColors ) { out << s.sprintf( "static const QRgb %s_ctable[] = {", (const char *)e->cname ); embedData( out, e->colorTable, e->numColors ); out << "\n};\n\n"; } } if ( !list_image.isEmpty() ) { out << "static struct EmbedImage {\n" " int width, height, depth;\n" " const unsigned char *data;\n" #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION " ulong compressed;\n" #endif " int numColors;\n" " const QRgb *colorTable;\n" " bool alpha;\n" " const char *name;\n" "} embed_image_vec[] = {\n"; EmbedImage *e = list_image.first(); while ( e ) { out << " { " << e->width << ", " << e->height << ", " << e->depth << ", " << "(const unsigned char*)" << e->cname << "_data, " #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION << e->compressed << ", " #endif << e->numColors << ", "; if ( e->numColors ) out << e->cname << "_ctable, "; else out << "0, "; if ( e->alpha ) out << "TRUE, "; else out << "FALSE, "; out << "\"" << e->name << "\" },\n"; e = list_image.next(); } #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION out << " { 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; #else out << " { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; #endif out << "\n" "static QImage uic_findImage( const QString& name )\n" "{\n" " for ( int i=0; embed_image_vec[i].data; i++ ) {\n" " if ( QString::fromUtf8(embed_image_vec[i].name) == name ) {\n" #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION " QByteArray baunzip;\n" " baunzip = qUncompress( embed_image_vec[i].data, \n" " embed_image_vec[i].compressed );\n" " QImage img((uchar*)baunzip.data(),\n" " embed_image_vec[i].width,\n" " embed_image_vec[i].height,\n" " embed_image_vec[i].depth,\n" " (QRgb*)embed_image_vec[i].colorTable,\n" " embed_image_vec[i].numColors,\n" " QImage::BigEndian\n" " );\n" " img = img.copy();\n" #else " QImage img((uchar*)embed_image_vec[i].data,\n" " embed_image_vec[i].width,\n" " embed_image_vec[i].height,\n" " embed_image_vec[i].depth,\n" " (QRgb*)embed_image_vec[i].colorTable,\n" " embed_image_vec[i].numColors,\n" " QImage::BigEndian\n" " );\n" #endif " if ( embed_image_vec[i].alpha )\n" " img.setAlphaBuffer(TRUE);\n" " return img;\n" " }\n" " }\n" " return QImage();\n" "}\n\n"; out << "class MimeSourceFactory_" << cProject << " : public QMimeSourceFactory\n"; out << "{\n"; out << "public:\n"; out << " MimeSourceFactory_" << cProject << "() {}\n"; out << " ~MimeSourceFactory_" << cProject << "() {}\n"; out << " const QMimeSource* data( const QString& abs_name ) const {\n"; out << "\tconst QMimeSource* d = QMimeSourceFactory::data( abs_name );\n"; out << "\tif ( d || abs_name.isNull() ) return d;\n"; out << "\tQImage img = uic_findImage( abs_name );\n"; out << "\tif ( !img.isNull() )\n"; out << "\t ((QMimeSourceFactory*)this)->setImage( abs_name, img );\n"; out << "\treturn QMimeSourceFactory::data( abs_name );\n"; out << " };\n"; out << "};\n\n"; out << "static QMimeSourceFactory* factory = 0;\n"; out << "\n"; out << "void qInitImages_" << cProject << "()\n"; out << "{\n"; out << " if ( !factory ) {\n"; out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n"; out << "\tQMimeSourceFactory::defaultFactory()->addFactory( factory );\n"; out << " }\n"; out << "}\n\n"; out << "void qCleanupImages_" << cProject << "()\n"; out << "{\n"; out << " if ( factory ) {\n"; out << "\tQMimeSourceFactory::defaultFactory()->removeFactory( factory );\n"; out << "\tdelete factory;\n"; out << "\tfactory = 0;\n"; out << " }\n"; out << "}\n\n"; out << "class StaticInitImages_" << cProject << "\n"; out << "{\n"; out << "public:\n"; out << " StaticInitImages_" << cProject << "() { qInitImages_" << cProject << "(); }\n"; out << "#if defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE)\n"; out << " ~StaticInitImages_" << cProject << "() { }\n"; out << "#else\n"; out << " ~StaticInitImages_" << cProject << "() { qCleanupImages_" << cProject << "(); }\n"; out << "#endif\n"; out << "};\n\n"; out << "static StaticInitImages_" << cProject << " staticImages;\n"; } }
static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQuality) { bool success = false; const QVector<QRgb> cmap = image.colorTable(); struct jpeg_compress_struct cinfo; JSAMPROW row_pointer[1]; row_pointer[0] = 0; struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device); struct my_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = my_error_exit; if (!setjmp(jerr.setjmp_buffer)) { // WARNING: // this if loop is inside a setjmp/longjmp branch // do not create C++ temporaries here because the destructor may never be called // if you allocate memory, make sure that you can free it (row_pointer[0]) jpeg_create_compress(&cinfo); cinfo.dest = iod_dest; cinfo.image_width = image.width(); cinfo.image_height = image.height(); bool gray=false; switch (image.format()) { case QImage::Format_Mono: case QImage::Format_MonoLSB: case QImage::Format_Indexed8: gray = true; for (int i = image.colorCount(); gray && i--;) { gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) && qRed(cmap[i]) == qBlue(cmap[i])); } cinfo.input_components = gray ? 1 : 3; cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB; break; default: cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; } jpeg_set_defaults(&cinfo); qreal diffInch = qAbs(image.dotsPerMeterX()*2.54/100. - qRound(image.dotsPerMeterX()*2.54/100.)) + qAbs(image.dotsPerMeterY()*2.54/100. - qRound(image.dotsPerMeterY()*2.54/100.)); qreal diffCm = (qAbs(image.dotsPerMeterX()/100. - qRound(image.dotsPerMeterX()/100.)) + qAbs(image.dotsPerMeterY()/100. - qRound(image.dotsPerMeterY()/100.)))*2.54; if (diffInch < diffCm) { cinfo.density_unit = 1; // dots/inch cinfo.X_density = qRound(image.dotsPerMeterX()*2.54/100.); cinfo.Y_density = qRound(image.dotsPerMeterY()*2.54/100.); } else { cinfo.density_unit = 2; // dots/cm cinfo.X_density = (image.dotsPerMeterX()+50) / 100; cinfo.Y_density = (image.dotsPerMeterY()+50) / 100; } int quality = sourceQuality >= 0 ? qMin(sourceQuality,100) : 75; #if defined(Q_OS_UNIXWARE) jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */); jpeg_start_compress(&cinfo, B_TRUE); #else jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */); jpeg_start_compress(&cinfo, true); #endif row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components]; int w = cinfo.image_width; while (cinfo.next_scanline < cinfo.image_height) { uchar *row = row_pointer[0]; switch (image.format()) { case QImage::Format_Mono: case QImage::Format_MonoLSB: if (gray) { const uchar* data = image.constScanLine(cinfo.next_scanline); if (image.format() == QImage::Format_MonoLSB) { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7))); row[i] = qRed(cmap[bit]); } } else { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7)))); row[i] = qRed(cmap[bit]); } } } else { const uchar* data = image.constScanLine(cinfo.next_scanline); if (image.format() == QImage::Format_MonoLSB) { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7))); *row++ = qRed(cmap[bit]); *row++ = qGreen(cmap[bit]); *row++ = qBlue(cmap[bit]); } } else { for (int i=0; i<w; i++) { bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7)))); *row++ = qRed(cmap[bit]); *row++ = qGreen(cmap[bit]); *row++ = qBlue(cmap[bit]); } } }
static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QByteArray &sourceFormat) { QByteArray str; QImage image = sourceImage; QByteArray format = sourceFormat; format = format.left(3); // ignore RAW part bool gray = format == "pgm"; if (format == "pbm") { image = image.convertToFormat(QImage::Format_Mono); } else if (gray) { image = image.convertToFormat(QImage::Format_Grayscale8); } else { switch (image.format()) { case QImage::Format_Mono: case QImage::Format_MonoLSB: image = image.convertToFormat(QImage::Format_Indexed8); break; case QImage::Format_Indexed8: case QImage::Format_RGB32: case QImage::Format_ARGB32: break; default: if (image.hasAlphaChannel()) image = image.convertToFormat(QImage::Format_ARGB32); else image = image.convertToFormat(QImage::Format_RGB32); break; } } if (image.depth() == 1 && image.colorCount() == 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 = "P\n"; str += QByteArray::number(w); str += ' '; str += QByteArray::number(h); str += '\n'; switch (image.depth()) { case 1: { str.insert(1, '4'); if (out->write(str, str.length()) != str.length()) return false; w = (w+7)/8; for (uint y=0; y<h; y++) { uchar* line = image.scanLine(y); if (w != (uint)out->write((char*)line, w)) return false; } } break; case 8: { str.insert(1, gray ? '5' : '6'); str.append("255\n"); if (out->write(str, str.length()) != str.length()) return false; uint bpl = w * (gray ? 1 : 3); uchar *buf = new uchar[bpl]; if (image.format() == QImage::Format_Indexed8) { QVector<QRgb> color = image.colorTable(); for (uint y=0; y<h; y++) { const uchar *b = image.constScanLine(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->write((char*)buf, bpl)) return false; } } else { for (uint y=0; y<h; y++) { const uchar *b = image.constScanLine(y); uchar *p = buf; uchar *end = buf + bpl; if (gray) { while (p < end) *p++ = *b++; } else { while (p < end) { uchar color = *b++; *p++ = color; *p++ = color; *p++ = color; } } if (bpl != (uint)out->write((char*)buf, bpl)) return false; } } delete [] buf; break; } case 32: { str.insert(1, '6'); str.append("255\n"); if (out->write(str, str.length()) != str.length()) return false; uint bpl = w * 3; uchar *buf = new uchar[bpl]; for (uint y=0; y<h; y++) { const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y)); uchar *p = buf; uchar *end = buf+bpl; while (p < end) { QRgb rgb = *b++; *p++ = qRed(rgb); *p++ = qGreen(rgb); *p++ = qBlue(rgb); } if (bpl != (uint)out->write((char*)buf, bpl)) return false; } delete [] buf; break; } default: return false; } return true; }
int main( int argc, char **argv ) { if ( argc < 2 ) { qWarning( "Usage:\n\t%s [--images] files", argv[0] ); return 1; } QFile output; bool output_hdr = FALSE; bool images = FALSE; output.open( IO_WriteOnly, stdout ); QTextStream out( &output ); QPtrList<EmbedImage> list_image; QPtrList<Embed> list; list.setAutoDelete( TRUE ); list_image.setAutoDelete( TRUE ); long l = rand(); out << "#ifndef _QEMBED_" << l << endl; out << "#define _QEMBED_" << l << endl; QStringList args; for ( int i = 1; i < argc; ++i ) { QString file( argv[i] ); #ifdef Q_WS_WIN // Since wildcards are not expanded automatically for us on Windows, we need to do // it ourselves if ( file.contains( '*' ) || file.contains( '?' ) ) { QDir d; const QFileInfoList *fiList = d.entryInfoList( file, QDir::Files ); QFileInfoListIterator it(*fiList); while ( it.current() ) { args << (*it)->filePath(); ++it; } } else #endif args << file; } for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it ) { QString arg = (*it); if ( arg == "--images" ) { if ( !images ) { out << "#include <qimage.h>\n"; out << "#include <qdict.h>\n"; images = TRUE; } } else { QFile f( *it ); if ( !f.open(IO_ReadOnly) ) { qWarning( "Cannot open file %s, ignoring it", (*it).latin1() ); continue; } QByteArray a( f.size() ); if ( f.size() == 0 || f.readBlock(a.data(), f.size()) != (int)f.size() ) { qWarning( "Cannot read file %s, ignoring it", (*it).latin1() ); continue; } if ( images ) { QImage img; if ( !img.loadFromData(a) ) { qWarning( "Cannot read image from file %s, ignoring it", (*it).latin1() ); continue; } EmbedImage *e = new EmbedImage; e->width = img.width(); e->height = img.height(); e->depth = img.depth(); e->numColors = img.numColors(); e->colorTable = new QRgb[e->numColors]; e->alpha = img.hasAlphaBuffer(); memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); QFileInfo fi( (*it) ); e->name = fi.baseName(); e->cname = convertFileNameToCIdentifier( e->name.latin1() ); list_image.append( e ); QString s; if ( e->depth == 32 ) { out << s.sprintf( "static const QRgb %s_data[] = {", (const char *)e->cname ); embedData( (QRgb*)img.bits(), e->width*e->height, &output ); } else { if ( e->depth == 1 ) img = img.convertBitOrder(QImage::BigEndian); out << s.sprintf( "static const unsigned char %s_data[] = {", (const char *)e->cname ); embedData( img.bits(), img.numBytes(), &output ); } out << "\n};\n\n"; if ( e->numColors ) { out << s.sprintf( "static const QRgb %s_ctable[] = {", (const char *)e->cname ); embedData( e->colorTable, e->numColors, &output ); out << "\n};\n\n"; } } else { Embed *e = new Embed; e->size = f.size(); e->name = (*it); e->cname = convertFileNameToCIdentifier( (*it) ); list.append( e ); QString s; out << s.sprintf( "static const unsigned int %s_len = %d;\n", (const char *)e->cname, e->size ); out << s.sprintf( "static const unsigned char %s_data[] = {", (const char *)e->cname ); embedData( a, &output ); out << "\n};\n\n"; } if ( !output_hdr ) { output_hdr = TRUE; out << header; } } } if ( list.count() > 0 ) { out << "#include <qcstring.h>\n"; if ( !images ) out << "#include <qdict.h>\n"; out << "static struct Embed {\n" " unsigned int size;\n" " const unsigned char *data;\n" " const char *name;\n" "} embed_vec[] = {\n"; Embed *e = list.first(); while ( e ) { out << " { " << e->size << ", " << e->cname << "_data, " << "\"" << e->name << "\" },\n"; e = list.next(); } out << " { 0, 0, 0 }\n};\n"; out << "\n" "static const QByteArray& qembed_findData( const char* name )\n" "{\n" " static QDict<QByteArray> dict;\n" " QByteArray* ba = dict.find( name );\n" " if ( !ba ) {\n" " for ( int i = 0; embed_vec[i].data; i++ ) {\n" " if ( strcmp(embed_vec[i].name, name) == 0 ) {\n" " ba = new QByteArray;\n" " ba->setRawData( (char*)embed_vec[i].data,\n" " embed_vec[i].size );\n" " dict.insert( name, ba );\n" " break;\n" " }\n" " }\n" " if ( !ba ) {\n" " static QByteArray dummy;\n" " return dummy;\n" " }\n" " }\n" " return *ba;\n" "}\n\n"; } if ( list_image.count() > 0 ) { out << "static struct EmbedImage {\n" " int width, height, depth;\n" " const unsigned char *data;\n" " int numColors;\n" " const QRgb *colorTable;\n" " bool alpha;\n" " const char *name;\n" "} embed_image_vec[] = {\n"; EmbedImage *e = list_image.first(); while ( e ) { out << " { " << e->width << ", " << e->height << ", " << e->depth << ", " << "(const unsigned char*)" << e->cname << "_data, " << e->numColors << ", "; if ( e->numColors ) out << e->cname << "_ctable, "; else out << "0, "; if ( e->alpha ) out << "TRUE, "; else out << "FALSE, "; out << "\"" << e->name << "\" },\n"; e = list_image.next(); } out << " { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; out << "\n" "static const QImage& qembed_findImage( const QString& name )\n" "{\n" " static QDict<QImage> dict;\n" " QImage* img = dict.find( name );\n" " if ( !img ) {\n" " for ( int i = 0; embed_image_vec[i].data; i++ ) {\n" " if ( strcmp(embed_image_vec[i].name, name.latin1()) == 0 ) {\n" " img = new QImage((uchar*)embed_image_vec[i].data,\n" " embed_image_vec[i].width,\n" " embed_image_vec[i].height,\n" " embed_image_vec[i].depth,\n" " (QRgb*)embed_image_vec[i].colorTable,\n" " embed_image_vec[i].numColors,\n" " QImage::BigEndian );\n" " if ( embed_image_vec[i].alpha )\n" " img->setAlphaBuffer( TRUE );\n" " dict.insert( name, img );\n" " break;\n" " }\n" " }\n" " if ( !img ) {\n" " static QImage dummy;\n" " return dummy;\n" " }\n" " }\n" " return *img;\n" "}\n\n"; } out << "#endif" << endl; return 0; }
bool ParupaintPanvasInputOutput::exportGIF(ParupaintPanvas * panvas, const QString & filename, QString & errorStr) { Q_ASSERT(panvas); if(filename.isEmpty()) return (errorStr = "Enter a filename to save to.").isEmpty(); #ifndef PARUPAINT_NOGIF int error = 0; GifFileType * gif = EGifOpenFileName(filename.toStdString().c_str(), false, &error); foreach(const QImage & image, panvas->mergedImageFrames(true)){ error = 0; bool alpha = false; QImage toWrite = convertToIndexed8(image, &alpha); QVector<QRgb> colorTable = toWrite.colorTable(); ColorMapObject cmap; int numColors = 1 << BitSize(toWrite.colorCount()); numColors = 256; cmap.ColorCount = numColors; cmap.BitsPerPixel = 8; /// @todo based on numColors (or not? we did ask for Format_Indexed8, so the data is always 8-bit, right?) GifColorType* colorValues = (GifColorType*)malloc(cmap.ColorCount * sizeof(GifColorType)); cmap.Colors = colorValues; int c = 0; for(; c < toWrite.colorCount(); ++c) { //qDebug("color %d has %02X%02X%02X", c, qRed(colorTable[c]), qGreen(colorTable[c]), qBlue(colorTable[c])); colorValues[c].Red = qRed(colorTable[c]); colorValues[c].Green = qGreen(colorTable[c]); colorValues[c].Blue = qBlue(colorTable[c]); } // In case we had an actual number of colors that's not a power of 2, // fill the rest with something (black perhaps). for (; c < numColors; ++c) { colorValues[c].Red = 0; colorValues[c].Green = 0; colorValues[c].Blue = 0; } /// @todo how to specify which version, or decide based on features in use // Because of this call, libgif is not re-entrant EGifSetGifVersion(gif, true); if ((error = EGifPutScreenDesc(gif, toWrite.width(), toWrite.height(), numColors, 0, &cmap)) == GIF_ERROR) qCritical("EGifPutScreenDesc returned error %d", error); int fps = (100.0/panvas->frameRate()); char flags = 1 << 3; if(alpha) flags |= 1; char graphics_ext[] = { flags, (char)(fps % 256), (char)(fps / 256), (char)(alpha ? 0x00 : 0xff) }; EGifPutExtension(gif, GRAPHICS_EXT_FUNC_CODE, 4, graphics_ext); if ((error = EGifPutImageDesc(gif, 0, 0, toWrite.width(), toWrite.height(), 0, &cmap)) == GIF_ERROR) qCritical("EGifPutImageDesc returned error %d", error); int lc = toWrite.height(); int llen = toWrite.bytesPerLine(); for (int l = 0; l < lc; ++l) { uchar* line = toWrite.scanLine(l); if ((error = EGifPutLine(gif, (GifPixelType*)line, llen)) == GIF_ERROR) { qCritical("EGifPutLine returned error %d", error); } } if(true){ // loop forever unsigned char loopblock[3] = {1, 0, 0}; EGifPutExtensionLeader(gif, APPLICATION_EXT_FUNC_CODE); EGifPutExtensionBlock(gif, 11, "NETSCAPE2.0"); EGifPutExtensionBlock(gif, 3, loopblock); EGifPutExtensionTrailer(gif); } } EGifCloseFile(gif, &error); return true; #endif return (errorStr = "GIF export not available.").isEmpty(); }
// Read an image as raw or byte data static int ReadSection(ImodImageFile *inFile, char *buf, int byte) { int ysize = inFile->ny; int i, pixel, y, maxind; float slope = inFile->slope; float offset = inFile->offset; int outmin = 0; int outmax = 255; int xmin, xmax, ymin, ymax; unsigned char *obuf; float *fbuf; unsigned char *bdata; unsigned char map[256]; QRgb *rgbdata; QRgb rgbval; QImage *image; QImage image2; unsigned char *map2 = NULL; QVector<QRgb> colorTable; if (inFile->axis == 2) return -1; if (byte && (inFile->format != IIFORMAT_LUMINANCE)) return -1; if (!inFile->header && iiReopen(inFile)) return -1; image = (QImage *)inFile->header; // Convert a 16-bpp image to 32 if (image->depth() == 16) { image2 = image->convertToFormat(QImage::Format_RGB32); if (image2.isNull()) return -1; image = &image2; } colorTable = image->colorTable(); /* set the dimensions to read in */ xmin = inFile->llx; ymin = inFile->lly; if (inFile->urx < 0) xmax = inFile->nx-1; else xmax = inFile->urx; if (inFile->ury < 0) ymax = inFile->ny-1; else ymax = inFile->ury; if (byte) { // Get a map for scaling the bytes, then get composite map to go from // pixel indexes to scaled value; map2 = get_byte_map(slope, offset, outmin, outmax, 0); maxind = B3DMAX(0, colorTable.size() - 1); for (i = 0; i < 256; i++) { pixel = qRed(colorTable[B3DMIN(i, maxind)]); map[i] = map2[pixel]; } } // Loop on the lines to get data obuf = (unsigned char *)buf; fbuf = (float *)buf; for (y = ymin; y <= ymax; y++) { bdata = image->scanLine(ysize - 1 - y); // Bytes: just map the index values if (byte == 1) { for (i = xmin; i <= xmax; i++) *obuf++ = map[bdata[i]]; } else if (byte == 2) { for (i = xmin; i <= xmax; i++) *fbuf++ = bdata[i]; // 8 bit RGB: look up in color table } else if (image->depth() == 8) { for (i = xmin; i <= xmax; i++) { rgbval = colorTable[bdata[i]]; *obuf++ = qRed(rgbval); *obuf++ = qGreen(rgbval); *obuf++ = qBlue(rgbval); } // 32-bit: convert scan line pointer to rgb, get components } else { rgbdata = (QRgb *)bdata; for (i = xmin; i <= xmax; i++) { rgbval = rgbdata[i]; *obuf++ = qRed(rgbval); *obuf++ = qGreen(rgbval); *obuf++ = qBlue(rgbval); } } } return 0; }
int main( int argc, char **argv ) { if ( argc < 2 ) { qWarning( "Usage:\n\t%s [--images] files", argv[0] ); return 1; } QFile output; bool images = FALSE; output.open( IO_WriteOnly, stdout ); QTextStream out( &output ); EmbedImageList list_image; QList<Embed> list; list.setAutoDelete( TRUE ); list_image.setAutoDelete( TRUE ); // Embed data for all input files out << "/* Generated by qembed */\n"; srand( time(0) ); long l = rand(); out << "#ifndef _" << l << endl; out << "#define _" << l << endl; for ( int i=1; i<argc; i++ ) { QString arg = argv[i]; if ( arg == "--images" ) { if ( !images ) { out << "#include <qimage.h>\n"; out << "#include <stdlib.h>\n"; images = TRUE; } } else { QFile f( argv[i] ); if ( !f.open(IO_ReadOnly) ) { qWarning( "Cannot open file %s, ignoring it", argv[i] ); continue; } QByteArray a( f.size() ); if ( f.readBlock(a.data(), f.size()) != (int)f.size() ) { qWarning( "Cannot read file %s, ignoring it", argv[i] ); f.close(); continue; } if ( images ) { QImage img; if ( !img.loadFromData(a) ) { qWarning( "Cannot read image from file %s, ignoring it", argv[i] ); f.close(); continue; } EmbedImage *e = new EmbedImage; e->width = img.width(); e->height = img.height(); e->depth = img.depth(); e->numColors = img.numColors(); e->colorTable = new QRgb[e->numColors]; e->alpha = img.hasAlphaBuffer(); memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); QFileInfo fi(argv[i]); e->name = fi.baseName(); e->cname = convertFileNameToCIdentifier( e->name.latin1() ); list_image.append( e ); QString s; if ( e->depth == 32 ) { out << s.sprintf( "static const QRgb %s_data[] = {", (const char *)e->cname ); embedData( (QRgb*)img.bits(), e->width*e->height, &output ); } else { if ( e->depth == 1 ) img = img.convertBitOrder(QImage::BigEndian); out << s.sprintf( "static const unsigned char %s_data[] = {", (const char *)e->cname ); embedData( img.bits(), img.numBytes(), &output ); } out << "\n};\n\n"; if ( e->numColors ) { out << s.sprintf( "static const QRgb %s_ctable[] = {", (const char *)e->cname ); embedData( e->colorTable, e->numColors, &output ); out << "\n};\n\n"; } } else { Embed *e = new Embed; e->size = f.size(); e->name = argv[i]; e->cname = convertFileNameToCIdentifier( argv[i] ); list.append( e ); QString s; out << s.sprintf( "static const unsigned int %s_len = %d;\n", (const char *)e->cname, e->size ); out << s.sprintf( "static const unsigned char %s_data[] = {", (const char *)e->cname ); embedData( a, &output ); out << "\n};\n\n"; } f.close(); } } // Generate summery if ( list.count() > 0 ) { out << "#include <qcstring.h>\n"; if ( !images ) out << "#include <qdict.h>\n"; out << "static struct Embed {\n" " unsigned int size;\n" " const unsigned char *data;\n" " const char *name;\n" "} embed_vec[] = {\n"; Embed *e = list.first(); while ( e ) { out << " { " << e->size << ", " << e->cname << "_data, " << "\"" << e->name << "\" },\n"; e = list.next(); } out << " { 0, 0, 0 }\n};\n"; out << "\n" "inline const QByteArray& qembed_findData(const char* name)\n" "{\n" " static QDict<QByteArray> dict;\n" " QByteArray* ba = dict.find(name);\n" " if ( !ba ) {\n" " for (int i=0; embed_vec[i].data; i++) {\n" " if ( 0==strcmp(embed_vec[i].name, name) ) {\n" " ba = new QByteArray;\n" " ba->setRawData( (char*)embed_vec[i].data,\n" " embed_vec[i].size );\n" " break;\n" " }\n" " }\n" " if ( !ba ) {\n" " static QByteArray dummy;\n" " return dummy;\n" " }\n" " }\n" " return *ba;\n" "}\n\n"; } if ( list_image.count() > 0 ) { out << "static struct EmbedImage {\n" " int width, height, depth;\n" " const unsigned char *data;\n" " int numColors;\n" " const QRgb *colorTable;\n" " bool alpha;\n" " const char *name;\n" "} embed_image_vec[] = {\n"; list_image.sort(); EmbedImage *e = list_image.first(); while ( e ) { out << " { " << e->width << ", " << e->height << ", " << e->depth << ", " << "(const unsigned char*)" << e->cname << "_data, " << e->numColors << ", "; if ( e->numColors ) out << e->cname << "_ctable, "; else out << "0, "; if ( e->alpha ) out << "TRUE, "; else out << "FALSE, "; out << "\"" << e->name << "\" },\n"; e = list_image.next(); } out << "};\n"; out << "\n" "static int cmpEmbedImage(const void *a, const void *b)\n" "{\n" " const EmbedImage* ea = (const EmbedImage*)a;\n" " const EmbedImage* eb = (const EmbedImage*)b;\n" " return strcmp(ea->name,eb->name);\n" "}\n" "inline const QImage& qembed_findImage(const char* name)\n" "{\n" " EmbedImage key; key.name = name;\n" " EmbedImage* r = (EmbedImage*)bsearch( &key, embed_image_vec,\n" " sizeof(embed_image_vec)/sizeof(EmbedImage), sizeof(EmbedImage), cmpEmbedImage );\n" " QImage* img;\n" " if ( r ) {\n" " img = new QImage((uchar*)r->data,\n" " r->width,\n" " r->height,\n" " r->depth,\n" " (QRgb*)r->colorTable,\n" " r->numColors,\n" " QImage::BigEndian\n" " );\n" " if ( r->alpha )\n" " img->setAlphaBuffer(TRUE);\n" " } else {\n" " static QImage dummy;\n" " img = &dummy;\n" " }\n" " return *img;\n" "}\n\n"; } out << "#endif" << endl; return 0; }