예제 #1
0
QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
{
    QImage::Format format = sourceFormat();
    int d = image->depth();
    if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
        format = QImage::Format_RGB32;
    else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
        format = sourceFormat();
    else
        format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
    return format;
}
예제 #2
0
void QVGPixmapData::ensureReadback(bool readOnly) const
{
    if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
        source = QVolatileImage(w, h, sourceFormat());
        source.beginDataAccess();
        vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
                          qt_vg_image_to_vg_format(source.format()),
                          0, 0, w, h);
        source.endDataAccess();
        if (readOnly) {
            recreate = false;
        } else {
            // Once we did a readback, the original VGImage must be destroyed
            // because it may be shared (e.g. created via SgImage) and a subsequent
            // upload of the image data may produce unexpected results.
            const_cast<QVGPixmapData *>(this)->destroyImages();
#if defined(Q_OS_SYMBIAN)
            // There is now an own copy of the data so drop the handle provider,
            // otherwise toVGImage() would request the handle again, which is wrong.
            nativeImageHandleProvider = 0;
#endif
            recreate = true;
        }
    }
}
예제 #3
0
// Force the pixmap data to be in QImage format.
void QVGPixmapData::forceToImage()
{
    if (!isValid())
        return;

    if (source.isNull())
        source = QImage(w, h, sourceFormat());

    recreate = true;
}
예제 #4
0
void QVGPixmapData::fromImage
        (const QImage &image, Qt::ImageConversionFlags flags)
{
    if (image.size() == QSize(w, h))
        setSerialNumber(++qt_vg_pixmap_serial);
    else
        resize(image.width(), image.height());
    source = image.convertToFormat(sourceFormat(), flags);
    recreate = true;
}
예제 #5
0
QImage QVGPixmapData::toImage() const
{
    if (!isValid())
        return QImage();
    ensureReadback(true);
    if (source.isNull()) {
        source = QVolatileImage(w, h, sourceFormat());
        recreate = true;
    }
    return source.toImage();
}
예제 #6
0
QImage QVGPixmapData::toImage() const
{
    if (!isValid())
        return QImage();

    if (source.isNull()) {
        source = QImage(w, h, sourceFormat());
        recreate = true;
    }

    return source;
}
예제 #7
0
// Ensures that the pixmap is backed by some valid data and forces the data to
// be re-uploaded to the VGImage when toVGImage() is called next time.
void QVGPixmapData::forceToImage(bool allowReadback)
{
    if (!isValid())
        return;

    if (allowReadback)
        ensureReadback(false);

    if (source.isNull())
        source = QVolatileImage(w, h, sourceFormat());

    recreate = true;
}
예제 #8
0
void QVGPixmapData::fill(const QColor &color)
{
    if (!isValid())
        return;

    if (source.isNull())
        source = QImage(w, h, sourceFormat());

    if (source.depth() == 1) {
        // Pick the best approximate color in the image's colortable.
        int gray = qGray(color.rgba());
        if (qAbs(qGray(source.color(0)) - gray) < qAbs(qGray(source.color(1)) - gray))
            source.fill(0);
        else
            source.fill(1);
    } else {
        source.fill(PREMUL(color.rgba()));
    }

    // Re-upload the image to VG the next time toVGImage() is called.
    recreate = true;
}
예제 #9
0
void* QVGPixmapData::toNativeType(NativeType type)
{
    if (type == QPixmapData::SgImage) {
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
        toVGImage();

        if (!isValid() || vgImage == VG_INVALID_HANDLE)
            return 0;

        TInt err = 0;

        RSgDriver driver;
        err = driver.Open();
        if (err != KErrNone)
            return 0;

        TSgImageInfo sgInfo;
        sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
        sgInfo.iSizeInPixels.SetSize(w, h);
        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;

        QScopedPointer<RSgImage> sgImage(new RSgImage());
        err = sgImage->Create(sgInfo, NULL, NULL);
        if (err != KErrNone) {
            driver.Close();
            return 0;
        }

        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
        EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
                EGL_NO_CONTEXT,
                EGL_NATIVE_PIXMAP_KHR,
                (EGLClientBuffer)sgImage.data(),
                (EGLint*)KEglImageAttribs);
        if (!eglImage || eglGetError() != EGL_SUCCESS) {
            sgImage->Close();
            driver.Close();
            return 0;
        }

        VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
        if (!dstVgImage || vgGetError() != VG_NO_ERROR) {
            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
            sgImage->Close();
            driver.Close();
            return 0;
        }

        vgCopyImage(dstVgImage, 0, 0,
                vgImage, 0, 0,
                w, h, VG_FALSE);

        if (vgGetError() != VG_NO_ERROR) {
            sgImage->Close();
            sgImage.reset();
        }

        // release stuff
        vgDestroyImage(dstVgImage);
        QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
        driver.Close();
        return reinterpret_cast<void*>(sgImage.take());
#endif
    } else if (type == QPixmapData::FbsBitmap && isValid()) {
        ensureReadback(true);
        if (source.isNull()) {
            source = QVolatileImage(w, h, sourceFormat());
        }
        // Just duplicate the bitmap handle, no data copying happens.
        return source.duplicateNativeImage();
    }
    return 0;
}