aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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;
};