| 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 |