diff options
author | Matt Sarett <msarett@google.com> | 2016-11-02 16:18:01 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-03 16:33:33 +0000 |
commit | d851795e7992565c1eb2b9474ee5ad01d1a01fad (patch) | |
tree | a7293bc7bf6609e882092ded278956f58852a981 /src/codec/SkBmpRLECodec.cpp | |
parent | eea7c16d59a163bd5b858891bc916c49063ed8ac (diff) |
Add F16, SkColorSpaceXform support to SkBmpCodec
BUG=skia:4895
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4300
Change-Id: I2f2b8d3854ea3a8c5904dd3c5bea0342e2be9789
Reviewed-on: https://skia-review.googlesource.com/4300
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src/codec/SkBmpRLECodec.cpp')
-rw-r--r-- | src/codec/SkBmpRLECodec.cpp | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp index 33ba851ec6..e502fe879f 100644 --- a/src/codec/SkBmpRLECodec.cpp +++ b/src/codec/SkBmpRLECodec.cpp @@ -44,10 +44,6 @@ SkCodec::Result SkBmpRLECodec::onGetPixels(const SkImageInfo& dstInfo, // Subsets are not supported. return kUnimplemented; } - if (!conversion_possible_ignore_color_space(dstInfo, this->getInfo())) { - SkCodecPrintf("Error: cannot convert input type to output type.\n"); - return kInvalidConversion; - } Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount); if (kSuccess != result) { @@ -267,7 +263,7 @@ void SkBmpRLECodec::setRGBPixel(void* dst, size_t dstRowBytes, } } -SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, +SkCodec::Result SkBmpRLECodec::onPrepareToDecode(const SkImageInfo& dstInfo, const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) { // FIXME: Support subsets for scanline decodes. if (options.fSubset) { @@ -306,39 +302,75 @@ SkCodec::Result SkBmpRLECodec::prepareToDecode(const SkImageInfo& dstInfo, */ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowBytes, const Options& opts) { - // Set RLE flags - static const uint8_t RLE_ESCAPE = 0; - static const uint8_t RLE_EOL = 0; - static const uint8_t RLE_EOF = 1; - static const uint8_t RLE_DELTA = 2; - const int width = this->getInfo().width(); int height = info.height(); - // Account for sampling. - SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), height); - - // Set the background as transparent. Then, if the RLE code skips pixels, - // the skipped pixels will be transparent. - // Because of the need for transparent pixels, kN32 is the only color - // type that makes sense for the destination format. - SkASSERT(kRGBA_8888_SkColorType == dstInfo.colorType() || - kBGRA_8888_SkColorType == dstInfo.colorType()); - if (dst) { - SkSampler::Fill(dstInfo, dst, dstRowBytes, SK_ColorTRANSPARENT, opts.fZeroInitialized); - } - // Adjust the height and the dst if the previous call to decodeRows() left us // with lines that need to be skipped. if (height > fLinesToSkip) { height -= fLinesToSkip; - dst = SkTAddOffset<void>(dst, fLinesToSkip * dstRowBytes); + if (dst) { + dst = SkTAddOffset<void>(dst, fLinesToSkip * dstRowBytes); + } fLinesToSkip = 0; } else { fLinesToSkip -= height; return height; } + // Account for sampling. + SkImageInfo dstInfo = info.makeWH(get_scaled_dimension(width, fSampleX), height); + + void* decodeDst = dst; + size_t decodeRowBytes = dstRowBytes; + SkImageInfo decodeInfo = dstInfo; + if (decodeDst) { + SkCodec::ZeroInitialized zeroInit = opts.fZeroInitialized; + if (this->colorXform()) { + decodeInfo = decodeInfo.makeColorType(kBGRA_8888_SkColorType); + if (kRGBA_F16_SkColorType == dstInfo.colorType()) { + int count = height * dstInfo.width(); + this->resetXformBuffer(count); + decodeDst = this->xformBuffer(); + decodeRowBytes = dstInfo.width() * sizeof(uint32_t); + zeroInit = SkCodec::kNo_ZeroInitialized; + } + } + + // Set the background as transparent. Then, if the RLE code skips pixels, + // the skipped pixels will be transparent. + // Because of the need for transparent pixels, kN32 is the only color + // type that makes sense for the destination format. + SkASSERT(kRGBA_8888_SkColorType == decodeInfo.colorType() || + kBGRA_8888_SkColorType == decodeInfo.colorType()); + SkSampler::Fill(decodeInfo, decodeDst, decodeRowBytes, SK_ColorTRANSPARENT, zeroInit); + } + + int decodedHeight = this->decodeRLE(decodeInfo, decodeDst, decodeRowBytes); + if (this->colorXform() && decodeDst) { + for (int y = 0; y < decodedHeight; y++) { + this->applyColorXform(dstInfo, dst, decodeDst); + decodeDst = SkTAddOffset<void>(decodeDst, decodeRowBytes); + dst = SkTAddOffset<void>(dst, dstRowBytes); + } + } + + return decodedHeight; +} + +int SkBmpRLECodec::decodeRLE(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes) { + // Use the original width to count the number of pixels in each row. + const int width = this->getInfo().width(); + + // This tells us the number of rows that we are meant to decode. + const int height = dstInfo.height(); + + // Set RLE flags + static const uint8_t RLE_ESCAPE = 0; + static const uint8_t RLE_EOL = 0; + static const uint8_t RLE_EOF = 1; + static const uint8_t RLE_DELTA = 2; + // Destination parameters int x = 0; int y = 0; |