aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-04-18 16:20:00 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-18 16:20:00 -0700
commitf682d9ad70d690a343bc15e26ef321d86770be41 (patch)
treed060890436619e2f3a03789400ed8276f421e5ce
parentbde57ed11b8a6bd6da6043189e000c58bf146422 (diff)
Add SkEncodedInfo to report properties of encoded image data
All this does is build an SkEncodedInfo for each codec, and then convert it to an SkImageInfo. In future steps I intend to: (1) Use SkEncodedInfo in place of SrcConfig in SkSwizzler. (2) Support more conversions in SkSwizzler (non-native BGRA/RGBA, 16-bit components, float, fixed point) (3) Investigate optimizing conversions from encoded data to linear color spaces. BUG=skia:4133 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1820073002 Review URL: https://codereview.chromium.org/1820073002
-rw-r--r--include/codec/SkCodec.h8
-rw-r--r--include/codec/SkEncodedInfo.h178
-rw-r--r--src/codec/SkBmpCodec.cpp82
-rw-r--r--src/codec/SkBmpCodec.h4
-rw-r--r--src/codec/SkBmpMaskCodec.cpp4
-rw-r--r--src/codec/SkBmpMaskCodec.h4
-rw-r--r--src/codec/SkBmpRLECodec.cpp4
-rw-r--r--src/codec/SkBmpRLECodec.h4
-rw-r--r--src/codec/SkBmpStandardCodec.cpp6
-rw-r--r--src/codec/SkBmpStandardCodec.h4
-rw-r--r--src/codec/SkCodec.cpp7
-rw-r--r--src/codec/SkGifCodec.cpp30
-rw-r--r--src/codec/SkGifCodec.h6
-rw-r--r--src/codec/SkIcoCodec.cpp10
-rw-r--r--src/codec/SkIcoCodec.h3
-rw-r--r--src/codec/SkJpegCodec.cpp17
-rw-r--r--src/codec/SkJpegCodec.h6
-rw-r--r--src/codec/SkJpegDecoderMgr.cpp14
-rw-r--r--src/codec/SkJpegDecoderMgr.h5
-rw-r--r--src/codec/SkPngCodec.cpp102
-rw-r--r--src/codec/SkPngCodec.h4
-rw-r--r--src/codec/SkRawCodec.cpp25
-rw-r--r--src/codec/SkWbmpCodec.cpp10
-rw-r--r--src/codec/SkWbmpCodec.h2
-rw-r--r--src/codec/SkWebpCodec.cpp59
-rw-r--r--src/codec/SkWebpCodec.h2
26 files changed, 434 insertions, 166 deletions
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index 629274d21c..50875e46c4 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -11,6 +11,7 @@
#include "../private/SkTemplates.h"
#include "SkColor.h"
#include "SkEncodedFormat.h"
+#include "SkEncodedInfo.h"
#include "SkImageInfo.h"
#include "SkSize.h"
#include "SkStream.h"
@@ -100,6 +101,8 @@ public:
*/
const SkImageInfo& getInfo() const { return fSrcInfo; }
+ const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
+
/**
* Returns the color space associated with the codec.
* Does not affect ownership.
@@ -511,7 +514,9 @@ protected:
/**
* Takes ownership of SkStream*
*/
- SkCodec(const SkImageInfo&,
+ SkCodec(int width,
+ int height,
+ const SkEncodedInfo&,
SkStream*,
sk_sp<SkColorSpace> = nullptr,
Origin = kTopLeft_Origin);
@@ -642,6 +647,7 @@ protected:
virtual int onOutputScanline(int inputScanline) const;
private:
+ const SkEncodedInfo fEncodedInfo;
const SkImageInfo fSrcInfo;
SkAutoTDelete<SkStream> fStream;
bool fNeedsRewind;
diff --git a/include/codec/SkEncodedInfo.h b/include/codec/SkEncodedInfo.h
new file mode 100644
index 0000000000..f91660529e
--- /dev/null
+++ b/include/codec/SkEncodedInfo.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkEncodedInfo_DEFINED
+#define SkEncodedInfo_DEFINED
+
+#include "SkImageInfo.h"
+
+struct SkEncodedInfo {
+public:
+
+ enum Alpha {
+ kOpaque_Alpha,
+ kUnpremul_Alpha,
+
+ // Each pixel is either fully opaque or fully transparent.
+ // There is no difference between requesting kPremul or kUnpremul.
+ kBinary_Alpha,
+
+ // Allows us to have a default constructor. Should be treated as
+ // invalid.
+ kUnknown_Alpha,
+ };
+
+ /*
+ * We strive to make the number of components per pixel obvious through
+ * our naming conventions.
+ * Ex: kRGB has 3 components. kRGBA has 4 components.
+ *
+ * This sometimes results in redundant Alpha and Color information.
+ * Ex: kRGB images must also be kOpaque.
+ */
+ enum Color {
+ // PNG, WBMP
+ kGray_Color,
+
+ // PNG
+ kGrayAlpha_Color,
+
+ // PNG, GIF, BMP
+ kPalette_Color,
+
+ // PNG, RAW
+ kRGB_Color,
+ kRGBA_Color,
+
+ // BMP
+ kBGR_Color,
+ kBGRX_Color,
+ kBGRA_Color,
+
+ // JPEG, WEBP
+ kYUV_Color,
+
+ // WEBP
+ kYUVA_Color,
+
+ // JPEG
+ // Photoshop actually writes inverted CMYK data into JPEGs, where zero
+ // represents 100% ink coverage. For this reason, we treat CMYK JPEGs
+ // as having inverted CMYK. libjpeg-turbo warns that this may break
+ // other applications, but the CMYK JPEGs we see on the web expect to
+ // be treated as inverted CMYK.
+ kInvertedCMYK_Color,
+ kYCCK_Color,
+
+ // Allows us to have a default constructor. Should be treated as
+ // invalid.
+ kUnknown_Color,
+ };
+
+ static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) {
+ SkASSERT(1 == bitsPerComponent ||
+ 2 == bitsPerComponent ||
+ 4 == bitsPerComponent ||
+ 8 == bitsPerComponent ||
+ 16 == bitsPerComponent);
+
+ switch (color) {
+ case kGray_Color:
+ SkASSERT(kOpaque_Alpha == alpha);
+ break;
+ case kGrayAlpha_Color:
+ SkASSERT(kOpaque_Alpha != alpha);
+ break;
+ case kPalette_Color:
+ SkASSERT(16 != bitsPerComponent);
+ break;
+ case kRGB_Color:
+ case kBGR_Color:
+ case kBGRX_Color:
+ SkASSERT(kOpaque_Alpha == alpha);
+ SkASSERT(bitsPerComponent >= 8);
+ break;
+ case kYUV_Color:
+ case kInvertedCMYK_Color:
+ case kYCCK_Color:
+ SkASSERT(kOpaque_Alpha == alpha);
+ SkASSERT(8 == bitsPerComponent);
+ break;
+ case kRGBA_Color:
+ SkASSERT(kOpaque_Alpha != alpha);
+ SkASSERT(bitsPerComponent >= 8);
+ break;
+ case kBGRA_Color:
+ case kYUVA_Color:
+ SkASSERT(kOpaque_Alpha != alpha);
+ SkASSERT(8 == bitsPerComponent);
+ break;
+ default:
+ SkASSERT(false);
+ break;
+ }
+
+ return SkEncodedInfo(color, alpha, bitsPerComponent);
+ }
+
+ /*
+ * Returns an SkImageInfo with Skia color and alpha types that are the
+ * closest possible match to the encoded info.
+ */
+ SkImageInfo makeImageInfo(int width, int height) const {
+ switch (fColor) {
+ case kGray_Color:
+ SkASSERT(kOpaque_Alpha == fAlpha);
+ return SkImageInfo::Make(width, height, kGray_8_SkColorType, kOpaque_SkAlphaType);
+ case kGrayAlpha_Color:
+ SkASSERT(kOpaque_Alpha != fAlpha);
+ return SkImageInfo::Make(width, height, kN32_SkColorType,
+ kUnpremul_SkAlphaType);
+ case kPalette_Color: {
+ SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType :
+ kUnpremul_SkAlphaType;
+ return SkImageInfo::Make(width, height, kIndex_8_SkColorType, alphaType);
+ }
+ case kRGB_Color:
+ case kBGR_Color:
+ case kBGRX_Color:
+ case kYUV_Color:
+ case kInvertedCMYK_Color:
+ case kYCCK_Color:
+ SkASSERT(kOpaque_Alpha == fAlpha);
+ return SkImageInfo::Make(width, height, kN32_SkColorType, kOpaque_SkAlphaType);
+ case kRGBA_Color:
+ case kBGRA_Color:
+ case kYUVA_Color:
+ SkASSERT(kOpaque_Alpha != fAlpha);
+ return SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
+ default:
+ SkASSERT(false);
+ return SkImageInfo::MakeUnknown();
+ }
+ }
+
+ SkEncodedInfo()
+ : fColor(kUnknown_Color)
+ , fAlpha(kUnknown_Alpha)
+ , fBitsPerComponent(0)
+ {}
+
+private:
+
+ SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent)
+ : fColor(color)
+ , fAlpha(alpha)
+ , fBitsPerComponent(bitsPerComponent)
+ {}
+
+ Color fColor;
+ Alpha fAlpha;
+ uint8_t fBitsPerComponent;
+};
+
+#endif
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index ad6f0ddc4d..680436ab91 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -415,33 +415,47 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco, SkCodec** codecOut) {
switch (inputFormat) {
case kStandard_BmpInputFormat: {
- // BMPs-in-ICOs often contain an alpha mask after the image, which
- // means we cannot guarantee that an image is opaque, even if the
- // embedded bmp is opaque.
- // We use |isOpaque| to indicate if the BMP itself is opaque, but
- // still need to recommend kUnpremul when it is contained in an ICO.
- SkColorType colorType = kN32_SkColorType;
- SkAlphaType alphaType = inIco ? kUnpremul_SkAlphaType : kOpaque_SkAlphaType;
+ // BMPs are generally opaque, however BMPs-in-ICOs may contain
+ // a transparency mask after the image. Therefore, we mark the
+ // alpha as kBinary if the BMP is contained in an ICO.
+ // We use |isOpaque| to indicate if the BMP itself is opaque.
+ SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
+ SkEncodedInfo::kOpaque_Alpha;
bool isOpaque = true;
+
+ SkEncodedInfo::Color color;
+ uint8_t bitsPerComponent;
switch (bitsPerPixel) {
// Palette formats
case 1:
case 2:
case 4:
case 8:
- // We cannot recommend a palette color type for ICOs because they
- // may contain a transparency mask.
- if (!inIco) {
- colorType = kIndex_8_SkColorType;
+ // In the case of ICO, kBGRA is actually the closest match,
+ // since we will need to apply a transparency mask.
+ if (inIco) {
+ color = SkEncodedInfo::kBGRA_Color;
+ bitsPerComponent = 8;
+ } else {
+ color = SkEncodedInfo::kPalette_Color;
+ bitsPerComponent = (uint8_t) bitsPerPixel;
}
break;
case 24:
+ color = SkEncodedInfo::kBGR_Color;
+ bitsPerComponent = 8;
+ break;
case 32:
// 32-bit BMP-in-ICOs actually use the alpha channel in place of a
// transparency mask.
if (inIco) {
isOpaque = false;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
+ color = SkEncodedInfo::kBGRA_Color;
+ } else {
+ color = SkEncodedInfo::kBGRX_Color;
}
+ bitsPerComponent = 8;
break;
default:
SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
@@ -453,11 +467,9 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco, SkCodec** codecOut) {
SkASSERT(!inIco || nullptr != stream->getMemoryBase());
// Set the image info and create a codec.
- const SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType,
- alphaType);
- *codecOut = new SkBmpStandardCodec(imageInfo, stream, bitsPerPixel, numColors,
- bytesPerColor, offset - bytesRead, rowOrder, isOpaque, inIco);
-
+ const SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, bitsPerComponent);
+ *codecOut = new SkBmpStandardCodec(width, height, info, stream, bitsPerPixel,
+ numColors, bytesPerColor, offset - bytesRead, rowOrder, isOpaque, inIco);
}
return true;
}
@@ -495,13 +507,22 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco, SkCodec** codecOut) {
return false;
}
- // Set the image info
- SkAlphaType alphaType = masks->getAlphaMask() ? kUnpremul_SkAlphaType :
- kOpaque_SkAlphaType;
- const SkImageInfo imageInfo = SkImageInfo::Make(width, height, kN32_SkColorType,
- alphaType);
- *codecOut = new SkBmpMaskCodec(imageInfo, stream, bitsPerPixel, masks.release(),
- rowOrder);
+ // Masked bmps are not a great fit for SkEncodedInfo, since they have
+ // arbitrary component orderings and bits per component. Here we choose
+ // somewhat reasonable values - it's ok that we don't match exactly
+ // because SkBmpMaskCodec has its own mask swizzler anyway.
+ SkEncodedInfo::Color color;
+ SkEncodedInfo::Alpha alpha;
+ if (masks->getAlphaMask()) {
+ color = SkEncodedInfo::kBGRA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
+ } else {
+ color = SkEncodedInfo::kBGR_Color;
+ alpha = SkEncodedInfo::kOpaque_Alpha;
+ }
+ const SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8);
+ *codecOut = new SkBmpMaskCodec(width, height, info, stream, bitsPerPixel,
+ masks.release(), rowOrder);
}
return true;
}
@@ -526,10 +547,11 @@ bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco, SkCodec** codecOut) {
if (codecOut) {
// RLE inputs may skip pixels, leaving them as transparent. This
// is uncommon, but we cannot be certain that an RLE bmp will be
- // opaque.
- const SkImageInfo imageInfo = SkImageInfo::Make(width, height, kN32_SkColorType,
- kUnpremul_SkAlphaType);
- *codecOut = new SkBmpRLECodec(imageInfo, stream, bitsPerPixel, numColors,
+ // opaque or that we will be able to represent it with a palette.
+ // For that reason, we always indicate that we are kBGRA.
+ const SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kBGRA_Color,
+ SkEncodedInfo::kBinary_Alpha, 8);
+ *codecOut = new SkBmpRLECodec(width, height, info, stream, bitsPerPixel, numColors,
bytesPerColor, offset - bytesRead, rowOrder, RLEBytes);
}
return true;
@@ -557,12 +579,12 @@ SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool inIco) {
return nullptr;
}
-SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
+SkBmpCodec::SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder)
- : INHERITED(info, stream)
+ : INHERITED(width, height, info, stream)
, fBitsPerPixel(bitsPerPixel)
, fRowOrder(rowOrder)
- , fSrcRowBytes(SkAlign4(compute_row_bytes(info.width(), fBitsPerPixel)))
+ , fSrcRowBytes(SkAlign4(compute_row_bytes(width, fBitsPerPixel)))
{}
bool SkBmpCodec::onRewind() {
diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h
index a7e8e58431..0ece7ad6ce 100644
--- a/src/codec/SkBmpCodec.h
+++ b/src/codec/SkBmpCodec.h
@@ -38,8 +38,8 @@ public:
protected:
- SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel,
- SkCodec::SkScanlineOrder rowOrder);
+ SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder);
SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index 21d231b15f..7d2d398bb4 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -12,10 +12,10 @@
/*
* Creates an instance of the decoder
*/
-SkBmpMaskCodec::SkBmpMaskCodec(const SkImageInfo& info, SkStream* stream,
+SkBmpMaskCodec::SkBmpMaskCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, SkMasks* masks,
SkCodec::SkScanlineOrder rowOrder)
- : INHERITED(info, stream, bitsPerPixel, rowOrder)
+ : INHERITED(width, height, info, stream, bitsPerPixel, rowOrder)
, fMasks(masks)
, fMaskSwizzler(nullptr)
, fSrcBuffer(new uint8_t [this->srcRowBytes()])
diff --git a/src/codec/SkBmpMaskCodec.h b/src/codec/SkBmpMaskCodec.h
index 93b3bca5a0..cc8af856e8 100644
--- a/src/codec/SkBmpMaskCodec.h
+++ b/src/codec/SkBmpMaskCodec.h
@@ -22,13 +22,13 @@ public:
* Called only by SkBmpCodec::NewFromStream
* There should be no other callers despite this being public
*
- * @param srcInfo contains the source width and height
+ * @param info contains properties of the encoded data
* @param stream the stream of encoded image data
* @param bitsPerPixel the number of bits used to store each pixel
* @param masks color masks for certain bmp formats
* @param rowOrder indicates whether rows are ordered top-down or bottom-up
*/
- SkBmpMaskCodec(const SkImageInfo& srcInfo, SkStream* stream,
+ SkBmpMaskCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, SkMasks* masks,
SkCodec::SkScanlineOrder rowOrder);
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 793bbfd260..d80dd1a18a 100644
--- a/src/codec/SkBmpRLECodec.cpp
+++ b/src/codec/SkBmpRLECodec.cpp
@@ -14,12 +14,12 @@
* Creates an instance of the decoder
* Called only by NewFromStream
*/
-SkBmpRLECodec::SkBmpRLECodec(const SkImageInfo& info, SkStream* stream,
+SkBmpRLECodec::SkBmpRLECodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, uint32_t numColors,
uint32_t bytesPerColor, uint32_t offset,
SkCodec::SkScanlineOrder rowOrder,
size_t RLEBytes)
- : INHERITED(info, stream, bitsPerPixel, rowOrder)
+ : INHERITED(width, height, info, stream, bitsPerPixel, rowOrder)
, fColorTable(nullptr)
, fNumColors(numColors)
, fBytesPerColor(bytesPerColor)
diff --git a/src/codec/SkBmpRLECodec.h b/src/codec/SkBmpRLECodec.h
index 2ddf8d8b90..e0afccd927 100644
--- a/src/codec/SkBmpRLECodec.h
+++ b/src/codec/SkBmpRLECodec.h
@@ -23,7 +23,7 @@ public:
* Called only by SkBmpCodec::NewFromStream
* There should be no other callers despite this being public
*
- * @param srcInfo contains the source width and height
+ * @param info contains properties of the encoded data
* @param stream the stream of encoded image data
* @param bitsPerPixel the number of bits used to store each pixel
* @param numColors the number of colors in the color table
@@ -35,7 +35,7 @@ public:
* @param RLEBytes indicates the amount of data left in the stream
* after decoding the headers
*/
- SkBmpRLECodec(const SkImageInfo& srcInfo, SkStream* stream,
+ SkBmpRLECodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor,
uint32_t offset, SkCodec::SkScanlineOrder rowOrder,
size_t RLEBytes);
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 80a989ae4d..a509c75b6d 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -14,12 +14,12 @@
* Creates an instance of the decoder
* Called only by NewFromStream
*/
-SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream,
- uint16_t bitsPerPixel, uint32_t numColors,
+SkBmpStandardCodec::SkBmpStandardCodec(int width, int height, const SkEncodedInfo& info,
+ SkStream* stream, uint16_t bitsPerPixel, uint32_t numColors,
uint32_t bytesPerColor, uint32_t offset,
SkCodec::SkScanlineOrder rowOrder,
bool isOpaque, bool inIco)
- : INHERITED(info, stream, bitsPerPixel, rowOrder)
+ : INHERITED(width, height, info, stream, bitsPerPixel, rowOrder)
, fColorTable(nullptr)
, fNumColors(numColors)
, fBytesPerColor(bytesPerColor)
diff --git a/src/codec/SkBmpStandardCodec.h b/src/codec/SkBmpStandardCodec.h
index 557f6535c9..b2b53df6c8 100644
--- a/src/codec/SkBmpStandardCodec.h
+++ b/src/codec/SkBmpStandardCodec.h
@@ -24,7 +24,7 @@ public:
* Called only by SkBmpCodec::NewFromStream
* There should be no other callers despite this being public
*
- * @param srcInfo contains the source width and height
+ * @param info contains properties of the encoded data
* @param stream the stream of encoded image data
* @param bitsPerPixel the number of bits used to store each pixel
* @param numColors the number of colors in the color table
@@ -37,7 +37,7 @@ public:
* the icp mask, if there is one)
* @param inIco indicates if the bmp is embedded in an ico file
*/
- SkBmpStandardCodec(const SkImageInfo& srcInfo, SkStream* stream,
+ SkBmpStandardCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor,
uint32_t offset, SkCodec::SkScanlineOrder rowOrder, bool isOpaque,
bool inIco);
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index 7bc831a6ac..8468f8a099 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -114,9 +114,10 @@ SkCodec* SkCodec::NewFromData(SkData* data, SkPngChunkReader* reader) {
return NewFromStream(new SkMemoryStream(data), reader);
}
-SkCodec::SkCodec(const SkImageInfo& info, SkStream* stream, sk_sp<SkColorSpace> colorSpace,
- Origin origin)
- : fSrcInfo(info)
+SkCodec::SkCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ sk_sp<SkColorSpace> colorSpace, Origin origin)
+ : fEncodedInfo(info)
+ , fSrcInfo(info.makeImageInfo(width, height))
, fStream(stream)
, fNeedsRewind(false)
, fColorSpace(colorSpace)
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index 2233c66c19..cdd9d088f1 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -199,25 +199,23 @@ bool SkGifCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType**
}
bool frameIsSubset = (size != frameRect.size());
- // Determine the recommended alpha type. The transIndex might be valid if it less
+ // Determine the encoded alpha type. The transIndex might be valid if it less
// than 256. We are not certain that the index is valid until we process the color
// table, since some gifs have color tables with less than 256 colors. If
// there might be a valid transparent index, we must indicate that the image has
// alpha.
- // In the case where we must support alpha, we have the option to set the
- // suggested alpha type to kPremul or kUnpremul. Both are valid since the alpha
- // component will always be 0xFF or the entire 32-bit pixel will be set to zero.
- // We prefer kPremul because we support kPremul, and it is more efficient to use
- // kPremul directly even when kUnpremul is supported.
- SkAlphaType alphaType = (transIndex < 256) ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
+ // In the case where we must support alpha, we indicate kBinary, since every
+ // pixel will either be fully opaque or fully transparent.
+ SkEncodedInfo::Alpha alpha = (transIndex < 256) ? SkEncodedInfo::kBinary_Alpha :
+ SkEncodedInfo::kOpaque_Alpha;
// Return the codec
- // kIndex is the most natural color type for gifs, so we set this as
- // the default.
- SkImageInfo imageInfo = SkImageInfo::Make(size.width(), size.height(), kIndex_8_SkColorType,
- alphaType);
- *codecOut = new SkGifCodec(imageInfo, streamDeleter.release(), gif.release(), transIndex,
- frameRect, frameIsSubset);
+ // Use kPalette since Gifs are encoded with a color table.
+ // Use 8-bits per component, since this is the output we get from giflib.
+ // FIXME: Gifs can actually be encoded with 4-bits per pixel. Can we support this?
+ SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kPalette_Color, alpha, 8);
+ *codecOut = new SkGifCodec(size.width(), size.height(), info, streamDeleter.release(),
+ gif.release(), transIndex, frameRect, frameIsSubset);
} else {
SkASSERT(nullptr != gifOut);
streamDeleter.release();
@@ -239,9 +237,9 @@ SkCodec* SkGifCodec::NewFromStream(SkStream* stream) {
return nullptr;
}
-SkGifCodec::SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType* gif,
- uint32_t transIndex, const SkIRect& frameRect, bool frameIsSubset)
- : INHERITED(srcInfo, stream)
+SkGifCodec::SkGifCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ GifFileType* gif, uint32_t transIndex, const SkIRect& frameRect, bool frameIsSubset)
+ : INHERITED(width, height, info, stream)
, fGif(gif)
, fSrcBuffer(new uint8_t[this->getInfo().width()])
, fFrameRect(frameRect)
diff --git a/src/codec/SkGifCodec.h b/src/codec/SkGifCodec.h
index a08e7ee552..984bceafd1 100644
--- a/src/codec/SkGifCodec.h
+++ b/src/codec/SkGifCodec.h
@@ -182,15 +182,15 @@ private:
* Creates an instance of the decoder
* Called only by NewFromStream
*
- * @param srcInfo contains the source width and height
+ * @param info contains properties of the encoded data
* @param stream the stream of image data
* @param gif pointer to library type that manages gif decode
* takes ownership
* @param transIndex The transparent index. An invalid value
* indicates that there is no transparent index.
*/
- SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType* gif, uint32_t transIndex,
- const SkIRect& frameRect, bool frameIsSubset);
+ SkGifCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ GifFileType* gif, uint32_t transIndex, const SkIRect& frameRect, bool frameIsSubset);
SkAutoTCallVProc<GifFileType, CloseGif> fGif; // owned
SkAutoTDeleteArray<uint8_t> fSrcBuffer;
diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp
index d74c150ff5..0e81b72407 100644
--- a/src/codec/SkIcoCodec.cpp
+++ b/src/codec/SkIcoCodec.cpp
@@ -168,20 +168,22 @@ SkCodec* SkIcoCodec::NewFromStream(SkStream* stream) {
maxIndex = i;
}
}
- SkImageInfo info = codecs->operator[](maxIndex)->getInfo();
+ int width = codecs->operator[](maxIndex)->getInfo().width();
+ int height = codecs->operator[](maxIndex)->getInfo().height();
+ SkEncodedInfo info = codecs->operator[](maxIndex)->getEncodedInfo();
// Note that stream is owned by the embedded codec, the ico does not need
// direct access to the stream.
- return new SkIcoCodec(info, codecs.release());
+ return new SkIcoCodec(width, height, info, codecs.release());
}
/*
* Creates an instance of the decoder
* Called only by NewFromStream
*/
-SkIcoCodec::SkIcoCodec(const SkImageInfo& info,
+SkIcoCodec::SkIcoCodec(int width, int height, const SkEncodedInfo& info,
SkTArray<SkAutoTDelete<SkCodec>, true>* codecs)
- : INHERITED(info, nullptr)
+ : INHERITED(width, height, info, nullptr)
, fEmbeddedCodecs(codecs)
, fCurrScanlineCodec(nullptr)
{}
diff --git a/src/codec/SkIcoCodec.h b/src/codec/SkIcoCodec.h
index 9a3f248af5..8c56aee4c6 100644
--- a/src/codec/SkIcoCodec.h
+++ b/src/codec/SkIcoCodec.h
@@ -71,7 +71,8 @@ private:
* Constructor called by NewFromStream
* @param embeddedCodecs codecs for the embedded images, takes ownership
*/
- SkIcoCodec(const SkImageInfo& srcInfo, SkTArray<SkAutoTDelete<SkCodec>, true>* embeddedCodecs);
+ SkIcoCodec(int width, int height, const SkEncodedInfo& info,
+ SkTArray<SkAutoTDelete<SkCodec>, true>* embeddedCodecs);
SkAutoTDelete<SkTArray<SkAutoTDelete<SkCodec>, true>> fEmbeddedCodecs; // owned
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 76d2ee8572..6b97b2fe4a 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -211,17 +211,20 @@ bool SkJpegCodec::ReadHeader(SkStream* stream, SkCodec** codecOut,
}
if (codecOut) {
- // Recommend the color type to decode to
- const SkColorType colorType = decoderMgr->getColorType();
+ // Get the encoded color type
+ SkEncodedInfo::Color color = decoderMgr->getEncodedColor();
+ if (SkEncodedInfo::kUnknown_Color == color) {
+ return false;
+ }
// Create image info object and the codec
- const SkImageInfo& imageInfo = SkImageInfo::Make(decoderMgr->dinfo()->image_width,
- decoderMgr->dinfo()->image_height, colorType, kOpaque_SkAlphaType);
+ SkEncodedInfo info = SkEncodedInfo::Make(color, SkEncodedInfo::kOpaque_Alpha, 8);
Origin orientation = get_exif_orientation(decoderMgr->dinfo());
sk_sp<SkColorSpace> colorSpace = get_icc_profile(decoderMgr->dinfo());
- *codecOut = new SkJpegCodec(imageInfo, stream, decoderMgr.release(), colorSpace,
+ *codecOut = new SkJpegCodec(decoderMgr->dinfo()->image_width,
+ decoderMgr->dinfo()->image_height, info, stream, decoderMgr.release(), colorSpace,
orientation);
} else {
SkASSERT(nullptr != decoderMgrOut);
@@ -242,9 +245,9 @@ SkCodec* SkJpegCodec::NewFromStream(SkStream* stream) {
return nullptr;
}
-SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream,
+SkJpegCodec::SkJpegCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, Origin origin)
- : INHERITED(srcInfo, stream, colorSpace, origin)
+ : INHERITED(width, height, info, stream, colorSpace, origin)
, fDecoderMgr(decoderMgr)
, fReadyState(decoderMgr->dinfo()->global_state)
, fSwizzlerSubset(SkIRect::MakeEmpty())
diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h
index d3ea132da7..f8cddd0221 100644
--- a/src/codec/SkJpegCodec.h
+++ b/src/codec/SkJpegCodec.h
@@ -86,13 +86,13 @@ private:
* Creates an instance of the decoder
* Called only by NewFromStream
*
- * @param srcInfo contains the source width and height
+ * @param info contains properties of the encoded data
* @param stream the encoded image data
* @param decoderMgr holds decompress struct, src manager, and error manager
* takes ownership
*/
- SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, JpegDecoderMgr* decoderMgr,
- sk_sp<SkColorSpace> colorSpace, Origin origin);
+ SkJpegCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ JpegDecoderMgr* decoderMgr, sk_sp<SkColorSpace> colorSpace, Origin origin);
/*
* Checks if the conversion between the input image and the requested output
diff --git a/src/codec/SkJpegDecoderMgr.cpp b/src/codec/SkJpegDecoderMgr.cpp
index 63228bb585..8517e0dac2 100644
--- a/src/codec/SkJpegDecoderMgr.cpp
+++ b/src/codec/SkJpegDecoderMgr.cpp
@@ -35,12 +35,20 @@ SkCodec::Result JpegDecoderMgr::returnFailure(const char caller[], SkCodec::Resu
return result;
}
-SkColorType JpegDecoderMgr::getColorType() {
+SkEncodedInfo::Color JpegDecoderMgr::getEncodedColor() {
switch (fDInfo.jpeg_color_space) {
case JCS_GRAYSCALE:
- return kGray_8_SkColorType;
+ return SkEncodedInfo::kGray_Color;
+ case JCS_YCbCr:
+ return SkEncodedInfo::kYUV_Color;
+ case JCS_RGB:
+ return SkEncodedInfo::kRGB_Color;
+ case JCS_YCCK:
+ return SkEncodedInfo::kYCCK_Color;
+ case JCS_CMYK:
+ return SkEncodedInfo::kInvertedCMYK_Color;
default:
- return kN32_SkColorType;
+ return SkEncodedInfo::kUnknown_Color;
}
}
diff --git a/src/codec/SkJpegDecoderMgr.h b/src/codec/SkJpegDecoderMgr.h
index e1127bad34..a5078bb2d3 100644
--- a/src/codec/SkJpegDecoderMgr.h
+++ b/src/codec/SkJpegDecoderMgr.h
@@ -43,9 +43,10 @@ public:
void init();
/*
- * Recommend a color type based on the encoded format
+ * Returns the encoded color type of the jpeg, or kUnknown if the
+ * color type can't be determined
*/
- SkColorType getColorType();
+ SkEncodedInfo::Color getEncodedColor();
/*
* Free memory used by the decode manager
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 8ae2360f25..33c3b6095b 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -279,7 +279,7 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
// png_structp on success.
// @param info_ptrp Optional output variable. If non-NULL, will be set to a new
// png_infop on success;
-// @param imageInfo Optional output variable. If non-NULL, will be set to
+// @param info Optional output variable. If non-NULL, will be set to
// reflect the properties of the encoded image on success.
// @param bitDepthPtr Optional output variable. If non-NULL, will be set to the
// bit depth of the encoded image on success.
@@ -290,7 +290,8 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
// If it returns false, the passed in fields (except stream) are unchanged.
static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
png_structp* png_ptrp, png_infop* info_ptrp,
- SkImageInfo* imageInfo, int* bitDepthPtr, int* numberPassesPtr) {
+ int* width, int* height, SkEncodedInfo* info, int* bitDepthPtr,
+ int* numberPassesPtr) {
// The image is known to be a PNG. Decode enough to know the SkImageInfo.
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
sk_error_fn, sk_warning_fn);
@@ -348,8 +349,8 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
// Now determine the default colorType and alphaType and set the required transforms.
// Often, we depend on SkSwizzler to perform any transforms that we need. However, we
// still depend on libpng for many of the rare and PNG-specific cases.
- SkColorType colorType = kUnknown_SkColorType;
- SkAlphaType alphaType = kUnknown_SkAlphaType;
+ SkEncodedInfo::Color color;
+ SkEncodedInfo::Alpha alpha;
switch (encodedColorType) {
case PNG_COLOR_TYPE_PALETTE:
// Extract multiple pixels with bit depths of 1, 2, and 4 from a single
@@ -359,20 +360,21 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
png_set_packing(png_ptr);
}
- colorType = kIndex_8_SkColorType;
- // Set the alpha type depending on if a transparency chunk exists.
- alphaType = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ?
- kUnpremul_SkAlphaType : kOpaque_SkAlphaType;
+ color = SkEncodedInfo::kPalette_Color;
+ // Set the alpha depending on if a transparency chunk exists.
+ alpha = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ?
+ SkEncodedInfo::kUnpremul_Alpha : SkEncodedInfo::kOpaque_Alpha;
break;
case PNG_COLOR_TYPE_RGB:
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
// Convert to RGBA if transparency chunk exists.
png_set_tRNS_to_alpha(png_ptr);
- alphaType = kUnpremul_SkAlphaType;
+ color = SkEncodedInfo::kRGBA_Color;
+ alpha = SkEncodedInfo::kBinary_Alpha;
} else {
- alphaType = kOpaque_SkAlphaType;
+ color = SkEncodedInfo::kRGB_Color;
+ alpha = SkEncodedInfo::kOpaque_Alpha;
}
- colorType = kN32_SkColorType;
break;
case PNG_COLOR_TYPE_GRAY:
// Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel.
@@ -383,29 +385,26 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_ptr);
-
- // We will recommend kN32 here since we do not support kGray
- // with alpha.
- colorType = kN32_SkColorType;
- alphaType = kUnpremul_SkAlphaType;
+ color = SkEncodedInfo::kGrayAlpha_Color;
+ alpha = SkEncodedInfo::kBinary_Alpha;
} else {
- colorType = kGray_8_SkColorType;
- alphaType = kOpaque_SkAlphaType;
+ color = SkEncodedInfo::kGray_Color;
+ alpha = SkEncodedInfo::kOpaque_Alpha;
}
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
- // We will recommend kN32 here since we do not support anything
- // similar to GRAY_ALPHA.
- colorType = kN32_SkColorType;
- alphaType = kUnpremul_SkAlphaType;
+ color = SkEncodedInfo::kGrayAlpha_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
break;
case PNG_COLOR_TYPE_RGBA:
- colorType = kN32_SkColorType;
- alphaType = kUnpremul_SkAlphaType;
+ color = SkEncodedInfo::kRGBA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
break;
default:
// All the color types have been covered above.
SkASSERT(false);
+ color = SkEncodedInfo::kRGBA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
}
int numberPasses = png_set_interlace_handling(png_ptr);
@@ -413,13 +412,14 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
*numberPassesPtr = numberPasses;
}
- SkColorProfileType profileType = kLinear_SkColorProfileType;
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
- profileType = kSRGB_SkColorProfileType;
+ if (info) {
+ *info = SkEncodedInfo::Make(color, alpha, 8);
}
-
- if (imageInfo) {
- *imageInfo = SkImageInfo::Make(origWidth, origHeight, colorType, alphaType, profileType);
+ if (width) {
+ *width = origWidth;
+ }
+ if (height) {
+ *height = origHeight;
}
autoClean.release();
if (png_ptrp) {
@@ -432,10 +432,10 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
return true;
}
-SkPngCodec::SkPngCodec(const SkImageInfo& info, SkStream* stream, SkPngChunkReader* chunkReader,
- png_structp png_ptr, png_infop info_ptr, int bitDepth, int numberPasses,
- sk_sp<SkColorSpace> colorSpace)
- : INHERITED(info, stream, colorSpace)
+SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
+ SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr,
+ int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
+ : INHERITED(width, height, info, stream, colorSpace)
, fPngChunkReader(SkSafeRef(chunkReader))
, fPng_ptr(png_ptr)
, fInfo_ptr(info_ptr)
@@ -538,7 +538,7 @@ bool SkPngCodec::onRewind() {
png_structp png_ptr;
png_infop info_ptr;
if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr,
- nullptr, nullptr, nullptr)) {
+ nullptr, nullptr, nullptr, nullptr, nullptr)) {
return false;
}
@@ -644,10 +644,11 @@ uint32_t SkPngCodec::onGetFillValue(SkColorType colorType) const {
// Subclass of SkPngCodec which supports scanline decoding
class SkPngScanlineDecoder : public SkPngCodec {
public:
- SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
+ SkPngScanlineDecoder(int width, int height, const SkEncodedInfo& info, SkStream* stream,
SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr, int bitDepth,
sk_sp<SkColorSpace> colorSpace)
- : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1, colorSpace)
+ : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1,
+ colorSpace)
, fSrcRow(nullptr)
{}
@@ -710,11 +711,11 @@ private:
class SkPngInterlacedScanlineDecoder : public SkPngCodec {
public:
- SkPngInterlacedScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
- SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr,
- int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
- : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, numberPasses,
- colorSpace)
+ SkPngInterlacedScanlineDecoder(int width, int height, const SkEncodedInfo& info,
+ SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr,
+ png_infop info_ptr, int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
+ : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth,
+ numberPasses, colorSpace)
, fHeight(-1)
, fCanSkipRewind(false)
{
@@ -836,23 +837,24 @@ SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead
SkAutoTDelete<SkStream> streamDeleter(stream);
png_structp png_ptr;
png_infop info_ptr;
- SkImageInfo imageInfo;
+ int width, height;
+ SkEncodedInfo imageInfo;
int bitDepth;
int numberPasses;
- if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &imageInfo, &bitDepth,
- &numberPasses)) {
+ if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &width, &height, &imageInfo,
+ &bitDepth, &numberPasses)) {
return nullptr;
}
auto colorSpace = read_color_space(png_ptr, info_ptr);
if (1 == numberPasses) {
- return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
- png_ptr, info_ptr, bitDepth, colorSpace);
+ return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
+ chunkReader, png_ptr, info_ptr, bitDepth, colorSpace);
}
- return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
- png_ptr, info_ptr, bitDepth, numberPasses,
- colorSpace);
+ return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
+ chunkReader, png_ptr, info_ptr, bitDepth,
+ numberPasses, colorSpace);
}
diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h
index 5673e5b4fa..8587bf8a14 100644
--- a/src/codec/SkPngCodec.h
+++ b/src/codec/SkPngCodec.h
@@ -41,8 +41,8 @@ protected:
return fSwizzler;
}
- SkPngCodec(const SkImageInfo&, SkStream*, SkPngChunkReader*, png_structp, png_infop, int, int,
- sk_sp<SkColorSpace>);
+ SkPngCodec(int width, int height, const SkEncodedInfo&, SkStream*, SkPngChunkReader*,
+ png_structp, png_infop, int, int, sk_sp<SkColorSpace>);
png_structp png_ptr() { return fPng_ptr; }
SkSwizzler* swizzler() { return fSwizzler; }
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index ef8ba700a4..51de2fcec0 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -515,8 +515,16 @@ public:
}
}
- const SkImageInfo& getImageInfo() const {
- return fImageInfo;
+ const SkEncodedInfo& getEncodedInfo() const {
+ return fEncodedInfo;
+ }
+
+ int width() const {
+ return fWidth;
+ }
+
+ int height() const {
+ return fHeight;
}
bool isScalable() const {
@@ -545,8 +553,11 @@ private:
return 0x2A == get_endian_short(header + 2, littleEndian);
}
- void init(const int width, const int height, const dng_point& cfaPatternSize) {
- fImageInfo = SkImageInfo::Make(width, height, kN32_SkColorType, kOpaque_SkAlphaType);
+ void init(int width, int height, const dng_point& cfaPatternSize) {
+ fWidth = width;
+ fHeight = height;
+ fEncodedInfo = SkEncodedInfo::Make(SkEncodedInfo::kRGB_Color,
+ SkEncodedInfo::kOpaque_Alpha, 8);
// The DNG SDK scales only during demosaicing, so scaling is only possible when
// a mosaic info is available.
@@ -616,7 +627,9 @@ private:
SkAutoTDelete<dng_negative> fNegative;
SkAutoTDelete<dng_stream> fDngStream;
- SkImageInfo fImageInfo;
+ int fWidth;
+ int fHeight;
+ SkEncodedInfo fEncodedInfo;
bool fIsScalable;
bool fIsXtransImage;
};
@@ -764,5 +777,5 @@ bool SkRawCodec::onDimensionsSupported(const SkISize& dim) {
SkRawCodec::~SkRawCodec() {}
SkRawCodec::SkRawCodec(SkDngImage* dngImage)
- : INHERITED(dngImage->getImageInfo(), nullptr)
+ : INHERITED(dngImage->width(), dngImage->height(), dngImage->getEncodedInfo(), nullptr)
, fDngImage(dngImage) {}
diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp
index 90ee322b1f..9a842ac91f 100644
--- a/src/codec/SkWbmpCodec.cpp
+++ b/src/codec/SkWbmpCodec.cpp
@@ -104,8 +104,8 @@ bool SkWbmpCodec::readRow(uint8_t* row) {
return this->stream()->read(row, fSrcRowBytes) == fSrcRowBytes;
}
-SkWbmpCodec::SkWbmpCodec(const SkImageInfo& info, SkStream* stream)
- : INHERITED(info, stream)
+SkWbmpCodec::SkWbmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream)
+ : INHERITED(width, height, info, stream)
, fSrcRowBytes(get_src_row_bytes(this->getInfo().width()))
, fSwizzler(nullptr)
, fColorTable(nullptr)
@@ -166,9 +166,9 @@ SkCodec* SkWbmpCodec::NewFromStream(SkStream* stream) {
if (!read_header(stream, &size)) {
return nullptr;
}
- SkImageInfo info = SkImageInfo::Make(size.width(), size.height(),
- kGray_8_SkColorType, kOpaque_SkAlphaType);
- return new SkWbmpCodec(info, streamDeleter.release());
+ SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kGray_Color,
+ SkEncodedInfo::kOpaque_Alpha, 1);
+ return new SkWbmpCodec(size.width(), size.height(), info, streamDeleter.release());
}
int SkWbmpCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) {
diff --git a/src/codec/SkWbmpCodec.h b/src/codec/SkWbmpCodec.h
index f43f615ed2..9f29237e23 100644
--- a/src/codec/SkWbmpCodec.h
+++ b/src/codec/SkWbmpCodec.h
@@ -44,7 +44,7 @@ private:
*/
bool readRow(uint8_t* row);
- SkWbmpCodec(const SkImageInfo&, SkStream*);
+ SkWbmpCodec(int width, int height, const SkEncodedInfo&, SkStream*);
const size_t fSrcRowBytes;
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index 77af8e5e8f..e40c3f2377 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -31,7 +31,7 @@ bool SkWebpCodec::IsWebp(const void* buf, size_t bytesRead) {
// Parse headers of RIFF container, and check for valid Webp (VP8) content.
// NOTE: This calls peek instead of read, since onGetPixels will need these
// bytes again.
-static bool webp_parse_header(SkStream* stream, SkImageInfo* info) {
+static bool webp_parse_header(SkStream* stream, int* width, int* height, SkEncodedInfo* info) {
unsigned char buffer[WEBP_VP8_HEADER_SIZE];
SkASSERT(WEBP_VP8_HEADER_SIZE <= SkCodec::MinBufferedBytesNeeded());
@@ -62,22 +62,55 @@ static bool webp_parse_header(SkStream* stream, SkImageInfo* info) {
}
if (info) {
- // FIXME: Is N32 the right type?
- // Is unpremul the right type? Clients of SkCodec may assume it's the
- // best type, when Skia currently cannot draw unpremul (and raster is faster
- // with premul).
- *info = SkImageInfo::Make(features.width, features.height, kN32_SkColorType,
- SkToBool(features.has_alpha) ? kUnpremul_SkAlphaType
- : kOpaque_SkAlphaType);
+ SkEncodedInfo::Color color;
+ SkEncodedInfo::Alpha alpha;
+ switch (features.format) {
+ case 0:
+ // This indicates a "mixed" format. We would see this for
+ // animated webps or for webps encoded in multiple fragments.
+ // I believe that this is a rare case.
+ // We could also guess kYUV here, but I think it makes more
+ // sense to guess kBGRA which is likely closer to the final
+ // output. Otherwise, we might end up converting
+ // BGRA->YUVA->BGRA.
+ color = SkEncodedInfo::kBGRA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
+ break;
+ case 1:
+ // This is the lossy format (YUV).
+ if (SkToBool(features.has_alpha)) {
+ color = SkEncodedInfo::kYUVA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
+ } else {
+ color = SkEncodedInfo::kYUV_Color;
+ alpha = SkEncodedInfo::kOpaque_Alpha;
+ }
+ break;
+ case 2:
+ // This is the lossless format (BGRA).
+ // FIXME: Should we check the has_alpha flag here? It looks
+ // like the image is encoded with an alpha channel
+ // regardless of whether or not the alpha flag is set.
+ color = SkEncodedInfo::kBGRA_Color;
+ alpha = SkEncodedInfo::kUnpremul_Alpha;
+ break;
+ default:
+ return false;
+ }
+
+ *width = features.width;
+ *height = features.height;
+ *info = SkEncodedInfo::Make(color, alpha, 8);
}
return true;
}
SkCodec* SkWebpCodec::NewFromStream(SkStream* stream) {
SkAutoTDelete<SkStream> streamDeleter(stream);
- SkImageInfo info;
- if (webp_parse_header(stream, &info)) {
- return new SkWebpCodec(info, streamDeleter.release());
+ int width, height;
+ SkEncodedInfo info;
+ if (webp_parse_header(stream, &width, &height, &info)) {
+ return new SkWebpCodec(width, height, info, streamDeleter.release());
}
return nullptr;
}
@@ -252,7 +285,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
}
}
-SkWebpCodec::SkWebpCodec(const SkImageInfo& info, SkStream* stream)
+SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream)
// The spec says an unmarked image is sRGB, so we return that space here.
// TODO: Add support for parsing ICC profiles from webps.
- : INHERITED(info, stream, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)) {}
+ : INHERITED(width, height, info, stream, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)) {}
diff --git a/src/codec/SkWebpCodec.h b/src/codec/SkWebpCodec.h
index 2d81cf3d9c..908bf2cd4f 100644
--- a/src/codec/SkWebpCodec.h
+++ b/src/codec/SkWebpCodec.h
@@ -34,7 +34,7 @@ protected:
bool onGetValidSubset(SkIRect* /* desiredSubset */) const override;
private:
- SkWebpCodec(const SkImageInfo&, SkStream*);
+ SkWebpCodec(int width, int height, const SkEncodedInfo&, SkStream*);
typedef SkCodec INHERITED;
};