aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkBmpRLECodec.cpp
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2016-11-03 16:15:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-03 20:58:13 +0000
commit1b96c6f91377431cd407c43fedac613fff21c2ed (patch)
tree0a4d5899f2cae7573aa85d56866ad7613338b6f2 /src/codec/SkBmpRLECodec.cpp
parent6e437b7d177cabdb9822b437ed2caefebe6b469b (diff)
Add F16, SkColorSpaceXform support to SkBmpCodec
BUG=skia:4895 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4390 Change-Id: I9cb727e7f13816b0ac882f62ec635a4528c3a524 Reviewed-on: https://skia-review.googlesource.com/4390 Reviewed-by: Matt Sarett <msarett@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src/codec/SkBmpRLECodec.cpp')
-rw-r--r--src/codec/SkBmpRLECodec.cpp63
1 files changed, 47 insertions, 16 deletions
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 6e7bac9c6d..85b965e611 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,12 +302,6 @@ 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();
@@ -320,10 +310,6 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
// 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);
}
@@ -332,13 +318,58 @@ int SkBmpRLECodec::decodeRows(const SkImageInfo& info, void* dst, size_t dstRowB
// 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;
+
+ dstInfo = dstInfo.makeWH(dstInfo.width(), height);
} else {
fLinesToSkip -= height;
return height;
}
+ void* decodeDst = dst;
+ size_t decodeRowBytes = dstRowBytes;
+ SkImageInfo decodeInfo = dstInfo;
+ if (decodeDst) {
+ if (this->colorXform()) {
+ decodeInfo = decodeInfo.makeColorType(kBGRA_8888_SkColorType);
+ if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
+ int count = height * dstInfo.width();
+ this->resetXformBuffer(count);
+ sk_bzero(this->xformBuffer(), count * sizeof(uint32_t));
+ decodeDst = this->xformBuffer();
+ decodeRowBytes = dstInfo.width() * sizeof(uint32_t);
+ }
+ }
+ }
+
+ 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;