bool SkImageGenerator::tryGenerateBitmap(SkBitmap* bitmap, const SkImageInfo* infoPtr) { const SkImageInfo info = infoPtr ? *infoPtr : this->getInfo(); const size_t rowBytes = info.minRowBytes(); const size_t pixelSize = info.getSafeSize(rowBytes); if (0 == pixelSize) { return false; } SkAutoFree pixelStorage(sk_malloc_flags(pixelSize, 0)); void* pixels = pixelStorage.get(); if (!pixels) { return false; } SkPMColor ctStorage[256]; int ctCount = 0; if (!this->getPixels(info, pixels, rowBytes, ctStorage, &ctCount)) { return false; } SkAutoTUnref<SkColorTable> ctable; if (ctCount > 0) { SkASSERT(kIndex_8_SkColorType == info.colorType()); ctable.reset(new SkColorTable(ctStorage, ctCount)); } else { SkASSERT(kIndex_8_SkColorType != info.colorType()); } return bitmap->installPixels(info, pixelStorage.detach(), rowBytes, ctable, release_malloc_proc, nullptr); }
DEF_TEST(Codec_jpeg_rewind, r) { const char* path = "mandrill_512_q075.jpg"; SkAutoTDelete<SkStream> stream(resource(path)); if (!stream) { SkDebugf("Missing resource '%s'\n", path); return; } SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.release())); if (!codec) { ERRORF(r, "Unable to create codec '%s'.", path); return; } const int width = codec->getInfo().width(); const int height = codec->getInfo().height(); size_t rowBytes = sizeof(SkPMColor) * width; SkAutoMalloc pixelStorage(height * rowBytes); // Perform a sampled decode. SkAndroidCodec::AndroidOptions opts; opts.fSampleSize = 12; codec->getAndroidPixels(codec->getInfo().makeWH(width / 12, height / 12), pixelStorage.get(), rowBytes, &opts); // Rewind the codec and perform a full image decode. SkCodec::Result result = codec->getPixels(codec->getInfo(), pixelStorage.get(), rowBytes); REPORTER_ASSERT(r, SkCodec::kSuccess == result); }
bool GReadBitmapFromFile(const char path[], GBitmap* bitmap) { FILE* file = fopen(path, "rb"); if (NULL == file) { return always_false(); } GAutoFClose afc(file); uint8_t signature[SIGNATURE_BYTES]; if (SIGNATURE_BYTES != fread(signature, 1, SIGNATURE_BYTES, file)) { return always_false(); } if (png_sig_cmp(signature, 0, SIGNATURE_BYTES)) { return always_false(); } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (NULL == png_ptr) { return always_false(); } png_infop info_ptr = png_create_info_struct(png_ptr); if (NULL == info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return always_false(); } GAutoPNGReader reader(png_ptr, info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { return always_false(); } png_init_io(png_ptr, file); png_set_sig_bytes(png_ptr, SIGNATURE_BYTES); png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bitDepth, colorType; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, NULL, NULL, NULL); if (8 != bitDepth) { return always_false(); // TODO: handle other formats } if (png_set_interlace_handling(png_ptr) > 1) { return always_false(); // TODO: support interleave } swizzle_row_proc row_proc = NULL; switch (colorType) { case PNG_COLOR_TYPE_RGB: row_proc = swizzle_rgb_row; break; case PNG_COLOR_TYPE_RGB_ALPHA: row_proc = swizzle_rgba_row; break; default: return always_false(); } png_read_update_info(png_ptr, info_ptr); GAutoFree rowStorage(malloc(png_get_rowbytes(png_ptr, info_ptr))); png_bytep srcRow = (png_bytep)rowStorage.get(); if (!srcRow) { return always_false(); } GAutoFree pixelStorage(malloc(height * width * 4)); GPixel* dstRow = (GPixel*)pixelStorage.get(); if (NULL == dstRow) { return always_false(); } for (int y = 0; y < height; y++) { uint8_t* tmp = srcRow; png_read_rows(png_ptr, &tmp, NULL, 1); row_proc(dstRow, srcRow, width); dstRow += width; } bitmap->fWidth = width; bitmap->fHeight = height; bitmap->fRowBytes = width * 4; bitmap->fPixels = (GPixel*)pixelStorage.detach(); return true; }