Chromium Code Reviews| 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 |