diff options
author | Matt Sarett <msarett@google.com> | 2017-03-21 16:14:42 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-03-22 13:57:58 +0000 |
commit | e3b95ce468c73af8247ba9582a7b84548b19f06a (patch) | |
tree | 5823adacd215f5b9f7030287fec35727332d041a /src/images | |
parent | c3efe6785666cdd13848e63f36fdadca26c48649 (diff) |
Add support for writing icc profiles to the jpeg encoder
Also, share the impl for skjpeg_error_mgr between the
jpeg decoder and encoder. They are already identical
anyway.
BUG=skia:
Change-Id: I029312406dee8734744cc3058acd1f153aefcd83
Reviewed-on: https://skia-review.googlesource.com/9971
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src/images')
-rw-r--r-- | src/images/SkImageEncoderFns.h (renamed from src/images/transform_scanline.h) | 20 | ||||
-rw-r--r-- | src/images/SkJPEGImageEncoder.cpp | 22 | ||||
-rw-r--r-- | src/images/SkJPEGWriteUtility.cpp | 4 | ||||
-rw-r--r-- | src/images/SkJPEGWriteUtility.h | 10 | ||||
-rw-r--r-- | src/images/SkPNGImageEncoder.cpp | 20 | ||||
-rw-r--r-- | src/images/SkWEBPImageEncoder.cpp | 2 |
6 files changed, 48 insertions, 30 deletions
diff --git a/src/images/transform_scanline.h b/src/images/SkImageEncoderFns.h index 3c754275e0..5120570c48 100644 --- a/src/images/transform_scanline.h +++ b/src/images/SkImageEncoderFns.h @@ -4,8 +4,9 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#ifndef transform_scanline_DEFINED -#define transform_scanline_DEFINED + +#ifndef SkImageEncoderFns_DEFINED +#define SkImageEncoderFns_DEFINED /** * Functions to transform scanlines between packed-pixel formats. @@ -14,6 +15,7 @@ #include "SkBitmap.h" #include "SkColor.h" #include "SkColorPriv.h" +#include "SkICC.h" #include "SkPreConfig.h" #include "SkRasterPipeline.h" #include "SkUnPreMultiply.h" @@ -273,4 +275,16 @@ static inline void transform_scanline_F16_premul_to_8888(char* SK_RESTRICT dst, p.append(SkRasterPipeline::store_8888, (void**) &dst); p.run(0, width); } -#endif // transform_scanline_DEFINED + +static inline sk_sp<SkData> icc_from_color_space(const SkColorSpace& cs) { + SkColorSpaceTransferFn fn; + SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); + if (cs.isNumericalTransferFn(&fn) && cs.toXYZD50(&toXYZD50)) { + return SkICC::WriteToICC(fn, toXYZD50); + } + + // TODO: Should we support writing ICC profiles for additional color spaces? + return nullptr; +} + +#endif // SkImageEncoderFns_DEFINED diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp index 1f8f0d6394..e87e9aceb8 100644 --- a/src/images/SkJPEGImageEncoder.cpp +++ b/src/images/SkJPEGImageEncoder.cpp @@ -10,10 +10,11 @@ #ifdef SK_HAS_JPEG_LIBRARY #include "SkColorPriv.h" +#include "SkImageEncoderFns.h" +#include "SkJpegUtility.h" #include "SkJPEGWriteUtility.h" #include "SkStream.h" #include "SkTemplates.h" -#include "transform_scanline.h" #include <stdio.h> @@ -112,7 +113,7 @@ bool SkEncodeImageAsJPEG(SkWStream* stream, const SkPixmap& pixmap, int quality) SkAutoTMalloc<uint8_t> storage; cinfo.err = jpeg_std_error(&sk_err); - sk_err.error_exit = skjpeg_error_exit; + sk_err.error_exit = skjpeg_write_error_exit; if (setjmp(sk_err.fJmpBuf)) { return false; } @@ -141,6 +142,23 @@ bool SkEncodeImageAsJPEG(SkWStream* stream, const SkPixmap& pixmap, int quality) jpeg_start_compress(&cinfo, TRUE); + if (pixmap.colorSpace()) { + sk_sp<SkData> icc = icc_from_color_space(*pixmap.colorSpace()); + if (icc) { + // Create a contiguous block of memory with the icc signature followed by the profile. + sk_sp<SkData> markerData = + SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size()); + uint8_t* ptr = (uint8_t*) markerData->writable_data(); + memcpy(ptr, kICCSig, sizeof(kICCSig)); + ptr += sizeof(kICCSig); + *ptr++ = 1; // This is the first marker. + *ptr++ = 1; // Out of one total markers. + memcpy(ptr, icc->data(), icc->size()); + + jpeg_write_marker(&cinfo, kICCMarker, markerData->bytes(), markerData->size()); + } + } + if (proc) { storage.reset(numComponents * pixmap.width()); } diff --git a/src/images/SkJPEGWriteUtility.cpp b/src/images/SkJPEGWriteUtility.cpp index aa0d3ec4d9..a5d2483898 100644 --- a/src/images/SkJPEGWriteUtility.cpp +++ b/src/images/SkJPEGWriteUtility.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ - +#include "SkJpegUtility.h" #include "SkJPEGWriteUtility.h" /////////////////////////////////////////////////////////////////////////////// @@ -52,7 +52,7 @@ skjpeg_destination_mgr::skjpeg_destination_mgr(SkWStream* stream) this->term_destination = sk_term_destination; } -void skjpeg_error_exit(j_common_ptr cinfo) { +void skjpeg_write_error_exit(j_common_ptr cinfo) { skjpeg_error_mgr* error = (skjpeg_error_mgr*)cinfo->err; (*error->output_message) (cinfo); diff --git a/src/images/SkJPEGWriteUtility.h b/src/images/SkJPEGWriteUtility.h index 91d07a3616..3f44863988 100644 --- a/src/images/SkJPEGWriteUtility.h +++ b/src/images/SkJPEGWriteUtility.h @@ -18,15 +18,7 @@ extern "C" { #include <setjmp.h> -/* Our error-handling struct. - * -*/ -struct skjpeg_error_mgr : jpeg_error_mgr { - jmp_buf fJmpBuf; -}; - - -void skjpeg_error_exit(j_common_ptr cinfo); +void skjpeg_write_error_exit(j_common_ptr cinfo); ///////////////////////////////////////////////////////////////////////////// /* Our destination struct for directing decompressed pixels to our stream diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp index 2eac91d0ca..e28ae12dc0 100644 --- a/src/images/SkPNGImageEncoder.cpp +++ b/src/images/SkPNGImageEncoder.cpp @@ -12,14 +12,13 @@ #include "SkColor.h" #include "SkColorPriv.h" #include "SkDither.h" -#include "SkICC.h" +#include "SkImageEncoderFns.h" #include "SkMath.h" #include "SkStream.h" #include "SkString.h" #include "SkTemplates.h" #include "SkUnPreMultiply.h" #include "SkUtils.h" -#include "transform_scanline.h" #include "png.h" @@ -40,9 +39,7 @@ static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { } } -static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkColorSpaceTransferFn& fn, - const SkMatrix44& toXYZD50) { - sk_sp<SkData> icc = SkICC::WriteToICC(fn, toXYZD50); +static void set_icc(png_structp png_ptr, png_infop info_ptr, sk_sp<SkData> icc) { #if PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5) const char* name = "Skia"; png_const_bytep iccPtr = icc->bytes(); @@ -351,17 +348,14 @@ static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, } if (pixmap.colorSpace()) { - SkColorSpaceTransferFn fn; - SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); if (pixmap.colorSpace()->isSRGB()) { png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); - } else if (pixmap.colorSpace()->isNumericalTransferFn(&fn) && - pixmap.colorSpace()->toXYZD50(&toXYZD50)) - { - set_icc(png_ptr, info_ptr, fn, toXYZD50); + } else { + sk_sp<SkData> icc = icc_from_color_space(*pixmap.colorSpace()); + if (icc) { + set_icc(png_ptr, info_ptr, std::move(icc)); + } } - - // TODO: Should we support writing ICC profiles for additional color spaces? } png_set_sBIT(png_ptr, info_ptr, &sig_bit); diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp index 8797ff5925..a9fcc31265 100644 --- a/src/images/SkWEBPImageEncoder.cpp +++ b/src/images/SkWEBPImageEncoder.cpp @@ -20,11 +20,11 @@ #include "SkBitmap.h" #include "SkColorPriv.h" +#include "SkImageEncoderFns.h" #include "SkStream.h" #include "SkTemplates.h" #include "SkUnPreMultiply.h" #include "SkUtils.h" -#include "transform_scanline.h" // A WebP decoder only, on top of (subset of) libwebp // For more information on WebP image format, and libwebp library, see: |