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 |