buffer_t::buffer_t( int width, int height, int channels) { RAMEN_ASSERT( ( channels == 1 || channels == 3 || channels == 4) && "buffer_t: only 1, 3 and 4 channels images supported"); init(); channels_ = channels; bounds_ = Imath::Box2i( Imath::V2i( 0, 0), Imath::V2i( width-1, height-1)); if( bounds_.isEmpty()) return; alloc_pixels(); }
buffer_t::buffer_t( const Imath::Box2i& bounds, int channels) { RAMEN_ASSERT( ( channels == 1 || channels == 3 || channels == 4) && "buffer_t: only 1, 3 and 4 channels images supported"); init(); bounds_ = bounds; channels_ = channels; if( bounds_.isEmpty()) return; alloc_pixels(); }
void SubsetSingleBench::onDraw(int n, SkCanvas* canvas) { // When the color type is kIndex8, we will need to store the color table. If it is // used, it will be initialized by the codec. int colorCount; SkPMColor colors[256]; if (fUseCodec) { for (int count = 0; count < n; count++) { SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream->duplicate())); const SkImageInfo info = codec->getInfo().makeColorType(fColorType); SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); codec->startScanlineDecode(info, nullptr, colors, &colorCount); SkBitmap bitmap; SkImageInfo subsetInfo = info.makeWH(fSubsetWidth, fSubsetHeight); alloc_pixels(&bitmap, subsetInfo, colors, colorCount); codec->skipScanlines(fOffsetTop); uint32_t bpp = info.bytesPerPixel(); for (uint32_t y = 0; y < fSubsetHeight; y++) { codec->getScanlines(row.get(), 1, 0); memcpy(bitmap.getAddr(0, y), row.get() + fOffsetLeft * bpp, fSubsetWidth * bpp); } } } else { for (int count = 0; count < n; count++) { SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); int width, height; decoder->buildTileIndex(fStream->duplicate(), &width, &height); SkBitmap bitmap; SkIRect rect = SkIRect::MakeXYWH(fOffsetLeft, fOffsetTop, fSubsetWidth, fSubsetHeight); decoder->decodeSubset(&bitmap, rect, fColorType); } } }
void SubsetZoomBench::onDraw(const int n, SkCanvas* canvas) { // When the color type is kIndex8, we will need to store the color table. If it is // used, it will be initialized by the codec. int colorCount; SkPMColor colors[256]; if (fUseCodec) { for (int count = 0; count < n; count++) { SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( SkScanlineDecoder::NewFromStream(fStream->duplicate())); const SkImageInfo info = scanlineDecoder->getInfo().makeColorType(fColorType); SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); scanlineDecoder->start(info, nullptr, colors, &colorCount); const int centerX = info.width() / 2; const int centerY = info.height() / 2; int w = fSubsetWidth; int h = fSubsetHeight; do { const int subsetStartX = SkTMax(0, centerX - w / 2); const int subsetStartY = SkTMax(0, centerY - h / 2); const int subsetWidth = SkTMin(w, info.width() - subsetStartX); const int subsetHeight = SkTMin(h, info.height() - subsetStartY); // Note that if we subsetted and scaled in a single step, we could use the // same bitmap - as is often done in actual use cases. SkBitmap bitmap; SkImageInfo subsetInfo = info.makeWH(subsetWidth, subsetHeight); alloc_pixels(&bitmap, subsetInfo, colors, colorCount); uint32_t bpp = info.bytesPerPixel(); scanlineDecoder->skipScanlines(subsetStartY); for (int y = 0; y < subsetHeight; y++) { scanlineDecoder->getScanlines(row.get(), 1, 0); memcpy(bitmap.getAddr(0, y), row.get() + subsetStartX * bpp, subsetWidth * bpp); } w <<= 1; h <<= 1; } while (w < 2 * info.width() || h < 2 * info.height()); } } else { for (int count = 0; count < n; count++) { int width, height; SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); decoder->buildTileIndex(fStream->duplicate(), &width, &height); const int centerX = width / 2; const int centerY = height / 2; int w = fSubsetWidth; int h = fSubsetHeight; do { const int subsetStartX = SkTMax(0, centerX - w / 2); const int subsetStartY = SkTMax(0, centerY - h / 2); const int subsetWidth = SkTMin(w, width - subsetStartX); const int subsetHeight = SkTMin(h, height - subsetStartY); SkBitmap bitmap; SkIRect rect = SkIRect::MakeXYWH(subsetStartX, subsetStartY, subsetWidth, subsetHeight); decoder->decodeSubset(&bitmap, rect, fColorType); w <<= 1; h <<= 1; } while (w < 2 * width || h < 2 * height); } } }
void SubsetTranslateBench::onDraw(const int n, SkCanvas* canvas) { // When the color type is kIndex8, we will need to store the color table. If it is // used, it will be initialized by the codec. int colorCount; SkPMColor colors[256]; if (fUseCodec) { for (int count = 0; count < n; count++) { SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( SkScanlineDecoder::NewFromStream(fStream->duplicate())); const SkImageInfo info = scanlineDecoder->getInfo().makeColorType(fColorType); SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); scanlineDecoder->start(info, nullptr, colors, &colorCount); SkBitmap bitmap; // Note that we use the same bitmap for all of the subsets. // It might be larger than necessary for the end subsets. SkImageInfo subsetInfo = info.makeWH(fSubsetWidth, fSubsetHeight); alloc_pixels(&bitmap, subsetInfo, colors, colorCount); for (int x = 0; x < info.width(); x += fSubsetWidth) { for (int y = 0; y < info.height(); y += fSubsetHeight) { scanlineDecoder->skipScanlines(y); const uint32_t currSubsetWidth = x + (int) fSubsetWidth > info.width() ? info.width() - x : fSubsetWidth; const uint32_t currSubsetHeight = y + (int) fSubsetHeight > info.height() ? info.height() - y : fSubsetHeight; const uint32_t bpp = info.bytesPerPixel(); for (uint32_t y = 0; y < currSubsetHeight; y++) { scanlineDecoder->getScanlines(row.get(), 1, 0); memcpy(bitmap.getAddr(0, y), row.get() + x * bpp, currSubsetWidth * bpp); } } } } } else { // We create a color table here to satisfy allocPixels() when the output // type is kIndex8. It's okay that this is uninitialized since we never // use it. SkColorTable* colorTable = new SkColorTable(colors, 0); for (int count = 0; count < n; count++) { int width, height; SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(fStream)); decoder->buildTileIndex(fStream->duplicate(), &width, &height); SkBitmap bitmap; // Note that we use the same bitmap for all of the subsets. // It might be larger than necessary for the end subsets. // If we do not include this step, decodeSubset() would allocate space // for the pixels automatically, but this would not allow us to reuse the // same bitmap as the other subsets. We want to reuse the same bitmap // because it gives a more fair comparison with SkCodec and is a common // use case of BitmapRegionDecoder. bitmap.allocPixels(SkImageInfo::Make(fSubsetWidth, fSubsetHeight, fColorType, kOpaque_SkAlphaType), nullptr, colorTable); for (int x = 0; x < width; x += fSubsetWidth) { for (int y = 0; y < height; y += fSubsetHeight) { const uint32_t currSubsetWidth = x + (int) fSubsetWidth > width ? width - x : fSubsetWidth; const uint32_t currSubsetHeight = y + (int) fSubsetHeight > height ? height - y : fSubsetHeight; SkIRect rect = SkIRect::MakeXYWH(x, y, currSubsetWidth, currSubsetHeight); decoder->decodeSubset(&bitmap, rect, fColorType); } } } } }