aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkBmpCodec.cpp
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 /src/codec/SkBmpCodec.cpp
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
Diffstat (limited to 'src/codec/SkBmpCodec.cpp')
-rw-r--r--src/codec/SkBmpCodec.cpp82
1 files changed, 52 insertions, 30 deletions
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() {