コード例 #1
0
bool GraphicsContext3D::getImageData(Image* image,
                                     GC3Denum format,
                                     GC3Denum type,
                                     bool premultiplyAlpha,
                                     bool ignoreGammaAndColorProfile,
                                     Vector<uint8_t>& outputVector)
{
    UNUSED_PARAM(ignoreGammaAndColorProfile);
    if (!image)
        return false;
    QImage nativeImage;
    // Is image already loaded? If not, load it.
    if (image->data())
        nativeImage = QImage::fromData(reinterpret_cast<const uchar*>(image->data()->data()), image->data()->size()).convertToFormat(QImage::Format_ARGB32);
    else {
        QPixmap* nativePixmap = image->nativeImageForCurrentFrame();
        nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32);
    }
    AlphaOp neededAlphaOp = AlphaDoNothing;
    if (premultiplyAlpha)
        neededAlphaOp = AlphaDoPremultiply;

    unsigned int packedSize;
    // Output data is tightly packed (alignment == 1).
    if (computeImageSizeInBytes(format, type, image->width(), image->height(), 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
        return false;
    outputVector.resize(packedSize);

    return packPixels(nativeImage.bits(), SourceFormatBGRA8, image->width(), image->height(), 0, format, type, neededAlphaOp, outputVector.data());
}
コード例 #2
0
bool GraphicsContext3D::getImageData(Image* image,
                                     unsigned int format,
                                     unsigned int type,
                                     bool premultiplyAlpha,
                                     Vector<uint8_t>& outputVector)
{
    if (!image || !image->data())
        return false;
    ImageSource decoder(false);
    decoder.setData(image->data(), true);
    if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
        return false;
    bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
    OwnPtr<NativeImageSkia> pixels(decoder.createFrameAtIndex(0));
    if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
        return false;
    SkBitmap::Config skiaConfig = pixels->config();
    if (skiaConfig != SkBitmap::kARGB_8888_Config)
        return false;
    SkBitmap& skiaImageRef = *pixels;
    SkAutoLockPixels lock(skiaImageRef);
    ASSERT(pixels->rowBytes() == pixels->width() * 4);
    outputVector.resize(pixels->rowBytes() * pixels->height());
    AlphaOp neededAlphaOp = kAlphaDoNothing;
    if (hasAlpha && premultiplyAlpha)
        neededAlphaOp = kAlphaDoPremultiply;
    return packPixels(reinterpret_cast<const uint8_t*>(pixels->getPixels()),
                      kSourceFormatBGRA8, pixels->width(), pixels->height(), 0,
                      format, type, neededAlphaOp, outputVector.data());
}
コード例 #3
0
TEST_F(WebGLImageConversionTest, ConvertRGBA8toR8) {
  uint8_t sourceData[40] = {0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56};
  uint8_t expectedData[10] = {0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
                              0x9a, 0x9a, 0x9a, 0x9a, 0x9a};
  uint8_t destinationData[10];
  packPixels(sourceData, WebGLImageConversion::DataFormatR8, 10,
             destinationData);
  EXPECT_EQ(0, memcmp(expectedData, destinationData, sizeof(destinationData)));
}
コード例 #4
0
TEST_F(WebGLImageConversionTest, ConvertRGBA8ToRGB565) {
  uint8_t sourceData[40] = {0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56,
                            0x34, 0x56, 0x34, 0x56, 0x34, 0x56, 0x34, 0x56};
  uint16_t expectedData[10] = {0x32a6, 0x32a6, 0x32a6, 0x32a6, 0x32a6,
                               0x32a6, 0x32a6, 0x32a6, 0x32a6, 0x32a6};
  uint16_t destinationData[10];
  packPixels(sourceData, WebGLImageConversion::DataFormatRGB565, 10,
             reinterpret_cast<uint8_t*>(&destinationData[0]));
  EXPECT_EQ(0, memcmp(expectedData, destinationData, sizeof(destinationData)));
}
コード例 #5
0
bool GraphicsContext3D::getImageData(Image* image, unsigned int format, unsigned int type, bool premultiplyAlpha, bool ignoreGammaAndColorProfile, Vector<uint8_t>& outputVector)
{
    if (!image)
        return false;
    // We need this to stay in scope because the native image is just a shallow copy of the data.
    ImageSource decoder(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied,
                        ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
    AlphaOp alphaOp = AlphaDoNothing;
    RefPtr<cairo_surface_t> imageSurface;
    if (image->data()) {
        decoder.setData(image->data(), true);
        if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
            return false;
        OwnPtr<NativeImageCairo> nativeImage = adoptPtr(decoder.createFrameAtIndex(0));
        imageSurface = nativeImage->surface();
    } else {
        imageSurface = image->nativeImageForCurrentFrame()->surface();
        if (!premultiplyAlpha)
            alphaOp = AlphaDoUnmultiply;
    }

    if (!imageSurface)
        return false;

    int width = cairo_image_surface_get_width(imageSurface.get());
    int height = cairo_image_surface_get_height(imageSurface.get());
    if (!width || !height)
        return false;

    if (cairo_image_surface_get_format(imageSurface.get()) != CAIRO_FORMAT_ARGB32)
        return false;

    unsigned int srcUnpackAlignment = 1;
    size_t bytesPerRow = cairo_image_surface_get_stride(imageSurface.get());
    size_t bitsPerPixel = 32;
    unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width;
    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }

    unsigned int packedSize;
    // Output data is tightly packed (alignment == 1).
    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
        return false;
    outputVector.resize(packedSize);

    return packPixels(cairo_image_surface_get_data(imageSurface.get()), SourceFormatBGRA8,
                      width, height, srcUnpackAlignment, format, type, alphaOp, outputVector.data());
}
コード例 #6
0
bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int height, GC3Denum format, GC3Denum type, unsigned int unpackAlignment, bool flipY, bool premultiplyAlpha, const void* pixels, Vector<uint8_t>& data)
{
    // Assumes format, type, etc. have already been validated.
    DataFormat sourceDataFormat = getDataFormat(format, type);

    // Resize the output buffer.
    unsigned int componentsPerPixel, bytesPerComponent;
    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
        return false;
    unsigned int bytesPerPixel = componentsPerPixel * bytesPerComponent;
    data.resize(width * height * bytesPerPixel);

    if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
        return false;

    return true;
}
コード例 #7
0
bool GraphicsContext3D::packImageData( Image* image, const void* pixels, GC3Denum format, GC3Denum type, bool flipY, AlphaOp alphaOp, DataFormat sourceFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, Vector<uint8_t>& data)
{
    if (!pixels)
        return false;

    unsigned packedSize;
    // Output data is tightly packed (alignment == 1).
    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
        return false;
    data.resize(packedSize);

    if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
        return false;
    if (ImageObserver* observer = image->imageObserver())
        observer->didDraw(image);
    return true;
}
コード例 #8
0
bool GraphicsContext3D::getImageData(Image* image,
                                     GC3Denum format,
                                     GC3Denum type,
                                     bool premultiplyAlpha,
                                     bool ignoreGammaAndColorProfile,
                                     Vector<uint8_t>& outputVector)
{
    if (!image)
        return false;
    OwnPtr<NativeImageSkia> pixels;
    NativeImageSkia* skiaImage = 0;
    AlphaOp neededAlphaOp = AlphaDoNothing;
    bool hasAlpha = image->isBitmapImage() ? static_cast<BitmapImage*>(image)->frameHasAlphaAtIndex(0) : true;
    if ((ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && image->data()) {
        ImageSource decoder(ImageSource::AlphaNotPremultiplied,
                            ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
        // Attempt to get raw unpremultiplied image data 
        decoder.setData(image->data(), true);
        if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
            return false;
        hasAlpha = decoder.frameHasAlphaAtIndex(0);
        pixels = adoptPtr(decoder.createFrameAtIndex(0));
        if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
            return false;
        SkBitmap::Config skiaConfig = pixels->config();
        if (skiaConfig != SkBitmap::kARGB_8888_Config)
            return false;
        skiaImage = pixels.get();
        if (hasAlpha && premultiplyAlpha)
            neededAlphaOp = AlphaDoPremultiply;
    } else {
        skiaImage = image->nativeImageForCurrentFrame();
        if (!premultiplyAlpha && hasAlpha)
            neededAlphaOp = AlphaDoUnmultiply;
    }
    if (!skiaImage)
        return false;
    SkBitmap& skiaImageRef = *skiaImage;
    SkAutoLockPixels lock(skiaImageRef);
    ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4);
    outputVector.resize(skiaImage->rowBytes() * skiaImage->height());
    return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()),
                      SourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0,
                      format, type, neededAlphaOp, outputVector.data());
}
コード例 #9
0
bool GraphicsContext3D::extractImageData(ImageData* imageData, GC3Denum format, GC3Denum type, bool flipY, bool premultiplyAlpha, Vector<uint8_t>& data)
{
    if (!imageData)
        return false;
    int width = imageData->width();
    int height = imageData->height();

    unsigned int packedSize;
    // Output data is tightly packed (alignment == 1).
    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
        return false;
    data.resize(packedSize);

    if (!packPixels(imageData->data()->data(), DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
        return false;

    return true;
}
コード例 #10
0
bool GraphicsContext3D::getImageData(Image* image,
                                     unsigned int format,
                                     unsigned int type,
                                     bool premultiplyAlpha,
                                     bool ignoreGammaAndColorProfile,
                                     Vector<uint8_t>& outputVector)
{
    if (!image)
        return false;
    OwnPtr<NativeImageSkia> pixels;
    NativeImageSkia* skiaImage = 0;
    AlphaOp neededAlphaOp = AlphaDoNothing;
    if (image->data()) {
        ImageSource decoder(ImageSource::AlphaNotPremultiplied,
                            ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied);
        decoder.setData(image->data(), true);
        if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
            return false;
        bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
        pixels = adoptPtr(decoder.createFrameAtIndex(0));
        if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
            return false;
        SkBitmap::Config skiaConfig = pixels->config();
        if (skiaConfig != SkBitmap::kARGB_8888_Config)
            return false;
        skiaImage = pixels.get();
        if (hasAlpha && premultiplyAlpha)
            neededAlphaOp = AlphaDoPremultiply;
    } else {
        // This is a special case for texImage2D with HTMLCanvasElement input.
        skiaImage = image->nativeImageForCurrentFrame();
        if (!premultiplyAlpha)
            neededAlphaOp = AlphaDoUnmultiply;
    }
    if (!skiaImage)
        return false;
    SkBitmap& skiaImageRef = *skiaImage;
    SkAutoLockPixels lock(skiaImageRef);
    ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4);
    outputVector.resize(skiaImage->rowBytes() * skiaImage->height());
    return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()),
                      SourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0,
                      format, type, neededAlphaOp, outputVector.data());
}
コード例 #11
0
ファイル: iff.cpp プロジェクト: AReim1982/scummvm
void IFFDecoder::loadBitmap(Common::SeekableReadStream &stream) {
	_numRelevantPlanes = MIN(_numRelevantPlanes, _header.numPlanes);

	if (_numRelevantPlanes != 1 && _numRelevantPlanes != 2 && _numRelevantPlanes != 4)
		_pixelPacking = false;

	uint16 outPitch = _header.width;

	if (_pixelPacking)
		outPitch /= (8 / _numRelevantPlanes);

	// FIXME: CLUT8 is not a proper format for packed bitmaps but there is no way to tell it to use 1, 2 or 4 bits per pixel
	_surface = new Graphics::Surface();
	_surface->create(outPitch, _header.height, Graphics::PixelFormat::createFormatCLUT8());

	if (_type == TYPE_ILBM) {
		uint32 scanlinePitch = ((_header.width + 15) >> 4) << 1;
		byte *scanlines = new byte[scanlinePitch * _header.numPlanes];
		byte *data = (byte *)_surface->getPixels();

		for (uint16 i = 0; i < _header.height; ++i) {
			byte *scanline = scanlines;

			for (uint16 j = 0; j < _header.numPlanes; ++j) {
				uint16 outSize = scanlinePitch;

				if (_header.compression) {
					Common::PackBitsReadStream packStream(stream);
					packStream.read(scanline, outSize);
				} else {
					stream.read(scanline, outSize);
				}

				scanline += outSize;
			}

			packPixels(scanlines, data, scanlinePitch, outPitch);
			data += outPitch;
		}

		delete[] scanlines;
	} else if (_type == TYPE_PBM) {
コード例 #12
0
bool GraphicsContext3D::getImageData(Image* image,
                                     unsigned int format,
                                     unsigned int type,
                                     bool premultiplyAlpha,
                                     Vector<uint8_t>& outputVector)
{
    if (!image)
        return false;
    CGImageRef cgImage;
    RetainPtr<CGImageRef> decodedImage;
    if (image->data()) {
        ImageSource decoder(false);
        decoder.setData(image->data(), true);
        if (!decoder.frameCount())
            return false;
        decodedImage = decoder.createFrameAtIndex(0);
        cgImage = decodedImage.get();
    } else
        cgImage = image->nativeImageForCurrentFrame();
    if (!cgImage)
        return false;
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    if (!width || !height)
        return false;
    size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
    size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
    if (bitsPerComponent != 8 && bitsPerComponent != 16)
        return false;
    if (bitsPerPixel % bitsPerComponent)
        return false;
    size_t componentsPerPixel = bitsPerPixel / bitsPerComponent;
    SourceDataFormat srcDataFormat = kSourceFormatRGBA8;
    AlphaOp neededAlphaOp = kAlphaDoNothing;
    switch (CGImageGetAlphaInfo(cgImage)) {
    case kCGImageAlphaPremultipliedFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        // This is a special case for texImage2D with HTMLCanvasElement input,
        // in which case image->data() should be null.
        ASSERT(!image->data());
        if (!premultiplyAlpha)
            neededAlphaOp = kAlphaDoUnmultiply;
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        if (premultiplyAlpha)
            neededAlphaOp = kAlphaDoPremultiply;
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatA8;
            else
                srcDataFormat = kSourceFormatA16;
            break;
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNoneSkipFirst:
        // This path is only accessible for MacOS earlier than 10.6.4.
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatAR8;
            else
                srcDataFormat = kSourceFormatAR16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatARGB8;
            else
                srcDataFormat = kSourceFormatARGB16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaPremultipliedLast:
        // This is a special case for texImage2D with HTMLCanvasElement input,
        // in which case image->data() should be null.
        ASSERT(!image->data());
        if (!premultiplyAlpha)
            neededAlphaOp = kAlphaDoUnmultiply;
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaLast:
        if (premultiplyAlpha)
            neededAlphaOp = kAlphaDoPremultiply;
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatA8;
            else
                srcDataFormat = kSourceFormatA16;
            break;
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNoneSkipLast:
        switch (componentsPerPixel) {
        case 2:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRA8;
            else
                srcDataFormat = kSourceFormatRA16;
            break;
        case 4:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGBA8;
            else
                srcDataFormat = kSourceFormatRGBA16;
            break;
        default:
            return false;
        }
        break;
    case kCGImageAlphaNone:
        switch (componentsPerPixel) {
        case 1:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatR8;
            else
                srcDataFormat = kSourceFormatR16;
            break;
        case 3:
            if (bitsPerComponent == 8)
                srcDataFormat = kSourceFormatRGB8;
            else
                srcDataFormat = kSourceFormatRGB16;
            break;
        default:
            return false;
        }
        break;
    default:
        return false;
    }
    RetainPtr<CFDataRef> pixelData;
    pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage)));
    if (!pixelData)
        return false;
    const UInt8* rgba = CFDataGetBytePtr(pixelData.get());
    outputVector.resize(width * height * 4);
    unsigned int srcUnpackAlignment = 0;
    size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
    unsigned int padding = bytesPerRow - bitsPerPixel / 8 * width;
    if (padding) {
        srcUnpackAlignment = padding + 1;
        while (bytesPerRow % srcUnpackAlignment)
            ++srcUnpackAlignment;
    }
    bool rt = packPixels(rgba, srcDataFormat, width, height, srcUnpackAlignment,
                         format, type, neededAlphaOp, outputVector.data());
    return rt;
}