aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--resources/webp-color-profile-crash.webpbin0 -> 35882 bytes
-rw-r--r--resources/webp-color-profile-lossless.webpbin0 -> 43866 bytes
-rw-r--r--resources/webp-color-profile-lossy-alpha.webpbin0 -> 16018 bytes
-rw-r--r--resources/webp-color-profile-lossy.webpbin0 -> 19436 bytes
-rw-r--r--src/codec/SkWebpCodec.cpp38
-rw-r--r--src/codec/SkWebpCodec.h2
-rw-r--r--tests/ColorSpaceTest.cpp66
7 files changed, 62 insertions, 44 deletions
diff --git a/resources/webp-color-profile-crash.webp b/resources/webp-color-profile-crash.webp
new file mode 100644
index 0000000000..3b0904e0f2
--- /dev/null
+++ b/resources/webp-color-profile-crash.webp
Binary files differ
diff --git a/resources/webp-color-profile-lossless.webp b/resources/webp-color-profile-lossless.webp
new file mode 100644
index 0000000000..4fd63d5794
--- /dev/null
+++ b/resources/webp-color-profile-lossless.webp
Binary files differ
diff --git a/resources/webp-color-profile-lossy-alpha.webp b/resources/webp-color-profile-lossy-alpha.webp
new file mode 100644
index 0000000000..1a13084e77
--- /dev/null
+++ b/resources/webp-color-profile-lossy-alpha.webp
Binary files differ
diff --git a/resources/webp-color-profile-lossy.webp b/resources/webp-color-profile-lossy.webp
new file mode 100644
index 0000000000..fdff0a9941
--- /dev/null
+++ b/resources/webp-color-profile-lossy.webp
Binary files differ
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index e4341421bb..c28d077bb3 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -18,6 +18,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/decode.h"
+#include "webp/demux.h"
#include "webp/encode.h"
bool SkWebpCodec::IsWebp(const void* buf, size_t bytesRead) {
@@ -97,18 +98,35 @@ SkCodec* SkWebpCodec::NewFromStream(SkStream* stream) {
return nullptr;
}
+ // FIXME (msarett):
+ // Temporary strategy for getting ICC profiles from webps. Once the incremental decoding
+ // API lands, we will use the WebPDemuxer to manage the entire decode.
+ sk_sp<SkColorSpace> colorSpace = nullptr;
+ const void* memory = stream->getMemoryBase();
+ if (memory) {
+ WebPData data = { (const uint8_t*) memory, stream->getLength() };
+ WebPDemuxState state;
+ SkAutoTCallVProc<WebPDemuxer, WebPDemuxDelete> demux(WebPDemuxPartial(&data, &state));
+
+ WebPChunkIterator chunkIterator;
+ SkAutoTCallVProc<WebPChunkIterator, WebPDemuxReleaseChunkIterator> autoCI(&chunkIterator);
+ if (demux && WebPDemuxGetChunk(demux, "ICCP", 1, &chunkIterator)) {
+ colorSpace = SkColorSpace::NewICC(chunkIterator.chunk.bytes, chunkIterator.chunk.size);
+ }
+ }
+
+ if (!colorSpace) {
+ colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
+ }
+
SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8);
- return new SkWebpCodec(features.width, features.height, info, streamDeleter.release());
+ return new SkWebpCodec(features.width, features.height, info, colorSpace,
+ streamDeleter.release());
}
// This version is slightly different from SkCodecPriv's version of conversion_possible. It
// supports both byte orders for 8888.
static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) {
- // FIXME: skbug.com/4895
- // Currently, we ignore the SkColorProfileType on the SkImageInfo. We
- // will treat the encoded data as linear regardless of what the client
- // requests.
-
if (!valid_alpha(dst.alphaType(), src.alphaType())) {
return false;
}
@@ -271,7 +289,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
}
}
-SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream)
- // The spec says an unmarked image is sRGB, so we return that space here.
- // TODO: Add support for parsing ICC profiles from webps.
- : INHERITED(width, height, info, stream, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named)) {}
+SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info,
+ sk_sp<SkColorSpace> colorSpace, SkStream* stream)
+ : INHERITED(width, height, info, stream, colorSpace)
+{}
diff --git a/src/codec/SkWebpCodec.h b/src/codec/SkWebpCodec.h
index 908bf2cd4f..6fda7c2824 100644
--- a/src/codec/SkWebpCodec.h
+++ b/src/codec/SkWebpCodec.h
@@ -34,7 +34,7 @@ protected:
bool onGetValidSubset(SkIRect* /* desiredSubset */) const override;
private:
- SkWebpCodec(int width, int height, const SkEncodedInfo&, SkStream*);
+ SkWebpCodec(int width, int height, const SkEncodedInfo&, sk_sp<SkColorSpace>, SkStream*);
typedef SkCodec INHERITED;
};
diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp
index 393d75310b..3eb145b2e8 100644
--- a/tests/ColorSpaceTest.cpp
+++ b/tests/ColorSpaceTest.cpp
@@ -21,9 +21,9 @@ static void test_space(skiatest::Reporter* r, SkColorSpace* space,
const float red[], const float green[], const float blue[],
const SkColorSpace::GammaNamed expectedGamma) {
+ REPORTER_ASSERT(r, nullptr != space);
REPORTER_ASSERT(r, expectedGamma == space->gammaNamed());
-
const SkMatrix44& mat = space->xyz();
const float src[] = {
1, 0, 0, 1,
@@ -39,23 +39,15 @@ static void test_space(skiatest::Reporter* r, SkColorSpace* space,
}
}
-const float g_sRGB_XYZ[] = { 0.4358f, 0.2224f, 0.0139f, // R
- 0.3853f, 0.7170f, 0.0971f, // G
- 0.1430f, 0.0606f, 0.7139f }; // B
-
-DEF_TEST(ColorSpace_sRGB, r) {
- test_space(r, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).get(),
- g_sRGB_XYZ, &g_sRGB_XYZ[3], &g_sRGB_XYZ[6], SkColorSpace::kSRGB_GammaNamed);
-
-}
-
static SkStreamAsset* resource(const char path[]) {
SkString fullPath = GetResourcePath(path);
return SkStream::NewFromFile(fullPath.c_str());
}
-DEF_TEST(ColorSpaceParsePngICCProfile, r) {
- SkAutoTDelete<SkStream> stream(resource("color_wheel_with_profile.png"));
+static void test_path(skiatest::Reporter* r, const char* path,
+ const float red[], const float green[], const float blue[],
+ const SkColorSpace::GammaNamed expectedGamma) {
+ SkAutoTDelete<SkStream> stream(resource(path));
REPORTER_ASSERT(r, nullptr != stream);
if (!stream) {
return;
@@ -63,36 +55,44 @@ DEF_TEST(ColorSpaceParsePngICCProfile, r) {
SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release()));
REPORTER_ASSERT(r, nullptr != codec);
+ if (!codec) {
+ return;
+ }
-#if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6)
SkColorSpace* colorSpace = codec->getInfo().colorSpace();
- REPORTER_ASSERT(r, nullptr != colorSpace);
-
- test_space(r, colorSpace, &g_sRGB_XYZ[0], &g_sRGB_XYZ[3], &g_sRGB_XYZ[6],
- SkColorSpace::kSRGB_GammaNamed);
-#endif
+ test_space(r, colorSpace, red, green, blue, expectedGamma);
}
-DEF_TEST(ColorSpaceParseJpegICCProfile, r) {
- SkAutoTDelete<SkStream> stream(resource("icc-v2-gbr.jpg"));
- REPORTER_ASSERT(r, nullptr != stream);
- if (!stream) {
- return;
- }
+const float g_sRGB_XYZ[] = { 0.4358f, 0.2224f, 0.0139f, // R
+ 0.3853f, 0.7170f, 0.0971f, // G
+ 0.1430f, 0.0606f, 0.7139f }; // B
- SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release()));
- REPORTER_ASSERT(r, nullptr != codec);
- if (!codec) {
- return;
- }
+DEF_TEST(ColorSpace_sRGB, r) {
+ test_space(r, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).get(),
+ g_sRGB_XYZ, &g_sRGB_XYZ[3], &g_sRGB_XYZ[6], SkColorSpace::kSRGB_GammaNamed);
- SkColorSpace* colorSpace = codec->getInfo().colorSpace();
- REPORTER_ASSERT(r, nullptr != colorSpace);
+}
+
+DEF_TEST(ColorSpaceParseICCProfiles, r) {
+
+#if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6)
+ test_path(r, "color_wheel_with_profile.png", &g_sRGB_XYZ[0], &g_sRGB_XYZ[3], &g_sRGB_XYZ[6],
+ SkColorSpace::kSRGB_GammaNamed);
+#endif
const float red[] = { 0.385117f, 0.716904f, 0.0970612f };
const float green[] = { 0.143051f, 0.0606079f, 0.713913f };
const float blue[] = { 0.436035f, 0.222488f, 0.013916f };
- test_space(r, colorSpace, red, green, blue, SkColorSpace::k2Dot2Curve_GammaNamed);
+ test_path(r, "icc-v2-gbr.jpg", red, green, blue, SkColorSpace::k2Dot2Curve_GammaNamed);
+
+ test_path(r, "webp-color-profile-crash.webp",
+ red, green, blue, SkColorSpace::kNonStandard_GammaNamed);
+ test_path(r, "webp-color-profile-lossless.webp",
+ red, green, blue, SkColorSpace::kNonStandard_GammaNamed);
+ test_path(r, "webp-color-profile-lossy.webp",
+ red, green, blue, SkColorSpace::kNonStandard_GammaNamed);
+ test_path(r, "webp-color-profile-lossy-alpha.webp",
+ red, green, blue, SkColorSpace::kNonStandard_GammaNamed);
}
DEF_TEST(ColorSpaceSRGBCompare, r) {