OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
3 * | 3 * |
4 * Portions are Copyright (C) 2001-6 mozilla.org | 4 * Portions are Copyright (C) 2001-6 mozilla.org |
5 * | 5 * |
6 * Other contributors: | 6 * Other contributors: |
7 * Stuart Parmenter <stuart@mozilla.com> | 7 * Stuart Parmenter <stuart@mozilla.com> |
8 * | 8 * |
9 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 9 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
10 * | 10 * |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 } | 298 } |
299 | 299 |
300 void close() | 300 void close() |
301 { | 301 { |
302 decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; | 302 decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; |
303 if (src) | 303 if (src) |
304 fastFree(src); | 304 fastFree(src); |
305 m_info.src = 0; | 305 m_info.src = 0; |
306 | 306 |
307 #if USE(QCMSLIB) | 307 #if USE(QCMSLIB) |
308 if (m_transform) | 308 clearColorTransform(); |
309 qcms_transform_release(m_transform); | |
310 m_transform = 0; | |
311 #endif | 309 #endif |
312 jpeg_destroy_decompress(&m_info); | 310 jpeg_destroy_decompress(&m_info); |
313 } | 311 } |
314 | 312 |
315 void skipBytes(long numBytes) | 313 void skipBytes(long numBytes) |
316 { | 314 { |
317 decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; | 315 decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; |
318 long bytesToSkip = std::min(numBytes, (long)src->pub.bytes_in_buffer); | 316 long bytesToSkip = std::min(numBytes, (long)src->pub.bytes_in_buffer); |
319 src->pub.bytes_in_buffer -= (size_t)bytesToSkip; | 317 src->pub.bytes_in_buffer -= (size_t)bytesToSkip; |
320 src->pub.next_input_byte += bytesToSkip; | 318 src->pub.next_input_byte += bytesToSkip; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height)
; | 382 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height)
; |
385 | 383 |
386 m_decoder->setOrientation(readImageOrientation(info())); | 384 m_decoder->setOrientation(readImageOrientation(info())); |
387 | 385 |
388 #if USE(QCMSLIB) | 386 #if USE(QCMSLIB) |
389 // Allow color management of the decoded RGBA pixels if possible. | 387 // Allow color management of the decoded RGBA pixels if possible. |
390 if (!m_decoder->ignoresGammaAndColorProfile()) { | 388 if (!m_decoder->ignoresGammaAndColorProfile()) { |
391 ColorProfile colorProfile; | 389 ColorProfile colorProfile; |
392 readColorProfile(info(), colorProfile); | 390 readColorProfile(info(), colorProfile); |
393 createColorTransform(colorProfile, colorSpaceHasAlpha(m_info.out
_color_space)); | 391 createColorTransform(colorProfile, colorSpaceHasAlpha(m_info.out
_color_space)); |
| 392 m_decoder->setHasColorProfile(!!m_transform); |
| 393 if (m_transform) { |
| 394 // FIXME: paint-time color correction is assumed here. |
| 395 qcms_profile* profile = qcms_profile_from_memory(colorProfil
e.data(), colorProfile.size()); |
| 396 RefPtr<ColorSpaceProfile> imageColorProfile = ColorSpaceProf
ile::create(profile); |
| 397 bool hasColorProfile = !!imageColorProfile->profile(); |
| 398 m_decoder->setHasColorProfile(hasColorProfile); |
| 399 m_decoder->setColorProfile(hasColorProfile ? imageColorProfi
le : nullptr); |
| 400 // Don't color correct decoded frames during decoding. |
| 401 clearColorTransform(); |
| 402 ASSERT(!m_transform); |
| 403 } |
394 #if defined(TURBO_JPEG_RGB_SWIZZLE) | 404 #if defined(TURBO_JPEG_RGB_SWIZZLE) |
395 // Input RGBA data to qcms. Note: restored to BGRA on output. | 405 // Input RGBA data to qcms. Note: restored to BGRA on output. |
396 if (m_transform && m_info.out_color_space == JCS_EXT_BGRA) | 406 if (m_transform && m_info.out_color_space == JCS_EXT_BGRA) |
397 m_info.out_color_space = JCS_EXT_RGBA; | 407 m_info.out_color_space = JCS_EXT_RGBA; |
398 #endif | 408 #endif |
399 m_decoder->setHasColorProfile(!!m_transform); | |
400 } | 409 } |
401 #endif | 410 #endif |
402 // Don't allocate a giant and superfluous memory buffer when the | 411 // Don't allocate a giant and superfluous memory buffer when the |
403 // image is a sequential JPEG. | 412 // image is a sequential JPEG. |
404 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); | 413 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); |
405 | 414 |
406 if (onlySize) { | 415 if (onlySize) { |
407 // We can stop here. Reduce our buffer length and available data
. | 416 // We can stop here. Reduce our buffer length and available data
. |
408 m_bufferLength -= m_info.src->bytes_in_buffer; | 417 m_bufferLength -= m_info.src->bytes_in_buffer; |
409 m_info.src->bytes_in_buffer = 0; | 418 m_info.src->bytes_in_buffer = 0; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 | 523 |
515 return true; | 524 return true; |
516 } | 525 } |
517 | 526 |
518 jpeg_decompress_struct* info() { return &m_info; } | 527 jpeg_decompress_struct* info() { return &m_info; } |
519 JSAMPARRAY samples() const { return m_samples; } | 528 JSAMPARRAY samples() const { return m_samples; } |
520 JPEGImageDecoder* decoder() { return m_decoder; } | 529 JPEGImageDecoder* decoder() { return m_decoder; } |
521 #if USE(QCMSLIB) | 530 #if USE(QCMSLIB) |
522 qcms_transform* colorTransform() const { return m_transform; } | 531 qcms_transform* colorTransform() const { return m_transform; } |
523 | 532 |
524 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) | 533 void clearColorTransform() |
525 { | 534 { |
526 if (m_transform) | 535 if (m_transform) |
527 qcms_transform_release(m_transform); | 536 qcms_transform_release(m_transform); |
528 m_transform = 0; | 537 m_transform = 0; |
| 538 } |
529 | 539 |
| 540 void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha) |
| 541 { |
| 542 clearColorTransform(); |
530 if (colorProfile.isEmpty()) | 543 if (colorProfile.isEmpty()) |
531 return; | 544 return; |
532 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); | 545 qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile(); |
533 if (!deviceProfile) | 546 if (!deviceProfile) |
534 return; | 547 return; |
535 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(
), colorProfile.size()); | 548 qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(
), colorProfile.size()); |
536 if (!inputProfile) | 549 if (!inputProfile) |
537 return; | 550 return; |
538 // We currently only support color profiles for RGB profiled images. | 551 // We currently only support color profiles for RGB profiled images. |
539 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); | 552 ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile)); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 if (frame.status() != ImageFrame::FrameComplete) { | 671 if (frame.status() != ImageFrame::FrameComplete) { |
659 PlatformInstrumentation::willDecodeImage("JPEG"); | 672 PlatformInstrumentation::willDecodeImage("JPEG"); |
660 decode(false); | 673 decode(false); |
661 PlatformInstrumentation::didDecodeImage(); | 674 PlatformInstrumentation::didDecodeImage(); |
662 } | 675 } |
663 | 676 |
664 frame.notifyBitmapIfPixelsChanged(); | 677 frame.notifyBitmapIfPixelsChanged(); |
665 return &frame; | 678 return &frame; |
666 } | 679 } |
667 | 680 |
| 681 PassRefPtr<ColorSpaceProfile> JPEGImageDecoder::colorProfile() const |
| 682 { |
| 683 #if USE(QCMSLIB) |
| 684 return m_colorProfile; |
| 685 #else |
| 686 return nullptr; |
| 687 #endif |
| 688 } |
| 689 |
668 bool JPEGImageDecoder::setFailed() | 690 bool JPEGImageDecoder::setFailed() |
669 { | 691 { |
670 m_reader.clear(); | 692 m_reader.clear(); |
671 return ImageDecoder::setFailed(); | 693 return ImageDecoder::setFailed(); |
672 } | 694 } |
673 | 695 |
674 template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame
::PixelData* pixel, JSAMPARRAY samples, int column) | 696 template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame
::PixelData* pixel, JSAMPARRAY samples, int column) |
675 { | 697 { |
676 JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4); | 698 JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4); |
677 | 699 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 // has failed. | 820 // has failed. |
799 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 821 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
800 setFailed(); | 822 setFailed(); |
801 // If we're done decoding the image, we don't need the JPEGImageReader | 823 // If we're done decoding the image, we don't need the JPEGImageReader |
802 // anymore. (If we failed, |m_reader| has already been cleared.) | 824 // anymore. (If we failed, |m_reader| has already been cleared.) |
803 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) | 825 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) |
804 m_reader.clear(); | 826 m_reader.clear(); |
805 } | 827 } |
806 | 828 |
807 } | 829 } |
OLD | NEW |