QImage QDirectFBPixmapData::toImage() const
{
    if (!dfbSurface)
        return QImage();

#if 0
    // In later versions of DirectFB one can set a flag to tell
    // DirectFB not to move the surface to videomemory. When that
    // happens we can use this (hopefully faster) codepath
#ifndef QT_NO_DIRECTFB_PREALLOCATED
    QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
    if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
        if (hasAlphaChannel()) {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
            imgSurface->Clear(imgSurface, 0, 0, 0, 0);
        } else {
            imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
        }
        imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
        imgSurface->ReleaseSource(imgSurface);
#endif
        imgSurface->Release(imgSurface);
        return ret;
    }
#endif
#endif

    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
    const QImage *img = that->buffer();
    return img->copy();
}
QImage QDirectFBPixmapData::toImage() const
{
    if (!surface)
        return QImage();

#ifdef QT_NO_DIRECTFB_PREALLOCATED
    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
    const QImage *img = that->buffer();
    const QImage copied = img->copy();
    that->unlockDirectFB();
    return copied;
#else

    int w, h;
    surface->GetSize(surface, &w, &h);

    DFBSurfacePixelFormat format;
    surface->GetPixelFormat(surface, &format);

    QImage::Format imageFormat = QDirectFBScreen::getImageFormat(format);
    if (imageFormat == QImage::Format_Invalid)
        imageFormat = QImage::Format_ARGB32_Premultiplied;
    imageFormat = QImage::Format_ARGB32;

    QImage image(w, h, imageFormat);

    DFBSurfaceDescription description;
    description = QDirectFBScreen::getSurfaceDescription(image);

    IDirectFB *fb = QDirectFBScreen::instance()->dfb();
    IDirectFBSurface *imgSurface;
    DFBResult result = fb->CreateSurface(fb, &description, &imgSurface);
    if (result != DFB_OK) {
        DirectFBError("QDirectFBPixmapData::toImage()", result);
        return QImage();
    }

    imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX);
    result = imgSurface->Blit(imgSurface, surface, 0, 0, 0);
    if (result != DFB_OK) {
        DirectFBError("QDirectFBPixmapData::toImage() blit failed", result);
        return QImage();
    }
    imgSurface->Release(imgSurface);

    return image;
#endif // QT_NO_DIRECTFB_PREALLOCATED
}
QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
                                         Qt::TransformationMode mode) const
{
    QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
#ifdef QT_NO_DIRECTFB_SUBSURFACE
    if (lockFlags())
        that->unlockSurface();
#endif

    if (!dfbSurface || transform.type() != QTransform::TxScale
        || mode != Qt::FastTransformation)
    {
        const QImage *image = that->buffer();
        Q_ASSERT(image);
        const QImage transformed = image->transformed(transform, mode);
        QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
        data->fromImage(transformed, Qt::AutoColor);
        return QPixmap(data);
    }

    const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
    if (size.isEmpty())
        return QPixmap();

    QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType);
    data->setSerialNumber(++global_ser_no);
    DFBSurfaceBlittingFlags flags = DSBLIT_NOFX;
    data->alpha = alpha;
    if (alpha) {
        flags = DSBLIT_BLEND_ALPHACHANNEL;
    }
    data->dfbSurface = screen->createDFBSurface(size,
                                                imageFormat,
                                                QDirectFBScreen::TrackSurface);
    if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
        data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0);
    }
    data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags);

    const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
    data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
    data->w = size.width();
    data->h = size.height();
    data->is_null = (data->w <= 0 || data->h <= 0);

#if (Q_DIRECTFB_VERSION >= 0x010000)
    data->dfbSurface->ReleaseSource(data->dfbSurface);
#endif
    return QPixmap(data);
}
QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
                                         Qt::TransformationMode mode) const
{
    if (!surface || transform.type() != QTransform::TxScale
        || mode != Qt::FastTransformation)
    {
        QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this);
        const QImage *image = that->buffer();
        if (image) { // avoid deep copy
            const QImage transformed = image->transformed(transform, mode);
            that->unlockDirectFB();
            QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType());
            data->fromImage(transformed, Qt::AutoColor);
            return QPixmap(data);
        }
        return QPixmapData::transformed(transform, mode);
    }

    int w, h;
    surface->GetSize(surface, &w, &h);

    const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
    if (size.isEmpty())
        return QPixmap();

    QDirectFBPixmapData *data = new QDirectFBPixmapData(pixelType());
    data->resize(size.width(), size.height());

    IDirectFBSurface *dest = data->surface;
    dest->SetBlittingFlags(dest, DSBLIT_NOFX);

    const DFBRectangle srcRect = { 0, 0, w, h };
    const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
    dest->StretchBlit(dest, surface, &srcRect, &destRect);

    return QPixmap(data);
}