aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-01-19 17:14:07 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-19 23:07:13 +0000
commit1da27ef853ae3e701b7f4aae670c21684396dcce (patch)
tree56fb2fed264ab2f3d1d130eac8bce03f4fa430a9 /src/images
parent0d7d8de00a3ce2e70cf1221392db3d960610ad62 (diff)
Add F16 support to SkPNGImageEncoder
BUG=skia: CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD Change-Id: Ifd221365a7b9f9a4a4fc5382621e0da7189e1148 Reviewed-on: https://skia-review.googlesource.com/6526 Reviewed-by: Mike Klein <mtklein@chromium.org> Reviewed-by: Leon Scroggins <scroggo@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkPNGImageEncoder.cpp68
-rw-r--r--src/images/transform_scanline.h46
2 files changed, 86 insertions, 28 deletions
diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp
index 55aead2c04..48aca8bb1e 100644
--- a/src/images/SkPNGImageEncoder.cpp
+++ b/src/images/SkPNGImageEncoder.cpp
@@ -83,6 +83,17 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info) {
case kIndex_8_SkColorType:
case kGray_8_SkColorType:
return transform_scanline_memcpy;
+ case kRGBA_F16_SkColorType:
+ switch (info.alphaType()) {
+ case kOpaque_SkAlphaType:
+ case kUnpremul_SkAlphaType:
+ return transform_scanline_F16;
+ case kPremul_SkAlphaType:
+ return transform_scanline_F16_premul;
+ default:
+ SkASSERT(false);
+ return nullptr;
+ }
default:
SkASSERT(false);
return nullptr;
@@ -168,19 +179,8 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp
if (!pixmap.addr() || pixmap.info().isEmpty()) {
return false;
}
- const SkColorType colorType = pixmap.colorType();
- switch (colorType) {
- case kIndex_8_SkColorType:
- case kGray_8_SkColorType:
- case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType:
- case kARGB_4444_SkColorType:
- case kRGB_565_SkColorType:
- break;
- default:
- return false;
- }
+ const SkColorType colorType = pixmap.colorType();
const SkAlphaType alphaType = pixmap.alphaType();
switch (alphaType) {
case kUnpremul_SkAlphaType:
@@ -197,12 +197,23 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp
}
const bool isOpaque = (kOpaque_SkAlphaType == alphaType);
- const int bitDepth = 8;
+ int bitDepth = 8;
png_color_8 sig_bit;
sk_bzero(&sig_bit, sizeof(png_color_8));
-
int pngColorType;
switch (colorType) {
+ case kRGBA_F16_SkColorType:
+ if (!pixmap.colorSpace() || !pixmap.colorSpace()->gammaIsLinear()) {
+ return false;
+ }
+
+ sig_bit.red = 16;
+ sig_bit.green = 16;
+ sig_bit.blue = 16;
+ sig_bit.alpha = 16;
+ bitDepth = 16;
+ pngColorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
+ break;
case kIndex_8_SkColorType:
sig_bit.red = 8;
sig_bit.green = 8;
@@ -240,6 +251,7 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp
default:
return false;
}
+
if (kIndex_8_SkColorType == colorType) {
SkColorTable* ctable = pixmap.ctable();
if (!ctable || ctable->count() == 0) {
@@ -250,9 +262,25 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp
// When ctable->count() <= 16, we could potentially use 1, 2,
// or 4 bit indices.
}
+
return do_encode(stream, pixmap, pngColorType, bitDepth, sig_bit);
}
+static int num_components(int pngColorType) {
+ switch (pngColorType) {
+ case PNG_COLOR_TYPE_PALETTE:
+ case PNG_COLOR_TYPE_GRAY:
+ return 1;
+ case PNG_COLOR_TYPE_RGB:
+ return 3;
+ case PNG_COLOR_TYPE_RGBA:
+ return 4;
+ default:
+ SkASSERT(false);
+ return 0;
+ }
+}
+
static bool do_encode(SkWStream* stream, const SkPixmap& pixmap,
int pngColorType, int bitDepth, png_color_8& sig_bit) {
png_structp png_ptr;
@@ -308,12 +336,18 @@ static bool do_encode(SkWStream* stream, const SkPixmap& pixmap,
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
png_write_info(png_ptr, info_ptr);
+ int pngBytesPerPixel = num_components(pngColorType) * (bitDepth / 8);
+ if (kRGBA_F16_SkColorType == pixmap.colorType() && kOpaque_SkAlphaType == pixmap.alphaType()) {
+ // For kOpaque, kRGBA_F16, we will keep the row as RGBA and tell libpng
+ // to skip the alpha channel.
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ pngBytesPerPixel = 8;
+ }
- const char* srcImage = (const char*)pixmap.addr();
- SkAutoSTMalloc<1024, char> rowStorage(pixmap.width() << 2);
+ SkAutoSTMalloc<1024, char> rowStorage(pixmap.width() * pngBytesPerPixel);
char* storage = rowStorage.get();
+ const char* srcImage = (const char*)pixmap.addr();
transform_scanline_proc proc = choose_proc(pixmap.info());
-
for (int y = 0; y < pixmap.height(); y++) {
png_bytep row_ptr = (png_bytep)storage;
proc(storage, srcImage, pixmap.width(), SkColorTypeBytesPerPixel(pixmap.colorType()));
diff --git a/src/images/transform_scanline.h b/src/images/transform_scanline.h
index 1ce67cd3a2..1c263487bd 100644
--- a/src/images/transform_scanline.h
+++ b/src/images/transform_scanline.h
@@ -96,7 +96,7 @@ static void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRIC
template <bool kIsRGBA>
static inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst,
- const char* SK_RESTRICT src, int width, int) {
+ const char* SK_RESTRICT src, int width) {
const uint32_t* srcP = (const SkPMColor*)src;
const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
@@ -132,21 +132,20 @@ static inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst,
* Transform from legacy kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
*/
static void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
- int bpp) {
- transform_scanline_unpremultiply<true>(dst, src, width, bpp);
+ int) {
+ transform_scanline_unpremultiply<true>(dst, src, width);
}
/**
* Transform from legacy kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
*/
static void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
- int bpp) {
- transform_scanline_unpremultiply<false>(dst, src, width, bpp);
+ int) {
+ transform_scanline_unpremultiply<false>(dst, src, width);
}
template <bool kIsRGBA>
-static inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width, int)
-{
+static inline void transform_scanline_unpremultiply_sRGB(void* dst, const void* src, int width) {
SkRasterPipeline p;
p.append(SkRasterPipeline::load_8888, &src);
if (!kIsRGBA) {
@@ -164,16 +163,16 @@ static inline void transform_scanline_unpremultiply_sRGB(void* dst, const void*
* Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
*/
static void transform_scanline_srgbA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
- int width, int bpp) {
- transform_scanline_unpremultiply_sRGB<true>(dst, src, width, bpp);
+ int width, int) {
+ transform_scanline_unpremultiply_sRGB<true>(dst, src, width);
}
/**
* Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremultiplied RGBA.
*/
static void transform_scanline_sbgrA(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
- int width, int bpp) {
- transform_scanline_unpremultiply_sRGB<false>(dst, src, width, bpp);
+ int width, int) {
+ transform_scanline_unpremultiply_sRGB<false>(dst, src, width);
}
/**
@@ -219,3 +218,28 @@ static void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRI
*dst++ = a;
}
}
+
+/**
+ * Transform from kRGBA_F16 to 4-bytes-per-pixel RGBA.
+ */
+static void transform_scanline_F16(char* SK_RESTRICT dst, const char* SK_RESTRICT src, int width,
+ int) {
+ SkRasterPipeline p;
+ p.append(SkRasterPipeline::load_f16, (const void**) &src);
+ p.append(SkRasterPipeline::to_srgb);
+ p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
+ p.run(0, 0, width);
+}
+
+/**
+ * Transform from kPremul, kRGBA_F16 to 4-bytes-per-pixel RGBA.
+ */
+static void transform_scanline_F16_premul(char* SK_RESTRICT dst, const char* SK_RESTRICT src,
+ int width, int) {
+ SkRasterPipeline p;
+ p.append(SkRasterPipeline::load_f16, (const void**) &src);
+ p.append(SkRasterPipeline::unpremul);
+ p.append(SkRasterPipeline::to_srgb);
+ p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
+ p.run(0, 0, width);
+}