void NearestSampler(PixelBox& dest, const PixelBox& src) { size_t bytesPerPix = BytesPerPixel(src.format); NEX_ASSERT(bytesPerPix == BytesPerPixel(dest.format)); float dstep = ((float) src.GetDepth() / (float) dest.GetDepth()) * .5f; float hstep = ((float) src.GetHeight() / (float) dest.GetHeight()) * .5f; float wstep = ((float) src.GetWidth() / (float) dest.GetWidth()) * .5f; for (uint32 d = dest.front; d < dest.back; ++d) { size_t doff = (uint32) (dstep * (src.slicePixelPitch * d * 2 + 1)); NEX_ASSERT(doff >= 0 && doff <= src.slicePixelPitch * d); void* destPlane = reinterpret_cast<uint8*>(dest.data) + d * dest.slicePixelPitch * bytesPerPix; for (uint32 h = dest.top; h < dest.bottom; ++h) { size_t hoff = (uint32) ((2 * h * src.rowPixelPitch + 1) * hstep); NEX_ASSERT(hoff >= 0 && hoff <= src.rowPixelPitch * h); uint8* destRow = reinterpret_cast<uint8*>(destPlane) + h * dest.rowPixelPitch * bytesPerPix; for (uint32 w = dest.left; w < dest.right; ++w) { size_t woff = (size_t) ((2 * w + 1) * wstep); NEX_ASSERT(woff >= 0 && woff <= w); uint8* srcData = reinterpret_cast<uint8*>(src.data) + (doff + hoff + woff) * bytesPerPix; // src offset uint8* destData = (destRow + w * bytesPerPix); for (uint32 j = 0; j < bytesPerPix; ++j) destData[j] = srcData[j]; } } } }
void SourceSurfaceD2D1::DrawTargetWillChange() { // At this point in time this should always be true here. MOZ_ASSERT(mRealizedBitmap); RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap; D2D1_BITMAP_PROPERTIES1 props; props.dpiX = 96; props.dpiY = 96; props.pixelFormat = D2DPixelFormat(mFormat); props.colorContext = nullptr; props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)getter_AddRefs(mRealizedBitmap)); if (FAILED(hr)) { gfxCriticalError() << "Failed to create bitmap to make DrawTarget copy. Size: " << mSize << " Code: " << hexa(hr); MarkIndependent(); return; } D2D1_POINT_2U point = D2D1::Point2U(0, 0); D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height); mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect); mImage = mRealizedBitmap; DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat); // We now no longer depend on the source surface content remaining the same. MarkIndependent(); }
void ClearDataSourceSurface(DataSourceSurface *aSurface) { DataSourceSurface::MappedSurface map; if (!aSurface->Map(DataSourceSurface::MapType::WRITE, &map)) { MOZ_ASSERT(false, "Failed to map DataSourceSurface"); return; } // We avoid writing into the gaps between the rows here since we can't be // sure that some drivers don't use those bytes. uint32_t width = aSurface->GetSize().width; uint32_t bytesPerRow = width * BytesPerPixel(aSurface->GetFormat()); uint8_t* row = map.mData; // converting to size_t here because otherwise the temporaries can overflow // and we can end up with |end| being a bad address! uint8_t* end = row + size_t(map.mStride) * size_t(aSurface->GetSize().height); while (row != end) { memset(row, 0, bytesPerRow); row += map.mStride; } aSurface->Unmap(); }
SharedSurface_Basic::SharedSurface_Basic(GLContext* gl, const IntSize& size, bool hasAlpha, SurfaceFormat format, GLuint tex) : SharedSurface_GL(SharedSurfaceType::Basic, AttachmentType::GLTexture, gl, size, hasAlpha) , mTex(tex), mFB(0) { mGL->MakeCurrent(); mGL->fGenFramebuffers(1, &mFB); ScopedBindFramebuffer autoFB(mGL, mFB); mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_TEXTURE_2D, mTex, 0); GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) { mGL->fDeleteFramebuffers(1, &mFB); mFB = 0; } mData = Factory::CreateDataSourceSurfaceWithStride(size, format, GetAlignedStride<4>(size.width * BytesPerPixel(format))); }
void SourceSurfaceD2DTarget::DrawTargetWillChange() { RefPtr<ID3D10Texture2D> oldTexture = mTexture; D3D10_TEXTURE2D_DESC desc; mTexture->GetDesc(&desc); // Our original texture might implement the keyed mutex flag. We shouldn't // need that here. We actually specifically don't want it since we don't lock // our texture for usage! desc.MiscFlags = 0; // Get a copy of the surface data so the content at snapshot time was saved. Factory::GetDirect3D10Device()->CreateTexture2D(&desc, nullptr, byRef(mTexture)); Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture); mBitmap = nullptr; DrawTargetD2D::mVRAMUsageSS += desc.Width * desc.Height * BytesPerPixel(mFormat); mOwnsCopy = true; // We now no longer depend on the source surface content remaining the same. MarkIndependent(); }
BBitmap* ImageProcessor::CreateDestImage(BBitmap* /* srcImage */) { color_space cs; BBitmap* bm; BRect rect; if (GetSrcImage() == NULL) return NULL; cs = GetSrcImage()->ColorSpace(); fBPP = BytesPerPixel(cs); if (fBPP < 1) return NULL; fWidth = GetSrcImage()->Bounds().IntegerWidth(); fHeight = GetSrcImage()->Bounds().IntegerHeight(); if (fOp == kRotateClockwise || fOp == kRotateCounterClockwise) { rect.Set(0, 0, fHeight, fWidth); } else { rect.Set(0, 0, fWidth, fHeight); } bm = new BBitmap(rect, cs); if (!IsBitmapValid(bm)) { delete bm; return NULL; } fSrcBPR = GetSrcImage()->BytesPerRow(); fDestBPR = bm->BytesPerRow(); return bm; }
bool DataSourceSurfaceCG::InitFromData(unsigned char *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { if (aSize.width <= 0 || aSize.height <= 0) { return false; } size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height); if (bufLen == 0) { mImage = nullptr; return false; } void *data = malloc(bufLen); memcpy(data, aData, bufLen - aStride + (aSize.width * BytesPerPixel(aFormat))); mFormat = aFormat; mImage = CreateCGImage(data, data, aSize, aStride, aFormat); if (!mImage) { free(data); return false; } return true; }
static unsigned int DataOffset(const IntPoint& aPoint, int32_t aStride, SurfaceFormat aFormat) { unsigned int data = aPoint.y * aStride; data += aPoint.x * BytesPerPixel(aFormat); return data; }
void SourceSurfaceD2D1::DrawTargetWillChange() { // At this point in time this should always be true here. MOZ_ASSERT(mRealizedBitmap); RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap; D2D1_BITMAP_PROPERTIES1 props; props.dpiX = 96; props.dpiY = 96; props.pixelFormat = D2DPixelFormat(mFormat); props.colorContext = nullptr; props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap)); D2D1_POINT_2U point = D2D1::Point2U(0, 0); D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height); mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect); mImage = mRealizedBitmap; DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat); mDrawTarget = nullptr; // We now no longer depend on the source surface content remaining the same. MarkIndependent(); }
bool SourceSurfaceAlignedRawData::Init(const IntSize &aSize, SurfaceFormat aFormat, bool aClearMem, uint8_t aClearValue, int32_t aStride) { mFormat = aFormat; mStride = aStride ? aStride : GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat)); size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height); if (bufLen > 0) { bool zeroMem = aClearMem && !aClearValue; static_assert(sizeof(decltype(mArray[0])) == 1, "mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen"); // AlignedArray uses cmalloc to zero mem for a fast path. mArray.Realloc(/* actually an object count */ bufLen, zeroMem); mSize = aSize; if (mArray && aClearMem && aClearValue) { memset(mArray, aClearValue, mStride * aSize.height); } } else { mArray.Dealloc(); mSize.SizeTo(0, 0); } return mArray != nullptr; }
void TextureHostFileMapping::UpdatedInternal(const nsIntRegion* aRegion) { if (!mProvider) { // This can happen if we send textures to a compositable that isn't yet // attached to a layer. return; } if (!mTextureSource) { mTextureSource = mProvider->CreateDataTextureSource(mFlags); } uint8_t* data = nullptr; int32_t totalBytes = BufferSizeFromDimensions(mSize.width, mSize.height, BytesPerPixel(mFormat)); if (totalBytes > 0) { data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_READ, 0, 0, totalBytes); } if (data) { RefPtr<DataSourceSurface> surf = Factory::CreateWrappingDataSourceSurface(data, mSize.width * BytesPerPixel(mFormat), mSize, mFormat); if (surf) { surf->AddUserData(&kFileMappingKey, data, UnmapFileData); if (!mTextureSource->Update(surf, const_cast<nsIntRegion*>(aRegion))) { mTextureSource = nullptr; } } else { mTextureSource = nullptr; } } else { mTextureSource = nullptr; } ReadUnlock(); }
bool MemoryDIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface) { RefPtr<gfxImageSurface> imgSurf = mSurface->GetAsImageSurface(); RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface(); if (!srcSurf) { gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (DIB)."; return false; } DataSourceSurface::MappedSurface sourceMap; if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) { gfxCriticalError() << "Failed to map source surface for UpdateFromSurface."; return false; } for (int y = 0; y < srcSurf->GetSize().height; y++) { memcpy(imgSurf->Data() + imgSurf->Stride() * y, sourceMap.mData + sourceMap.mStride * y, srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat())); } srcSurf->Unmap(); return true; }
bool TextureScaler::IsEmptyOrFlat(u32* data, int pixels, int fmt) { int pixelsPerWord = 4 / BytesPerPixel(fmt); u32 ref = data[0]; for (int i = 0; i < pixels / pixelsPerWord; ++i) { if (data[i] != ref) return false; } return true; }
/** * aSrcRect: Rect relative to the aSrc surface * aDestPoint: Point inside aDest surface */ void CopyRect(DataSourceSurface* aSrc, DataSourceSurface* aDest, IntRect aSrcRect, IntPoint aDestPoint) { if (aSrcRect.Overflows() || IntRect(aDestPoint, aSrcRect.Size()).Overflows()) { MOZ_CRASH("we should never be getting invalid rects at this point"); } MOZ_RELEASE_ASSERT(aSrc->GetFormat() == aDest->GetFormat(), "different surface formats"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aSrc->GetSize()).Contains(aSrcRect), "source rect too big for source surface"); MOZ_RELEASE_ASSERT(IntRect(IntPoint(), aDest->GetSize()).Contains(IntRect(aDestPoint, aSrcRect.Size())), "dest surface too small"); if (aSrcRect.IsEmpty()) { return; } DataSourceSurface::ScopedMap srcMap(aSrc, DataSourceSurface::READ); DataSourceSurface::ScopedMap destMap(aDest, DataSourceSurface::WRITE); if (MOZ2D_WARN_IF(!srcMap.IsMapped() || !destMap.IsMapped())) { return; } uint8_t* sourceData = DataAtOffset(aSrc, srcMap.GetMappedSurface(), aSrcRect.TopLeft()); uint32_t sourceStride = srcMap.GetStride(); uint8_t* destData = DataAtOffset(aDest, destMap.GetMappedSurface(), aDestPoint); uint32_t destStride = destMap.GetStride(); if (BytesPerPixel(aSrc->GetFormat()) == 4) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy((int32_t*)destData, (int32_t*)sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } else if (BytesPerPixel(aSrc->GetFormat()) == 1) { for (int32_t y = 0; y < aSrcRect.height; y++) { PodCopy(destData, sourceData, aSrcRect.width); sourceData += sourceStride; destData += destStride; } } }
bool BufferTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface) { if (mDescriptor.type() != BufferDescriptor::TRGBDescriptor) { return false; } const RGBDescriptor& rgb = mDescriptor.get_RGBDescriptor(); uint32_t stride = ImageDataSerializer::GetRGBStride(rgb); RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateWrappingDataSourceSurface(GetBuffer(), stride, rgb.size(), rgb.format()); if (!surface) { gfxCriticalError() << "Failed to get serializer as surface!"; return false; } RefPtr<gfx::DataSourceSurface> srcSurf = aSurface->GetDataSurface(); if (!srcSurf) { gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (BT)."; return false; } if (surface->GetSize() != srcSurf->GetSize() || surface->GetFormat() != srcSurf->GetFormat()) { gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format (BT)! This: " << surface->GetSize() << " " << surface->GetFormat() << " Other: " << aSurface->GetSize() << " " << aSurface->GetFormat(); return false; } gfx::DataSourceSurface::MappedSurface sourceMap; gfx::DataSourceSurface::MappedSurface destMap; if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) { gfxCriticalError() << "Failed to map source surface for UpdateFromSurface (BT)."; return false; } if (!surface->Map(gfx::DataSourceSurface::WRITE, &destMap)) { srcSurf->Unmap(); gfxCriticalError() << "Failed to map destination surface for UpdateFromSurface."; return false; } for (int y = 0; y < srcSurf->GetSize().height; y++) { memcpy(destMap.mData + destMap.mStride * y, sourceMap.mData + sourceMap.mStride * y, srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat())); } srcSurf->Unmap(); surface->Unmap(); return true; }
bool SourceSurfaceAlignedRawData::Init(const IntSize &aSize, SurfaceFormat aFormat) { mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat)); mArray.Realloc(mStride * aSize.height); mSize = aSize; mFormat = aFormat; return mArray != nullptr; }
SourceSurfaceD2DTarget::~SourceSurfaceD2DTarget() { // We don't need to do anything special here to notify our mDrawTarget. It must // already have cleared its mSnapshot field, otherwise this object would // be kept alive. if (mOwnsCopy) { IntSize size = GetSize(); DrawTargetD2D::mVRAMUsageSS -= size.width * size.height * BytesPerPixel(mFormat); } }
void image::alloc_data() { shell = false; data = new byte[width*height*BytesPerPixel(bpp)]; assert(data); //we are going to assume that pixels are 4byte aligned. assert((((int)data) & 3) == 0); pitch = width; }
static void Interpret(std::byte *target_data, enum _Interchange_buffer::pixel_layout target_layout, enum _Interchange_buffer::alpha_mode target_alpha_mode, int target_stride, const std::byte *source_data, enum _Interchange_buffer::pixel_layout source_layout, enum _Interchange_buffer::alpha_mode source_alpha_mode, int source_width, int source_height, int source_stride) noexcept { const auto dst_bpp = BytesPerPixel(target_layout); const auto src_bpp = BytesPerPixel(source_layout); for( int row = 0; row < source_height; ++row ) { for( int column = 0; column < source_width; ++column ) { auto src = source_data + row * source_stride + column * src_bpp; auto dst = target_data + row * target_stride + column * dst_bpp; Cast(dst, target_layout, target_alpha_mode, src, source_layout, source_alpha_mode); } } }
bool ShmemDIBTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface) { RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface(); if (!srcSurf) { gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface (DTD)."; return false; } DataSourceSurface::MappedSurface sourceMap; if (!srcSurf->Map(gfx::DataSourceSurface::READ, &sourceMap)) { gfxCriticalError() << "Failed to map source surface for UpdateFromSurface."; return false; } GdiFlush(); uint32_t stride = mSize.width * BytesPerPixel(mFormat); uint8_t* data = (uint8_t*)::MapViewOfFile(mFileMapping, FILE_MAP_WRITE, 0, 0, stride * mSize.height); if (!data) { gfxCriticalError() << "Failed to map view of file for UpdateFromSurface."; srcSurf->Unmap(); return false; } for (int y = 0; y < srcSurf->GetSize().height; y++) { memcpy(data + stride * y, sourceMap.mData + sourceMap.mStride * y, srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat())); } ::UnmapViewOfFile(data); srcSurf->Unmap(); return true; }
image::image(const image &img) :width(img.width) ,height(img.height) ,bpp(img.bpp) ,pitch(img.pitch) ,cx1(img.cx1),cy1(img.cy1) ,cx2(img.cx2),cy2(img.cy2) ,shell(img.shell) ,alpha(img.alpha) ,alphaChannel(img.alphaChannel) { alloc_data(); memcpy(data, img.data, width*height*BytesPerPixel(bpp)); }
bool SourceSurfaceCG::InitFromData(unsigned char *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { assert(aSize.width >= 0 && aSize.height >= 0); void *data = malloc(aStride * aSize.height); // Copy all the data except the stride padding on the very last // row since we can't guarantee that is readable. memcpy(data, aData, aStride * (aSize.height - 1) + (aSize.width * BytesPerPixel(aFormat))); mFormat = aFormat; mImage = CreateCGImage(data, data, aSize, aStride, aFormat); return mImage != nullptr; }
uint8_t* DataAtOffset(DataSourceSurface* aSurface, IntPoint aPoint) { if (!SurfaceContainsPoint(aSurface, aPoint)) { MOZ_CRASH("sample position needs to be inside surface!"); } MOZ_ASSERT(Factory::CheckSurfaceSize(aSurface->GetSize()), "surface size overflows - this should have been prevented when the surface was created"); uint8_t* data = aSurface->GetData() + aPoint.y * aSurface->Stride() + aPoint.x * BytesPerPixel(aSurface->GetFormat()); if (data < aSurface->GetData()) { MOZ_CRASH("out-of-range data access"); } return data; }
void SourceSurfaceD2DTarget::DrawTargetWillChange() { RefPtr<ID3D10Texture2D> oldTexture = mTexture; D3D10_TEXTURE2D_DESC desc; mTexture->GetDesc(&desc); // Get a copy of the surface data so the content at snapshot time was saved. Factory::GetDirect3D10Device()->CreateTexture2D(&desc, nullptr, byRef(mTexture)); Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture); mBitmap = nullptr; DrawTargetD2D::mVRAMUsageSS += desc.Width * desc.Height * BytesPerPixel(mFormat); mOwnsCopy = true; // We now no longer depend on the source surface content remaining the same. MarkIndependent(); }
BBitmapAccessor::BBitmapAccessor( BBitmap *bitmap, const BRect *section) : BitmapAccessor() , mBitmap(bitmap) , mDispose(true) , mLastAreaChanged(false) , mCreateInvoker(NULL) , mUpdateInvoker(NULL) { if (bitmap) { mBounds = bitmap->Bounds(); if (section) mBounds = mBounds & (*section); mPixelSize = BytesPerPixel(); } }
bool SourceSurfaceAlignedRawData::Init(const IntSize &aSize, SurfaceFormat aFormat) { mFormat = aFormat; mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat)); size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height); if (bufLen > 0) { static_assert(sizeof(decltype(mArray[0])) == 1, "mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen"); mArray.Realloc(/* actually an object count */ bufLen); mSize = aSize; } else { mArray.Dealloc(); mSize.SizeTo(0, 0); } return mArray != nullptr; }
// // BMPファイルを読み込む // // DIBが作成されていない場合、BMPの大きさで作成する // BOOL CDib::LoadBMP(CFile &file, int ox, int oy) { BITMAPFILEHEADER header; BITMAPINFOHEADER infoHeader; if (file.Read(&header, sizeof(header)) != sizeof(header) || header.bfType != ((WORD) ('M' << 8) | 'B') || file.Read(&infoHeader, sizeof(infoHeader)) != sizeof(infoHeader) || infoHeader.biSize < sizeof(BITMAPINFOHEADER) || infoHeader.biCompression != BI_RGB) return FALSE; int width = infoHeader.biWidth; int height = infoHeader.biHeight; int depth = infoHeader.biBitCount; if (!IsOK()) { if (!Create(width + ox, height + oy, depth)) return FALSE; } if (width + ox > Width() || height + oy > Height() || depth != Depth()) return FALSE; int bits_offset = sizeof(BITMAPFILEHEADER) + infoHeader.biSize; if (depth == 8) { int csize = sizeof(RGBQUAD) * 256; if (file.Read(Info->bmiColors, csize) != csize) return FALSE; bits_offset += csize; } file.Seek(bits_offset, CFile::begin); int length = width * BytesPerPixel(); int filler = ScanBytes(width, depth) - length; for (int y=height-1; y>=0; y--) { if (file.Read(GetBits(ox, oy + y), length) != length) return FALSE; if (filler) file.Seek(filler, CFile::current); } return TRUE; }
bool BBitmapAccessor::CreateBitmap( BRect bounds, color_space space) { if (mDispose) delete mBitmap; mBitmap = new BBitmap(bounds, space); mBounds = mBitmap->Bounds(); mPixelSize = BytesPerPixel(); if (mCreateInvoker) { BMessage msg(*mCreateInvoker->Message()); msg.AddPointer("bitmap", mBitmap); mCreateInvoker->Invoke(&msg); } return IsValid(); }
TemporaryRef<DataSourceSurface> ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFormat) { gl->MakeCurrent(); gl->GuaranteeResolve(); gl->fActiveTexture(LOCAL_GL_TEXTURE0); gl->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture); IntSize size; gl->fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_WIDTH, &size.width); gl->fGetTexLevelParameteriv(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_TEXTURE_HEIGHT, &size.height); RefPtr<DataSourceSurface> surf = Factory::CreateDataSourceSurfaceWithStride(size, SurfaceFormat::B8G8R8A8, GetAlignedStride<4>(size.width * BytesPerPixel(SurfaceFormat::B8G8R8A8))); if (!surf) { return nullptr; } uint32_t currentPackAlignment = 0; gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*)¤tPackAlignment); if (currentPackAlignment != 4) { gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); } gl->fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, surf->GetData()); if (currentPackAlignment != 4) { gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); } if (aFormat == SurfaceFormat::R8G8B8A8 || aFormat == SurfaceFormat::R8G8B8X8) { SwapRAndBComponents(surf); } if (aYInvert) { surf = YInvertImageSurface(surf); } return surf.forget(); }
bool DataSourceSurfaceCG::InitFromData(unsigned char *aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat) { if (aSize.width <= 0 || aSize.height <= 0) { return false; } void *data = malloc(aStride * aSize.height); memcpy(data, aData, aStride * (aSize.height - 1) + (aSize.width * BytesPerPixel(aFormat))); mFormat = aFormat; mImage = CreateCGImage(data, data, aSize, aStride, aFormat); if (!mImage) { free(data); return false; } return true; }