aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-03-21 16:14:42 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-22 13:57:58 +0000
commite3b95ce468c73af8247ba9582a7b84548b19f06a (patch)
tree5823adacd215f5b9f7030287fec35727332d041a /src/images
parentc3efe6785666cdd13848e63f36fdadca26c48649 (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.cpp22
-rw-r--r--src/images/SkJPEGWriteUtility.cpp4
-rw-r--r--src/images/SkJPEGWriteUtility.h10
-rw-r--r--src/images/SkPNGImageEncoder.cpp20
-rw-r--r--src/images/SkWEBPImageEncoder.cpp2
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: