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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp

Issue 1309393007: [poc] redecode Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: resetColorProfileForTesting rename Created 5 years 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 | « third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h ('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 (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 11 matching lines...) Expand all
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29 #include "config.h" 29 #include "config.h"
30 #include "platform/image-decoders/webp/WEBPImageDecoder.h" 30 #include "platform/image-decoders/webp/WEBPImageDecoder.h"
31 31
32 #include "platform/graphics/GraphicsScreen.h"
33
32 #if USE(QCMSLIB) 34 #if USE(QCMSLIB)
33 #include "qcms.h" 35 #include "qcms.h"
34 #endif 36 #endif
35 37
36 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) 38 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN)
37 #error Blink assumes a little-endian target. 39 #error Blink assumes a little-endian target.
38 #endif 40 #endif
39 41
40 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). 42 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android).
41 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M ODE_RGBA; } 43 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M ODE_RGBA; }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 , m_hasColorProfile(false) 132 , m_hasColorProfile(false)
131 #if USE(QCMSLIB) 133 #if USE(QCMSLIB)
132 , m_transform(0) 134 , m_transform(0)
133 #endif 135 #endif
134 , m_demux(0) 136 , m_demux(0)
135 , m_demuxState(WEBP_DEMUX_PARSING_HEADER) 137 , m_demuxState(WEBP_DEMUX_PARSING_HEADER)
136 , m_haveAlreadyParsedThisData(false) 138 , m_haveAlreadyParsedThisData(false)
137 , m_repetitionCount(cAnimationLoopOnce) 139 , m_repetitionCount(cAnimationLoopOnce)
138 , m_decodedHeight(0) 140 , m_decodedHeight(0)
139 { 141 {
142 fprintf(stderr, "WEBP decoder %p created %s\n", this, !isMainThread() ? "imp l-side-thread" : "");
143
140 m_blendFunction = (alphaOption == AlphaPremultiplied) ? alphaBlendPremultipl ied : alphaBlendNonPremultiplied; 144 m_blendFunction = (alphaOption == AlphaPremultiplied) ? alphaBlendPremultipl ied : alphaBlendNonPremultiplied;
141 } 145 }
142 146
143 WEBPImageDecoder::~WEBPImageDecoder() 147 WEBPImageDecoder::~WEBPImageDecoder()
144 { 148 {
145 clear(); 149 clear();
146 } 150 }
147 151
148 void WEBPImageDecoder::clear() 152 void WEBPImageDecoder::clear()
149 { 153 {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 // Repetition count is the number of animation cycles to show, 235 // Repetition count is the number of animation cycles to show,
232 // where 0 means "infinite". But ImageSource::repetitionCount() 236 // where 0 means "infinite". But ImageSource::repetitionCount()
233 // returns -1 for "infinite", and 0 and up for "show the image 237 // returns -1 for "infinite", and 0 and up for "show the image
234 // animation one cycle more than the value". Subtract one here 238 // animation one cycle more than the value". Subtract one here
235 // to correctly handle the finite and infinite cases. 239 // to correctly handle the finite and infinite cases.
236 --m_repetitionCount; 240 --m_repetitionCount;
237 // FIXME: Implement ICC profile support for animated images. 241 // FIXME: Implement ICC profile support for animated images.
238 m_formatFlags &= ~ICCP_FLAG; 242 m_formatFlags &= ~ICCP_FLAG;
239 } 243 }
240 244
245 fprintf(stderr, "WEBP decoder %p headerAvailable %dx%d %s\n", this, size ().width(), size().height(), "size-only-decode");
246
241 #if USE(QCMSLIB) 247 #if USE(QCMSLIB)
242 if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile()) 248 if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile())
243 readColorProfile(); 249 readColorProfile();
244 #endif 250 #endif
245 } 251 }
246 252
247 ASSERT(isDecodedSizeAvailable()); 253 ASSERT(isDecodedSizeAvailable());
248 return true; 254 return true;
249 } 255 }
250 256
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 315
310 #if USE(QCMSLIB) 316 #if USE(QCMSLIB)
311 317
312 void WEBPImageDecoder::clearColorTransform() 318 void WEBPImageDecoder::clearColorTransform()
313 { 319 {
314 if (m_transform) 320 if (m_transform)
315 qcms_transform_release(m_transform); 321 qcms_transform_release(m_transform);
316 m_transform = 0; 322 m_transform = 0;
317 } 323 }
318 324
319 bool WEBPImageDecoder::createColorTransform(const char* data, size_t size) 325 PassRefPtr<ColorSpaceProfile> WEBPImageDecoder::createColorTransform(const char* data, size_t size)
320 { 326 {
321 clearColorTransform(); 327 clearColorTransform();
322 328
329 fprintf(stderr, "WEBP decoder %p createColorTransform ", this);
330
331 if (m_deviceProfile)
332 fprintf(stderr, ": device %p\n", m_deviceProfile.get());
333 else
334 fprintf(stderr, ": %p\n", nullptr);
335 fprintf(stderr, "image color profiles enabled: %d\n", imageColorProfilesEnab led());
336 fflush(stderr);
337
323 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); 338 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
339 if (m_deviceProfile)
340 deviceProfile = m_deviceProfile->profile();
324 if (!deviceProfile) 341 if (!deviceProfile)
325 return false; 342 return nullptr;
343
326 qcms_profile* inputProfile = qcms_profile_from_memory(data, size); 344 qcms_profile* inputProfile = qcms_profile_from_memory(data, size);
327 if (!inputProfile) 345 if (!inputProfile)
328 return false; 346 return nullptr;
347
348 fprintf(stderr, " from source profile [%s]", qcms_profile_get_description(in putProfile));
349 fprintf(stderr, " to [%s]\n", qcms_profile_get_description(deviceProfile));
350 fflush(stderr);
351
352 // There is no need to create a color transform if the color profiles match.
353 if (imageColorProfilesEnabled() && qcms_profile_match(inputProfile, devicePr ofile))
354 return ColorSpaceProfile::create(inputProfile);
329 355
330 // We currently only support color profiles for RGB profiled images. 356 // We currently only support color profiles for RGB profiled images.
331 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); 357 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile));
332 // The input image pixels are RGBA format. 358 // The input image pixels are RGBA format.
333 qcms_data_type format = QCMS_DATA_RGBA_8; 359 qcms_data_type format = QCMS_DATA_RGBA_8;
334 // FIXME: Don't force perceptual intent if the image profile contains an int ent. 360 // FIXME: Don't force perceptual intent if the image profile contains an int ent.
335 m_transform = qcms_transform_create(inputProfile, format, deviceProfile, QCM S_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL); 361 m_transform = qcms_transform_create(inputProfile, format, deviceProfile, QCM S_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL);
362 if (m_transform)
363 return ColorSpaceProfile::create(inputProfile);
336 364
337 qcms_profile_release(inputProfile); 365 qcms_profile_release(inputProfile);
338 return !!m_transform; 366 return nullptr;
339 } 367 }
340 368
341 void WEBPImageDecoder::readColorProfile() 369 void WEBPImageDecoder::readColorProfile()
342 { 370 {
343 WebPChunkIterator chunkIterator; 371 WebPChunkIterator chunkIterator;
344 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { 372 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) {
373 RELEASE_ASSERT(!m_hasColorProfile && !m_transform);
345 WebPDemuxReleaseChunkIterator(&chunkIterator); 374 WebPDemuxReleaseChunkIterator(&chunkIterator);
346 return; 375 return;
347 } 376 }
348 377
349 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk. bytes); 378 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk. bytes);
350 size_t profileSize = chunkIterator.chunk.size; 379 size_t profileSize = chunkIterator.chunk.size;
351 380
352 // Only accept RGB color profiles from input class devices. 381 // Only accept RGB color profiles from input class devices.
353 bool ignoreProfile = false; 382 bool ignoreProfile = false;
354 if (profileSize < ImageDecoder::iccColorProfileHeaderLength) 383 if (profileSize < ImageDecoder::iccColorProfileHeaderLength)
355 ignoreProfile = true; 384 ignoreProfile = true;
356 else if (!ImageDecoder::rgbColorProfile(profileData, profileSize)) 385 else if (!ImageDecoder::rgbColorProfile(profileData, profileSize))
357 ignoreProfile = true; 386 ignoreProfile = true;
358 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize)) 387 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize))
359 ignoreProfile = true; 388 ignoreProfile = true;
360 389
361 if (!ignoreProfile) 390 if (ignoreProfile) {
362 m_hasColorProfile = createColorTransform(profileData, profileSize); 391 RELEASE_ASSERT(!m_hasColorProfile && !m_transform);
392 WebPDemuxReleaseChunkIterator(&chunkIterator);
393 return;
394 }
395
396 RefPtr<ColorSpaceProfile> imageColorProfile = createColorTransform(profileDa ta, profileSize);
397 m_hasColorProfile = !!imageColorProfile.get();
398 if (m_hasColorProfile && imageColorProfilesEnabled()) {
399 RELEASE_ASSERT(imageColorProfile->profile());
400 m_colorProfile = imageColorProfile;
401 }
363 402
364 WebPDemuxReleaseChunkIterator(&chunkIterator); 403 WebPDemuxReleaseChunkIterator(&chunkIterator);
365 } 404 }
366 405
367 #endif // USE(QCMSLIB) 406 #endif // USE(QCMSLIB)
368 407
369 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) 408 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex)
370 { 409 {
371 ImageFrame& buffer = m_frameBufferCache[frameIndex]; 410 ImageFrame& buffer = m_frameBufferCache[frameIndex];
372 int width; 411 int width;
373 int decodedHeight; 412 int decodedHeight;
374 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0)) 413 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0))
375 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062 414 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062
376 if (decodedHeight <= 0) 415 if (decodedHeight <= 0)
377 return; 416 return;
378 417
379 const IntRect& frameRect = buffer.originalFrameRect(); 418 const IntRect& frameRect = buffer.originalFrameRect();
380 ASSERT_WITH_SECURITY_IMPLICATION(width == frameRect.width()); 419 ASSERT_WITH_SECURITY_IMPLICATION(width == frameRect.width());
381 ASSERT_WITH_SECURITY_IMPLICATION(decodedHeight <= frameRect.height()); 420 ASSERT_WITH_SECURITY_IMPLICATION(decodedHeight <= frameRect.height());
382 const int left = frameRect.x(); 421 const int left = frameRect.x();
383 const int top = frameRect.y(); 422 const int top = frameRect.y();
384 423
424 if (m_decodedHeight < decodedHeight)
425 fprintf(stderr, "WEBP decoder %p %dx%d decode row %d\n", this, size().wi dth(), size().height(), decodedHeight);
426
385 #if USE(QCMSLIB) 427 #if USE(QCMSLIB)
386 if (qcms_transform* transform = colorTransform()) { 428 if (qcms_transform* transform = colorTransform()) {
429 if (m_decodedHeight < decodedHeight)
430 fprintf(stderr, "WEBP decoder %p %dx%d color transform row %d\n", th is, size().width(), size().height(), decodedHeight);
387 for (int y = m_decodedHeight; y < decodedHeight; ++y) { 431 for (int y = m_decodedHeight; y < decodedHeight; ++y) {
388 const int canvasY = top + y; 432 const int canvasY = top + y;
389 uint8_t* row = reinterpret_cast<uint8_t*>(buffer.getAddr(left, canva sY)); 433 uint8_t* row = reinterpret_cast<uint8_t*>(buffer.getAddr(left, canva sY));
390 qcms_transform_data_type(transform, row, row, width, QCMS_OUTPUT_RGB X); 434 qcms_transform_data_type(transform, row, row, width, QCMS_OUTPUT_RGB X);
391 uint8_t* pixel = row; 435 uint8_t* pixel = row;
392 for (int x = 0; x < width; ++x, pixel += 4) { 436 for (int x = 0; x < width; ++x, pixel += 4) {
393 const int canvasX = left + x; 437 const int canvasX = left + x;
394 buffer.setRGBA(canvasX, canvasY, pixel[0], pixel[1], pixel[2], p ixel[3]); 438 buffer.setRGBA(canvasX, canvasY, pixel[0], pixel[1], pixel[2], p ixel[3]);
395 } 439 }
396 } 440 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 } 581 }
538 582
539 m_decoderBuffer.u.RGBA.rgba = reinterpret_cast<uint8_t*>(buffer.getAddr(fram eRect.x(), frameRect.y())); 583 m_decoderBuffer.u.RGBA.rgba = reinterpret_cast<uint8_t*>(buffer.getAddr(fram eRect.x(), frameRect.y()));
540 584
541 switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) { 585 switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) {
542 case VP8_STATUS_OK: 586 case VP8_STATUS_OK:
543 applyPostProcessing(frameIndex); 587 applyPostProcessing(frameIndex);
544 buffer.setHasAlpha((m_formatFlags & ALPHA_FLAG) || m_frameBackgroundHasA lpha); 588 buffer.setHasAlpha((m_formatFlags & ALPHA_FLAG) || m_frameBackgroundHasA lpha);
545 buffer.setStatus(ImageFrame::FrameComplete); 589 buffer.setStatus(ImageFrame::FrameComplete);
546 clearDecoder(); 590 clearDecoder();
591 fflush(stderr);
547 return true; 592 return true;
548 case VP8_STATUS_SUSPENDED: 593 case VP8_STATUS_SUSPENDED:
549 if (!isAllDataReceived() && !frameIsCompleteAtIndex(frameIndex)) { 594 if (!isAllDataReceived() && !frameIsCompleteAtIndex(frameIndex)) {
550 applyPostProcessing(frameIndex); 595 applyPostProcessing(frameIndex);
596 fflush(stderr);
551 return false; 597 return false;
552 } 598 }
553 // FALLTHROUGH 599 // FALLTHROUGH
554 default: 600 default:
555 clear(); 601 clear();
556 return setFailed(); 602 return setFailed();
557 } 603 }
558 } 604 }
559 605
560 } // namespace blink 606 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698