diff options
author | Steve Block <steveblock@google.com> | 2011-05-18 13:36:51 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-24 15:38:28 +0100 |
commit | 2fc2651226baac27029e38c9d6ef883fa32084db (patch) | |
tree | e396d4bf89dcce6ed02071be66212495b1df1dec /Source/WebCore/platform/image-decoders | |
parent | b3725cedeb43722b3b175aaeff70552e562d2c94 (diff) | |
download | external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.zip external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.gz external_webkit-2fc2651226baac27029e38c9d6ef883fa32084db.tar.bz2 |
Merge WebKit at r78450: Initial merge by git.
Change-Id: I6d3e5f1f868ec266a0aafdef66182ddc3f265dc1
Diffstat (limited to 'Source/WebCore/platform/image-decoders')
12 files changed, 155 insertions, 160 deletions
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index 17208b5..2aae205 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -38,7 +38,9 @@ using namespace std; namespace WebCore { -static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset) +namespace { + +unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset) { unsigned bytesExtracted = 0; const char* moreData; @@ -53,55 +55,80 @@ static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const return bytesExtracted; } +<<<<<<< HEAD #if !OS(ANDROID) // This method requires BMPImageDecoder, PNGImageDecoder, ICOImageDecoder and // JPEGDecoder, which aren't used on Android, and which don't all compile. // TODO: Find a better fix. +======= +bool matchesGIFSignature(char* contents) +{ + return !memcmp(contents, "GIF8", 4); +} + +bool matchesPNGSignature(char* contents) +{ + return !memcmp(contents, "\x89\x50\x4E\x47", 4); +} + +bool matchesJPEGSignature(char* contents) +{ + return !memcmp(contents, "\xFF\xD8\xFF", 3); +} + +#if USE(WEBP) +bool matchesWebPSignature(char* contents) +{ + return !memcmp(contents, "RIFF", 4) && !memcmp(contents + 8, "WEBPVP", 6); +} +#endif + +bool matchesBMPSignature(char* contents) +{ + return !memcmp(contents, "BM", 2); +} + +bool matchesICOSignature(char* contents) +{ + return !memcmp(contents, "\x00\x00\x01\x00", 4); +} + +bool matchesCURSignature(char* contents) +{ + return !memcmp(contents, "\x00\x00\x02\x00", 4); +} + +} + +>>>>>>> webkit.org at r78450 ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) { - // We need at least 4 bytes to figure out what kind of image we're dealing - // with. - static const unsigned maxMarkerLength = 4; - char contents[maxMarkerLength]; - unsigned length = copyFromSharedBuffer(contents, maxMarkerLength, data, 0); - if (length < maxMarkerLength) + static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP" + char contents[lengthOfLongestSignature]; + unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data, 0); + if (length < lengthOfLongestSignature) return 0; - // GIFs begin with GIF8(7 or 9). - if (strncmp(contents, "GIF8", 4) == 0) + if (matchesGIFSignature(contents)) return new GIFImageDecoder(alphaOption, gammaAndColorProfileOption); - // Test for PNG. - if (!memcmp(contents, "\x89\x50\x4E\x47", 4)) + if (matchesPNGSignature(contents)) return new PNGImageDecoder(alphaOption, gammaAndColorProfileOption); - // JPEG - if (!memcmp(contents, "\xFF\xD8\xFF", 3)) + if (matchesJPEGSignature(contents)) return new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption); #if USE(WEBP) - if (!memcmp(contents, "RIFF", 4)) { - static const unsigned webpExtraMarker = 6; - static const unsigned webpExtraMarkeroffset = 8; - char header[webpExtraMarker]; - unsigned length = copyFromSharedBuffer(header, webpExtraMarker, data, webpExtraMarkeroffset); - if (length >= webpExtraMarker) { - if (!memcmp(header, "WEBPVP", webpExtraMarker)) - return new WEBPImageDecoder(alphaOption, gammaAndColorProfileOption); - } - } + if (matchesWebPSignature(contents)) + return new WEBPImageDecoder(alphaOption, gammaAndColorProfileOption); #endif - // BMP - if (strncmp(contents, "BM", 2) == 0) + if (matchesBMPSignature(contents)) return new BMPImageDecoder(alphaOption, gammaAndColorProfileOption); - // ICOs always begin with a 2-byte 0 followed by a 2-byte 1. - // CURs begin with 2-byte 0 followed by 2-byte 2. - if (!memcmp(contents, "\x00\x00\x01\x00", 4) || !memcmp(contents, "\x00\x00\x02\x00", 4)) + if (matchesICOSignature(contents) || matchesCURSignature(contents)) return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption); - // Give up. We don't know what the heck this is. return 0; } #endif // !OS(ANDROID) @@ -123,7 +150,7 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other) return *this; copyReferenceToBitmapData(other); - setRect(other.rect()); + setOriginalFrameRect(other.originalFrameRect()); setStatus(other.status()); setDuration(other.duration()); setDisposalMethod(other.disposalMethod()); @@ -131,7 +158,7 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other) return *this; } -void ImageFrame::clear() +void ImageFrame::clearPixelData() { m_backingStore.clear(); m_bytes = 0; @@ -142,7 +169,7 @@ void ImageFrame::clear() // later. } -void ImageFrame::zeroFill() +void ImageFrame::zeroFillPixelData() { memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData)); m_hasAlpha = true; @@ -176,8 +203,7 @@ bool ImageFrame::setSize(int newWidth, int newHeight) m_bytes = m_backingStore.data(); m_size = IntSize(newWidth, newHeight); - // Zero the image. - zeroFill(); + zeroFillPixelData(); return true; } diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h index c581ba1..7d0d0d4 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h @@ -50,9 +50,8 @@ namespace WebCore { // FIXME: Do we want better encapsulation? typedef Vector<char> ColorProfile; - // The ImageFrame object represents the decoded image data in RGBA32 - // format. This buffer is what all decoders write a single frame into. - // Frames are then instantiated for drawing by being handed this buffer. + // ImageFrame represents the decoded image data. This buffer is what all + // decoders write a single frame into. class ImageFrame { public: enum FrameStatus { FrameEmpty, FramePartial, FrameComplete }; @@ -80,19 +79,17 @@ namespace WebCore { // create a new copy of the image data, only increase the ref count. ImageFrame& operator=(const ImageFrame& other); - // Deletes the pixel data entirely; used by ImageDecoder to save memory - // when we no longer need to display a frame and only need its metadata. - void clear(); + // These do not touch other metadata, only the raw pixel data. + void clearPixelData(); + void zeroFillPixelData(); - // Zeroes the pixel data in the buffer, setting it to fully-transparent. - void zeroFill(); - - // Creates a new copy of the image data in |other|, so the two images - // can be modified independently. Returns whether the copy succeeded. + // Makes this frame have an independent copy of the provided image's + // pixel data, so that modifications in one frame are not reflected in + // the other. Returns whether the copy succeeded. bool copyBitmapData(const ImageFrame&); - // Creates a new reference to the image data in |other|. The two images - // share a common backing store. + // Makes this frame reference the provided image's pixel data, so that + // modifications in one frame are reflected in the other. void copyReferenceToBitmapData(const ImageFrame&); // Copies the pixel data at [(startX, startY), (endX, startY)) to the @@ -116,18 +113,17 @@ namespace WebCore { #endif // Allocates space for the pixel data. Must be called before any pixels - // are written. Will return true on success, false if the memory - // allocation fails. Calling this multiple times is undefined and may - // leak memory. + // are written. Must only be called once. Returns whether allocation + // succeeded. bool setSize(int newWidth, int newHeight); - // To be used by ImageSource::createFrameAtIndex(). Returns a pointer - // to the underlying native image data. This pointer will be owned by - // the BitmapImage and freed in FrameData::clear(). + // Returns a caller-owned pointer to the underlying native image data. + // (Actual use: This pointer will be owned by BitmapImage and freed in + // FrameData::clear()). NativeImagePtr asNewNativeImage() const; bool hasAlpha() const; - const IntRect& rect() const { return m_rect; } + const IntRect& originalFrameRect() const { return m_originalFrameRect; } FrameStatus status() const { return m_status; } unsigned duration() const { return m_duration; } FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } @@ -135,7 +131,7 @@ namespace WebCore { void setHasAlpha(bool alpha); void setColorProfile(const ColorProfile&); - void setRect(const IntRect& r) { m_rect = r; } + void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } void setStatus(FrameStatus status); void setDuration(unsigned duration) { m_duration = duration; } void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; } @@ -184,7 +180,11 @@ namespace WebCore { g = static_cast<unsigned>(g * alphaPercent); b = static_cast<unsigned>(b * alphaPercent); } +<<<<<<< HEAD #if PLATFORM(ANDROID) +======= +#if PLATFORM(SKIA) +>>>>>>> webkit.org at r78450 *dest = SkPackARGB32(a, r, g, b); #else *dest = (a << 24 | r << 16 | g << 8 | b); @@ -202,35 +202,26 @@ namespace WebCore { #else NativeBackingStore m_backingStore; PixelData* m_bytes; // The memory is backed by m_backingStore. - IntSize m_size; // The size of the buffer. This should be the - // same as ImageDecoder::m_size. - bool m_hasAlpha; // Whether or not any of the pixels in the buffer - // have transparency. + IntSize m_size; + bool m_hasAlpha; ColorProfile m_colorProfile; #endif - IntRect m_rect; // The rect of the original specified frame within - // the overall buffer. This will always just be - // the entire buffer except for GIF frames whose - // original rect was smaller than the overall - // image size. - FrameStatus m_status; // Whether or not this frame is completely - // finished decoding. - unsigned m_duration; // The animation delay. - FrameDisposalMethod m_disposalMethod; // What to do with this frame's data when - // initializing the next frame. - bool m_premultiplyAlpha; // Whether to premultiply alpha into R, G, B - // channels; by default it's true. + IntRect m_originalFrameRect; // This will always just be the entire + // buffer except for GIF frames whose + // original rect was smaller than the + // overall image size. + FrameStatus m_status; + unsigned m_duration; + FrameDisposalMethod m_disposalMethod; + bool m_premultiplyAlpha; }; - // The ImageDecoder class represents a base class for specific image format - // decoders (e.g., GIF, JPG, PNG, ICO) to derive from. All decoders decode - // into RGBA32 format and the base class manages the RGBA32 frame cache. + // ImageDecoder is a base for all format-specific decoders + // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache. // - // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to write - // directly to scaled output buffers by down sampling. Call - // setMaxNumPixels() to specify the biggest size that decoded images can - // have. Image decoders will deflate those images that are bigger than - // m_maxNumPixels. (Not supported by all image decoders yet) + // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample + // at decode time. Image decoders will downsample any images larger than + // |m_maxNumPixels|. FIXME: Not yet supported by all decoders. class ImageDecoder { WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED; public: @@ -241,19 +232,15 @@ namespace WebCore { , m_sizeAvailable(false) , m_maxNumPixels(-1) , m_isAllDataReceived(false) - , m_failed(false) - { - } + , m_failed(false) { } - virtual ~ImageDecoder() {} + virtual ~ImageDecoder() { } - // Factory function to create an ImageDecoder. Ports that subclass - // ImageDecoder can provide their own implementation of this to avoid - // needing to write a dedicated setData() implementation. + // Returns a caller-owned decoder of the appropriate type. Returns 0 if + // we can't sniff a supported type from the provided data (possibly + // because there isn't enough data yet). static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption); - // The the filename extension usually associated with an undecoded image - // of this type. virtual String filenameExtension() const = 0; bool isAllDataReceived() const { return m_isAllDataReceived; } @@ -266,41 +253,33 @@ namespace WebCore { m_isAllDataReceived = allDataReceived; } - // Whether or not the size information has been decoded yet. This - // default implementation just returns true if the size has been set and - // we have not seen a failure. Decoders may want to override this to - // lazily decode enough of the image to get the size. + // Lazily-decodes enough of the image to get the size (if possible). + // FIXME: Right now that has to be done by each subclass; factor the + // decode call out and use it here. virtual bool isSizeAvailable() { - return !m_failed && m_sizeAvailable; + return !m_failed && m_sizeAvailable; } - // Returns the size of the image. - virtual IntSize size() const - { - return m_size; - } + virtual IntSize size() const { return m_size; } IntSize scaledSize() const { return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size(); } - // Returns the size of frame |index|. This will only differ from size() - // for formats where different frames are different sizes (namely ICO, - // where each frame represents a different icon within the master file). - // Notably, this does not return different sizes for different GIF - // frames, since while these may be stored as smaller rectangles, during - // decoding they are composited to create a full-size frame. + // This will only differ from size() for ICO (where each frame is a + // different icon) or other formats where different frames are different + // sizes. This does NOT differ from size() for GIF, since decoding GIFs + // composites any smaller frames against previous frames to create full- + // size frames. virtual IntSize frameSizeAtIndex(size_t) const { return size(); } - // Called by the image decoders to set their decoded size, this also - // checks the size for validity. It will return true if the size was - // set, or false if there is an error. On error, the m_failed flag will - // be set and the caller should immediately stop decoding. + // Returns whether the size is legal (i.e. not going to result in + // overflow elsewhere). If not, marks decoding as failed. virtual bool setSize(unsigned width, unsigned height) { if (isOverSize(width, height)) @@ -310,26 +289,19 @@ namespace WebCore { return true; } - // The total number of frames for the image. Classes that support - // multiple frames will scan the image data for the answer if they need - // to (without necessarily decoding all of the individual frames). + // Lazily-decodes enough of the image to get the frame count (if + // possible), without decoding the individual frames. + // FIXME: Right now that has to be done by each subclass; factor the + // decode call out and use it here. virtual size_t frameCount() { return 1; } - // The number of repetitions to perform for an animation loop. virtual int repetitionCount() const { return cAnimationNone; } - // Called to obtain the ImageFrame full of decoded data for rendering. - // The decoder plugin will decode as much of the frame as it can before - // handing back the buffer. + // Decodes as much of the requested frame as possible, and returns an + // ImageDecoder-owned pointer. virtual ImageFrame* frameBufferAtIndex(size_t) = 0; - // Whether or not the underlying image format even supports alpha - // transparency. - virtual bool supportsAlpha() const { return true; } - void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; } - - // Whether or not the gamma and color profile are applied. bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; } // Sets the "decode failure" flag. For caller convenience (since so @@ -344,13 +316,10 @@ namespace WebCore { bool failed() const { return m_failed; } - // Wipe out frames in the frame buffer cache before |clearBeforeFrame|, - // assuming this can be done without breaking decoding. Different - // decoders place different restrictions on what frames are safe to - // destroy, so this is left to them to implement. - // For convenience's sake, we provide a default (empty) implementation, - // since in practice only GIFs will ever use this. - virtual void clearFrameBufferCache(size_t clearBeforeFrame) { } + // Clears decoded pixel data from before the provided frame unless that + // data may be needed to decode future frames (e.g. due to GIF frame + // compositing). + virtual void clearFrameBufferCache(size_t) { } #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) void setMaxNumPixels(int m) { m_maxNumPixels = m; } @@ -378,8 +347,6 @@ namespace WebCore { // and return it as a (signed) int. Avoid overflow. static bool isOverSize(unsigned width, unsigned height) { - // width * height must not exceed (2 ^ 29) - 1, so that we don't - // overflow when we multiply by 4. unsigned long long total_size = static_cast<unsigned long long>(width) * static_cast<unsigned long long>(height); return total_size > ((1 << 29) - 1); diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp index 1805bc7..5c00553 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp @@ -87,7 +87,7 @@ bool BMPImageReader::decodeBMP(bool onlySize) m_buffer->setHasAlpha(false); // For BMPs, the frame always fills the entire image. - m_buffer->setRect(IntRect(IntPoint(), m_parent->size())); + m_buffer->setOriginalFrameRect(IntRect(IntPoint(), m_parent->size())); if (!m_isTopDown) m_coord.setY(m_parent->size().height() - 1); @@ -707,7 +707,7 @@ BMPImageReader::ProcessingResult BMPImageReader::processNonRLEData(bool inRLE, i } else { m_seenNonZeroAlphaPixel = true; if (m_seenZeroAlphaPixel) { - m_buffer->zeroFill(); + m_buffer->zeroFillPixelData(); m_seenZeroAlphaPixel = false; } else if (alpha != 255) m_buffer->setHasAlpha(true); diff --git a/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp b/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp index 0b90107..43d6a52 100644 --- a/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp +++ b/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp @@ -72,7 +72,7 @@ bool ImageFrame::setSize(int newWidth, int newHeight) m_bytes = reinterpret_cast<PixelData*>(CFDataGetMutableBytePtr(m_backingStore.get())); m_size = IntSize(newWidth, newHeight); - zeroFill(); + zeroFillPixelData(); return true; } diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index e6de597..7e334a9 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -174,14 +174,14 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) Vector<ImageFrame>::iterator i(end); for (; (i != m_frameBufferCache.begin()) && ((i->status() == ImageFrame::FrameEmpty) || (i->disposalMethod() == ImageFrame::DisposeOverwritePrevious)); --i) { if ((i->status() == ImageFrame::FrameComplete) && (i != end)) - i->clear(); + i->clearPixelData(); } // Now |i| holds the last frame we need to preserve; clear prior frames. for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j) { ASSERT(j->status() != ImageFrame::FramePartial); if (j->status() != ImageFrame::FrameEmpty) - j->clear(); + j->clearPixelData(); } } @@ -266,7 +266,7 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, if (!m_currentBufferSawAlpha) { // The whole frame was non-transparent, so it's possible that the entire // resulting buffer was non-transparent, and we can setHasAlpha(false). - if (buffer.rect().contains(IntRect(IntPoint(), scaledSize()))) + if (buffer.originalFrameRect().contains(IntRect(IntPoint(), scaledSize()))) buffer.setHasAlpha(false); else if (frameIndex) { // Tricky case. This frame does not have alpha only if everywhere @@ -289,7 +289,7 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, // The only remaining case is a DisposeOverwriteBgcolor frame. If // it had no alpha, and its rect is contained in the current frame's // rect, we know the current frame has no alpha. - if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor) && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect())) + if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuffer->originalFrameRect())) buffer.setHasAlpha(false); } } @@ -327,17 +327,17 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) IntRect frameRect(frameReader->x_offset, frameReader->y_offset, frameReader->width, frameReader->height); // Make sure the frameRect doesn't extend outside the buffer. - if (frameRect.right() > size().width()) + if (frameRect.maxX() > size().width()) frameRect.setWidth(size().width() - frameReader->x_offset); - if (frameRect.bottom() > size().height()) + if (frameRect.maxY() > size().height()) frameRect.setHeight(size().height() - frameReader->y_offset); ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; int left = upperBoundScaledX(frameRect.x()); - int right = lowerBoundScaledX(frameRect.right(), left); + int right = lowerBoundScaledX(frameRect.maxX(), left); int top = upperBoundScaledY(frameRect.y()); - int bottom = lowerBoundScaledY(frameRect.bottom(), top); - buffer->setRect(IntRect(left, top, right - left, bottom - top)); + int bottom = lowerBoundScaledY(frameRect.maxY(), top); + buffer->setOriginalFrameRect(IntRect(left, top, right - left, bottom - top)); if (!frameIndex) { // This is the first frame, so we're not relying on any previous data. @@ -367,7 +367,7 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) } else { // We want to clear the previous frame to transparent, without // affecting pixels in the image outside of the frame. - const IntRect& prevRect = prevBuffer->rect(); + const IntRect& prevRect = prevBuffer->originalFrameRect(); const IntSize& bufferSize = scaledSize(); if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) { // Clearing the first frame, or a frame the size of the whole @@ -378,8 +378,8 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) // Copy the whole previous buffer, then clear just its frame. if (!buffer->copyBitmapData(*prevBuffer)) return setFailed(); - for (int y = prevRect.y(); y < prevRect.bottom(); ++y) { - for (int x = prevRect.x(); x < prevRect.right(); ++x) + for (int y = prevRect.y(); y < prevRect.maxY(); ++y) { + for (int x = prevRect.x(); x < prevRect.maxX(); ++x) buffer->setRGBA(x, y, 0, 0, 0, 0); } if ((prevRect.width() > 0) && (prevRect.height() > 0)) diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index a255c25..1434c65 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -222,6 +222,12 @@ public: // jpeglib cannot convert these to rgb, but it can convert ycck // to cmyk. m_info.out_color_space = JCS_CMYK; + + // Same as with grayscale images, we convert CMYK images to RGBA + // ones. When we keep the color profiles of these CMYK images, + // CoreGraphics will convert their colors again. So, we discard + // their color profiles to prevent color corruption. + m_decoder->setIgnoreGammaAndColorProfile(true); break; default: return m_decoder->setFailed(); @@ -462,7 +468,7 @@ bool JPEGImageDecoder::outputScanlines() buffer.setColorProfile(m_colorProfile); // For JPEGs, the frame always fills the entire image. - buffer.setRect(IntRect(IntPoint(), size())); + buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); } jpeg_decompress_struct* info = m_reader->info(); diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 801f1ab..d095cbb 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -45,7 +45,6 @@ namespace WebCore { virtual bool isSizeAvailable(); virtual bool setSize(unsigned width, unsigned height); virtual ImageFrame* frameBufferAtIndex(size_t index); - virtual bool supportsAlpha() const { return false; } // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid // accessing deleted memory, especially when calling this from inside // JPEGImageReader! diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 755d704..8edfe36 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -341,7 +341,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, buffer.setColorProfile(m_colorProfile); // For PNGs, the frame always fills the entire image. - buffer.setRect(IntRect(IntPoint(), size())); + buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); if (m_reader->pngPtr()->interlaced) m_reader->createInterlaceBuffer((m_reader->hasAlpha() ? 4 : 3) * size().width() * size().height()); diff --git a/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp b/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp index 81c22cf..a3cfbf6 100644 --- a/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp +++ b/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp @@ -50,14 +50,14 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other) return *this; copyBitmapData(other); - setRect(other.rect()); + setOriginalFrameRect(other.originalFrameRect()); setStatus(other.status()); setDuration(other.duration()); setDisposalMethod(other.disposalMethod()); return *this; } -void ImageFrame::clear() +void ImageFrame::clearPixelData() { m_pixmap = QPixmap(); m_image = QImage(); @@ -68,7 +68,7 @@ void ImageFrame::clear() // other metadata out of this frame later. } -void ImageFrame::zeroFill() +void ImageFrame::zeroFillPixelData() { if (m_pixmap.isNull() && !m_image.isNull()) { m_pixmap = QPixmap(m_image.width(), m_image.height()); @@ -101,8 +101,7 @@ bool ImageFrame::setSize(int newWidth, int newHeight) if (m_pixmap.isNull()) return false; - // Zero the image. - zeroFill(); + zeroFillPixelData(); return true; } diff --git a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp index a1c8261..c7dcc7a 100644 --- a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp +++ b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp @@ -51,7 +51,7 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other) // Keep the pixels locked since we will be writing directly into the // bitmap throughout this object's lifetime. m_bitmap.lockPixels(); - setRect(other.rect()); + setOriginalFrameRect(other.originalFrameRect()); setStatus(other.status()); setDuration(other.duration()); setDisposalMethod(other.disposalMethod()); @@ -59,7 +59,7 @@ ImageFrame& ImageFrame::operator=(const ImageFrame& other) return *this; } -void ImageFrame::clear() +void ImageFrame::clearPixelData() { m_bitmap.reset(); m_status = FrameEmpty; @@ -69,7 +69,7 @@ void ImageFrame::clear() // other metadata out of this frame later. } -void ImageFrame::zeroFill() +void ImageFrame::zeroFillPixelData() { m_bitmap.eraseARGB(0, 0, 0, 0); } @@ -93,8 +93,7 @@ bool ImageFrame::setSize(int newWidth, int newHeight) if (!m_bitmap.allocPixels()) return false; - // Zero the image. - zeroFill(); + zeroFillPixelData(); return true; } diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp index 8045ada..3db00f6 100644 --- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp @@ -116,7 +116,7 @@ bool WEBPImageDecoder::decode(bool onlySize) } buffer.setStatus(ImageFrame::FrameComplete); buffer.setHasAlpha(false); - buffer.setRect(IntRect(IntPoint(), size())); + buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); return true; } diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h index cde1bbf..c32e047 100644 --- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h @@ -42,7 +42,6 @@ public: virtual String filenameExtension() const { return "vp8"; } virtual bool isSizeAvailable(); virtual ImageFrame* frameBufferAtIndex(size_t index); - virtual bool supportsAlpha() const { return false; } private: // Returns false in case of decoding failure. |