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; }
void ColorPaletteSwatchArea::mousePressEvent(QMouseEvent *event) { assert(event); //if (event->button() != Qt::LeftButton) //return; const int x = event->x(); const int y = event->y(); const int w = width(); const int h = height(); if (x < 0 || x >= w ||y < 0 || y >= h) return; Image *currentImage = ImageArea::getCurrentImage(); if (!currentImage) return; QImage *image = currentImage->getImage(); assert(image); const int numColorSwatchesXY = sqrt(image->colorCount()); assert(w > 0); const int clickColumn = (int)(x * ((float)numColorSwatchesXY / w)); assert(h > 0); const int clickRow = (int)(y * ((float)numColorSwatchesXY / h)); currentImage->setSelectedColorIndex(clickRow * numColorSwatchesXY + clickColumn); repaint(); }
QImage DetailWindow::imageFromChromagram(const KeyFinder::Chromagram& ch){ // 64 colours (plus black at index 0) // don't draw individual pixels; draw blocks of chromaScaleV*chromaScaleH. Sharpens image. QImage img = QImage(ch.getHops()*chromaScaleH,ch.getBins()*chromaScaleV,QImage::Format_Indexed8); prefs.setImageColours(img,ui->chromaColourCombo->currentIndex()); // get max to normalise float max = 0; for(unsigned int h = 0; h < ch.getHops(); h++){ for(unsigned int b = 0; b < ch.getBins(); b++){ float mag = ch.getMagnitude(h,b); if(mag>max) max = mag; } } // set pixels for(unsigned int h = 0; h < ch.getHops(); h++){ for(unsigned int b = 0; b < ch.getBins(); b++){ int pixVal = ch.getMagnitude(h,b) / max * img.colorCount() - 1; if(pixVal<1) pixVal = 1; for(int x=0; x<chromaScaleH; x++) for(int y=0; y<chromaScaleV; y++) img.setPixel(h*chromaScaleH+x, (ch.getBins()-1-b)*chromaScaleV+y, pixVal); } } return img; }
// ------------------------------------------------------------------------- void ctkQImageView::addImage( const QImage & image ) { Q_D( ctkQImageView ); d->ImageList.push_back( image ); d->TmpXMin = 0; d->TmpXMax = image.width(); d->TmpYMin = 0; d->TmpYMax = image.height(); if( image.isGrayscale() ) { d->IntensityMin = 0; d->IntensityMax = image.colorCount(); this->setIntensityWindowLevel( image.colorCount(), image.colorCount()/2 ); } this->update( true, false ); this->setCenter( image.width()/2.0, image.height()/2.0 ); }
int player_preview_area::get_colorn_from_rgb(QImage &image, int r, int g, int b) { QColor temp_key_color1(r, g, b); for (int i=0; i<image.colorCount(); i++) { if (temp_key_color1.rgb() == image.color(i)) { return i; } } return 0; }
void drawMandelbrot(QImage & image, int iterations, QVector2D offset, double size, ComplexNumber critical) { ComplexNumber fz, c; double rx, ry; float color = 0.0; int wx = image.width(), wy = image.height(); int byteOffset = image.bytesPerLine() / image.width(); #pragma omp parallel for ordered schedule(dynamic) for(int y = 0; y < wy; ++y) { uchar *scanline = image.scanLine(y); for(int x = 0; x < wx; x++) { rx = (2.0 * ((double)x / (double)wx) - 1.0); ry = (2.0 * ((double)y / (double)wy) - 1.0); c = ComplexNumber(rx * size + offset.x(), ry * size + offset.y()); fz = critical; //qDebug() << "x: " << z << ", y: " << c; //fz = mandelbrot(fz, c); int i = 0; for(i = 0; i < iterations && abs(fz) <= 2.0; ++i) { fz = mandelbrot(fz, c); } #pragma omp ordered { color = (float)i / (float)iterations; if(image.format() == QImage::Format_RGB888) { *(scanline + x * byteOffset) = 255 * color; *(scanline + x * byteOffset + 1) = 255 * color; *(scanline + x * byteOffset + 2) = 255 * color; } if(image.format() == QImage::Format_Indexed8) { *(scanline + x * byteOffset) = i % (image.colorCount() + 1);// * color; } } //image.setPixel(x, y, qRgb(i % 256, i % 256, i % 256)); //image.setPixel(x, y, i % 256); } } }
void QMacPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags) { setSerialNumber(++qt_pixmap_serial); // the conversion code only handles format >= // Format_ARGB32_Premultiplied at the moment.. if (img.format() > QImage::Format_ARGB32_Premultiplied) { QImage image; if (img.hasAlphaChannel()) image = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); else image = img.convertToFormat(QImage::Format_RGB32); fromImage(image, flags); return; } w = img.width(); h = img.height(); is_null = (w <= 0 || h <= 0); d = (pixelType() == BitmapType ? 1 : img.depth()); QImage image = img; int dd = QPixmap::defaultDepth(); bool force_mono = (dd == 1 || (flags & Qt::ColorMode_Mask)==Qt::MonoOnly); if (force_mono) { // must be monochrome if (d != 1) { image = image.convertToFormat(QImage::Format_MonoLSB, flags); // dither d = 1; } } else { // can be both bool conv8 = false; if(d > 8 && dd <= 8) { // convert to 8 bit if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither) flags = (flags & ~Qt::DitherMode_Mask) | Qt::PreferDither; conv8 = true; } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) { conv8 = d == 1; // native depth wanted } else if (d == 1) { if (image.colorCount() == 2) { QRgb c0 = image.color(0); // Auto: convert to best QRgb c1 = image.color(1); conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255); } else { // eg. 1-color monochrome images (they do exist). conv8 = true; } } if (conv8) { image = image.convertToFormat(QImage::Format_Indexed8, flags); d = 8; } } if (image.depth()==1) { image.setColor(0, QColor(Qt::color0).rgba()); image.setColor(1, QColor(Qt::color1).rgba()); } if (d == 16 || d == 24) { image = image.convertToFormat(QImage::Format_RGB32, flags); fromImage(image, flags); return; } // different size or depth, make a new pixmap resize(w, h); quint32 *dptr = pixels, *drow; const uint dbpr = bytesPerRow; const QImage::Format sfmt = image.format(); const unsigned short sbpr = image.bytesPerLine(); // use const_cast to prevent a detach const uchar *sptr = const_cast<const QImage &>(image).bits(), *srow; for (int y = 0; y < h; ++y) { drow = dptr + (y * (dbpr / 4)); srow = sptr + (y * sbpr); switch(sfmt) { case QImage::Format_MonoLSB: case QImage::Format_Mono:{ for (int x = 0; x < w; ++x) { char one_bit = *(srow + (x / 8)); if (sfmt == QImage::Format_Mono) one_bit = one_bit >> (7 - (x % 8)); else one_bit = one_bit >> (x % 8); if ((one_bit & 0x01)) *(drow+x) = 0xFF000000; else *(drow+x) = 0xFFFFFFFF; } break; } case QImage::Format_Indexed8: { int numColors = image.numColors(); if (numColors > 0) { for (int x = 0; x < w; ++x) { int index = *(srow + x); *(drow+x) = PREMUL(image.color(qMin(index, numColors))); } } } break; case QImage::Format_RGB32: for (int x = 0; x < w; ++x) *(drow+x) = *(((quint32*)srow) + x) | 0xFF000000; break; case QImage::Format_ARGB32: case QImage::Format_ARGB32_Premultiplied: for (int x = 0; x < w; ++x) { if(sfmt == QImage::Format_RGB32) *(drow+x) = 0xFF000000 | (*(((quint32*)srow) + x) & 0x00FFFFFF); else if(sfmt == QImage::Format_ARGB32_Premultiplied) *(drow+x) = *(((quint32*)srow) + x); else *(drow+x) = PREMUL(*(((quint32*)srow) + x)); } break; default: qWarning("Qt: internal: Oops: Forgot a format [%d] %s:%d", sfmt, __FILE__, __LINE__); break; } }
GLTexture::GLTexture(const QImage& image, GLenum target) : d_ptr(new GLTexturePrivate()) { Q_D(GLTexture); if (image.isNull()) return; d->m_target = target; if (d->m_target != GL_TEXTURE_RECTANGLE_ARB) { d->m_scale.setWidth(1.0 / image.width()); d->m_scale.setHeight(1.0 / image.height()); } else { d->m_scale.setWidth(1.0); d->m_scale.setHeight(1.0); } d->m_size = image.size(); d->m_yInverted = true; d->m_canUseMipmaps = false; d->m_mipLevels = 1; d->updateMatrix(); glGenTextures(1, &d->m_texture); bind(); if (!GLPlatform::instance()->isGLES()) { // Note: Blending is set up to expect premultiplied data, so non-premultiplied // formats must always be converted. struct { GLenum internalFormat; GLenum format; GLenum type; } static const table[] = { { 0, 0, 0 }, // QImage::Format_Invalid { 0, 0, 0 }, // QImage::Format_Mono { 0, 0, 0 }, // QImage::Format_MonoLSB { GL_R8, GL_RED, GL_UNSIGNED_BYTE }, // QImage::Format_Indexed8 { GL_RGB8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, // QImage::Format_RGB32 { 0, 0, 0 }, // QImage::Format_ARGB32 { GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, // QImage::Format_ARGB32_Premultiplied { GL_RGB8, GL_BGR, GL_UNSIGNED_SHORT_5_6_5_REV }, // QImage::Format_RGB16 { 0, 0, 0 }, // QImage::Format_ARGB8565_Premultiplied { 0, 0, 0 }, // QImage::Format_RGB666 { GL_RGB5, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV }, // QImage::Format_RGB555 { 0, 0, 0 }, // QImage::Format_ARGB8555_Premultiplied { GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE }, // QImage::Format_RGB888 { GL_RGB4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV }, // QImage::Format_RGB444 { GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV }, // QImage::Format_ARGB4444_Premultiplied { GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE }, // QImage::Format_RGBX8888 { 0, 0, 0 }, // QImage::Format_RGBA8888 { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }, // QImage::Format_RGBA8888_Premultiplied { GL_RGB10, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV }, // QImage::Format_BGR30 { GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV }, // QImage::Format_A2BGR30_Premultiplied { GL_RGB10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV }, // QImage::Format_RGB30 { GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV }, // QImage::Format_A2RGB30_Premultiplied }; QImage im; GLenum internalFormat; GLenum format; GLenum type; const QImage::Format index = image.format(); if (index < sizeof(table) / sizeof(table[0]) && table[index].internalFormat && !(index == QImage::Format_Indexed8 && image.colorCount() > 0)) { internalFormat = table[index].internalFormat; format = table[index].format; type = table[index].type; im = image; } else { im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); internalFormat = GL_RGBA8; format = GL_BGRA; type = GL_UNSIGNED_INT_8_8_8_8_REV; } d->m_internalFormat = internalFormat; if (d->s_supportsTextureStorage) { glTexStorage2D(d->m_target, 1, internalFormat, im.width(), im.height()); glTexSubImage2D(d->m_target, 0, 0, 0, im.width(), im.height(), format, type, im.bits()); d->m_immutable = true; } else { glTexParameteri(d->m_target, GL_TEXTURE_MAX_LEVEL, d->m_mipLevels - 1); glTexImage2D(d->m_target, 0, internalFormat, im.width(), im.height(), 0, format, type, im.bits()); } } else { d->m_internalFormat = GL_RGBA8; if (d->s_supportsARGB32) { const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); glTexImage2D(d->m_target, 0, GL_BGRA_EXT, im.width(), im.height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.bits()); } else { const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied); glTexImage2D(d->m_target, 0, GL_RGBA, im.width(), im.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits()); } } unbind(); setFilter(GL_LINEAR); }
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]); } } }
void Ui3Reader::embed(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 for Qt version " << QT_VERSION_STR << "\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 <qmime.h>\n"; out << "#include <q3mimefactory.h>\n"; out << "#include <q3dragobject.h>\n"; out << "\n"; QList<EmbedImage*> list_image; 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.colorCount(); e->colorTable = new QRgb[e->numColors]; e->alpha = img.hasAlphaBuffer(); QVector<QRgb> ct = img.colorTable(); memcpy(e->colorTable, ct.constData(), e->numColors*sizeof(QRgb)); QFileInfo fi( *it ); e->name = fi.fileName(); e->cname = QString::fromLatin1("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[] = {", e->cname.latin1() ); #ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION e->compressed = #endif embedData( out, img.bits(), img.byteCount() ); out << "\n};\n\n"; if ( e->numColors ) { out << s.sprintf( "static const QRgb %s_ctable[] = {", e->cname.latin1() ); embedData( out, e->colorTable, e->numColors ); out << "\n};\n\n"; } } if ( !list_image.isEmpty() ) { out << "static const 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 = 0; int i; for (i = 0; i < list_image.count(); ++i) { e = list_image.at(i); 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"; delete e; } #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 Q3MimeSourceFactory\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 = Q3MimeSourceFactory::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 ((Q3MimeSourceFactory*)this)->setImage( abs_name, img );\n"; out << "\treturn Q3MimeSourceFactory::data( abs_name );\n"; out << " };\n"; out << "};\n\n"; out << "static Q3MimeSourceFactory* factory = 0;\n"; out << "\n"; out << "void qInitImages_" << cProject << "()\n"; out << "{\n"; out << " if ( !factory ) {\n"; out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n"; out << "\tQ3MimeSourceFactory::defaultFactory()->addFactory( factory );\n"; out << " }\n"; out << "}\n\n"; out << "void qCleanupImages_" << cProject << "()\n"; out << "{\n"; out << " if ( factory ) {\n"; out << "\tQ3MimeSourceFactory::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_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; }
bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description, int off_x_in, int off_y_in) { QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { return false; } png_set_error_fn(png_ptr, 0, 0, qt_png_warning); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, 0); return false; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return false; } int quality = quality_in; if (quality >= 0) { if (quality > 9) { qWarning("PNG: Quality %d out of range", quality); quality = 9; } png_set_compression_level(png_ptr, quality); } png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); int color_type = 0; if (image.colorCount()) { if (image.isGrayscale()) color_type = PNG_COLOR_TYPE_GRAY; else color_type = PNG_COLOR_TYPE_PALETTE; } else if (image.format() == QImage::Format_Grayscale8) color_type = PNG_COLOR_TYPE_GRAY; else if (image.hasAlphaChannel()) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), image.depth() == 1 ? 1 : 8, // per channel color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); } if (image.format() == QImage::Format_MonoLSB) png_set_packswap(png_ptr); if (color_type == PNG_COLOR_TYPE_PALETTE) { // Paletted int num_palette = qMin(256, image.colorCount()); png_color palette[256]; png_byte trans[256]; int num_trans = 0; for (int i=0; i<num_palette; i++) { QRgb rgba=image.color(i); palette[i].red = qRed(rgba); palette[i].green = qGreen(rgba); palette[i].blue = qBlue(rgba); trans[i] = qAlpha(rgba); if (trans[i] < 255) { num_trans = i+1; } } png_set_PLTE(png_ptr, info_ptr, palette, num_palette); if (num_trans) { png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0); } } // Swap ARGB to RGBA (normal PNG format) before saving on // BigEndian machines if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { png_set_swap_alpha(png_ptr); } // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless if (QSysInfo::ByteOrder == QSysInfo::LittleEndian && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } if (off_x || off_y) { png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL); } if (frames_written > 0) png_set_sig_bytes(png_ptr, 8); if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) { png_set_pHYs(png_ptr, info_ptr, image.dotsPerMeterX(), image.dotsPerMeterY(), PNG_RESOLUTION_METER); } set_text(image, png_ptr, info_ptr, description); png_write_info(png_ptr, info_ptr); if (image.depth() != 1) png_set_packing(png_ptr); if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); if (looping >= 0 && frames_written == 0) { uchar data[13] = "NETSCAPE2.0"; // 0123456789aBC data[0xB] = looping%0x100; data[0xC] = looping/0x100; png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13); } if (ms_delay >= 0 || disposal!=Unspecified) { uchar data[4]; data[0] = disposal; data[1] = 0; data[2] = (ms_delay/10)/0x100; // hundredths data[3] = (ms_delay/10)%0x100; png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4); } int height = image.height(); int width = image.width(); switch (image.format()) { case QImage::Format_Mono: case QImage::Format_MonoLSB: case QImage::Format_Indexed8: case QImage::Format_Grayscale8: case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_RGB888: { png_bytep* row_pointers = new png_bytep[height]; for (int y=0; y<height; y++) row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y)); png_write_image(png_ptr, row_pointers); delete [] row_pointers; } break; default: { QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32; QImage row; png_bytep row_pointers[1]; for (int y=0; y<height; y++) { row = image.copy(0, y, width, 1).convertToFormat(fmt); row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0)); png_write_rows(png_ptr, row_pointers, 1); } } break; } png_write_end(png_ptr, info_ptr); frames_written++; png_destroy_write_struct(&png_ptr, &info_ptr); return true; }
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(); }
void ColorPaletteSwatchArea::paintEvent(QPaintEvent*) { Image *currentImage = ImageArea::getCurrentImage(); if (!currentImage) { QPainter painter(this); painter.setPen(QPen(Qt::lightGray)); painter.setBrush(QBrush(Qt::lightGray)); painter.drawRect(0, 0, width(), height()); painter.setPen(QPen(Qt::black)); painter.setBrush(QBrush(Qt::black)); painter.drawLine(0, 0, width(), height()); painter.drawLine(width(), 0, 0, height()); return; } QImage *image = currentImage->getImage(); assert(image); const int numColorSwatchesXY = sqrt(image->colorCount()); const float w = width() / numColorSwatchesXY; const float h = height() / numColorSwatchesXY; QPainter painter(this); painter.setPen(QPen(Qt::black)); painter.setBrush(QBrush(Qt::black)); painter.drawRect(0, 0, width(), height()); for (int y = 0; y < numColorSwatchesXY; ++y) { for (int x = 0; x < numColorSwatchesXY; ++x) { const unsigned int index = x + numColorSwatchesXY * y; QColor color = image->color(index); painter.setPen(QPen(color)); painter.setBrush(QBrush(color)); painter.drawRect(x * w, y * h, w, h); if (index == currentImage->getSelectedColorIndex()) { painter.setBrush(QBrush(Qt::transparent)); painter.setPen(QPen(Qt::white)); painter.drawRect(x * w, y * h, w - 1, h - 1); painter.setPen(QPen(Qt::black)); painter.drawRect(x * w + 1, y * h + 1, w - 3, h - 3); } short hotkeyGroupForColorIndex = currentImage->getHotkeyGroupForColorIndex(index); if (hotkeyGroupForColorIndex >= 0) { const unsigned int numberX = x * w + 2; const unsigned int numberY = (y + 1) * h - 2; if (color.redF() + color.greenF() + color.blueF() > 1.5f) // bright color // so write text in black painter.setPen(QPen(Qt::black)); else // dark color // write text in white painter.setPen(QPen(Qt::white)); painter.drawText(QPoint(numberX, numberY), QString::number(hotkeyGroupForColorIndex)); } } } }