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 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 } | 602 } |
603 | 603 |
604 bool JPEGImageDecoder::isSizeAvailable() | 604 bool JPEGImageDecoder::isSizeAvailable() |
605 { | 605 { |
606 if (!ImageDecoder::isSizeAvailable()) | 606 if (!ImageDecoder::isSizeAvailable()) |
607 decode(true); | 607 decode(true); |
608 | 608 |
609 return ImageDecoder::isSizeAvailable(); | 609 return ImageDecoder::isSizeAvailable(); |
610 } | 610 } |
611 | 611 |
612 bool JPEGImageDecoder::setSize(unsigned width, unsigned height) | |
613 { | |
614 if (!ImageDecoder::setSize(width, height)) | |
615 return false; | |
616 | |
617 prepareScaleDataIfNecessary(); | |
618 return true; | |
619 } | |
620 | |
621 ImageFrame* JPEGImageDecoder::frameBufferAtIndex(size_t index) | 612 ImageFrame* JPEGImageDecoder::frameBufferAtIndex(size_t index) |
622 { | 613 { |
623 if (index) | 614 if (index) |
624 return 0; | 615 return 0; |
625 | 616 |
626 if (m_frameBufferCache.isEmpty()) { | 617 if (m_frameBufferCache.isEmpty()) { |
627 m_frameBufferCache.resize(1); | 618 m_frameBufferCache.resize(1); |
628 m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); | 619 m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); |
629 } | 620 } |
630 | 621 |
(...skipping 30 matching lines...) Expand all Loading... |
661 // Thus, from Inverted CMYK to CMY is: | 652 // Thus, from Inverted CMYK to CMY is: |
662 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK | 653 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK |
663 // From CMY (0..1) to RGB (0..1): | 654 // From CMY (0..1) to RGB (0..1): |
664 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] | 655 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] |
665 unsigned k = jsample[3]; | 656 unsigned k = jsample[3]; |
666 buffer.setRGBA(currentAddress, jsample[0] * k / 255, jsample[1] * k / 25
5, jsample[2] * k / 255, 0xFF); | 657 buffer.setRGBA(currentAddress, jsample[0] * k / 255, jsample[1] * k / 25
5, jsample[2] * k / 255, 0xFF); |
667 break; | 658 break; |
668 } | 659 } |
669 } | 660 } |
670 | 661 |
671 template <J_COLOR_SPACE colorSpace, bool isScaled> | |
672 bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) | |
673 { | |
674 JSAMPARRAY samples = m_reader->samples(); | |
675 jpeg_decompress_struct* info = m_reader->info(); | |
676 int width = isScaled ? m_scaledColumns.size() : info->output_width; | |
677 | |
678 while (info->output_scanline < info->output_height) { | |
679 // jpeg_read_scanlines will increase the scanline counter, so we | |
680 // save the scanline before calling it. | |
681 int sourceY = info->output_scanline; | |
682 /* Request one scanline. Returns 0 or 1 scanlines. */ | |
683 if (jpeg_read_scanlines(info, samples, 1) != 1) | |
684 return false; | |
685 | |
686 int destY = scaledY(sourceY); | |
687 if (destY < 0) | |
688 continue; | |
689 | |
690 #if USE(QCMSLIB) | |
691 if (m_reader->colorTransform() && colorSpace == JCS_RGB) | |
692 qcms_transform_data(m_reader->colorTransform(), *samples, *samples,
info->output_width); | |
693 #endif | |
694 | |
695 ImageFrame::PixelData* currentAddress = buffer.getAddr(0, destY); | |
696 for (int x = 0; x < width; ++x) { | |
697 setPixel<colorSpace>(buffer, currentAddress, samples, isScaled ? m_s
caledColumns[x] : x); | |
698 ++currentAddress; | |
699 } | |
700 } | |
701 return true; | |
702 } | |
703 | |
704 template <J_COLOR_SPACE colorSpace> | 662 template <J_COLOR_SPACE colorSpace> |
705 bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) | 663 bool JPEGImageDecoder::outputScanlines(ImageFrame& buffer) |
706 { | 664 { |
707 return m_scaled ? outputScanlines<colorSpace, true>(buffer) : outputScanline
s<colorSpace, false>(buffer); | 665 JSAMPARRAY samples = m_reader->samples(); |
| 666 jpeg_decompress_struct* info = m_reader->info(); |
| 667 int width = info->output_width; |
| 668 |
| 669 while (info->output_scanline < info->output_height) { |
| 670 // jpeg_read_scanlines will increase the scanline counter, so we |
| 671 // save the scanline before calling it. |
| 672 int y = info->output_scanline; |
| 673 // Request one scanline: returns 0 or 1 scanlines. |
| 674 if (jpeg_read_scanlines(info, samples, 1) != 1) |
| 675 return false; |
| 676 #if USE(QCMSLIB) |
| 677 if (m_reader->colorTransform() && colorSpace == JCS_RGB) |
| 678 qcms_transform_data(m_reader->colorTransform(), *samples, *samples,
info->output_width); |
| 679 #endif |
| 680 ImageFrame::PixelData* currentAddress = buffer.getAddr(0, y); |
| 681 for (int x = 0; x < width; ++x) { |
| 682 setPixel<colorSpace>(buffer, currentAddress, samples, x); |
| 683 ++currentAddress; |
| 684 } |
| 685 } |
| 686 |
| 687 return true; |
708 } | 688 } |
709 | 689 |
710 bool JPEGImageDecoder::outputScanlines() | 690 bool JPEGImageDecoder::outputScanlines() |
711 { | 691 { |
712 if (m_frameBufferCache.isEmpty()) | 692 if (m_frameBufferCache.isEmpty()) |
713 return false; | 693 return false; |
714 | 694 |
715 // Initialize the framebuffer if needed. | 695 // Initialize the framebuffer if needed. |
716 ImageFrame& buffer = m_frameBufferCache[0]; | 696 ImageFrame& buffer = m_frameBufferCache[0]; |
717 if (buffer.status() == ImageFrame::FrameEmpty) { | 697 if (buffer.status() == ImageFrame::FrameEmpty) { |
718 if (!buffer.setSize(scaledSize().width(), scaledSize().height())) | 698 if (!buffer.setSize(size().width(), size().height())) |
719 return setFailed(); | 699 return setFailed(); |
720 buffer.setStatus(ImageFrame::FramePartial); | 700 buffer.setStatus(ImageFrame::FramePartial); |
721 // The buffer is transparent outside the decoded area while the image is | 701 // The buffer is transparent outside the decoded area while the image is |
722 // loading. The completed image will be marked fully opaque in jpegCompl
ete(). | 702 // loading. The completed image will be marked fully opaque in jpegCompl
ete(). |
723 buffer.setHasAlpha(true); | 703 buffer.setHasAlpha(true); |
724 | 704 |
725 // For JPEGs, the frame always fills the entire image. | 705 // For JPEGs, the frame always fills the entire image. |
726 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); | 706 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); |
727 } | 707 } |
728 | 708 |
729 jpeg_decompress_struct* info = m_reader->info(); | 709 jpeg_decompress_struct* info = m_reader->info(); |
730 | 710 |
731 #if defined(TURBO_JPEG_RGB_SWIZZLE) | 711 #if defined(TURBO_JPEG_RGB_SWIZZLE) |
732 if (!m_scaled && turboSwizzled(info->out_color_space)) { | 712 if (turboSwizzled(info->out_color_space)) { |
733 while (info->output_scanline < info->output_height) { | 713 while (info->output_scanline < info->output_height) { |
734 unsigned char* row = reinterpret_cast<unsigned char*>(buffer.getAddr
(0, info->output_scanline)); | 714 unsigned char* row = reinterpret_cast<unsigned char*>(buffer.getAddr
(0, info->output_scanline)); |
735 if (jpeg_read_scanlines(info, &row, 1) != 1) | 715 if (jpeg_read_scanlines(info, &row, 1) != 1) |
736 return false; | 716 return false; |
737 #if USE(QCMSLIB) | 717 #if USE(QCMSLIB) |
738 if (qcms_transform* transform = m_reader->colorTransform()) | 718 if (qcms_transform* transform = m_reader->colorTransform()) |
739 qcms_transform_data_type(transform, row, row, info->output_width
, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); | 719 qcms_transform_data_type(transform, row, row, info->output_width
, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX); |
740 #endif | 720 #endif |
741 } | 721 } |
742 return true; | 722 return true; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 // has failed. | 763 // has failed. |
784 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 764 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
785 setFailed(); | 765 setFailed(); |
786 // If we're done decoding the image, we don't need the JPEGImageReader | 766 // If we're done decoding the image, we don't need the JPEGImageReader |
787 // anymore. (If we failed, |m_reader| has already been cleared.) | 767 // anymore. (If we failed, |m_reader| has already been cleared.) |
788 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) | 768 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() ==
ImageFrame::FrameComplete)) |
789 m_reader.clear(); | 769 m_reader.clear(); |
790 } | 770 } |
791 | 771 |
792 } | 772 } |
OLD | NEW |