PassRefPtr<ImageData> ImageBufferData::getImageData(const IntRect& rect, const IntSize& size, VGImageFormat format) const { ASSERT(m_surface); PassRefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); unsigned char* data = result->data()->data()->data(); // If this copy operation won't fill all of the pixels in the target image, // paint it black in order to avoid random uninitialized pixel garbage. if (rect.x() < 0 || rect.y() < 0 || (rect.right()) > size.width() || (rect.bottom()) > size.height()) memset(data, 0, result->data()->length()); if (!m_tiledImage) m_surface->makeCurrent(); // OpenVG ignores pixels that are out of bounds, so we can just // call vgReadPixels() without any further safety assurances. if (m_surface->isCurrent()) { vgReadPixels(data, rect.width() * 4, format, rect.x(), rect.y(), rect.width(), rect.height()); } else { vgGetImageSubData(m_tiledImage->tile(0, 0), data, rect.width() * 4, format, rect.x(), rect.y(), rect.width(), rect.height()); } ASSERT_VG_NO_ERROR(); return result; }
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; } } }
void BitmapImage::checkForSolidColor() { TiledImageOpenVG* tiledImage = 0; if (m_frameCount == 1 && m_size.width() == 1 && m_size.height() == 1) tiledImage = nativeImageForCurrentFrame(); if (tiledImage) { m_isSolidColor = true; RGBA32 pixel; vgGetImageSubData(tiledImage->tile(0, 0), &pixel, 0, VG_sARGB_8888, 0, 0, 1, 1); ASSERT_VG_NO_ERROR(); m_solidColor.setRGB(pixel); } else m_isSolidColor = false; m_checkedForSolidColor = true; }
bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) { if (this == &other) return true; m_size = other.m_size; m_image.clear(); // This will usually be called from a completed frame. Depending on whether // or not we have already replaced the original buffer (m_bytes) with the // native image pointer (m_image), we either copy m_bytes directly or // need to extract the pixel data from the image tiles. if (TiledImageOpenVG* image = other.m_image.get()) { m_bytes.resize(m_size.width() * m_size.height()); static const VGImageFormat bufferFormat = VG_sARGB_8888_PRE; const int numColumns = image->numColumns(); const int numRows = image->numRows(); image->makeCompatibleContextCurrent(); for (int yIndex = 0; yIndex < numRows; ++yIndex) { for (int xIndex = 0; xIndex < numColumns; ++xIndex) { IntRect tileRect = image->tileRect(xIndex, yIndex); VGImage tile = image->tile(xIndex, yIndex); PixelData* pixelData = m_bytes.data(); pixelData += (tileRect.y() * width()) + tileRect.x(); vgGetImageSubData(tile, reinterpret_cast<unsigned char*>(pixelData), tileRect.width() * sizeof(PixelData), bufferFormat, 0, 0, tileRect.width(), tileRect.height()); ASSERT_VG_NO_ERROR(); } } } else m_bytes = other.m_bytes; setHasAlpha(other.m_hasAlpha); return true; }
void ImageBufferData::transformColorSpace(const Vector<int>& lookUpTable) { ASSERT(m_surface); VGint width = m_surface->width(); VGint height = m_surface->height(); VGubyte* data = new VGubyte[width * height * 4]; VGubyte* currentPixel = data; if (!m_tiledImage) m_surface->makeCurrent(); if (m_surface->isCurrent()) vgReadPixels(data, width * 4, IMAGEBUFFER_VG_EXCHANGE_FORMAT, 0, 0, width, height); else vgGetImageSubData(m_tiledImage->tile(0, 0), data, width * 4, IMAGEBUFFER_VG_EXCHANGE_FORMAT, 0, 0, width, height); ASSERT_VG_NO_ERROR(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; currentPixel += 4, x++) { currentPixel[IMAGEBUFFER_A] = lookUpTable[currentPixel[IMAGEBUFFER_A]]; currentPixel[IMAGEBUFFER_R] = lookUpTable[currentPixel[IMAGEBUFFER_R]]; currentPixel[IMAGEBUFFER_G] = lookUpTable[currentPixel[IMAGEBUFFER_G]]; currentPixel[IMAGEBUFFER_B] = lookUpTable[currentPixel[IMAGEBUFFER_B]]; } } if (m_surface->isCurrent()) vgWritePixels(data, width * 4, IMAGEBUFFER_VG_EXCHANGE_FORMAT, 0, 0, width, height); else vgImageSubData(m_tiledImage->tile(0, 0), data, width * 4, IMAGEBUFFER_VG_EXCHANGE_FORMAT, 0, 0, width, height); ASSERT_VG_NO_ERROR(); delete[] data; }
void CTReadWriteChild::ReadImageFuncL() { vgGetImageSubData(iImage, iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight); VgLeaveIfErrorL(); }