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 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 } | 630 } |
631 return &frame; | 631 return &frame; |
632 } | 632 } |
633 | 633 |
634 bool JPEGImageDecoder::setFailed() | 634 bool JPEGImageDecoder::setFailed() |
635 { | 635 { |
636 m_reader.clear(); | 636 m_reader.clear(); |
637 return ImageDecoder::setFailed(); | 637 return ImageDecoder::setFailed(); |
638 } | 638 } |
639 | 639 |
640 template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame
::PixelData* pixel, JSAMPARRAY samples, int column) | 640 static bool outputRows(JPEGImageReader* reader, ImageFrame& buffer, J_COLOR_SPAC
E colorSpace) |
641 { | |
642 JSAMPLE* jsample = *samples + column * (colorSpace == JCS_RGB ? 3 : 4); | |
643 | |
644 switch (colorSpace) { | |
645 case JCS_RGB: | |
646 buffer.setRGBA(pixel, jsample[0], jsample[1], jsample[2], 0xFF); | |
647 break; | |
648 case JCS_CMYK: | |
649 // Source is 'Inverted CMYK', output is RGB. | |
650 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 | |
651 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb | |
652 // From CMYK to CMY: | |
653 // X = X * (1 - K ) + K [for X = C, M, or Y] | |
654 // Thus, from Inverted CMYK to CMY is: | |
655 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK | |
656 // From CMY (0..1) to RGB (0..1): | |
657 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] | |
658 unsigned k = jsample[3]; | |
659 buffer.setRGBA(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsampl
e[2] * k / 255, 0xFF); | |
660 break; | |
661 } | |
662 } | |
663 | |
664 template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, Ima
geFrame& buffer) | |
665 { | 641 { |
666 JSAMPARRAY samples = reader->samples(); | 642 JSAMPARRAY samples = reader->samples(); |
667 jpeg_decompress_struct* info = reader->info(); | 643 jpeg_decompress_struct* info = reader->info(); |
668 int width = info->output_width; | 644 int width = info->output_width; |
669 | 645 |
670 while (info->output_scanline < info->output_height) { | 646 while (info->output_scanline < info->output_height) { |
671 // jpeg_read_scanlines will increase the scanline counter, so we | 647 // jpeg_read_scanlines will increase the scanline counter, so we |
672 // save the scanline before calling it. | 648 // save the scanline before calling it. |
673 int y = info->output_scanline; | 649 int y = info->output_scanline; |
674 // Request one scanline: returns 0 or 1 scanlines. | 650 // Request one scanline: returns 0 or 1 scanlines. |
675 if (jpeg_read_scanlines(info, samples, 1) != 1) | 651 if (jpeg_read_scanlines(info, samples, 1) != 1) |
676 return false; | 652 return false; |
677 #if USE(QCMSLIB) | 653 #if USE(QCMSLIB) |
678 if (reader->colorTransform() && colorSpace == JCS_RGB) | 654 if (reader->colorTransform() && colorSpace == JCS_RGB) |
679 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi
dth); | 655 qcms_transform_data(reader->colorTransform(), *samples, *samples, wi
dth); |
680 #endif | 656 #endif |
681 ImageFrame::PixelData* pixel = buffer.getAddr(0, y); | 657 unsigned const char* row = *samples; |
682 for (int x = 0; x < width; ++pixel, ++x) | 658 if (colorSpace == JCS_RGB) |
683 setPixel<colorSpace>(buffer, pixel, samples, x); | 659 buffer.fillRowFromRGBSource(y, row); |
| 660 else if (colorSpace == JCS_CMYK) |
| 661 buffer.fillRowFromInvertedCMYK(y, row); |
| 662 else |
| 663 ASSERT_NOT_REACHED(); |
684 } | 664 } |
685 | 665 |
686 return true; | 666 return true; |
687 } | 667 } |
688 | 668 |
689 bool JPEGImageDecoder::outputScanlines() | 669 bool JPEGImageDecoder::outputScanlines() |
690 { | 670 { |
691 if (m_frameBufferCache.isEmpty()) | 671 if (m_frameBufferCache.isEmpty()) |
692 return false; | 672 return false; |
693 | 673 |
(...skipping 21 matching lines...) Expand all Loading... |
715 return false; | 695 return false; |
716 #if USE(QCMSLIB) | 696 #if USE(QCMSLIB) |
717 if (qcms_transform* transform = m_reader->colorTransform()) | 697 if (qcms_transform* transform = m_reader->colorTransform()) |
718 qcms_transform_data_type(transform, row, row, info->output_width
, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); | 698 qcms_transform_data_type(transform, row, row, info->output_width
, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); |
719 #endif | 699 #endif |
720 } | 700 } |
721 return true; | 701 return true; |
722 } | 702 } |
723 #endif | 703 #endif |
724 | 704 |
725 switch (info->out_color_space) { | 705 return outputRows(m_reader.get(), buffer, info->out_color_space); |
726 case JCS_RGB: | |
727 return outputRows<JCS_RGB>(m_reader.get(), buffer); | |
728 case JCS_CMYK: | |
729 return outputRows<JCS_CMYK>(m_reader.get(), buffer); | |
730 default: | |
731 ASSERT_NOT_REACHED(); | |
732 } | |
733 | |
734 return setFailed(); | |
735 } | 706 } |
736 | 707 |
737 void JPEGImageDecoder::jpegComplete() | 708 void JPEGImageDecoder::jpegComplete() |
738 { | 709 { |
739 if (m_frameBufferCache.isEmpty()) | 710 if (m_frameBufferCache.isEmpty()) |
740 return; | 711 return; |
741 | 712 |
742 // Hand back an appropriately sized buffer, even if the image ended up being | 713 // Hand back an appropriately sized buffer, even if the image ended up being |
743 // empty. | 714 // empty. |
744 ImageFrame& buffer = m_frameBufferCache[0]; | 715 ImageFrame& buffer = m_frameBufferCache[0]; |
(...skipping 13 matching lines...) Expand all Loading... |
758 // has failed. | 729 // has failed. |
759 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 730 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
760 setFailed(); | 731 setFailed(); |
761 // If we're done decoding the image, we don't need the JPEGImageReader | 732 // If we're done decoding the image, we don't need the JPEGImageReader |
762 // anymore. (If we failed, |m_reader| has already been cleared.) | 733 // anymore. (If we failed, |m_reader| has already been cleared.) |
763 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) | 734 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) |
764 m_reader.clear(); | 735 m_reader.clear(); |
765 } | 736 } |
766 | 737 |
767 } | 738 } |
OLD | NEW |