Beispiel #1
0
void ImgCache::insertImage(int page, const QImage &img)
{
	mtx.lock();
	if (autoAdjust && (img.numBytes() + maxItemSizeSoFar > cache.maxCost()))
	{
		cache.setMaxCost(img.numBytes() + maxItemSizeSoFar);
		if (img.numBytes() > maxItemSizeSoFar)
			maxItemSizeSoFar = img.numBytes();
	}
	cache.insert(page, new QImage(img), img.numBytes());
	mtx.unlock();
}
PixelBuffer& PixelBuffer::operator=(const QImage& image)
{
    QImage swapped     = image.rgbSwapped();
    QSize  swappedSize = swapped.size();

    int w = swappedSize.width();
    int h = swappedSize.height();
    int numPixels = w * h;
    int numBytes  = w * h * 4;
    if (swappedSize != m_sizeInPixels)
    {
        deleteBuffer();
        m_sizeInPixels = QSize(w, h);
        m_buffer = new uchar[numBytes];
    }

    // Copy the memory over.
    // We'll add defensive code in case rgbSwapped has a different size
    const uchar* from = swapped.constBits();
    int numFromBytes = swapped.numBytes();
    int numToCopy = std::min(numFromBytes, numBytes);

    memcpy(m_buffer, from, numToCopy);
    if (numToCopy < numBytes)
    {
        memset(m_buffer + numToCopy, 0x00, numBytes - numToCopy);
    }

    return *this;
}
Beispiel #3
0
uint MltPreview::imageVariance(QImage image)
{
    if (image.isNull()) return 0;
    uint delta = 0;
    uint avg = 0;
    uint bytes = image.numBytes();
    uint STEPS = bytes / 2;
    QVarLengthArray<uchar> pivot(STEPS);
    kDebug(DBG_AREA) << "Using " << STEPS << " steps\n";
    const uchar *bits=image.bits();
    // First pass: get pivots and taking average
    for( uint i=0; i<STEPS ; i++ ){
        pivot[i] = bits[2 * i];
#if QT_VERSION >= 0x040700
        avg+=pivot.at(i);
#else
        avg+=pivot[i];
#endif
    }
    avg=avg/STEPS;
    // Second Step: calculate delta (average?)
    for (uint i=0; i<STEPS; i++)
    {
#if QT_VERSION >= 0x040700
        int curdelta=abs(int(avg - pivot.at(i)));
#else
        int curdelta=abs(int(avg - pivot[i]));
#endif
        delta+=curdelta;
    }
    return delta / STEPS;
}
bool VideoThumbnailer::isFrameInteresting(const QImage &frame)
{
    float variance = 0;
    //taken from mplayerthumbs
    uint delta=0;
    uint avg=0;
    uint bytes=frame.numBytes();
    uint STEPS=bytes/2;
    QVarLengthArray<uchar> pivot(STEPS);

    const uchar *bits=frame.bits();
    // First pass: get pivots and taking average
    for( uint i=0; i<STEPS ; i++ ){
        pivot[i]=bits[i*(bytes/STEPS)];
        avg+=pivot[i];
    }
    avg=avg/STEPS;
    // Second Step: calculate delta (average?)
    for (uint i=0; i<STEPS; i++)
    {
        int curdelta=abs(int(avg-pivot[i]));
        delta+=curdelta;
    }
    variance= delta/STEPS;

    return variance > THRESHOLD_FRAME_VARIANCE;
}
void syImgReaderCodec::LoadCurrentFrame(syBitmap* dest) {
    if(!dest) {
        return;
    }
    sySafeMutexLocker lock(m_Mutex);
    if(lock.IsLocked()) {
        // 1. Check if m_Image is null. If not, abort (can't create the image, we could be in a worker thread)
        if(!m_Image) {
            return;
        }

        // 2. Read the image into m_Image.
        if(!m_ImageLoaded && m_Reader->read(m_Image)) {
            m_ImageLoaded = true;
        }

        // 3. Copy the image to dest.
        if(m_ImageLoaded) {
            const unsigned char* bits = m_Image->bits();
            dest->CopyFrom(bits,GetWidth(),GetHeight(),vcfRGB32,m_Image->numBytes());
        } else {
            dest->Clear();
        }
    }
}
Beispiel #6
0
//static
uint KThumb::imageVariance(QImage image )
{
    uint delta = 0;
    uint avg = 0;
    uint bytes = image.numBytes();
    uint STEPS = bytes/2;
    QVarLengthArray<uchar> pivot(STEPS);
    const uchar *bits=image.bits();
    // First pass: get pivots and taking average
    for( uint i=0; i<STEPS ; i++ ){
        pivot[i] = bits[2 * i];
#if QT_VERSION >= 0x040700
        avg+=pivot.at(i);
#else
        avg+=pivot[i];
#endif
    }
    avg=avg/STEPS;
    // Second Step: calculate delta (average?)
    for (uint i=0; i<STEPS; i++)
    {
#if QT_VERSION >= 0x040700
        int curdelta=abs(int(avg - pivot.at(i)));
#else
        int curdelta=abs(int(avg - pivot[i]));
#endif
        delta+=curdelta;
    }
    return delta/STEPS;
}
void pwan::imageviewer_backend_qt::do_work()
{
    while(!abort)
    {
        while(!fileName.empty())
        {
            QImage image;
            boost::shared_ptr<imagebuffer> buffer(new imagebuffer);
            image = QImage(0,0,QImage::Format_Invalid);
            QTextCodec *codec = QTextCodec::codecForName("UTF-8");
            QTextCodec::setCodecForCStrings (codec);

            m_mutex.lock();
            image.load(QString().fromStdString(fileName.at(0)));
            m_mutex.unlock();
            if(!image.isNull())
            {
                buffer->filename = fileName.at(0);
                buffer->width = image.width();
                buffer->height = image.height();
                buffer->depth = image.depth();
                buffer->data.reset(new uchar[image.numBytes()]);
                buffer->noOfBytes = image.numBytes();
                m_mutex.lock();
                memcpy(buffer->data.get(), image.bits(), image.numBytes());
                image2 = image1;
                image1 = buffer;
                m_mutex.unlock();
            }
            m_mutex.lock();
            fileName.erase(fileName.begin());
            m_mutex.unlock();
        }
        m_mutex.lock();
        if (abort)
            break;
        m_mutex.unlock();
        boost::asio::io_service io;
        boost::asio::deadline_timer t(io, boost::posix_time::millisec(20));
        t.wait();
    }
}
Beispiel #8
0
void BitmapFactoryInst::convert(const QImage& p, SoSFImage& img) const
{
    SbVec2s size;
    size[0] = p.width();
    size[1] = p.height();

    int buffersize = p.numBytes();
    int numcomponents = buffersize / ( size[0] * size[1] );

    // allocate image data
    img.setValue(size, numcomponents, NULL);

    unsigned char * bytes = img.startEditing(size, numcomponents);

    int width  = (int)size[0];
    int height = (int)size[1];

    for (int y = 0; y < height; y++) 
    {
        unsigned char * line = &bytes[width*numcomponents*(height-(y+1))];
        for (int x = 0; x < width; x++) 
        {
            QRgb rgb = p.pixel(x,y);
            switch (numcomponents) 
            {
            default:
                break;
            case 1:
                line[0] = qGray( rgb );
                break;
            case 2:
                line[0] = qGray( rgb );
                line[1] = qAlpha( rgb );
                break;
            case 3:
                line[0] = qRed( rgb );
                line[1] = qGreen( rgb );
                line[2] = qBlue( rgb );
                break;
            case 4:
                line[0] = qRed( rgb );
                line[1] = qGreen( rgb );
                line[2] = qBlue( rgb );
                line[3] = qAlpha( rgb );
                break;
            }

            line += numcomponents;
        }
    }

    img.finishEditing();
}
void QFontEngineQPF::loadGlyph(glyph_t glyph)
{
    quint32 glyphPos = ~0;

    if (!renderingFontEngine)
        return;

    QImage img = renderingFontEngine->alphaMapForGlyph(glyph).convertToFormat(QImage::Format_Indexed8);
    glyph_metrics_t metrics = renderingFontEngine->boundingBox(glyph);
    renderingFontEngine->removeGlyphFromCache(glyph);

    off_t oldSize = ::lseek(fd, 0, SEEK_END);
    if (oldSize == (off_t)-1)
        return;

    Glyph g;
    g.width = img.width();
    g.height = img.height();
    g.bytesPerLine = img.bytesPerLine();
    g.x = qRound(metrics.x);
    g.y = qRound(metrics.y);
    g.advance = qRound(metrics.xoff);

    ::write(fd, &g, sizeof(g));
    ::write(fd, img.bits(), img.numBytes());

    glyphPos = oldSize - glyphDataOffset;
#if 0 && defined(DEBUG_FONTENGINE)
    qDebug() << "glyphPos for new glyph" << glyph << "is" << glyphPos << "oldSize" << oldSize << "glyphDataOffset" << glyphDataOffset;
#endif

    quint32 *gmap = (quint32 *)(fontData + glyphMapOffset);
    gmap[glyph] = qToBigEndian(glyphPos);

    glyphDataSize = glyphPos + sizeof(g) + img.numBytes();
    quint32 *blockSizePtr = (quint32 *)(fontData + glyphDataOffset - 4);
    *blockSizePtr = qToBigEndian(glyphDataSize);
}
/**
 * Automatic marshaling of a QImage for org.freedesktop.Notifications.Notify
 *
 * This function is from the Clementine project (see
 * http://www.clementine-player.org) and licensed under the GNU General Public
 * License, version 3 or later.
 *
 * Copyright 2010, David Sansome <*****@*****.**>
 */
