aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--infra/bots/assets/skimage/VERSION2
-rw-r--r--infra/bots/tasks.json8
-rw-r--r--src/codec/SkBmpCodec.cpp23
-rw-r--r--src/codec/SkBmpCodec.h16
-rw-r--r--src/codec/SkBmpMaskCodec.cpp30
-rw-r--r--src/codec/SkBmpMaskCodec.h2
-rw-r--r--src/codec/SkBmpRLECodec.cpp82
-rw-r--r--src/codec/SkBmpRLECodec.h3
-rw-r--r--src/codec/SkBmpStandardCodec.cpp43
-rw-r--r--src/codec/SkBmpStandardCodec.h2
-rw-r--r--src/codec/SkMaskSwizzler.h7
11 files changed, 158 insertions, 60 deletions
diff --git a/infra/bots/assets/skimage/VERSION b/infra/bots/assets/skimage/VERSION
index f11c82a4cb..9a037142aa 100644
--- a/infra/bots/assets/skimage/VERSION
+++ b/infra/bots/assets/skimage/VERSION
@@ -1 +1 @@
-9 \ No newline at end of file
+10 \ No newline at end of file
diff --git a/infra/bots/tasks.json b/infra/bots/tasks.json
index 83cd4e83ea..0f4f3162cb 100644
--- a/infra/bots/tasks.json
+++ b/infra/bots/tasks.json
@@ -172,7 +172,7 @@
{
"name": "skia/bots/skimage",
"path": "skimage",
- "version": "version:9"
+ "version": "version:10"
},
{
"name": "skia/bots/skp",
@@ -219,7 +219,7 @@
{
"name": "skia/bots/skimage",
"path": "skimage",
- "version": "version:9"
+ "version": "version:10"
},
{
"name": "skia/bots/skp",
@@ -265,7 +265,7 @@
{
"name": "skia/bots/skimage",
"path": "skimage",
- "version": "version:9"
+ "version": "version:10"
},
{
"name": "skia/bots/skp",
@@ -398,4 +398,4 @@
"priority": 0.8
}
}
-} \ No newline at end of file
+}
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index b0ef8ad1d8..d99ba3ae43 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -587,6 +587,7 @@ SkBmpCodec::SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStrea
, fBitsPerPixel(bitsPerPixel)
, fRowOrder(rowOrder)
, fSrcRowBytes(SkAlign4(compute_row_bytes(width, fBitsPerPixel)))
+ , fXformBuffer(nullptr)
{}
bool SkBmpCodec::onRewind() {
@@ -601,13 +602,17 @@ int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
return height - y - 1;
}
-SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
+SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
- if (!conversion_possible_ignore_color_space(dstInfo, this->getInfo())) {
- SkCodecPrintf("Error: cannot convert input type to output type.\n");
+ if (!conversion_possible(dstInfo, this->getInfo()) || !this->initializeColorXform(dstInfo)) {
return kInvalidConversion;
}
+ return this->onPrepareToDecode(dstInfo, options, inputColorPtr, inputColorCount);
+}
+
+SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
+ const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
return prepareToDecode(dstInfo, options, inputColorPtr, inputColorCount);
}
@@ -627,3 +632,15 @@ bool SkBmpCodec::skipRows(int count) {
bool SkBmpCodec::onSkipScanlines(int count) {
return this->skipRows(count);
}
+
+void SkBmpCodec::applyColorXform(const SkImageInfo& dstInfo, void* dst, void* src) const {
+ SkColorSpaceXform* xform = this->colorXform();
+ if (xform) {
+ SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
+ SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kBGRA_8888_ColorFormat;
+ SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
+ this->getInfo().alphaType());
+ SkAssertResult(xform->apply(dstFormat, dst, srcFormat, src, dstInfo.width(),
+ alphaType));
+ }
+}
diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h
index 0ece7ad6ce..a51bbcecc3 100644
--- a/src/codec/SkBmpCodec.h
+++ b/src/codec/SkBmpCodec.h
@@ -99,9 +99,16 @@ protected:
* will be set to the number of colors in the
* color table.
*/
- virtual SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
+ virtual SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[],
int* inputColorCount) = 0;
+ SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
+ const SkCodec::Options& options, SkPMColor inputColorPtr[],
+ int* inputColorCount);
+
+ void applyColorXform(const SkImageInfo& dstInfo, void* dst, void* src) const;
+ uint32_t* xformBuffer() const { return fXformBuffer.get(); }
+ void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); }
private:
@@ -138,9 +145,10 @@ private:
bool onSkipScanlines(int count) override;
- const uint16_t fBitsPerPixel;
- const SkScanlineOrder fRowOrder;
- const size_t fSrcRowBytes;
+ const uint16_t fBitsPerPixel;
+ const SkScanlineOrder fRowOrder;
+ const size_t fSrcRowBytes;
+ std::unique_ptr<uint32_t[]> fXformBuffer;
typedef SkCodec INHERITED;
};
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index 5b28252f7c..68f31b29e1 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -39,11 +39,6 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
return kInvalidScale;
}
- 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) {
return result;
@@ -57,10 +52,22 @@ SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
return kSuccess;
}
-SkCodec::Result SkBmpMaskCodec::prepareToDecode(const SkImageInfo& dstInfo,
+SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
+ if (this->colorXform()) {
+ this->resetXformBuffer(dstInfo.width());
+ }
+
+ SkImageInfo swizzlerInfo = dstInfo;
+ if (this->colorXform()) {
+ swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
+ if (kPremul_SkAlphaType == dstInfo.alphaType()) {
+ swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
+ }
+ }
+
// Initialize the mask swizzler
- fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(dstInfo, this->getInfo(), fMasks,
+ fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(swizzlerInfo, this->getInfo(), fMasks,
this->bitsPerPixel(), options));
SkASSERT(fMaskSwizzler);
@@ -86,7 +93,14 @@ int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
// Decode the row in destination format
uint32_t row = this->getDstRow(y, height);
void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
- fMaskSwizzler->swizzle(dstRow, srcRow);
+
+ if (this->colorXform()) {
+ SkImageInfo xformInfo = dstInfo.makeWH(fMaskSwizzler->swizzleWidth(), dstInfo.height());
+ fMaskSwizzler->swizzle(this->xformBuffer(), srcRow);
+ this->applyColorXform(xformInfo, dstRow, this->xformBuffer());
+ } else {
+ fMaskSwizzler->swizzle(dstRow, srcRow);
+ }
}
// Finished decoding the entire image
diff --git a/src/codec/SkBmpMaskCodec.h b/src/codec/SkBmpMaskCodec.h
index 4cfd4d2531..21c8db05ec 100644
--- a/src/codec/SkBmpMaskCodec.h
+++ b/src/codec/SkBmpMaskCodec.h
@@ -38,7 +38,7 @@ protected:
size_t dstRowBytes, const Options&, SkPMColor*,
int*, int*) override;
- SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
+ SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[],
int* inputColorCount) override;
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;
diff --git a/src/codec/SkBmpRLECodec.h b/src/codec/SkBmpRLECodec.h
index 1291e9f617..c2459c0b22 100644
--- a/src/codec/SkBmpRLECodec.h
+++ b/src/codec/SkBmpRLECodec.h
@@ -48,7 +48,7 @@ protected:
size_t dstRowBytes, const Options&, SkPMColor*,
int*, int*) override;
- SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
+ SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[],
int* inputColorCount) override;
@@ -89,6 +89,7 @@ private:
*/
int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
const Options& opts) override;
+ int decodeRLE(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes);
bool skipRows(int count) override;
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 2dbb338a07..2a703fdff9 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -48,10 +48,6 @@ SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
SkCodecPrintf("Error: scaling not supported.\n");
return kInvalidScale;
}
- 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) {
@@ -153,13 +149,13 @@ void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Op
// In the case of bmp-in-icos, we will report BGRA to the client,
// since we may be required to apply an alpha mask after the decode.
// However, the swizzler needs to know the actual format of the bmp.
- SkEncodedInfo swizzlerInfo = this->getEncodedInfo();
+ SkEncodedInfo encodedInfo = this->getEncodedInfo();
if (fInIco) {
if (this->bitsPerPixel() <= 8) {
- swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color,
- swizzlerInfo.alpha(), this->bitsPerPixel());
+ encodedInfo = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color,
+ encodedInfo.alpha(), this->bitsPerPixel());
} else if (this->bitsPerPixel() == 24) {
- swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kBGR_Color,
+ encodedInfo = SkEncodedInfo::Make(SkEncodedInfo::kBGR_Color,
SkEncodedInfo::kOpaque_Alpha, 8);
}
}
@@ -167,13 +163,29 @@ void SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Op
// Get a pointer to the color table if it exists
const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
- // Create swizzler
- fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, colorPtr, dstInfo, opts));
+ SkImageInfo swizzlerInfo = dstInfo;
+ SkCodec::Options swizzlerOptions = opts;
+ if (this->colorXform()) {
+ swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
+ if (kPremul_SkAlphaType == dstInfo.alphaType()) {
+ swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
+ }
+
+ swizzlerOptions.fZeroInitialized = kNo_ZeroInitialized;
+ }
+
+
+ fSwizzler.reset(SkSwizzler::CreateSwizzler(encodedInfo, colorPtr, swizzlerInfo,
+ swizzlerOptions));
SkASSERT(fSwizzler);
}
-SkCodec::Result SkBmpStandardCodec::prepareToDecode(const SkImageInfo& dstInfo,
+SkCodec::Result SkBmpStandardCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
+ if (this->colorXform()) {
+ this->resetXformBuffer(dstInfo.width());
+ }
+
// Create the color table if necessary and prepare the stream for decode
// Note that if it is non-NULL, inputColorCount will be modified
if (!this->createColorTable(dstInfo.colorType(), dstInfo.alphaType(), inputColorCount)) {
@@ -207,7 +219,14 @@ int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
uint32_t row = this->getDstRow(y, dstInfo.height());
void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
- fSwizzler->swizzle(dstRow, fSrcBuffer.get());
+
+ if (this->colorXform()) {
+ SkImageInfo xformInfo = dstInfo.makeWH(fSwizzler->swizzleWidth(), dstInfo.height());
+ fSwizzler->swizzle(this->xformBuffer(), fSrcBuffer.get());
+ this->applyColorXform(xformInfo, dstRow, this->xformBuffer());
+ } else {
+ fSwizzler->swizzle(dstRow, fSrcBuffer.get());
+ }
}
if (fInIco && fIsOpaque) {
diff --git a/src/codec/SkBmpStandardCodec.h b/src/codec/SkBmpStandardCodec.h
index edb88acd0c..06730a6b6a 100644
--- a/src/codec/SkBmpStandardCodec.h
+++ b/src/codec/SkBmpStandardCodec.h
@@ -52,7 +52,7 @@ protected:
return fInIco;
}
- SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
+ SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
const SkCodec::Options& options, SkPMColor inputColorPtr[],
int* inputColorCount) override;
diff --git a/src/codec/SkMaskSwizzler.h b/src/codec/SkMaskSwizzler.h
index 3bf8d1758f..5d2955caab 100644
--- a/src/codec/SkMaskSwizzler.h
+++ b/src/codec/SkMaskSwizzler.h
@@ -45,6 +45,13 @@ public:
SkSampler::Fill(fillInfo, dst, rowBytes, colorOrIndex, zeroInit);
}
+ /**
+ * Returns the byte offset at which we write to destination memory, taking
+ * scaling, subsetting, and partial frames into account.
+ * A similar function exists on SkSwizzler.
+ */
+ int swizzleWidth() const { return fDstWidth; }
+
private:
/*