aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkBmpRLECodec.cpp
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2016-11-02 16:18:01 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-03 16:33:33 +0000
commitd851795e7992565c1eb2b9474ee5ad01d1a01fad (patch)
treea7293bc7bf6609e882092ded278956f58852a981 /src/codec/SkBmpRLECodec.cpp
parenteea7c16d59a163bd5b858891bc916c49063ed8ac (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.cpp82
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;