本文整理汇总了C++中SkAutoMalloc类的典型用法代码示例。如果您正苦于以下问题:C++ SkAutoMalloc类的具体用法?C++ SkAutoMalloc怎么用?C++ SkAutoMalloc使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SkAutoMalloc类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SkStreamToDataProvider
static CGDataProviderRef SkStreamToDataProvider(SkStream* stream) {
// TODO: use callbacks, so we don't have to load all the data into RAM
SkAutoMalloc storage;
const size_t len = CopyStreamToStorage(&storage, stream);
void* data = storage.detach();
return CGDataProviderCreateWithData(data, data, len, malloc_release_proc);
}
示例2: nullGLMapBuffer
GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access) {
// We just reserve 32MB of RAM for all locks and hope its big enough
static SkAutoMalloc gBufferData(32 * (1 << 20));
GrGLuint buf = 0;
switch (target) {
case GR_GL_ARRAY_BUFFER:
buf = gCurrArrayBuffer;
break;
case GR_GL_ELEMENT_ARRAY_BUFFER:
buf = gCurrElementArrayBuffer;
break;
}
if (buf) {
*gMappedBuffers.append() = buf;
}
return gBufferData.get();
}
示例3: onDecode
SkImageDecoder::Result SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
// First read the entire stream, so that all of the data can be passed to
// the BmpDecoderHelper.
// Allocated space used to hold the data.
SkAutoMalloc storage;
// Byte length of all of the data.
const size_t length = SkCopyStreamToStorage(&storage, stream);
if (0 == length) {
return kFailure;
}
const bool justBounds = SkImageDecoder::kDecodeBounds_Mode == mode;
SkBmpDecoderCallback callback(justBounds);
// Now decode the BMP into callback's rgb() array [r,g,b, r,g,b, ...]
{
image_codec::BmpDecoderHelper helper;
const int max_pixels = 16383*16383; // max width*height
if (!helper.DecodeImage((const char*)storage.get(), length,
max_pixels, &callback)) {
return kFailure;
}
}
// we don't need this anymore, so free it now (before we try to allocate
// the bitmap's pixels) rather than waiting for its destructor
storage.free();
int width = callback.width();
int height = callback.height();
SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, false);
// only accept prefConfig if it makes sense for us
if (kARGB_4444_SkColorType != colorType && kRGB_565_SkColorType != colorType) {
colorType = kN32_SkColorType;
}
SkScaledBitmapSampler sampler(width, height, getSampleSize());
bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
colorType, kOpaque_SkAlphaType));
if (justBounds) {
return kSuccess;
}
if (!this->allocPixelRef(bm, NULL)) {
return kFailure;
}
SkAutoLockPixels alp(*bm);
if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) {
return kFailure;
}
const int srcRowBytes = width * 3;
const int dstHeight = sampler.scaledHeight();
const uint8_t* srcRow = callback.rgb();
srcRow += sampler.srcY0() * srcRowBytes;
for (int y = 0; y < dstHeight; y++) {
sampler.next(srcRow);
srcRow += sampler.srcDY() * srcRowBytes;
}
return kSuccess;
}
示例4: onDecodeRegion
bool SkJPEGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) {
if (index == NULL) {
return false;
}
int startX = region.fLeft;
int startY = region.fTop;
int width = region.width();
int height = region.height();
jpeg_decompress_struct *cinfo = index->cinfo;
SkAutoMalloc srcStorage;
skjpeg_error_mgr sk_err;
cinfo->err = jpeg_std_error(&sk_err);
sk_err.error_exit = skjpeg_error_exit;
if (setjmp(sk_err.fJmpBuf)) {
return false;
}
int requestedSampleSize = this->getSampleSize();
cinfo->scale_denom = requestedSampleSize;
if (this->getPreferQualityOverSpeed()) {
cinfo->dct_method = JDCT_ISLOW;
} else {
cinfo->dct_method = JDCT_IFAST;
}
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
if (config != SkBitmap::kARGB_8888_Config &&
config != SkBitmap::kARGB_4444_Config &&
config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
/* default format is RGB */
cinfo->out_color_space = JCS_RGB;
#ifdef ANDROID_RGB
cinfo->dither_mode = JDITHER_NONE;
if (config == SkBitmap::kARGB_8888_Config) {
cinfo->out_color_space = JCS_RGBA_8888;
} else if (config == SkBitmap::kRGB_565_Config) {
cinfo->out_color_space = JCS_RGB_565;
if (this->getDitherImage()) {
cinfo->dither_mode = JDITHER_ORDERED;
}
}
#endif
int oriStartX = startX;
int oriStartY = startY;
int oriWidth = width;
int oriHeight = height;
jpeg_init_read_tile_scanline(cinfo, index->index,
&startX, &startY, &width, &height);
int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_size);
SkBitmap *bitmap = new SkBitmap;
SkAutoTDelete<SkBitmap> adb(bitmap);
#ifdef ANDROID_RGB
/* short-circuit the SkScaledBitmapSampler when possible, as this gives
a significant performance boost.
*/
if (skiaSampleSize == 1 &&
((config == SkBitmap::kARGB_8888_Config &&
cinfo->out_color_space == JCS_RGBA_8888) ||
(config == SkBitmap::kRGB_565_Config &&
cinfo->out_color_space == JCS_RGB_565)))
{
bitmap->setConfig(config, cinfo->output_width, height);
bitmap->setIsOpaque(true);
if (!this->allocPixelRef(bitmap, NULL)) {
return return_false(*cinfo, *bitmap, "allocPixelRef");
}
SkAutoLockPixels alp(*bitmap);
JSAMPLE* rowptr = (JSAMPLE*)bitmap->getPixels();
INT32 const bpr = bitmap->rowBytes();
int row_total_count = 0;
while (row_total_count < height) {
int row_count = jpeg_read_tile_scanline(cinfo,
index->index, &rowptr);
// if row_count == 0, then we didn't get a scanline, so abort.
// if we supported partial images, we might return true in this case
if (0 == row_count) {
return return_false(*cinfo, *bitmap, "read_scanlines");
}
if (this->shouldCancelDecode()) {
return return_false(*cinfo, *bitmap, "shouldCancelDecode");
}
row_total_count += row_count;
rowptr += bpr;
}
cropBitmap(bm, bitmap, actualSampleSize, oriStartX, oriStartY,
oriWidth, oriHeight, startX, startY);
return true;
}
#endif
// check for supported formats
SkScaledBitmapSampler::SrcConfig sc;
//.........这里部分代码省略.........
示例5: atm
bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
#ifdef TIME_DECODE
AutoTimeMillis atm("JPEG Decode");
#endif
SkAutoMalloc srcStorage;
JPEGAutoClean autoClean;
jpeg_decompress_struct cinfo;
skjpeg_error_mgr sk_err;
skjpeg_source_mgr sk_stream(stream, this, false);
cinfo.err = jpeg_std_error(&sk_err);
sk_err.error_exit = skjpeg_error_exit;
// All objects need to be instantiated before this setjmp call so that
// they will be cleaned up properly if an error occurs.
if (setjmp(sk_err.fJmpBuf)) {
return return_false(cinfo, *bm, "setjmp");
}
jpeg_create_decompress(&cinfo);
autoClean.set(&cinfo);
#ifdef SK_BUILD_FOR_ANDROID
overwrite_mem_buffer_size(&cinfo);
#endif
//jpeg_stdio_src(&cinfo, file);
cinfo.src = &sk_stream;
int status = jpeg_read_header(&cinfo, true);
if (status != JPEG_HEADER_OK) {
return return_false(cinfo, *bm, "read_header");
}
/* Try to fulfill the requested sampleSize. Since jpeg can do it (when it
can) much faster that we, just use their num/denom api to approximate
the size.
*/
int sampleSize = this->getSampleSize();
if (this->getPreferQualityOverSpeed()) {
cinfo.dct_method = JDCT_ISLOW;
} else {
cinfo.dct_method = JDCT_IFAST;
}
cinfo.scale_num = 1;
cinfo.scale_denom = sampleSize;
/* this gives about 30% performance improvement. In theory it may
reduce the visual quality, in practice I'm not seeing a difference
*/
cinfo.do_fancy_upsampling = 0;
/* this gives another few percents */
cinfo.do_block_smoothing = 0;
/* default format is RGB */
cinfo.out_color_space = JCS_RGB;
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
// only these make sense for jpegs
if (config != SkBitmap::kARGB_8888_Config &&
config != SkBitmap::kARGB_4444_Config &&
config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
#ifdef ANDROID_RGB
cinfo.dither_mode = JDITHER_NONE;
if (config == SkBitmap::kARGB_8888_Config) {
cinfo.out_color_space = JCS_RGBA_8888;
} else if (config == SkBitmap::kRGB_565_Config) {
cinfo.out_color_space = JCS_RGB_565;
if (this->getDitherImage()) {
cinfo.dither_mode = JDITHER_ORDERED;
}
}
#endif
if (sampleSize == 1 && mode == SkImageDecoder::kDecodeBounds_Mode) {
bm->setConfig(config, cinfo.image_width, cinfo.image_height);
bm->setIsOpaque(true);
return true;
}
/* image_width and image_height are the original dimensions, available
after jpeg_read_header(). To see the scaled dimensions, we have to call
jpeg_start_decompress(), and then read output_width and output_height.
*/
if (!jpeg_start_decompress(&cinfo)) {
/* If we failed here, we may still have enough information to return
to the caller if they just wanted (subsampled bounds). If sampleSize
was 1, then we would have already returned. Thus we just check if
we're in kDecodeBounds_Mode, and that we have valid output sizes.
One reason to fail here is that we have insufficient stream data
to complete the setup. However, output dimensions seem to get
//.........这里部分代码省略.........
示例6: getImage
void SkScalerContext::getImage(const SkGlyph& origGlyph) {
const SkGlyph* glyph = &origGlyph;
SkGlyph tmpGlyph;
// in case we need to call generateImage on a mask-format that is different
// (i.e. larger) than what our caller allocated by looking at origGlyph.
SkAutoMalloc tmpGlyphImageStorage;
// If we are going to draw-from-path, then we cannot generate color, since
// the path only makes a mask. This case should have been caught up in
// generateMetrics().
SkASSERT(!fGenerateImageFromPath ||
SkMask::kARGB32_Format != origGlyph.fMaskFormat);
if (fMaskFilter) { // restore the prefilter bounds
tmpGlyph.initGlyphIdFrom(origGlyph);
// need the original bounds, sans our maskfilter
SkMaskFilter* mf = fMaskFilter;
fMaskFilter = nullptr; // temp disable
this->getMetrics(&tmpGlyph);
fMaskFilter = mf; // restore
// we need the prefilter bounds to be <= filter bounds
SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth);
SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight);
if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) {
tmpGlyph.fImage = origGlyph.fImage;
} else {
tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize());
tmpGlyph.fImage = tmpGlyphImageStorage.get();
}
glyph = &tmpGlyph;
}
if (fGenerateImageFromPath) {
SkPath devPath, fillPath;
SkMatrix fillToDevMatrix;
SkMask mask;
this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix);
glyph->toMask(&mask);
if (fRasterizer) {
mask.fFormat = SkMask::kA8_Format;
sk_bzero(glyph->fImage, mask.computeImageSize());
if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr,
fMaskFilter, &mask,
SkMask::kJustRenderImage_CreateMode)) {
return;
}
if (fPreBlend.isApplicable()) {
applyLUTToA8Mask(mask, fPreBlend.fG);
}
} else {
SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
generateMask(mask, devPath, fPreBlend);
}
} else {
generateImage(*glyph);
}
if (fMaskFilter) {
SkMask srcM, dstM;
SkMatrix matrix;
// the src glyph image shouldn't be 3D
SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat);
SkAutoSMalloc<32*32> a8storage;
glyph->toMask(&srcM);
if (SkMask::kARGB32_Format == srcM.fFormat) {
// now we need to extract the alpha-channel from the glyph's image
// and copy it into a temp buffer, and then point srcM at that temp.
srcM.fFormat = SkMask::kA8_Format;
srcM.fRowBytes = SkAlign4(srcM.fBounds.width());
size_t size = srcM.computeImageSize();
a8storage.reset(size);
srcM.fImage = (uint8_t*)a8storage.get();
extract_alpha(srcM,
(const SkPMColor*)glyph->fImage, glyph->rowBytes());
}
fRec.getMatrixFrom2x2(&matrix);
if (fMaskFilter->filterMask(&dstM, srcM, matrix, nullptr)) {
int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width());
int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height());
int dstRB = origGlyph.rowBytes();
int srcRB = dstM.fRowBytes;
const uint8_t* src = (const uint8_t*)dstM.fImage;
uint8_t* dst = (uint8_t*)origGlyph.fImage;
if (SkMask::k3D_Format == dstM.fFormat) {
// we have to copy 3 times as much
height *= 3;
}
//.........这里部分代码省略.........
示例7: load_yuv_texture
static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKey,
const SkBitmap& bm, const GrSurfaceDesc& desc) {
// Subsets are not supported, the whole pixelRef is loaded when using YUV decoding
SkPixelRef* pixelRef = bm.pixelRef();
if ((NULL == pixelRef) ||
(pixelRef->info().width() != bm.info().width()) ||
(pixelRef->info().height() != bm.info().height())) {
return NULL;
}
const bool useCache = optionalKey.isValid();
SkYUVPlanesCache::Info yuvInfo;
SkAutoTUnref<SkCachedData> cachedData;
SkAutoMalloc storage;
if (useCache) {
cachedData.reset(SkYUVPlanesCache::FindAndRef(pixelRef->getGenerationID(), &yuvInfo));
}
void* planes[3];
if (cachedData.get()) {
planes[0] = (void*)cachedData->data();
planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
} else {
// Fetch yuv plane sizes for memory allocation. Here, width and height can be
// rounded up to JPEG block size and be larger than the image's width and height.
if (!pixelRef->getYUV8Planes(yuvInfo.fSize, NULL, NULL, NULL)) {
return NULL;
}
// Allocate the memory for YUV
size_t totalSize(0);
for (int i = 0; i < 3; ++i) {
yuvInfo.fRowBytes[i] = yuvInfo.fSize[i].fWidth;
yuvInfo.fSizeInMemory[i] = yuvInfo.fRowBytes[i] * yuvInfo.fSize[i].fHeight;
totalSize += yuvInfo.fSizeInMemory[i];
}
if (useCache) {
cachedData.reset(SkResourceCache::NewCachedData(totalSize));
planes[0] = cachedData->writable_data();
} else {
storage.reset(totalSize);
planes[0] = storage.get();
}
planes[1] = (uint8_t*)planes[0] + yuvInfo.fSizeInMemory[0];
planes[2] = (uint8_t*)planes[1] + yuvInfo.fSizeInMemory[1];
// Get the YUV planes and update plane sizes to actual image size
if (!pixelRef->getYUV8Planes(yuvInfo.fSize, planes, yuvInfo.fRowBytes,
&yuvInfo.fColorSpace)) {
return NULL;
}
if (useCache) {
// Decoding is done, cache the resulting YUV planes
SkYUVPlanesCache::Add(pixelRef->getGenerationID(), cachedData, &yuvInfo);
}
}
GrSurfaceDesc yuvDesc;
yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
SkAutoTUnref<GrTexture> yuvTextures[3];
for (int i = 0; i < 3; ++i) {
yuvDesc.fWidth = yuvInfo.fSize[i].fWidth;
yuvDesc.fHeight = yuvInfo.fSize[i].fHeight;
bool needsExactTexture =
(yuvDesc.fWidth != yuvInfo.fSize[0].fWidth) ||
(yuvDesc.fHeight != yuvInfo.fSize[0].fHeight);
if (needsExactTexture) {
yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, true));
} else {
yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc));
}
if (!yuvTextures[i] ||
!yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight,
yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) {
return NULL;
}
}
GrSurfaceDesc rtDesc = desc;
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
GrTexture* result = create_texture_for_bmp(ctx, optionalKey, rtDesc, pixelRef, NULL, 0);
if (!result) {
return NULL;
}
GrRenderTarget* renderTarget = result->asRenderTarget();
SkASSERT(renderTarget);
GrPaint paint;
SkAutoTUnref<GrFragmentProcessor>
yuvToRgbProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager(), yuvTextures[0],
yuvTextures[1], yuvTextures[2],
yuvInfo.fSize, yuvInfo.fColorSpace));
paint.addColorProcessor(yuvToRgbProcessor);
SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
SkIntToScalar(yuvInfo.fSize[0].fHeight));
//.........这里部分代码省略.........
示例8: DEF_TEST
//.........这里部分代码省略.........
} else { // Tests expect a 2x2 bitmap, so make smaller.
src.allocPixels(SkImageInfo::Make(subW, subH,
gPairs[i].fColorType,
kPremul_SkAlphaType));
}
SkSafeUnref(ct);
// Either copy src or extract into 'subset', which is used
// for subsequent calls to copyPixelsTo/From.
bool srcReady = false;
// Test relies on older behavior that extractSubset will fail on
// kUnknown_SkColorType
if (kUnknown_SkColorType != src.colorType() &&
isExtracted[copyCase]) {
// The extractedSubset() test case allows us to test copy-
// ing when src and dst mave possibly different strides.
SkIRect r;
r.set(1, 0, 1 + subW, subH); // 2x2 extracted bitmap
srcReady = src.extractSubset(&subset, r);
} else {
srcReady = src.copyTo(&subset);
}
// Not all configurations will generate a valid 'subset'.
if (srcReady) {
// Allocate our target buffer 'buf' for all copies.
// To simplify verifying correctness of copies attach
// buf to a SkBitmap, but copies are done using the
// raw buffer pointer.
const size_t bufSize = subH *
SkColorTypeMinRowBytes(src.colorType(), subW) * 2;
SkAutoMalloc autoBuf (bufSize);
uint8_t* buf = static_cast<uint8_t*>(autoBuf.get());
SkBitmap bufBm; // Attach buf to this bitmap.
bool successExpected;
// Set up values for each pixel being copied.
Coordinates coords(subW * subH);
for (int x = 0; x < subW; ++x)
for (int y = 0; y < subH; ++y)
{
int index = y * subW + x;
SkASSERT(index < coords.length);
coords[index]->fX = x;
coords[index]->fY = y;
}
writeCoordPixels(subset, coords);
// Test #1 ////////////////////////////////////////////
const SkImageInfo info = SkImageInfo::Make(subW, subH,
gPairs[i].fColorType,
kPremul_SkAlphaType);
// Before/after comparisons easier if we attach buf
// to an appropriately configured SkBitmap.
memset(buf, 0xFF, bufSize);
// Config with stride greater than src but that fits in buf.
bufBm.installPixels(info, buf, info.minRowBytes() * 2);
successExpected = false;
// Then attempt to copy with a stride that is too large
// to fit in the buffer.
REPORTER_ASSERT(reporter,
示例9: SkCopyStreamToStorage
SkImageDecoder::Result SkASTCImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
SkAutoMalloc autoMal;
const size_t length = SkCopyStreamToStorage(&autoMal, stream);
if (0 == length) {
return kFailure;
}
unsigned char* buf = (unsigned char*)autoMal.get();
// Make sure that the magic header is there...
SkASSERT(SkEndian_SwapLE32(*(reinterpret_cast<uint32_t*>(buf))) == kASTCMagicNumber);
// Advance past the magic header
buf += 4;
const int blockDimX = buf[0];
const int blockDimY = buf[1];
const int blockDimZ = buf[2];
if (1 != blockDimZ) {
// We don't support decoding 3D
return kFailure;
}
// Choose the proper ASTC format
SkTextureCompressor::Format astcFormat;
if (4 == blockDimX && 4 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_4x4_Format;
} else if (5 == blockDimX && 4 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_5x4_Format;
} else if (5 == blockDimX && 5 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_5x5_Format;
} else if (6 == blockDimX && 5 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_6x5_Format;
} else if (6 == blockDimX && 6 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_6x6_Format;
} else if (8 == blockDimX && 5 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_8x5_Format;
} else if (8 == blockDimX && 6 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_8x6_Format;
} else if (8 == blockDimX && 8 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_8x8_Format;
} else if (10 == blockDimX && 5 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_10x5_Format;
} else if (10 == blockDimX && 6 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_10x6_Format;
} else if (10 == blockDimX && 8 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_10x8_Format;
} else if (10 == blockDimX && 10 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_10x10_Format;
} else if (12 == blockDimX && 10 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_12x10_Format;
} else if (12 == blockDimX && 12 == blockDimY) {
astcFormat = SkTextureCompressor::kASTC_12x12_Format;
} else {
// We don't support any other block dimensions..
return kFailure;
}
// Advance buf past the block dimensions
buf += 3;
// Read the width/height/depth from the buffer...
const int width = read_24bit(buf);
const int height = read_24bit(buf + 3);
const int depth = read_24bit(buf + 6);
if (1 != depth) {
// We don't support decoding 3D.
return kFailure;
}
// Advance the buffer past the image dimensions
buf += 9;
// Setup the sampler...
SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
// Determine the alpha of the bitmap...
SkAlphaType alphaType = kOpaque_SkAlphaType;
if (this->getRequireUnpremultipliedColors()) {
alphaType = kUnpremul_SkAlphaType;
} else {
alphaType = kPremul_SkAlphaType;
}
// Set the config...
bm->setInfo(SkImageInfo::MakeN32(sampler.scaledWidth(), sampler.scaledHeight(), alphaType));
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return kSuccess;
}
if (!this->allocPixelRef(bm, NULL)) {
return kFailure;
}
// Lock the pixels, since we're about to write to them...
SkAutoLockPixels alp(*bm);
//.........这里部分代码省略.........
示例10: onDecodeRegion
bool SkJPEGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) {
if (index == NULL) {
return false;
}
jpeg_decompress_struct *cinfo = index->cinfo;
SkIRect rect = SkIRect::MakeWH(this->imageWidth, this->imageHeight);
if (!rect.intersect(region)) {
// If the requested region is entirely outsides the image, just
// returns false
return false;
}
SkAutoMalloc srcStorage;
skjpeg_error_mgr sk_err;
cinfo->err = jpeg_std_error(&sk_err);
sk_err.error_exit = skjpeg_error_exit;
if (setjmp(sk_err.fJmpBuf)) {
return false;
}
int requestedSampleSize = this->getSampleSize();
cinfo->scale_denom = requestedSampleSize;
if (this->getPreferQualityOverSpeed()) {
cinfo->dct_method = JDCT_ISLOW;
} else {
cinfo->dct_method = JDCT_IFAST;
}
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
if (config != SkBitmap::kARGB_8888_Config &&
config != SkBitmap::kARGB_4444_Config &&
config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
/* default format is RGB */
cinfo->out_color_space = JCS_RGB;
#ifdef ANDROID_RGB
cinfo->dither_mode = JDITHER_NONE;
if (config == SkBitmap::kARGB_8888_Config) {
cinfo->out_color_space = JCS_RGBA_8888;
} else if (config == SkBitmap::kRGB_565_Config) {
cinfo->out_color_space = JCS_RGB_565;
if (this->getDitherImage()) {
cinfo->dither_mode = JDITHER_ORDERED;
}
}
#endif
int startX = rect.fLeft;
int startY = rect.fTop;
int width = rect.width();
int height = rect.height();
jpeg_init_read_tile_scanline(cinfo, index->index,
&startX, &startY, &width, &height);
int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_size);
SkBitmap *bitmap = new SkBitmap;
SkAutoTDelete<SkBitmap> adb(bitmap);
#ifdef ANDROID_RGB
/* short-circuit the SkScaledBitmapSampler when possible, as this gives
a significant performance boost.
*/
if (skiaSampleSize == 1 &&
((config == SkBitmap::kARGB_8888_Config &&
cinfo->out_color_space == JCS_RGBA_8888) ||
(config == SkBitmap::kRGB_565_Config &&
cinfo->out_color_space == JCS_RGB_565)))
{
bitmap->setConfig(config, cinfo->output_width, height);
bitmap->setIsOpaque(true);
// Check ahead of time if the swap(dest, src) is possible or not.
// If yes, then we will stick to AllocPixelRef since it's cheaper
// with the swap happening. If no, then we will use alloc to allocate
// pixels to prevent garbage collection.
//
// Not using a recycled-bitmap and the output rect is same as the
// decoded region.
int w = rect.width() / actualSampleSize;
int h = rect.height() / actualSampleSize;
bool swapOnly = (rect == region) && bm->isNull() &&
(w == bitmap->width()) && (h == bitmap->height()) &&
((startX - rect.x()) / actualSampleSize == 0) &&
((startY - rect.y()) / actualSampleSize == 0);
if (swapOnly) {
if (!this->allocPixelRef(bitmap, NULL)) {
return return_false(*cinfo, *bitmap, "allocPixelRef");
}
} else {
if (!bitmap->allocPixels()) {
return return_false(*cinfo, *bitmap, "allocPixels");
}
}
SkAutoLockPixels alp(*bitmap);
JSAMPLE* rowptr = (JSAMPLE*)bitmap->getPixels();
//.........这里部分代码省略.........
示例11: atm
bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
SkBitmap::Config prefConfig, Mode mode) {
#ifdef TIME_DECODE
AutoTimeMillis atm("JPEG Decode");
#endif
SkAutoMalloc srcStorage;
JPEGAutoClean autoClean;
jpeg_decompress_struct cinfo;
sk_error_mgr sk_err;
sk_source_mgr sk_stream(stream);
cinfo.err = jpeg_std_error(&sk_err);
sk_err.error_exit = sk_error_exit;
// All objects need to be instantiated before this setjmp call so that
// they will be cleaned up properly if an error occurs.
if (setjmp(sk_err.fJmpBuf)) {
return false;
}
jpeg_create_decompress(&cinfo);
autoClean.set(&cinfo);
//jpeg_stdio_src(&cinfo, file);
cinfo.src = &sk_stream;
jpeg_read_header(&cinfo, true);
/* Try to fulfill the requested sampleSize. Since jpeg can do it (when it
can) much faster that we, just use their num/denom api to approximate
the size.
*/
int sampleSize = this->getSampleSize();
cinfo.dct_method = JDCT_IFAST;
cinfo.scale_num = 1;
cinfo.scale_denom = sampleSize;
/* image_width and image_height are the original dimensions, available
after jpeg_read_header(). To see the scaled dimensions, we have to call
jpeg_start_decompress(), and then read output_width and output_height.
*/
jpeg_start_decompress(&cinfo);
/* If we need to better match the request, we might examine the image and
output dimensions, and determine if the downsampling jpeg provided is
not sufficient. If so, we can recompute a modified sampleSize value to
make up the difference.
To skip this additional scaling, just set sampleSize = 1; below.
*/
sampleSize = sampleSize * cinfo.output_width / cinfo.image_width;
// check for supported formats
bool isRGB; // as opposed to gray8
if (3 == cinfo.num_components && JCS_RGB == cinfo.out_color_space) {
isRGB = true;
} else if (1 == cinfo.num_components &&
JCS_GRAYSCALE == cinfo.out_color_space) {
isRGB = false; // could use Index8 config if we want...
} else {
SkDEBUGF(("SkJPEGImageDecoder: unsupported jpeg colorspace %d with %d components\n",
cinfo.jpeg_color_space, cinfo.num_components));
return false;
}
SkBitmap::Config config = prefConfig;
// if no user preference, see what the device recommends
if (config == SkBitmap::kNo_Config)
config = SkImageDecoder::GetDeviceConfig();
// only these make sense for jpegs
if (config != SkBitmap::kARGB_8888_Config &&
config != SkBitmap::kARGB_4444_Config &&
config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
// should we allow the Chooser (if present) to pick a config for us???
if (!this->chooseFromOneChoice(config, cinfo.output_width,
cinfo.output_height)) {
return false;
}
SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height,
sampleSize);
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
// jpegs are always opauqe (i.e. have no per-pixel alpha)
bm->setIsOpaque(true);
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
return true;
}
if (!this->allocPixelRef(bm, NULL)) {
return false;
}
//.........这里部分代码省略.........