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 SkAutoTCallVProc<WebPDemuxer, WebPDemuxDelete> demux(WebPDemuxPartial(&d
ata, &state)); |
| 110 |
| 111 WebPChunkIterator chunkIterator; |
| 112 SkAutoTCallVProc<WebPChunkIterator, WebPDemuxReleaseChunkIterator> autoC
I(&chunkIterator); |
| 113 if (demux && WebPDemuxGetChunk(demux, "ICCP", 1, &chunkIterator)) { |
| 114 colorSpace = SkColorSpace::NewICC(chunkIterator.chunk.bytes, chunkIt
erator.chunk.size); |
| 115 } |
| 116 } |
| 117 |
| 118 if (!colorSpace) { |
| 119 colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); |
| 120 } |
| 121 |
100 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); | 122 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); |
101 return new SkWebpCodec(features.width, features.height, info, streamDeleter.
release()); | 123 return new SkWebpCodec(features.width, features.height, info, colorSpace, |
| 124 streamDeleter.release()); |
102 } | 125 } |
103 | 126 |
104 // This version is slightly different from SkCodecPriv's version of conversion_p
ossible. It | 127 // This version is slightly different from SkCodecPriv's version of conversion_p
ossible. It |
105 // supports both byte orders for 8888. | 128 // supports both byte orders for 8888. |
106 static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo&
src) { | 129 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())) { | 130 if (!valid_alpha(dst.alphaType(), src.alphaType())) { |
113 return false; | 131 return false; |
114 } | 132 } |
115 | 133 |
116 switch (dst.colorType()) { | 134 switch (dst.colorType()) { |
117 // Both byte orders are supported. | 135 // Both byte orders are supported. |
118 case kBGRA_8888_SkColorType: | 136 case kBGRA_8888_SkColorType: |
119 case kRGBA_8888_SkColorType: | 137 case kRGBA_8888_SkColorType: |
120 return true; | 138 return true; |
121 case kRGB_565_SkColorType: | 139 case kRGB_565_SkColorType: |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 return kSuccess; | 282 return kSuccess; |
265 case VP8_STATUS_SUSPENDED: | 283 case VP8_STATUS_SUSPENDED: |
266 // Break out of the switch statement. Continue the loop. | 284 // Break out of the switch statement. Continue the loop. |
267 break; | 285 break; |
268 default: | 286 default: |
269 return kInvalidInput; | 287 return kInvalidInput; |
270 } | 288 } |
271 } | 289 } |
272 } | 290 } |
273 | 291 |
274 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, SkStr
eam* stream) | 292 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, |
275 // The spec says an unmarked image is sRGB, so we return that space here. | 293 sk_sp<SkColorSpace> colorSpace, SkStream* stream) |
276 // TODO: Add support for parsing ICC profiles from webps. | 294 : INHERITED(width, height, info, stream, colorSpace) |
277 : INHERITED(width, height, info, stream, SkColorSpace::NewNamed(SkColorSpace
::kSRGB_Named)) {} | 295 {} |
OLD | NEW |