QDBusArgument &operator<<( QDBusArgument &arg, const QImage &image )
{
  if ( image.isNull() )
  {
    arg.beginStructure();
    arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray();
    arg.endStructure();
    return arg;
  }

  QImage scaled = image.scaledToHeight( 100, Qt::SmoothTransformation );
  scaled = scaled.convertToFormat( QImage::Format_ARGB32 );

#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
  // ABGR -> ARGB
  QImage i = scaled.rgbSwapped();
#else
  // ABGR -> GBAR
  QImage i( scaled.size(), scaled.format() );
  for ( int y = 0; y < i.height(); ++y )
  {
    QRgb *p = ( QRgb * ) scaled.scanLine( y );
    QRgb *q = ( QRgb * ) i.scanLine( y );
    QRgb *end = p + scaled.width();
    while ( p < end )
    {
      *q = qRgba( qGreen( *p ), qBlue( *p ), qAlpha( *p ), qRed( *p ) );
      p++;
      q++;
    }
  }
#endif

  arg.beginStructure();
  arg << i.width();
  arg << i.height();
  arg << i.bytesPerLine();
  arg << i.hasAlphaChannel();
  int channels = i.isGrayscale() ? 1 : ( i.hasAlphaChannel() ? 4 : 3 );
  arg << i.depth() / channels;
  arg << channels;
  arg << QByteArray( reinterpret_cast<const char *>( i.bits() ), i.numBytes() );
  arg.endStructure();
  return arg;
}
void LH_LgLcdThread::setQVGA( QImage img )
{
    if( img.isNull() )
    {
        qvga_bm.hdr.Format = 0;
        return;
    }

    Q_ASSERT( img.numBytes() == sizeof( qvga_bm.bmp_qvga32.pixels ) );

    qvga_bm.bmp_qvga32.hdr.Format = LGLCD_BMP_FORMAT_QVGAx32;
    memcpy( qvga_bm.bmp_qvga32.pixels,
#ifdef Q_WS_MAC
            img.rgbSwapped().bits(),
#else
            img.bits(),
#endif
            sizeof( qvga_bm.bmp_qvga32.pixels ) );

    sem_.release();
}
Beispiel #12
0
QDBusArgument& operator<< (QDBusArgument& arg, const DBusNotifyImageData &data) {
	if (data.image.isNull()) {
		// Sometimes this gets called with a null QImage for no obvious reason.
		// - There is one reason: Qt calls this method at first time to research it's structure
		arg.beginStructure();
		arg << 0 << 0 << 0 << false << 0 << 0 << QByteArray();
		arg.endStructure();
		return arg;
	}
	QImage scaled = data.image.scaledToHeight(qMin(100, qMin(data.image.height(), data.image.width())),
											  Qt::SmoothTransformation).toImage();
	QImage i = scaled.convertToFormat(QImage::Format_ARGB32).rgbSwapped();
	arg.beginStructure();
	arg << i.width();
	arg << i.height();
	arg << i.bytesPerLine();
	arg << i.hasAlphaChannel();
	int channels = i.isGrayscale() ? 1 : (i.hasAlphaChannel() ? 4 : 3);
	arg << i.depth() / channels;
	arg << channels;
	arg << QByteArray(reinterpret_cast<const char*>(i.bits()), i.numBytes());
	arg.endStructure();
	return arg;
}
Beispiel #13
0
bool ImageResize::imageResize(const EmailSettingsContainer& settings,
                              const KUrl& orgUrl, const QString& destName, QString& err)
{
    EmailSettingsContainer emailSettings = settings;
    QFileInfo fi(orgUrl.path());

    if (!fi.exists() || !fi.isReadable())
    {
        err = i18n("Error opening input file");
        return false;
    }

    QFileInfo tmp(destName);
    QFileInfo tmpDir(tmp.dir().absolutePath());

    kDebug() << "tmpDir: " << tmp.dir().absolutePath();

    if (!tmpDir.exists() || !tmpDir.isWritable())
    {
        err = i18n("Error opening temporary folder");
        return false;
    }

    QImage img;

    // Check if RAW file.
    QString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
    if (rawFilesExt.toUpper().contains( fi.suffix().toUpper() ))
        KDcrawIface::KDcraw::loadDcrawPreview(img, orgUrl.path());
    else
        img.load(orgUrl.path());

    int sizeFactor = emailSettings.size();

    if ( !img.isNull() )
    {
        int w = img.width();
        int h = img.height();

        if( w > sizeFactor || h > sizeFactor )
        {
            if( w > h )
            {
                h = (int)( (double)( h * sizeFactor ) / w );

                if ( h == 0 ) h = 1;

                w = sizeFactor;
                Q_ASSERT( h <= sizeFactor );
            }
            else
            {
                w = (int)( (double)( w * sizeFactor ) / h );

                if ( w == 0 ) w = 1;

                h = sizeFactor;
                Q_ASSERT( w <= sizeFactor );
            }

            const QImage scaledImg(img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));

            if ( scaledImg.width() != w || scaledImg.height() != h )
            {
                err = i18n("Cannot resize image. Aborting.");
                return false;
            }

            img = scaledImg;
        }

        QString destPath = destName;

        KExiv2Iface::KExiv2 meta;

        meta.load(orgUrl.path());
        meta.setImageProgramId(QString("Kipi-plugins"), QString(kipiplugins_version));
        meta.setImageDimensions(img.size());

        if (emailSettings.format() == QString("JPEG"))
        {
            if ( !img.save(destPath, emailSettings.format().toLatin1(), emailSettings.imageCompression) )
            {
                err = i18n("Cannot save resized image (JPEG). Aborting.");
                return false;
            }
            else
            {
                meta.save(destPath);
            }
        }
        else if (emailSettings.format() == QString("PNG"))
        {
            QByteArray data((const char*)img.bits(), img.numBytes());
            KIPIPlugins::KPWriteImage wImageIface;
            wImageIface.setImageData(data, img.width(), img.height(), false, true, QByteArray(), meta);
            if ( !wImageIface.write2PNG(destPath) )
            {
                err = i18n("Cannot save resized image (PNG). Aborting.");
                return false;
            }
        }

        return true;
    }

    return false;
}
Beispiel #14
0
// static
QPixmap QPixmap::fromPmHBITMAP(HBITMAP hbm, HBITMAP hbmMask)
{
    QPixmap res;

    if (hbm == NULLHANDLE)
        return res;

    // bitmap header + 2 palette entries (for the monochrome bitmap)
    char bmi[sizeof(BITMAPINFOHEADER2) + 4 * 2];
    memset(bmi, 0, sizeof(bmi));
    PBITMAPINFOHEADER2 bmh = (PBITMAPINFOHEADER2)bmi;
    bmh->cbFix = sizeof(BITMAPINFOHEADER2);
    PULONG pal = (PULONG)(bmi + sizeof(BITMAPINFOHEADER2));

    if (!GpiQueryBitmapInfoHeader(hbm, bmh))
        return res;

    HPS hps = qt_alloc_mem_ps(bmh->cx, bmh->cy * 2);
    if (hps == NULLHANDLE)
        return res;

    GpiSetBitmap(hps, hbm);

    QImage img;
    bool succeeded = false;

    if (bmh->cPlanes == 1 && bmh->cBitCount == 1) {
        // monochrome bitmap
        img = QImage(bmh->cx, bmh->cy, QImage::Format_Mono);
        if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(),
                               (PBITMAPINFO2)&bmi) != GPI_ALTERROR) {
            succeeded = true;
            // take the palette
            QVector<QRgb> colors(2);
            colors[0] = QRgb(pal[0]);
            colors[1] = QRgb(pal[1]);
            img.setColorTable(colors);
        }
    } else {
        // always convert to 32-bit otherwise
        img = QImage(bmh->cx, bmh->cy, QImage::Format_RGB32);
        bmh->cPlanes = 1;
        bmh->cBitCount = 32;
        if (GpiQueryBitmapBits(hps, 0, img.height(), (PBYTE)img.bits(),
                               (PBITMAPINFO2)&bmi) != GPI_ALTERROR) {
            succeeded = true;
            // try to auto-detect if there is a real alpha channel
            bool allZero = true;
            for (int i = 0; i < img.numBytes(); ++i) {
                if (img.bits()[i] & 0xFF000000) {
                    allZero = false;
                    break;
                }
            }
            if (!allZero) {
                // assume we've got the alpha channel
                QImage alphaImg = QImage(bmh->cx, bmh->cy, QImage::Format_ARGB32);
                memcpy(alphaImg.bits(), img.bits(), img.numBytes());
                img = alphaImg;
            }
            // flip the bitmap top to bottom to cancel PM inversion
            img = img.mirrored();
        }
    }

    QImage mask;

    if (hbmMask != NULLHANDLE && GpiQueryBitmapInfoHeader(hbmMask, bmh)) {
        // get the AND+XOR mask
        if ((int)bmh->cx == img.width() &&
            (int)bmh->cy == img.height() * 2 &&
            bmh->cPlanes == 1 && bmh->cBitCount == 1) {
            GpiSetBitmap(hps, hbmMask);
            mask = QImage(bmh->cx, bmh->cy, QImage::Format_Mono);
            if (GpiQueryBitmapBits(hps, 0, mask.height(), (PBYTE)mask.bits(),
                                   (PBITMAPINFO2)&bmi) != GPI_ALTERROR) {
                // take the palette
                QVector<QRgb> colors(2);
                colors[0] = QRgb(pal[0]);
                colors[1] = QRgb(pal[1]);
                mask.setColorTable(colors);
                // flip the bitmap top to bottom to cancel PM inversion
                mask = mask.mirrored(false, true);
                // drop the XOR mask
                mask = mask.copy(0, 0, mask.width(), mask.height() / 2);
                // create a normal mask from the AND mask
                mask.invertPixels();
            } else {
                mask = QImage();
            }
            GpiSetBitmap(hps, NULLHANDLE);
        } else {
            Q_ASSERT(false);
        }
    }

    qt_free_mem_ps(hps);

    if (succeeded) {
        res = QPixmap::fromImage(img);
        if (!mask.isNull())
            res.setMask(QBitmap::fromImage(mask));
    }

    return res;
}
Beispiel #15
0
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";
    }
}
extern "C" void gxpport_decodeimmutable_to_platformbuffer
(unsigned char* srcBuffer, long length, 
 unsigned char** ret_dataBuffer, long* ret_length,
 gxutl_native_image_error_codes* creationErrorPtr) {

    gxutl_image_format format;
    MIDP_ERROR err;
    unsigned int w, h;

    err = gxutl_image_get_info(srcBuffer, (unsigned int)length,
			       &format, &w, &h);
    
    switch (err) {

    case MIDP_ERROR_NONE:
	break; /* continue */

    case MIDP_ERROR_IMAGE_CORRUPTED:
	*creationErrorPtr = GXUTL_NATIVE_IMAGE_DECODING_ERROR;
	return;
    
    default:
	*creationErrorPtr = GXUTL_NATIVE_IMAGE_UNSUPPORTED_FORMAT_ERROR;
	return;
    }
		     
    switch (format) {

    case GXUTL_IMAGE_FORMAT_RAW:
        /* already in RAW format. make a copy */
	{
	    unsigned char* dataBuffer = (unsigned char*) midpMalloc(length);
            
	    if (NULL == dataBuffer) {
		*creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
	    } else {
                
		memcpy(dataBuffer, srcBuffer, length);
                
		*ret_dataBuffer = dataBuffer;
		*ret_length = length;

		*creationErrorPtr = GXUTL_NATIVE_IMAGE_NO_ERROR;
	    }
	}
        break;

    case GXUTL_IMAGE_FORMAT_JPEG:
    case GXUTL_IMAGE_FORMAT_PNG:
        {
            QImage qimage;
            
            if (qimage.loadFromData((uchar*)srcBuffer, 
                                    (unsigned int)length)) {
                int imgWidth  = qimage.width();
                int imgHeight = qimage.height();
                
                if ((0 == imgWidth) || (0 == imgHeight)) {
                    *creationErrorPtr = GXUTL_NATIVE_IMAGE_DECODING_ERROR;
                } else {
                    QImage image;
                    if (IMAGE_DEPTH != qimage.depth()) {
                        image = qimage.convertDepth(IMAGE_DEPTH);
                    } else {
                        image = qimage;
                    }
                    
                    *ret_length = offsetof(gxutl_image_buffer_raw, data)
				+ image.numBytes();

                    gxutl_image_buffer_raw *dataBuffer =
			(gxutl_image_buffer_raw *) midpMalloc(*ret_length);
                    
                    if (NULL == dataBuffer) {
                        *creationErrorPtr = GXUTL_NATIVE_IMAGE_OUT_OF_MEMORY_ERROR;
                    } else {
                        dataBuffer->width    = (unsigned int)imgWidth;
                        dataBuffer->height   = (unsigned int)imgHeight;
                        dataBuffer->hasAlpha = (unsigned int)image.hasAlphaBuffer();
                        
                        memcpy(dataBuffer->header, gxutl_raw_header, 4);
                        memcpy(dataBuffer->data, image.bits(), image.numBytes());
                        
                        *ret_dataBuffer = (unsigned char *)dataBuffer;
                        *creationErrorPtr = GXUTL_NATIVE_IMAGE_NO_ERROR;
                    }
                }
            } else {
                *creationErrorPtr = GXUTL_NATIVE_IMAGE_DECODING_ERROR;
            }
        }
        break;
    
    default:
        *creationErrorPtr = GXUTL_NATIVE_IMAGE_UNSUPPORTED_FORMAT_ERROR;
        break;

    } /* switch (format) */
}
Beispiel #17
0
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;
}
Beispiel #18
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;
}
/*!
    This function decodes some data into image changes.

    Returns the number of bytes consumed.
*/
int QGIFFormat::decode(QImage& img, QImageConsumer* consumer,
	const uchar* buffer, int length)
{
    // We are required to state that
    //    "The Graphics Interchange Format(c) is the Copyright property of
    //    CompuServe Incorporated. GIF(sm) is a Service Mark property of
    //    CompuServe Incorporated."

#define LM(l, m) (((m)<<8)|l)
    digress = FALSE;
    int initial = length;
    QRgb** line = (QRgb **)img.jumpTable();
    while (!digress && length) {
	length--;
	unsigned char ch=*buffer++;
	switch (state) {
	  case Header:
	    hold[count++]=ch;
	    if (count==6) {
		// Header
		gif89=(hold[3]!='8' || hold[4]!='7');
		state=LogicalScreenDescriptor;
		count=0;
	    }
	    break;
	  case LogicalScreenDescriptor:
	    hold[count++]=ch;
	    if (count==7) {
		// Logical Screen Descriptor
		swidth=LM(hold[0], hold[1]);
		sheight=LM(hold[2], hold[3]);
		gcmap=!!(hold[4]&0x80);
		//UNUSED: bpchan=(((hold[4]&0x70)>>3)+1);
		//UNUSED: gcmsortflag=!!(hold[4]&0x08);
		gncols=2<<(hold[4]&0x7);
		bgcol=(gcmap) ? hold[5] : -1;
		//aspect=hold[6] ? double(hold[6]+15)/64.0 : 1.0;

		trans_index = -1;
		count=0;
		ncols=gncols;
		if (gcmap) {
		    ccount=0;
		    state=GlobalColorMap;
		    globalcmap = new QRgb[gncols+1]; // +1 for trans_index
		    globalcmap[gncols] = Q_TRANSPARENT;
		} else {
		    state=Introducer;
		}
	    }
	    break;
	  case GlobalColorMap: case LocalColorMap:
	    hold[count++]=ch;
	    if (count==3) {
		QRgb rgb = qRgb(hold[0], hold[1], hold[2]);
		if ( state == LocalColorMap ) {
		    if ( ccount < lncols )
			localcmap[ccount] =  rgb;
		} else {
		    globalcmap[ccount] = rgb;
		}
		if (++ccount >= ncols) {
		    if ( state == LocalColorMap )
			state=TableImageLZWSize;
		    else
			state=Introducer;
		}
		count=0;
	    }
	    break;
	  case Introducer:
	    hold[count++]=ch;
	    switch (ch) {
	      case ',':
		state=ImageDescriptor;
		break;
	      case '!':
		state=ExtensionLabel;
		break;
	      case ';':
		if (consumer) {
		    if ( out_of_bounds ) // flush anything that survived
			consumer->changed(QRect(0,0,swidth,sheight));
		    consumer->end();
		}
		state=Done;
		break;
	      default:
		digress=TRUE;
		// Unexpected Introducer - ignore block
		state=Error;
	    }
	    break;
	  case ImageDescriptor:
	    hold[count++]=ch;
	    if (count==10) {
		int newleft=LM(hold[1], hold[2]);
		int newtop=LM(hold[3], hold[4]);
		int width=LM(hold[5], hold[6]);
		int height=LM(hold[7], hold[8]);

		// disbelieve ridiculous logical screen sizes,
		// unless the image frames are also large.
		if ( swidth/10 > QMAX(width,200) )
		    swidth = -1;
		if ( sheight/10 > QMAX(height,200) )
		    sheight = -1;

		if ( swidth <= 0 )
		    swidth = newleft + width;
		if ( sheight <= 0 )
		    sheight = newtop + height;

		if (img.isNull()) {
		    img.create(swidth, sheight, 32);
		    memset( img.bits(), 0, img.numBytes() );
		    if (consumer) consumer->setSize(swidth, sheight);
		}
		img.setAlphaBuffer(trans_index >= 0);
		line = (QRgb **)img.jumpTable();

		disposePrevious( img, consumer );
		disposed = FALSE;

		left = newleft;
		top = newtop;

		// Sanity check frame size - must fit on "screen".
		if (left >= swidth) left=QMAX(0, swidth-1);
		if (top >= sheight) top=QMAX(0, sheight-1);
		if (left+width >= swidth) {
		    if ( width <= swidth )
			left=swidth-width;
		    else
			width=swidth-left;
		}
		if (top+height >= sheight) {
		    if ( height <= sheight )
			top=sheight-height;
		    else
			height=sheight-top;
		}

		right=QMAX( 0, left+width-1);
		bottom=QMAX(0, top+height-1);
		lcmap=!!(hold[9]&0x80);
		interlace=!!(hold[9]&0x40);
		//bool lcmsortflag=!!(hold[9]&0x20);
		lncols=lcmap ? (2<<(hold[9]&0x7)) : 0;
		if (lncols) {
		    if ( localcmap )
			delete [] localcmap;
		    localcmap = new QRgb[lncols+1];
		    localcmap[lncols] = Q_TRANSPARENT;
		    ncols = lncols;
		} else {
		    ncols = gncols;
		}
		frame++;
		if ( frame == 0 ) {
		    if ( left || top || width!=swidth || height!=sheight ) {
			// Not full-size image - erase with bg or transparent
			if ( trans_index >= 0 ) {
			    fillRect(img, 0, 0, swidth, sheight, color(trans_index));
			    if (consumer) consumer->changed(QRect(0,0,swidth,sheight));
			} else if ( bgcol>=0 ) {
			    fillRect(img, 0, 0, swidth, sheight, color(bgcol));
			    if (consumer) consumer->changed(QRect(0,0,swidth,sheight));
			}
		    }
		}

		if ( disposal == RestoreImage ) {
		    int l = QMIN(swidth-1,left);
		    int r = QMIN(swidth-1,right);
		    int t = QMIN(sheight-1,top);
		    int b = QMIN(sheight-1,bottom);
		    int w = r-l+1;
		    int h = b-t+1;

		    if (backingstore.width() < w
			|| backingstore.height() < h) {
			// We just use the backing store as a byte array
			backingstore.create( QMAX(backingstore.width(), w),
					     QMAX(backingstore.height(), h),
					     32);
			memset( img.bits(), 0, img.numBytes() );
		    }
		    for (int ln=0; ln<h; ln++) {
			memcpy(backingstore.scanLine(ln),
			       line[t+ln]+l, w*sizeof(QRgb));
		    }
		}

		count=0;
		if (lcmap) {
		    ccount=0;
		    state=LocalColorMap;
		} else {
		    state=TableImageLZWSize;
		}
		x = left;
		y = top;
		accum = 0;
		bitcount = 0;
		sp = stack;
		needfirst = FALSE;
		out_of_bounds = FALSE;
	    }
	    break;
	  case TableImageLZWSize: {
	    lzwsize=ch;
	    if ( lzwsize > max_lzw_bits ) {
		state=Error;
	    } else {
		code_size=lzwsize+1;
		clear_code=1<<lzwsize;
		end_code=clear_code+1;
		max_code_size=2*clear_code;
		max_code=clear_code+2;
		int i;
		for (i=0; i<clear_code && i<(1<<max_lzw_bits); i++) {
		    table[0][i]=0;
		    table[1][i]=i;
		}
		for (i=clear_code; i<(1<<max_lzw_bits); i++) {
		    table[0][i]=table[1][i]=0;
		}
		state=ImageDataBlockSize;
	    }
	    count=0;
	    break;
	  } case ImageDataBlockSize:
	    expectcount=ch;
	    if (expectcount) {
		state=ImageDataBlock;
	    } else {
		if (consumer) {
		    consumer->frameDone();
		    digress = TRUE;
		}

		state=Introducer;
	    }
	    break;
	  case ImageDataBlock:
	    count++;
	    accum|=(ch<<bitcount);
	    bitcount+=8;
	    while (bitcount>=code_size && state==ImageDataBlock) {
		int code=accum&((1<<code_size)-1);
		bitcount-=code_size;
		accum>>=code_size;

		if (code==clear_code) {
		    if (!needfirst) {
			int i;
			code_size=lzwsize+1;
			max_code_size=2*clear_code;
			max_code=clear_code+2;
			for (i=0; i<clear_code; i++) {
			    table[0][i]=0;
			    table[1][i]=i;
			}
			for (i=clear_code; i<(1<<max_lzw_bits); i++) {
			    table[0][i]=table[1][i]=0;
			}
		    }
		    needfirst=TRUE;
		} else if (code==end_code) {
		    bitcount = -32768;
		    // Left the block end arrive
		} else {
		    if (needfirst) {
			firstcode=oldcode=code;
			if (!out_of_bounds && line && firstcode!=trans_index)
			    line[y][x] = color(firstcode);
			x++;
			if (x>=swidth) out_of_bounds = TRUE;
			needfirst=FALSE;
			if (x>right) {
			    x=left;
			    if (out_of_bounds)
				out_of_bounds = left>=swidth || y>=sheight;
			    nextY(img,consumer);
			}
		    } else {
			incode=code;
			if (code>=max_code) {
			    *sp++=firstcode;
			    code=oldcode;
			}
			while (code>=clear_code) {
			    *sp++=table[1][code];
			    if (code==table[0][code]) {
				state=Error;
				break;
			    }
			    if (sp-stack>=(1<<(max_lzw_bits))*2) {
				state=Error;
				break;
			    }
			    code=table[0][code];
			}
			*sp++=firstcode=table[1][code];
			code=max_code;
			if (code<(1<<max_lzw_bits)) {
			    table[0][code]=oldcode;
			    table[1][code]=firstcode;
			    max_code++;
			    if ((max_code>=max_code_size)
			     && (max_code_size<(1<<max_lzw_bits)))
			    {
				max_code_size*=2;
				code_size++;
			    }
			}
			oldcode=incode;
			while (sp>stack) {
			    --sp;
			    if (!out_of_bounds && *sp!=trans_index)
				line[y][x] = color(*sp);
			    x++;
			    if (x>=swidth) out_of_bounds = TRUE;
			    if (x>right) {
				x=left;
				if (out_of_bounds)
				    out_of_bounds = left>=swidth || y>=sheight;
				nextY(img,consumer);
			    }
			}
		    }
		}
	    }
	    if (count==expectcount) {
		count=0;
		state=ImageDataBlockSize;
	    }
	    break;
	  case ExtensionLabel:
	    switch (ch) {
	    case 0xf9:
		state=GraphicControlExtension;
		break;
	    case 0xff:
		state=ApplicationExtension;
		break;
#if 0
	    case 0xfe:
		state=CommentExtension;
		break;
	    case 0x01:
		break;
#endif
	    default:
		state=SkipBlockSize;
	    }
	    count=0;
	    break;
	  case ApplicationExtension:
	    if (count<11) hold[count]=ch;
	    count++;
	    if (count==hold[0]+1) {
		if (qstrncmp((char*)(hold+1), "NETSCAPE", 8)==0) {
		    // Looping extension
		    state=NetscapeExtensionBlockSize;
		} else {
		    state=SkipBlockSize;
		}
		count=0;
	    }
	    break;
	  case NetscapeExtensionBlockSize:
	    expectcount=ch;
	    count=0;
	    if (expectcount) state=NetscapeExtensionBlock;
	    else state=Introducer;
	    break;
	  case NetscapeExtensionBlock:
	    if (count<3) hold[count]=ch;
	    count++;
	    if (count==expectcount) {
		int loop = hold[0]+hold[1]*256;
		if (consumer) consumer->setLooping(loop);
		state=SkipBlockSize; // Ignore further blocks
	    }
	    break;
	  case GraphicControlExtension:
	    if (count<5) hold[count]=ch;
	    count++;
	    if (count==hold[0]+1) {
		disposePrevious( img, consumer );
		disposal=Disposal((hold[1]>>2)&0x7);
		//UNUSED: waitforuser=!!((hold[1]>>1)&0x1);
		int delay=count>3 ? LM(hold[2], hold[3]) : 1;
		// IE and mozilla use a minimum delay of 10. With the minumum delay of 10
		// we are compatible to them and avoid huge loads on the app and xserver.
		if ( delay < 10 )
		    delay = 10;

		bool havetrans=hold[1]&0x1;
 		trans_index = havetrans ? hold[4] : -1;

		if (consumer) consumer->setFramePeriod(delay*10);
		count=0;
		state=SkipBlockSize;
	    }
	    break;
	  case SkipBlockSize:
	    expectcount=ch;
	    count=0;
	    if (expectcount) state=SkipBlock;
	    else state=Introducer;
	    break;
	  case SkipBlock:
	    count++;
	    if (count==expectcount) state=SkipBlockSize;
	    break;
	  case Done:
	    digress=TRUE;
	    /* Netscape ignores the junk, so we do too.
	    length++; // Unget
	    state=Error; // More calls to this is an error
	    */
	    break;
	  case Error:
	    return -1; // Called again after done.
	}
    }
Beispiel #20
0
void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges)
{
    const quint16 glyphCount = fe->glyphCount();

    QByteArray gmap;
    gmap.resize(glyphCount * sizeof(quint32));
    gmap.fill(char(0xff));
    //qDebug() << "glyphCount" << glyphCount;

    QByteArray glyphs;
    if (options & RenderGlyphs) {
        // this is only a rough estimation
        glyphs.reserve(glyphCount 
                * (sizeof(QFontEngineQPF::Glyph) 
                    + qRound(fe->maxCharWidth() * (fe->ascent() + fe->descent()).toReal())));

        QGlyphLayout layout[10];

        foreach (CharacterRange range, ranges) {
            if (debugVerbosity > 2)
                qDebug() << "rendering range from" << range.start << "to" << range.end;
            for (uint uc = range.start; uc < range.end; ++uc) {
                QChar ch(uc);
                int nglyphs = 10;
                if (!fe->stringToCMap(&ch, 1, &layout[0], &nglyphs, /*flags*/ 0))
                    continue;

                if (nglyphs != 1)
                    continue;

                const quint32 glyphIndex = layout[0].glyph;

                if (!glyphIndex)
                    continue;

                Q_ASSERT(glyphIndex < glyphCount);

                QImage img = fe->alphaMapForGlyph(glyphIndex).convertToFormat(QImage::Format_Indexed8);
                glyph_metrics_t metrics = fe->boundingBox(glyphIndex);

                const quint32 oldSize = glyphs.size();
                glyphs.resize(glyphs.size() + sizeof(QFontEngineQPF::Glyph) + img.numBytes());
                uchar *data = reinterpret_cast<uchar *>(glyphs.data() + oldSize);

                uchar *gmapPtr = reinterpret_cast<uchar *>(gmap.data() + glyphIndex * sizeof(quint32));
                qToBigEndian(oldSize, gmapPtr);

                QFontEngineQPF::Glyph *glyph = reinterpret_cast<QFontEngineQPF::Glyph *>(data);
                glyph->width = img.width();
                glyph->height = img.height();
                glyph->bytesPerLine = img.bytesPerLine();
                glyph->x = qRound(metrics.x);
                glyph->y = qRound(metrics.y);
                glyph->advance = qRound(metrics.xoff);
                data += sizeof(QFontEngineQPF::Glyph);

                if (debugVerbosity && uc >= 'A' && uc <= 'z' || debugVerbosity > 1) {
                    qDebug() << "adding glyph with index" << glyphIndex << " uc =" << char(uc) << ":\n"
                        << "    glyph->x =" << glyph->x << "rounded from" << metrics.x << "\n"
                        << "    glyph->y =" << glyph->y << "rounded from" << metrics.y << "\n"
                        << "    width =" << glyph->width << "height =" << glyph->height
                        << "    advance =" << glyph->advance << "rounded from" << metrics.xoff
                        ;
                }

                qMemCopy(data, img.bits(), img.numBytes());
            }
        }
    }