aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2018-01-25 09:09:32 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-30 22:02:20 +0000
commitac568a934f8f82bf3a359b757d67eb3a797d3593 (patch)
tree08b667b597933b0e2baf0af8c5ddac7ec8e63cef /src/images
parent1c5906f5623cc6b019281b35ba387f620f13f969 (diff)
1010102, 101010x, 888x in sw
Same sort of deal as before, now with all three new formats. While I was at it, I made sure RGBA 8888 and BGRA 8888 both work too. We don't want the 101010's in lowp, but 888x should be fine. After looking at the DM images on monitors at work, I decided to re-enable dither even on 10-bit images. Looking at the GMs in 888x or 101010x is interesting... I think we must not be clearing the memory allocated for layers? Seems like we want to allocate layers as 8888? Change-Id: I3a85b4f00877792a6425a7e7eb31eacb04ae9218 Reviewed-on: https://skia-review.googlesource.com/101640 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkImageEncoderFns.h58
-rw-r--r--src/images/SkPngEncoder.cpp40
2 files changed, 98 insertions, 0 deletions
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index 52c547616d..8637541720 100644
--- a/src/images/SkImageEncoderFns.h
+++ b/src/images/SkImageEncoderFns.h
@@ -267,6 +267,64 @@ static inline void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK
}
}
+// 888x is opaque RGB in four bytes, with 8 junk bits. We convert that to 3 byte RGB.
+static inline void transform_scanline_888x(char* dst, const char* src,
+ int width, int, const SkPMColor*) {
+ while (width --> 0) {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst += 3;
+ src += 4;
+ }
+}
+
+// 101010x is opaque RGB in four bytes, with 2 bits junk. We convert to 6 byte RGB (big endian).
+static inline void transform_scanline_101010x(char* dst, const char* src,
+ int width, int, const SkPMColor*) {
+ auto d = ( uint16_t*)dst;
+ auto s = (const uint32_t*)src;
+ while (width --> 0) {
+ uint32_t r = (*s >> 0) & 1023,
+ g = (*s >> 10) & 1023,
+ b = (*s >> 20) & 1023;
+
+ // Scale 10-bit unorms to 16-bit by replicating the most significant bits.
+ r = (r << 6) | (r >> 4);
+ g = (g << 6) | (g >> 4);
+ b = (b << 6) | (b >> 4);
+
+ // Store big-endian.
+ d[0] = (r >> 8) | (r << 8);
+ d[1] = (g >> 8) | (g << 8);
+ d[2] = (b >> 8) | (b << 8);
+
+ d += 3; // 3 channels
+ s += 1; // 1 whole pixel
+ }
+}
+
+static inline void transform_scanline_1010102(char* dst, const char* src,
+ int width, int, const SkPMColor*) {
+ SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
+ dst_ctx = { (void*)dst, 0 };
+ SkRasterPipeline_<256> p;
+ p.append(SkRasterPipeline::load_1010102, &src_ctx);
+ p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
+ p.run(0,0, width,1);
+}
+
+static inline void transform_scanline_1010102_premul(char* dst, const char* src,
+ int width, int, const SkPMColor*) {
+ SkJumper_MemoryCtx src_ctx = { (void*)src, 0 },
+ dst_ctx = { (void*)dst, 0 };
+ SkRasterPipeline_<256> p;
+ p.append(SkRasterPipeline::load_1010102, &src_ctx);
+ p.append(SkRasterPipeline::unpremul);
+ p.append(SkRasterPipeline::store_u16_be, &dst_ctx);
+ p.run(0,0, width,1);
+}
+
/**
* Transform from kRGBA_F16 to 8-bytes-per-pixel RGBA.
*/
diff --git a/src/images/SkPngEncoder.cpp b/src/images/SkPngEncoder.cpp
index 211efa8618..c7952df57a 100644
--- a/src/images/SkPngEncoder.cpp
+++ b/src/images/SkPngEncoder.cpp
@@ -130,6 +130,14 @@ bool SkPngEncoderMgr::setHeader(const SkImageInfo& srcInfo, const SkPngEncoder::
pngColorType = srcInfo.isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
fPngBytesPerPixel = srcInfo.isOpaque() ? 3 : 4;
break;
+ case kRGB_888x_SkColorType:
+ sigBit.red = 8;
+ sigBit.green = 8;
+ sigBit.blue = 8;
+ pngColorType = PNG_COLOR_TYPE_RGB;
+ fPngBytesPerPixel = 3;
+ SkASSERT(srcInfo.isOpaque());
+ break;
case kARGB_4444_SkColorType:
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
return false;
@@ -156,6 +164,23 @@ bool SkPngEncoderMgr::setHeader(const SkImageInfo& srcInfo, const SkPngEncoder::
pngColorType = PNG_COLOR_TYPE_GRAY_ALPHA;
fPngBytesPerPixel = 2;
break;
+ case kRGBA_1010102_SkColorType:
+ bitDepth = 16;
+ sigBit.red = 10;
+ sigBit.green = 10;
+ sigBit.blue = 10;
+ sigBit.alpha = 2;
+ pngColorType = srcInfo.isOpaque() ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+ fPngBytesPerPixel = 8;
+ break;
+ case kRGB_101010x_SkColorType:
+ bitDepth = 16;
+ sigBit.red = 10;
+ sigBit.green = 10;
+ sigBit.blue = 10;
+ pngColorType = PNG_COLOR_TYPE_RGB;
+ fPngBytesPerPixel = 6;
+ break;
default:
return false;
}
@@ -237,6 +262,8 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info,
}
case kRGB_565_SkColorType:
return transform_scanline_565;
+ case kRGB_888x_SkColorType:
+ return transform_scanline_888x;
case kARGB_4444_SkColorType:
switch (info.alphaType()) {
case kOpaque_SkAlphaType:
@@ -261,6 +288,19 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info,
SkASSERT(false);
return nullptr;
}
+ case kRGBA_1010102_SkColorType:
+ switch (info.alphaType()) {
+ case kOpaque_SkAlphaType:
+ case kUnpremul_SkAlphaType:
+ return transform_scanline_1010102;
+ case kPremul_SkAlphaType:
+ return transform_scanline_1010102_premul;
+ default:
+ SkASSERT(false);
+ return nullptr;
+ }
+ case kRGB_101010x_SkColorType:
+ return transform_scanline_101010x;
case kAlpha_8_SkColorType:
return transform_scanline_A8_to_GrayAlpha;
default: