Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: src/codec/SkWebpCodec.cpp

Issue 2318253004: Revert of Add color xform support to SkWebpCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkPngCodec.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkColorSpaceXform.h"
10 #include "SkWebpCodec.h" 9 #include "SkWebpCodec.h"
11 #include "SkStreamPriv.h" 10 #include "SkStreamPriv.h"
12 #include "SkTemplates.h" 11 #include "SkTemplates.h"
13 12
14 // A WebP decoder on top of (subset of) libwebp 13 // A WebP decoder on top of (subset of) libwebp
15 // For more information on WebP image format, and libwebp library, see: 14 // For more information on WebP image format, and libwebp library, see:
16 // https://code.google.com/speed/webp/ 15 // https://code.google.com/speed/webp/
17 // http://www.webmproject.org/code/#libwebp-webp-image-library 16 // http://www.webmproject.org/code/#libwebp-webp-image-library
18 // https://chromium.googlesource.com/webm/libwebp 17 // https://chromium.googlesource.com/webm/libwebp
19 18
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 break; 136 break;
138 default: 137 default:
139 return nullptr; 138 return nullptr;
140 } 139 }
141 140
142 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8); 141 SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8);
143 return new SkWebpCodec(features.width, features.height, info, std::move(colo rSpace), 142 return new SkWebpCodec(features.width, features.height, info, std::move(colo rSpace),
144 streamDeleter.release(), demux.release(), std::move(d ata)); 143 streamDeleter.release(), demux.release(), std::move(d ata));
145 } 144 }
146 145
147 static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src, 146 // This version is slightly different from SkCodecPriv's version of conversion_p ossible. It
148 SkColorSpaceXform* colorXform) { 147 // supports both byte orders for 8888.
148 static bool webp_conversion_possible(const SkImageInfo& dst, const SkImageInfo& src) {
149 if (!valid_alpha(dst.alphaType(), src.alphaType())) { 149 if (!valid_alpha(dst.alphaType(), src.alphaType())) {
150 return false; 150 return false;
151 } 151 }
152 152
153 switch (dst.colorType()) { 153 switch (dst.colorType()) {
154 case kRGBA_F16_SkColorType: 154 // Both byte orders are supported.
155 return nullptr != colorXform;
156 case kBGRA_8888_SkColorType: 155 case kBGRA_8888_SkColorType:
157 case kRGBA_8888_SkColorType: 156 case kRGBA_8888_SkColorType:
158 return true; 157 return true;
159 case kRGB_565_SkColorType: 158 case kRGB_565_SkColorType:
160 return nullptr == colorXform && src.alphaType() == kOpaque_SkAlphaTy pe; 159 return src.alphaType() == kOpaque_SkAlphaType;
161 default: 160 default:
162 return false; 161 return false;
163 } 162 }
164 } 163 }
165 164
166 SkISize SkWebpCodec::onGetScaledDimensions(float desiredScale) const { 165 SkISize SkWebpCodec::onGetScaledDimensions(float desiredScale) const {
167 SkISize dim = this->getInfo().dimensions(); 166 SkISize dim = this->getInfo().dimensions();
168 // SkCodec treats zero dimensional images as errors, so the minimum size 167 // SkCodec treats zero dimensional images as errors, so the minimum size
169 // that we will recommend is 1x1. 168 // that we will recommend is 1x1.
170 dim.fWidth = SkTMax(1, SkScalarRoundToInt(desiredScale * dim.fWidth)); 169 dim.fWidth = SkTMax(1, SkScalarRoundToInt(desiredScale * dim.fWidth));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 // As stated below, libwebp snaps to even left and top. Make sure top and le ft are even, so we 203 // As stated below, libwebp snaps to even left and top. Make sure top and le ft are even, so we
205 // decode this exact subset. 204 // decode this exact subset.
206 // Leave right and bottom unmodified, so we suggest a slightly larger subset than requested. 205 // Leave right and bottom unmodified, so we suggest a slightly larger subset than requested.
207 desiredSubset->fLeft = (desiredSubset->fLeft >> 1) << 1; 206 desiredSubset->fLeft = (desiredSubset->fLeft >> 1) << 1;
208 desiredSubset->fTop = (desiredSubset->fTop >> 1) << 1; 207 desiredSubset->fTop = (desiredSubset->fTop >> 1) << 1;
209 return true; 208 return true;
210 } 209 }
211 210
212 SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, 211 SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
213 const Options& options, SkPMColor*, int *, 212 const Options& options, SkPMColor*, int *,
214 int* rowsDecodedPtr) { 213 int* rowsDecoded) {
215 214 if (!webp_conversion_possible(dstInfo, this->getInfo())) {
216 std::unique_ptr<SkColorSpaceXform> colorXform = nullptr;
217 if (needs_color_xform(dstInfo, this->getInfo())) {
218 colorXform = SkColorSpaceXform::New(sk_ref_sp(this->getInfo().colorSpace ()),
219 sk_ref_sp(dstInfo.colorSpace()));
220 }
221
222 if (!webp_conversion_possible(dstInfo, this->getInfo(), colorXform.get())) {
223 return kInvalidConversion; 215 return kInvalidConversion;
224 } 216 }
225 217
226 WebPDecoderConfig config; 218 WebPDecoderConfig config;
227 if (0 == WebPInitDecoderConfig(&config)) { 219 if (0 == WebPInitDecoderConfig(&config)) {
228 // ABI mismatch. 220 // ABI mismatch.
229 // FIXME: New enum for this? 221 // FIXME: New enum for this?
230 return kInvalidInput; 222 return kInvalidInput;
231 } 223 }
232 224
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 } 262 }
271 263
272 SkISize dstDimensions = dstInfo.dimensions(); 264 SkISize dstDimensions = dstInfo.dimensions();
273 if (bounds.size() != dstDimensions) { 265 if (bounds.size() != dstDimensions) {
274 // Caller is requesting scaling. 266 // Caller is requesting scaling.
275 config.options.use_scaling = 1; 267 config.options.use_scaling = 1;
276 config.options.scaled_width = dstDimensions.width(); 268 config.options.scaled_width = dstDimensions.width();
277 config.options.scaled_height = dstDimensions.height(); 269 config.options.scaled_height = dstDimensions.height();
278 } 270 }
279 271
280 // FIXME (msarett): 272 config.output.colorspace = webp_decode_mode(dstInfo.colorType(),
281 // Lossless webp is encoded as BGRA. In that case, it would be more efficie nt to 273 dstInfo.alphaType() == kPremul_SkAlphaType);
282 // to decode BGRA and apply the color xform to a BGRA buffer. 274 config.output.u.RGBA.rgba = (uint8_t*) dst;
283 config.output.colorspace = colorXform ? MODE_RGBA : 275 config.output.u.RGBA.stride = (int) rowBytes;
284 webp_decode_mode(dstInfo.colorType(), dstInfo.alphaType() == kPremul _SkAlphaType); 276 config.output.u.RGBA.size = dstInfo.getSafeSize(rowBytes);
285 config.output.is_external_memory = 1; 277 config.output.is_external_memory = 1;
286 278
287 // We will decode the entire image and then perform the color transform. li bwebp
288 // does not provide a row-by-row API. This is a shame particularly in the F 16 case,
289 // where we need to allocate an extra image-sized buffer.
290 SkAutoTMalloc<uint32_t> pixels;
291 if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
292 pixels.reset(dstDimensions.width() * dstDimensions.height());
293 config.output.u.RGBA.rgba = (uint8_t*) pixels.get();
294 config.output.u.RGBA.stride = (int) dstDimensions.width() * sizeof(uint3 2_t);
295 config.output.u.RGBA.size = config.output.u.RGBA.stride * dstDimensions. height();
296 } else {
297 config.output.u.RGBA.rgba = (uint8_t*) dst;
298 config.output.u.RGBA.stride = (int) rowBytes;
299 config.output.u.RGBA.size = dstInfo.getSafeSize(rowBytes);
300 }
301
302 WebPIterator frame; 279 WebPIterator frame;
303 SkAutoTCallVProc<WebPIterator, WebPDemuxReleaseIterator> autoFrame(&frame); 280 SkAutoTCallVProc<WebPIterator, WebPDemuxReleaseIterator> autoFrame(&frame);
304 // If this succeeded in NewFromStream(), it should succeed again here. 281 // If this succeeded in NewFromStream(), it should succeed again here.
305 SkAssertResult(WebPDemuxGetFrame(fDemux, 1, &frame)); 282 SkAssertResult(WebPDemuxGetFrame(fDemux, 1, &frame));
306 283
307 SkAutoTCallVProc<WebPIDecoder, WebPIDelete> idec(WebPIDecode(nullptr, 0, &co nfig)); 284 SkAutoTCallVProc<WebPIDecoder, WebPIDelete> idec(WebPIDecode(nullptr, 0, &co nfig));
308 if (!idec) { 285 if (!idec) {
309 return kInvalidInput; 286 return kInvalidInput;
310 } 287 }
311 288
312 int rowsDecoded;
313 SkCodec::Result result;
314 switch (WebPIUpdate(idec, frame.fragment.bytes, frame.fragment.size)) { 289 switch (WebPIUpdate(idec, frame.fragment.bytes, frame.fragment.size)) {
315 case VP8_STATUS_OK: 290 case VP8_STATUS_OK:
316 rowsDecoded = dstInfo.height(); 291 return kSuccess;
317 result = kSuccess;
318 break;
319 case VP8_STATUS_SUSPENDED: 292 case VP8_STATUS_SUSPENDED:
320 WebPIDecGetRGB(idec, rowsDecodedPtr, nullptr, nullptr, nullptr); 293 WebPIDecGetRGB(idec, rowsDecoded, nullptr, nullptr, nullptr);
321 rowsDecoded = *rowsDecodedPtr; 294 return kIncompleteInput;
322 result = kIncompleteInput;
323 break;
324 default: 295 default:
325 return kInvalidInput; 296 return kInvalidInput;
326 } 297 }
327
328 if (colorXform) {
329 SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(),
330 this->getInfo().alphaTyp e());
331
332 uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba;
333 size_t srcRowBytes = config.output.u.RGBA.stride;
334 for (int y = 0; y < rowsDecoded; y++) {
335 colorXform->apply(dst, src, dstInfo.width(), dstInfo.colorType(), xf ormAlphaType);
336 dst = SkTAddOffset<void>(dst, rowBytes);
337 src = SkTAddOffset<uint32_t>(src, srcRowBytes);
338 }
339 }
340
341 return result;
342 } 298 }
343 299
344 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info, 300 SkWebpCodec::SkWebpCodec(int width, int height, const SkEncodedInfo& info,
345 sk_sp<SkColorSpace> colorSpace, SkStream* stream, WebPD emuxer* demux, 301 sk_sp<SkColorSpace> colorSpace, SkStream* stream, WebPD emuxer* demux,
346 sk_sp<SkData> data) 302 sk_sp<SkData> data)
347 : INHERITED(width, height, info, stream, std::move(colorSpace)) 303 : INHERITED(width, height, info, stream, std::move(colorSpace))
348 , fDemux(demux) 304 , fDemux(demux)
349 , fData(std::move(data)) 305 , fData(std::move(data))
350 {} 306 {}
OLDNEW
« no previous file with comments | « src/codec/SkPngCodec.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698