| 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 |