OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCodecPriv.h" | 8 #include "SkCodecPriv.h" |
9 #include "SkWebpCodec.h" | 9 #include "SkWebpCodec.h" |
10 #include "SkTemplates.h" | 10 #include "SkTemplates.h" |
11 | 11 |
12 // A WebP decoder on top of (subset of) libwebp | 12 // A WebP decoder on top of (subset of) libwebp |
13 // For more information on WebP image format, and libwebp library, see: | 13 // For more information on WebP image format, and libwebp library, see: |
14 // https://code.google.com/speed/webp/ | 14 // https://code.google.com/speed/webp/ |
15 // http://www.webmproject.org/code/#libwebp-webp-image-library | 15 // http://www.webmproject.org/code/#libwebp-webp-image-library |
16 // https://chromium.googlesource.com/webm/libwebp | 16 // https://chromium.googlesource.com/webm/libwebp |
17 | 17 |
18 // If moving libwebp out of skia source tree, path for webp headers must be | 18 // If moving libwebp out of skia source tree, path for webp headers must be |
19 // updated accordingly. Here, we enforce using local copy in webp sub-directory. | 19 // updated accordingly. Here, we enforce using local copy in webp sub-directory. |
20 #include "webp/decode.h" | 20 #include "webp/decode.h" |
21 #include "webp/demux.h" | |
21 #include "webp/encode.h" | 22 #include "webp/encode.h" |
22 | 23 |
23 bool SkWebpCodec::IsWebp(const void* buf, size_t bytesRead) { | 24 bool SkWebpCodec::IsWebp(const void* buf, size_t bytesRead) { |
24 // WEBP starts with the following: | 25 // WEBP starts with the following: |
25 // RIFFXXXXWEBPVP | 26 // RIFFXXXXWEBPVP |
26 // Where XXXX is unspecified. | 27 // Where XXXX is unspecified. |
27 const char* bytes = static_cast<const char*>(buf); | 28 const char* bytes = static_cast<const char*>(buf); |
28 return bytesRead >= 14 && !memcmp(bytes, "RIFF", 4) && !memcmp(&bytes[8], "W EBPVP", 6); | 29 return bytesRead >= 14 && !memcmp(bytes, "RIFF", 4) && !memcmp(&bytes[8], "W EBPVP", 6); |
29 } | 30 } |
30 | 31 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 break; | 91 break; |
91 case 2: | 92 case 2: |
92 // This is the lossless format (BGRA). | 93 // This is the lossless format (BGRA). |
93 color = SkEncodedInfo::kBGRA_Color; | 94 color = SkEncodedInfo::kBGRA_Color; |
94 alpha = SkEncodedInfo::kUnpremul_Alpha; | 95 alpha = SkEncodedInfo::kUnpremul_Alpha; |
95 break; | 96 break; |
96 default: | 97 default: |
97 return nullptr; | 98 return nullptr; |
98 } | 99 } |
99 | 100 |
101 // FIXME (msarett): | |
102 // Temporary strategy for getting ICC profiles from webps. Once the increme ntal decoding | |
103 // API lands, we will use the WebPDemuxer to manage the entire decode. | |
104 sk_sp<SkColorSpace> colorSpace = nullptr; | |
105 const void* memory = stream->getMemoryBase(); | |
106 if (memory) { | |
107 WebPData data = { (const uint8_t*) memory, stream->getLength() }; | |
108 WebPDemuxState state; | |
109 WebPDemuxer* demux = WebPDemuxPartial(&data, &state); | |
mtklein
2016/08/24 12:56:50
Might want to see what this all looks like using a
msarett
2016/08/24 13:14:24
Done.
| |
110 WebPChunkIterator chunkIterator; | |
111 if (WebPDemuxGetChunk(demux, "ICCP", 1, &chunkIterator)) { | |
112 const void* profileData = chunkIterator.chunk.bytes; | |
113 size_t profileSize = chunkIterator.chunk.size; | |
114 colorSpace = SkColorSpace::NewICC(profileData, profileSize); | |
mtklein
2016/08/24 12:56:50
I might just skip some of the intermediate names h
msarett
2016/08/24 13:14:24
Done.
| |
115 } | |
116 WebPDemuxReleaseChunkIterator(&chunkIterator); | |
117 WebPDemuxDelete(demux); | |
118 } | |
119 | |
120 if (!colorSpace) { | |
121 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); | |
122 } | |
123 | |
100 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); | 124 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); |
101 return new SkWebpCodec(features.width, features.height, info, streamDeleter. release()); | 125 return new SkWebpCodec(features.width, features.height, info, colorSpace, |
126 streamDeleter.release()); | |
102 } | 127 } |
103 | 128 |
104 // This version is slightly different from SkCodecPriv's version of conversion_p ossible. It | 129 // This version is slightly different from SkCodecPriv's version of conversion_p ossible. It |
105 // supports both byte orders for 8888. | 130 // supports both byte orders for 8888. |
106 static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) { | 131 static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) { |
107 // FIXME: skbug.com/4895 | |
108 // Currently, we ignore the SkColorProfileType on the SkImageInfo. We | |
109 // will treat the encoded data as linear regardless of what the client | |
110 // requests. | |
111 | |
112 if (!valid_alpha(dst.alphaType(), src.alphaType())) { | 132 if (!valid_alpha(dst.alphaType(), src.alphaType())) { |
113 return false; | 133 return false; |
114 } | 134 } |
115 | 135 |
116 switch (dst.colorType()) { | 136 switch (dst.colorType()) { |
117 // Both byte orders are supported. | 137 // Both byte orders are supported. |
118 case kBGRA_8888_SkColorType: | 138 case kBGRA_8888_SkColorType: |
119 case kRGBA_8888_SkColorType: | 139 case kRGBA_8888_SkColorType: |
120 return true; | 140 return true; |
121 case kRGB_565_SkColorType: | 141 case kRGB_565_SkColorType: |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 return kSuccess; | 284 return kSuccess; |
265 case VP8_STATUS_SUSPENDED: | 285 case VP8_STATUS_SUSPENDED: |
266 // Break out of the switch statement. Continue the loop. | 286 // Break out of the switch statement. Continue the loop. |
267 break; | 287 break; |
268 default: | 288 default: |
269 return kInvalidInput; | 289 return kInvalidInput; |
270 } | 290 } |
271 } | 291 } |
272 } | 292 } |
273 | 293 |
274 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, SkStr eam* stream) | 294 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, |
275 // The spec says an unmarked image is sRGB, so we return that space here. | 295 sk_sp<SkColorSpace> colorSpace, SkStream* stream) |
276 // TODO: Add support for parsing ICC profiles from webps. | 296 : INHERITED(width, height, info, stream, colorSpace) |
277 : INHERITED(width, height, info, stream, SkColorSpace::NewNamed(SkColorSpace ::kSRGB_Named)) {} | 297 {} |
OLD | NEW |