| OLD | NEW |
| 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 10 matching lines...) Expand all Loading... |
| 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 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 "platform/image-decoders/webp/WEBPImageDecoder.h" | 29 #include "platform/image-decoders/webp/WEBPImageDecoder.h" |
| 30 | 30 |
| 31 #include "platform/graphics/GraphicsScreen.h" |
| 32 |
| 31 #if USE(QCMSLIB) | 33 #if USE(QCMSLIB) |
| 32 #include "qcms.h" | 34 #include "qcms.h" |
| 33 #endif | 35 #endif |
| 34 | 36 |
| 35 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) | 37 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) |
| 36 #error Blink assumes a little-endian target. | 38 #error Blink assumes a little-endian target. |
| 37 #endif | 39 #endif |
| 38 | 40 |
| 39 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). | 41 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). |
| 40 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M
ODE_RGBA; } | 42 inline WEBP_CSP_MODE outputMode(bool hasAlpha) { return hasAlpha ? MODE_rgbA : M
ODE_RGBA; } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 310 |
| 309 #if USE(QCMSLIB) | 311 #if USE(QCMSLIB) |
| 310 | 312 |
| 311 void WEBPImageDecoder::clearColorTransform() | 313 void WEBPImageDecoder::clearColorTransform() |
| 312 { | 314 { |
| 313 if (m_transform) | 315 if (m_transform) |
| 314 qcms_transform_release(m_transform); | 316 qcms_transform_release(m_transform); |
| 315 m_transform = 0; | 317 m_transform = 0; |
| 316 } | 318 } |
| 317 | 319 |
| 318 bool WEBPImageDecoder::createColorTransform(const char* data, size_t size) | 320 PassRefPtr<ColorSpaceProfile> WEBPImageDecoder::createColorTransform(const char*
data, size_t size) |
| 319 { | 321 { |
| 320 clearColorTransform(); | 322 clearColorTransform(); |
| 321 | 323 |
| 322 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); | 324 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); |
| 323 if (!deviceProfile) | 325 if (!deviceProfile) |
| 324 return false; | 326 return nullptr; |
| 327 |
| 325 qcms_profile* inputProfile = qcms_profile_from_memory(data, size); | 328 qcms_profile* inputProfile = qcms_profile_from_memory(data, size); |
| 326 if (!inputProfile) | 329 if (!inputProfile) |
| 327 return false; | 330 return nullptr; |
| 331 |
| 332 if (imageColorProfilesEnabled()) |
| 333 return ColorSpaceProfile::create(inputProfile); |
| 328 | 334 |
| 329 // We currently only support color profiles for RGB profiled images. | 335 // We currently only support color profiles for RGB profiled images. |
| 330 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); | 336 ASSERT(rgbData == qcms_profile_get_color_space(inputProfile)); |
| 331 | 337 |
| 332 if (qcms_profile_match(inputProfile, deviceProfile)) { | 338 if (qcms_profile_match(inputProfile, deviceProfile)) { |
| 333 qcms_profile_release(inputProfile); | 339 qcms_profile_release(inputProfile); |
| 334 return false; | 340 return nullptr; |
| 335 } | 341 } |
| 336 | 342 |
| 337 // The input image pixels are RGBA format. | 343 // The input image pixels are RGBA format. |
| 338 qcms_data_type format = QCMS_DATA_RGBA_8; | 344 qcms_data_type format = QCMS_DATA_RGBA_8; |
| 339 // FIXME: Don't force perceptual intent if the image profile contains an int
ent. | 345 // FIXME: Don't force perceptual intent if the image profile contains an int
ent. |
| 340 m_transform = qcms_transform_create(inputProfile, format, deviceProfile, QCM
S_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL); | 346 m_transform = qcms_transform_create(inputProfile, format, deviceProfile, QCM
S_DATA_RGBA_8, QCMS_INTENT_PERCEPTUAL); |
| 341 | 347 |
| 348 if (m_transform) |
| 349 return ColorSpaceProfile::create(inputProfile); |
| 350 |
| 342 qcms_profile_release(inputProfile); | 351 qcms_profile_release(inputProfile); |
| 343 return !!m_transform; | 352 return nullptr; |
| 344 } | 353 } |
| 345 | 354 |
| 346 void WEBPImageDecoder::readColorProfile() | 355 void WEBPImageDecoder::readColorProfile() |
| 347 { | 356 { |
| 348 WebPChunkIterator chunkIterator; | 357 WebPChunkIterator chunkIterator; |
| 349 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { | 358 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { |
| 359 RELEASE_ASSERT(!m_hasColorProfile && !m_transform); |
| 350 WebPDemuxReleaseChunkIterator(&chunkIterator); | 360 WebPDemuxReleaseChunkIterator(&chunkIterator); |
| 351 return; | 361 return; |
| 352 } | 362 } |
| 353 | 363 |
| 354 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.
bytes); | 364 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.
bytes); |
| 355 size_t profileSize = chunkIterator.chunk.size; | 365 size_t profileSize = chunkIterator.chunk.size; |
| 356 | 366 |
| 357 // Only accept RGB color profiles from input class devices. | 367 // Only accept RGB color profiles from input class devices. |
| 358 bool ignoreProfile = false; | 368 bool ignoreProfile = false; |
| 359 if (profileSize < ImageDecoder::iccColorProfileHeaderLength) | 369 if (profileSize < ImageDecoder::iccColorProfileHeaderLength) |
| 360 ignoreProfile = true; | 370 ignoreProfile = true; |
| 361 else if (!ImageDecoder::rgbColorProfile(profileData, profileSize)) | 371 else if (!ImageDecoder::rgbColorProfile(profileData, profileSize)) |
| 362 ignoreProfile = true; | 372 ignoreProfile = true; |
| 363 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize)) | 373 else if (!ImageDecoder::inputDeviceColorProfile(profileData, profileSize)) |
| 364 ignoreProfile = true; | 374 ignoreProfile = true; |
| 365 | 375 |
| 366 if (!ignoreProfile) | 376 if (ignoreProfile) { |
| 367 m_hasColorProfile = createColorTransform(profileData, profileSize); | 377 RELEASE_ASSERT(!m_hasColorProfile && !m_transform); |
| 378 WebPDemuxReleaseChunkIterator(&chunkIterator); |
| 379 return; |
| 380 } |
| 381 |
| 382 RefPtr<ColorSpaceProfile> imageColorProfile = createColorTransform(profileDa
ta, profileSize); |
| 383 m_hasColorProfile = !!imageColorProfile.get(); |
| 384 |
| 385 if (m_hasColorProfile && imageColorProfilesEnabled()) { |
| 386 RELEASE_ASSERT(imageColorProfile->profile()); |
| 387 m_colorProfile = imageColorProfile; |
| 388 // Do not color correct decoded frames during decoding. |
| 389 clearColorTransform(); |
| 390 RELEASE_ASSERT(!m_transform); |
| 391 } |
| 368 | 392 |
| 369 WebPDemuxReleaseChunkIterator(&chunkIterator); | 393 WebPDemuxReleaseChunkIterator(&chunkIterator); |
| 370 } | 394 } |
| 371 | 395 |
| 372 #endif // USE(QCMSLIB) | 396 #endif // USE(QCMSLIB) |
| 373 | 397 |
| 374 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) | 398 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) |
| 375 { | 399 { |
| 376 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 400 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 377 int width; | 401 int width; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 return false; | 580 return false; |
| 557 } | 581 } |
| 558 // FALLTHROUGH | 582 // FALLTHROUGH |
| 559 default: | 583 default: |
| 560 clear(); | 584 clear(); |
| 561 return setFailed(); | 585 return setFailed(); |
| 562 } | 586 } |
| 563 } | 587 } |
| 564 | 588 |
| 565 } // namespace blink | 589 } // namespace blink |
| OLD | NEW |