bool CompressStream(Serializer& dest, Deserializer& src) { unsigned srcSize = src.GetSize() - src.GetPosition(); // Prepend the source and dest. data size in the stream so that we know to buffer & uncompress the right amount if (!srcSize) { dest.WriteUInt(0); dest.WriteUInt(0); return true; } unsigned maxDestSize = LZ4_compressBound(srcSize); SharedArrayPtr<unsigned char> srcBuffer(new unsigned char[srcSize]); SharedArrayPtr<unsigned char> destBuffer(new unsigned char[maxDestSize]); if (src.Read(srcBuffer, srcSize) != srcSize) return false; unsigned destSize = LZ4_compressHC((const char*)srcBuffer.Get(), (char*)destBuffer.Get(), srcSize); bool success = true; success &= dest.WriteUInt(srcSize); success &= dest.WriteUInt(destSize); success &= dest.Write(destBuffer, destSize) == destSize; return success; }
// ----------------------------------------------------------------------------- // CDrmUtilityGlobalNoteWrapper::ShowNoteL // ----------------------------------------------------------------------------- // TInt DRM::CDrmUtilityGlobalNoteWrapper::ShowNoteL( TInt aResourceId, const TDesC& aString ) { TBuf<DRM::KDRMNoteBufferMaxSize> srcBuffer( iResourceReader->ReadResourceString( aResourceId ) ); StringLoader::Format( iTextBuffer, srcBuffer, -1, aString ); return DoShowNoteL( aResourceId, aString ); }
// Test out the layer replacement functionality with and w/o a BBH void test_replacements(skiatest::Reporter* r, GrContext* context, bool doReplace) { sk_sp<SkPicture> pic; { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); SkPaint paint; canvas->saveLayer(nullptr, &paint); canvas->clear(SK_ColorRED); canvas->restore(); canvas->drawRect(SkRect::MakeWH(SkIntToScalar(kWidth / 2), SkIntToScalar(kHeight / 2)), SkPaint()); pic = recorder.finishRecordingAsPicture(); } SkAutoTUnref<GrTexture> texture; SkPaint paint; GrLayerCache* layerCache = context->getLayerCache(); if (doReplace) { int key[1] = { 0 }; GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, SkIRect::MakeWH(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight), SkMatrix::I(), key, 1, &paint); GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidth; desc.fHeight = kHeight; desc.fSampleCnt = 0; // Giving the texture some initial data so the Gpu (specifically vulkan) does not complain // when reading from an uninitialized texture. SkAutoTMalloc<uint32_t> srcBuffer(kWidth*kHeight); memset(srcBuffer.get(), 0, kWidth*kHeight*sizeof(uint32_t)); texture.reset(context->textureProvider()->createTexture( desc, SkBudgeted::kNo, srcBuffer.get(), 0)); layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight), false); } SkRecord rerecord; SkRecorder canvas(&rerecord, kWidth, kHeight); GrRecordReplaceDraw(pic.get(), &canvas, layerCache, SkMatrix::I(), nullptr/*callback*/); int numLayers = count_instances_of_type<SkRecords::SaveLayer>(rerecord); if (doReplace) { REPORTER_ASSERT(r, 0 == numLayers); } else { REPORTER_ASSERT(r, 1 == numLayers); } }
void aggPixelPainter<pixel_fmt>::copy(void* data, unsigned width, unsigned height, int stride, aggCanvas::PixelFormat format) { agg::rendering_buffer srcBuffer(reinterpret_cast<agg::int8u*>(data), width, height, -stride); switch (format) { case aggCanvas::Gray8_Blend: { gray_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::Gray16_Blend: { gray16_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::RGBA8_Blend: { color32_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::RGBA16_Blend: { color64_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::RGB8_Blend: { color24_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::RGB16_Blend: { color48_pixel_fmt srcPixFmt(srcBuffer); agg::copy_rect(srcPixFmt, pixFmt); break; } case aggCanvas::FF_Blend: case aggCanvas::FF24_Blend: case aggCanvas::QT_Blend: assert(false); break; default: break; } }
already_AddRefed<VideoData> GonkVideoDecoderManager::CreateVideoDataFromGraphicBuffer(MediaBuffer* aSource, gfx::IntRect& aPicture) { sp<GraphicBuffer> srcBuffer(aSource->graphicBuffer()); RefPtr<TextureClient> textureClient; if (mNeedsCopyBuffer) { // Copy buffer contents for bug 1199809. if (!mCopyAllocator) { mCopyAllocator = new TextureClientRecycleAllocator(ImageBridgeChild::GetSingleton()); } if (!mCopyAllocator) { GVDM_LOG("Create buffer allocator failed!"); return nullptr; } gfx::IntSize size(Align(aPicture.width, 2) , Align(aPicture.height, 2)); textureClient = mCopyAllocator->CreateOrRecycle(gfx::SurfaceFormat::YUV, size, BackendSelector::Content, TextureFlags::DEFAULT, ALLOC_DISALLOW_BUFFERTEXTURECLIENT); if (!textureClient) { GVDM_LOG("Copy buffer allocation failed!"); return nullptr; } // Update size to match buffer's. aPicture.width = size.width; aPicture.height = size.height; sp<GraphicBuffer> destBuffer = static_cast<GrallocTextureClientOGL*>(textureClient.get())->GetGraphicBuffer(); CopyGraphicBuffer(srcBuffer, destBuffer); } else { textureClient = mNativeWindow->getTextureClientFromBuffer(srcBuffer.get()); textureClient->SetRecycleCallback(GonkVideoDecoderManager::RecycleCallback, this); GrallocTextureClientOGL* grallocClient = static_cast<GrallocTextureClientOGL*>(textureClient.get()); grallocClient->SetMediaBuffer(aSource); } RefPtr<VideoData> data = VideoData::Create(mInfo.mVideo, mImageContainer, 0, // Filled later by caller. 0, // Filled later by caller. 1, // No way to pass sample duration from muxer to // OMX codec, so we hardcode the duration here. textureClient, false, // Filled later by caller. -1, aPicture); return data.forget(); }
void BasicThebesLayerBuffer::SetBackingBufferAndUpdateFrom( gfxASurface* aBuffer, gfxASurface* aSource, const nsIntRect& aRect, const nsIntPoint& aRotation, const nsIntRegion& aUpdateRegion) { SetBackingBuffer(aBuffer, aRect, aRotation); nsRefPtr<gfxContext> destCtx = GetContextForQuadrantUpdate(aUpdateRegion.GetBounds()); destCtx->SetOperator(gfxContext::OPERATOR_SOURCE); if (IsClippingCheap(destCtx, aUpdateRegion)) { gfxUtils::ClipToRegion(destCtx, aUpdateRegion); } BasicThebesLayerBuffer srcBuffer(aSource, aRect, aRotation); srcBuffer.DrawBufferWithRotation(destCtx, 1.0); }
// ----------------------------------------------------------------------------- // CDrmUtilityGlobalNoteWrapper::ShowNoteWithButtonsL // ----------------------------------------------------------------------------- // TInt DRM::CDrmUtilityGlobalNoteWrapper::ShowNoteWithButtonsL( TInt aResourceId, TInt aButtonsId, const TDesC& aString ) { TInt ret( 0 ); TBuf<DRM::KDRMNoteBufferMaxSize> srcBuffer( iResourceReader->ReadResourceString( aResourceId ) ); StringLoader::Format( iTextBuffer, srcBuffer, -1, aString ); iButtonsId = aButtonsId; ret = DoShowNoteL( aResourceId, aString ); iButtonsId = R_AVKON_SOFTKEYS_YES_NO__YES; return ret; }
bool DecompressStream(Serializer& dest, Deserializer& src) { if (src.IsEof()) return false; unsigned destSize = src.ReadUInt(); unsigned srcSize = src.ReadUInt(); if (!srcSize || !destSize) return true; // No data if (srcSize > src.GetSize()) return false; // Illegal source (packed data) size reported, possibly not valid data SharedArrayPtr<unsigned char> srcBuffer(new unsigned char[srcSize]); SharedArrayPtr<unsigned char> destBuffer(new unsigned char[destSize]); if (src.Read(srcBuffer, srcSize) != srcSize) return false; LZ4_decompress_fast((const char*)srcBuffer.Get(), (char*)destBuffer.Get(), destSize); return dest.Write(destBuffer, destSize) == destSize; }
void dng_limit_float_depth_task::Process (uint32 /* threadIndex */, const dng_rect &tile, dng_abort_sniffer * /* sniffer */) { dng_const_tile_buffer srcBuffer (fSrcImage, tile); dng_dirty_tile_buffer dstBuffer (fDstImage, tile); uint32 count0 = tile.H (); uint32 count1 = tile.W (); uint32 count2 = fDstImage.Planes (); int32 sStep0 = srcBuffer.fRowStep; int32 sStep1 = srcBuffer.fColStep; int32 sStep2 = srcBuffer.fPlaneStep; int32 dStep0 = dstBuffer.fRowStep; int32 dStep1 = dstBuffer.fColStep; int32 dStep2 = dstBuffer.fPlaneStep; const void *sPtr = srcBuffer.ConstPixel (tile.t, tile.l, 0); void *dPtr = dstBuffer.DirtyPixel (tile.t, tile.l, 0); OptimizeOrder (sPtr, dPtr, srcBuffer.fPixelSize, dstBuffer.fPixelSize, count0, count1, count2, sStep0, sStep1, sStep2, dStep0, dStep1, dStep2); const real32 *sPtr0 = (const real32 *) sPtr; real32 *dPtr0 = ( real32 *) dPtr; real32 scale = fScale; bool limit16 = (fBitDepth == 16); bool limit24 = (fBitDepth == 24); for (uint32 index0 = 0; index0 < count0; index0++) { const real32 *sPtr1 = sPtr0; real32 *dPtr1 = dPtr0; for (uint32 index1 = 0; index1 < count1; index1++) { // If the scale is a NOP, and the data is packed solid, we can just do memory // copy. if (scale == 1.0f && sStep2 == 1 && dStep2 == 1) { if (dPtr1 != sPtr1) // srcImage != dstImage { memcpy (dPtr1, sPtr1, count2 * (uint32) sizeof (real32)); } } else { const real32 *sPtr2 = sPtr1; real32 *dPtr2 = dPtr1; for (uint32 index2 = 0; index2 < count2; index2++) { real32 x = sPtr2 [0]; x *= scale; dPtr2 [0] = x; sPtr2 += sStep2; dPtr2 += dStep2; } } // The data is now in the destination buffer. if (limit16) { uint32 *dPtr2 = (uint32 *) dPtr1; for (uint32 index2 = 0; index2 < count2; index2++) { uint32 x = dPtr2 [0]; uint16 y = DNG_FloatToHalf (x); x = DNG_HalfToFloat (y); dPtr2 [0] = x; dPtr2 += dStep2; } } else if (limit24) { uint32 *dPtr2 = (uint32 *) dPtr1; for (uint32 index2 = 0; index2 < count2; index2++) { uint32 x = dPtr2 [0]; uint8 temp [3]; DNG_FloatToFP24 (x, temp); x = DNG_FP24ToFloat (temp); dPtr2 [0] = x; dPtr2 += dStep2; } } sPtr1 += sStep1; dPtr1 += dStep1; } sPtr0 += sStep0; dPtr0 += dStep0; } }
/* * Performs the jpeg decode */ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options& options, SkPMColor*, int*) { // Rewind the stream if needed if (!this->handleRewind()) { fDecoderMgr->returnFailure("could not rewind stream", kCouldNotRewind); } // Get a pointer to the decompress info since we will use it quite frequently jpeg_decompress_struct* dinfo = fDecoderMgr->dinfo(); // Set the jump location for libjpeg errors if (setjmp(fDecoderMgr->getJmpBuf())) { return fDecoderMgr->returnFailure("setjmp", kInvalidInput); } // Check if we can decode to the requested destination if (!conversion_possible(dstInfo, this->getInfo())) { return fDecoderMgr->returnFailure("conversion_possible", kInvalidConversion); } // Perform the necessary scaling if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) { fDecoderMgr->returnFailure("cannot scale to requested dims", kInvalidScale); } // Now, given valid output dimensions, we can start the decompress if (!jpeg_start_decompress(dinfo)) { return fDecoderMgr->returnFailure("startDecompress", kInvalidInput); } // Create the swizzler this->initializeSwizzler(dstInfo, dst, dstRowBytes, options); if (NULL == fSwizzler) { return fDecoderMgr->returnFailure("getSwizzler", kUnimplemented); } // This is usually 1, but can also be 2 or 4. // If we wanted to always read one row at a time, we could, but we will save space and time // by using the recommendation from libjpeg. const uint32_t rowsPerDecode = dinfo->rec_outbuf_height; SkASSERT(rowsPerDecode <= 4); // Create a buffer to contain decoded rows (libjpeg requires a 2D array) SkASSERT(0 != fSrcRowBytes); SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, fSrcRowBytes * rowsPerDecode)); JSAMPLE* srcRows[4]; uint8_t* srcPtr = srcBuffer.get(); for (uint8_t i = 0; i < rowsPerDecode; i++) { srcRows[i] = (JSAMPLE*) srcPtr; srcPtr += fSrcRowBytes; } // Ensure that we loop enough times to decode all of the rows // libjpeg will prevent us from reading past the bottom of the image uint32_t dstHeight = dstInfo.height(); for (uint32_t y = 0; y < dstHeight + rowsPerDecode - 1; y += rowsPerDecode) { // Read rows of the image uint32_t rowsDecoded = jpeg_read_scanlines(dinfo, srcRows, rowsPerDecode); // Convert to RGB if necessary if (JCS_CMYK == dinfo->out_color_space) { convert_CMYK_to_RGB(srcRows[0], dstInfo.width() * rowsDecoded); } // Swizzle to output destination for (uint32_t i = 0; i < rowsDecoded; i++) { fSwizzler->next(srcRows[i]); } // If we cannot read enough rows, assume the input is incomplete if (rowsDecoded < rowsPerDecode && y + rowsDecoded < dstHeight) { // Fill the remainder of the image with black. This error handling // behavior is unspecified but SkCodec consistently uses black as // the fill color for opaque images. If the destination is kGray, // the low 8 bits of SK_ColorBLACK will be used. Conveniently, // these are zeros, which is the representation for black in kGray. SkSwizzler::Fill(fSwizzler->getDstRow(), dstInfo, dstRowBytes, dstHeight - y - rowsDecoded, SK_ColorBLACK, NULL); // Prevent libjpeg from failing on incomplete decode dinfo->output_scanline = dstHeight; // Finish the decode and indicate that the input was incomplete. jpeg_finish_decompress(dinfo); return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput); } } jpeg_finish_decompress(dinfo); return kSuccess; }
bool GifTranscoder::resizeBoxFilter(GifFileType* gifIn, GifFileType* gifOut) { ASSERT(gifIn != NULL, "gifIn cannot be NULL"); ASSERT(gifOut != NULL, "gifOut cannot be NULL"); if (gifIn->SWidth < 0 || gifIn->SHeight < 0) { LOGE("Input GIF has invalid size: %d x %d", gifIn->SWidth, gifIn->SHeight); return false; } // Output GIF will be 50% the size of the original. if (EGifPutScreenDesc(gifOut, gifIn->SWidth / 2, gifIn->SHeight / 2, gifIn->SColorResolution, gifIn->SBackGroundColor, gifIn->SColorMap) == GIF_ERROR) { LOGE("Could not write screen descriptor"); return false; } LOGD("Wrote screen descriptor"); // Index of the current image. int imageIndex = 0; // Transparent color of the current image. int transparentColor = NO_TRANSPARENT_COLOR; // Buffer for reading raw images from the input GIF. std::vector<GifByteType> srcBuffer(gifIn->SWidth * gifIn->SHeight); // Buffer for rendering images from the input GIF. std::unique_ptr<ColorARGB> renderBuffer(new ColorARGB[gifIn->SWidth * gifIn->SHeight]); // Buffer for writing new images to output GIF (one row at a time). std::unique_ptr<GifByteType> dstRowBuffer(new GifByteType[gifOut->SWidth]); // Many GIFs use DISPOSE_DO_NOT to make images draw on top of previous images. They can also // use DISPOSE_BACKGROUND to clear the last image region before drawing the next one. We need // to keep track of the disposal mode as we go along to properly render the GIF. int disposalMode = DISPOSAL_UNSPECIFIED; int prevImageDisposalMode = DISPOSAL_UNSPECIFIED; GifImageDesc prevImageDimens; // Background color (applies to entire GIF). ColorARGB bgColor = TRANSPARENT; GifRecordType recordType; do { if (DGifGetRecordType(gifIn, &recordType) == GIF_ERROR) { LOGE("Could not get record type"); return false; } LOGD("Read record type: %d", recordType); switch (recordType) { case IMAGE_DESC_RECORD_TYPE: { if (DGifGetImageDesc(gifIn) == GIF_ERROR) { LOGE("Could not read image descriptor (%d)", imageIndex); return false; } // Sanity-check the current image position. if (gifIn->Image.Left < 0 || gifIn->Image.Top < 0 || gifIn->Image.Left + gifIn->Image.Width > gifIn->SWidth || gifIn->Image.Top + gifIn->Image.Height > gifIn->SHeight) { LOGE("GIF image extends beyond logical screen"); return false; } // Write the new image descriptor. if (EGifPutImageDesc(gifOut, 0, // Left 0, // Top gifOut->SWidth, gifOut->SHeight, false, // Interlace gifIn->Image.ColorMap) == GIF_ERROR) { LOGE("Could not write image descriptor (%d)", imageIndex); return false; } // Read the image from the input GIF. The buffer is already initialized to the // size of the GIF, which is usually equal to the size of all the images inside it. // If not, the call to resize below ensures that the buffer is the right size. srcBuffer.resize(gifIn->Image.Width * gifIn->Image.Height); if (readImage(gifIn, srcBuffer.data()) == false) { LOGE("Could not read image data (%d)", imageIndex); return false; } LOGD("Read image data (%d)", imageIndex); // Render the image from the input GIF. if (renderImage(gifIn, srcBuffer.data(), imageIndex, transparentColor, renderBuffer.get(), bgColor, prevImageDimens, prevImageDisposalMode) == false) { LOGE("Could not render %d", imageIndex); return false; } LOGD("Rendered image (%d)", imageIndex); // Generate the image in the output GIF. for (int y = 0; y < gifOut->SHeight; y++) { for (int x = 0; x < gifOut->SWidth; x++) { const GifByteType dstColorIndex = computeNewColorIndex( gifIn, transparentColor, renderBuffer.get(), x, y); *(dstRowBuffer.get() + x) = dstColorIndex; } if (EGifPutLine(gifOut, dstRowBuffer.get(), gifOut->SWidth) == GIF_ERROR) { LOGE("Could not write raster data (%d)", imageIndex); return false; } } LOGD("Wrote raster data (%d)", imageIndex); // Save the disposal mode for rendering the next image. // We only support DISPOSE_DO_NOT and DISPOSE_BACKGROUND. prevImageDisposalMode = disposalMode; if (prevImageDisposalMode == DISPOSAL_UNSPECIFIED) { prevImageDisposalMode = DISPOSE_DO_NOT; } else if (prevImageDisposalMode == DISPOSE_PREVIOUS) { prevImageDisposalMode = DISPOSE_BACKGROUND; } if (prevImageDisposalMode == DISPOSE_BACKGROUND) { prevImageDimens.Left = gifIn->Image.Left; prevImageDimens.Top = gifIn->Image.Top; prevImageDimens.Width = gifIn->Image.Width; prevImageDimens.Height = gifIn->Image.Height; } if (gifOut->Image.ColorMap) { GifFreeMapObject(gifOut->Image.ColorMap); gifOut->Image.ColorMap = NULL; } imageIndex++; } break; case EXTENSION_RECORD_TYPE: { int extCode; GifByteType* ext; if (DGifGetExtension(gifIn, &extCode, &ext) == GIF_ERROR) { LOGE("Could not read extension block"); return false; } LOGD("Read extension block, code: %d", extCode); if (extCode == GRAPHICS_EXT_FUNC_CODE) { GraphicsControlBlock gcb; if (DGifExtensionToGCB(ext[0], ext + 1, &gcb) == GIF_ERROR) { LOGE("Could not interpret GCB extension"); return false; } transparentColor = gcb.TransparentColor; // This logic for setting the background color based on the first GCB // doesn't quite match the GIF spec, but empirically it seems to work and it // matches what libframesequence (Rastermill) does. if (imageIndex == 0 && gifIn->SColorMap) { if (gcb.TransparentColor == NO_TRANSPARENT_COLOR) { GifColorType bgColorIndex = gifIn->SColorMap->Colors[gifIn->SBackGroundColor]; bgColor = gifColorToColorARGB(bgColorIndex); LOGD("Set background color based on first GCB"); } } // Record the original disposal mode and then update it. disposalMode = gcb.DisposalMode; gcb.DisposalMode = DISPOSE_BACKGROUND; EGifGCBToExtension(&gcb, ext + 1); } if (EGifPutExtensionLeader(gifOut, extCode) == GIF_ERROR) { LOGE("Could not write extension leader"); return false; } if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) { LOGE("Could not write extension block"); return false; } LOGD("Wrote extension block"); while (ext != NULL) { if (DGifGetExtensionNext(gifIn, &ext) == GIF_ERROR) { LOGE("Could not read extension continuation"); return false; } if (ext != NULL) { LOGD("Read extension continuation"); if (EGifPutExtensionBlock(gifOut, ext[0], ext + 1) == GIF_ERROR) { LOGE("Could not write extension continuation"); return false; } LOGD("Wrote extension continuation"); } } if (EGifPutExtensionTrailer(gifOut) == GIF_ERROR) { LOGE("Could not write extension trailer"); return false; } } break; } } while (recordType != TERMINATE_RECORD_TYPE); LOGD("No more records"); return true; }