Revert "Revert "Add support for writing ICC profiles to webp encoder""
This reverts commit e87d7781db75a7ec22a103eda0886c2ca8dc4d9d.
Reason for revert: Not the cause of the crashes.
Original change's description:
> Revert "Add support for writing ICC profiles to webp encoder"
>
> This reverts commit 0c9d0b4e03b6c10778329e995b5dfdcb97954b28.
>
> Reason for revert: Looks like it's breaking a number of bots.
>
> Original change's description:
> > Add support for writing ICC profiles to webp encoder
> >
> > Bug: skia:
> > Change-Id: If0a8f84ed88da96924370b841f2283c0ff8e32ab
> > Reviewed-on: https://skia-review.googlesource.com/10212
> > Commit-Queue: Matt Sarett <msarett@google.com>
> > Reviewed-by: Leon Scroggins <scroggo@google.com>
> >
>
> TBR=msarett@google.com,scroggo@google.com,reviews@skia.org,jzern@google.com
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
>
> Change-Id: Ic06ad9f19a4d743b34f8d3bd33f171b9d74badcb
> Reviewed-on: https://skia-review.googlesource.com/11408
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>
>
TBR=jvanverth@google.com,msarett@google.com,scroggo@google.com,reviews@skia.org,jzern@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Change-Id: I42f6ddefaf87c87b155640950b52a456952130ec
Reviewed-on: https://skia-review.googlesource.com/11410
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp
index 28dff05..728dbc7 100644
--- a/src/images/SkWEBPImageEncoder.cpp
+++ b/src/images/SkWEBPImageEncoder.cpp
@@ -26,7 +26,7 @@
#include "SkUnPreMultiply.h"
#include "SkUtils.h"
-// A WebP decoder only, on top of (subset of) libwebp
+// A WebP encoder only, on top of (subset of) libwebp
// For more information on WebP image format, and libwebp library, see:
// http://code.google.com/speed/webp/
// http://www.webmproject.org/code/#libwebp_webp_image_decoder_library
@@ -37,6 +37,7 @@
// If moving libwebp out of skia source tree, path for webp headers must be
// updated accordingly. Here, we enforce using local copy in webp sub-directory.
#include "webp/encode.h"
+#include "webp/mux.h"
}
static transform_scanline_proc choose_proc(const SkImageInfo& info) {
@@ -174,10 +175,17 @@
WebPPicture pic;
WebPPictureInit(&pic);
+ SkAutoTCallVProc<WebPPicture, WebPPictureFree> autoPic(&pic);
pic.width = pixmap.width();
pic.height = pixmap.height();
pic.writer = stream_writer;
- pic.custom_ptr = (void*)stream;
+
+ // If there is no need to embed an ICC profile, we write directly to the input stream.
+ // Otherwise, we will first encode to |tmp| and use a mux to add the ICC chunk. libwebp
+ // forces us to have an encoded image before we can add a profile.
+ sk_sp<SkData> icc = pixmap.colorSpace() ? icc_from_color_space(*pixmap.colorSpace()) : nullptr;
+ SkDynamicMemoryWStream tmp;
+ pic.custom_ptr = icc ? (void*)&tmp : (void*)stream;
const uint8_t* src = (uint8_t*)pixmap.addr();
const int rgbStride = pic.width * bpp;
@@ -190,21 +198,47 @@
proc((char*) &rgb[y * rgbStride], (const char*) &src[y * rowBytes], pic.width, bpp, colors);
}
- bool ok;
- if (bpp == 3) {
- ok = SkToBool(WebPPictureImportRGB(&pic, &rgb[0], rgbStride));
- } else {
+ auto importProc = WebPPictureImportRGB;
+ if (3 != bpp) {
if (pixmap.isOpaque()) {
- ok = SkToBool(WebPPictureImportRGBX(&pic, &rgb[0], rgbStride));
+ importProc = WebPPictureImportRGBX;
} else {
- ok = SkToBool(WebPPictureImportRGBA(&pic, &rgb[0], rgbStride));
+ importProc = WebPPictureImportRGBA;
}
}
- ok = ok && WebPEncode(&webp_config, &pic);
- WebPPictureFree(&pic);
+ if (!importProc(&pic, &rgb[0], rgbStride)) {
+ return false;
+ }
- return ok;
+ if (!WebPEncode(&webp_config, &pic)) {
+ return false;
+ }
+
+ if (icc) {
+ sk_sp<SkData> encodedData = tmp.detachAsData();
+ WebPData encoded = { encodedData->bytes(), encodedData->size() };
+ WebPData iccChunk = { icc->bytes(), icc->size() };
+
+ SkAutoTCallVProc<WebPMux, WebPMuxDelete> mux(WebPMuxNew());
+ if (WEBP_MUX_OK != WebPMuxSetImage(mux, &encoded, 0)) {
+ return false;
+ }
+
+ if (WEBP_MUX_OK != WebPMuxSetChunk(mux, "ICCP", &iccChunk, 0)) {
+ return false;
+ }
+
+ WebPData assembled;
+ if (WEBP_MUX_OK != WebPMuxAssemble(mux, &assembled)) {
+ return false;
+ }
+
+ stream->write(assembled.bytes, assembled.size);
+ WebPDataClear(&assembled);
+ }
+
+ return true;
}
bool SkEncodeImageAsWEBP(SkWStream* stream, const SkPixmap& src, int quality) {
diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp
index f3a393d..3897878 100644
--- a/tests/CodecTest.cpp
+++ b/tests/CodecTest.cpp
@@ -1538,6 +1538,9 @@
case SkEncodedImageFormat::kJPEG:
SkEncodeImageAsJPEG(stream, pixmap, opts);
break;
+ case SkEncodedImageFormat::kWEBP:
+ SkEncodeImageAsWEBP(stream, pixmap, opts);
+ break;
default:
SkASSERT(false);
break;
@@ -1586,4 +1589,5 @@
DEF_TEST(Codec_EncodeICC, r) {
test_encode_icc(r, SkEncodedImageFormat::kPNG);
test_encode_icc(r, SkEncodedImageFormat::kJPEG);
+ test_encode_icc(r, SkEncodedImageFormat::kWEBP);
}
diff --git a/third_party/libwebp/BUILD.gn b/third_party/libwebp/BUILD.gn
index 3e9bd06..7fec982 100644
--- a/third_party/libwebp/BUILD.gn
+++ b/third_party/libwebp/BUILD.gn
@@ -128,6 +128,10 @@
"../externals/libwebp/src/enc/tree_enc.c",
"../externals/libwebp/src/enc/vp8l_enc.c",
"../externals/libwebp/src/enc/webp_enc.c",
+ "../externals/libwebp/src/mux/anim_encode.c",
+ "../externals/libwebp/src/mux/muxedit.c",
+ "../externals/libwebp/src/mux/muxinternal.c",
+ "../externals/libwebp/src/mux/muxread.c",
"../externals/libwebp/src/utils/bit_reader_utils.c",
"../externals/libwebp/src/utils/bit_writer_utils.c",
"../externals/libwebp/src/utils/color_cache_utils.c",