• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 #include "GIFImageDecoder.h"
28 #include "GIFImageReader.h"
29 
30 namespace WebCore {
31 
GIFImageDecoder()32 GIFImageDecoder::GIFImageDecoder()
33     : m_frameCountValid(true)
34     , m_repetitionCount(cAnimationLoopOnce)
35     , m_readOffset(0)
36 {
37 }
38 
~GIFImageDecoder()39 GIFImageDecoder::~GIFImageDecoder()
40 {
41 }
42 
43 // Take the data and store it.
setData(SharedBuffer * data,bool allDataReceived)44 void GIFImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
45 {
46     if (m_failed)
47         return;
48 
49     // Cache our new data.
50     ImageDecoder::setData(data, allDataReceived);
51 
52     // Our frame count is now unknown.
53     m_frameCountValid = false;
54 
55     // Create the GIF reader.
56     if (!m_reader && !m_failed)
57         m_reader.set(new GIFImageReader(this));
58 }
59 
60 // Whether or not the size information has been decoded yet.
isSizeAvailable()61 bool GIFImageDecoder::isSizeAvailable()
62 {
63     if (!ImageDecoder::isSizeAvailable() && !failed() && m_reader)
64          decode(GIFSizeQuery, 0);
65 
66     return ImageDecoder::isSizeAvailable();
67 }
68 
69 // The total number of frames for the image.  Will scan the image data for the answer
70 // (without necessarily decoding all of the individual frames).
frameCount()71 size_t GIFImageDecoder::frameCount()
72 {
73     // If the decoder had an earlier error, we will just return what we had decoded
74     // so far.
75     if (!m_frameCountValid) {
76         // FIXME: Scanning all the data has O(n^2) behavior if the data were to come in really
77         // slowly.  Might be interesting to try to clone our existing read session to preserve
78         // state, but for now we just crawl all the data.  Note that this is no worse than what
79         // ImageIO does on Mac right now (it also crawls all the data again).
80         GIFImageReader reader(0);
81         // This function may fail, but we want to keep any partial data it may
82         // have decoded, so don't mark it is invalid. If there is an overflow
83         // or some serious error, m_failed will have gotten set for us.
84         reader.read((const unsigned char*)m_data->data(), m_data->size(), GIFFrameCountQuery, static_cast<unsigned>(-1));
85         m_frameCountValid = true;
86         m_frameBufferCache.resize(reader.images_count);
87     }
88 
89     return m_frameBufferCache.size();
90 }
91 
92 // The number of repetitions to perform for an animation loop.
repetitionCount() const93 int GIFImageDecoder::repetitionCount() const
94 {
95     // This value can arrive at any point in the image data stream.  Most GIFs
96     // in the wild declare it near the beginning of the file, so it usually is
97     // set by the time we've decoded the size, but (depending on the GIF and the
98     // packets sent back by the webserver) not always.  Our caller is
99     // responsible for waiting until image decoding has finished to ask this if
100     // it needs an authoritative answer.  In the meantime, we should default to
101     // "loop once".
102     if (m_reader) {
103         // Added wrinkle: ImageSource::clear() may destroy the reader, making
104         // the result from the reader _less_ authoritative on future calls.  To
105         // detect this, the reader returns cLoopCountNotSeen (-2) instead of
106         // cAnimationLoopOnce (-1) when its current incarnation hasn't actually
107         // seen a loop count yet; in this case we return our previously-cached
108         // value.
109         const int repetitionCount = m_reader->loop_count;
110         if (repetitionCount != cLoopCountNotSeen)
111             m_repetitionCount = repetitionCount;
112     }
113     return m_repetitionCount;
114 }
115 
frameBufferAtIndex(size_t index)116 RGBA32Buffer* GIFImageDecoder::frameBufferAtIndex(size_t index)
117 {
118     if (index >= frameCount())
119         return 0;
120 
121     RGBA32Buffer& frame = m_frameBufferCache[index];
122     if (frame.status() != RGBA32Buffer::FrameComplete && m_reader)
123         decode(GIFFullQuery, index + 1); // Decode this frame.
124     return &frame;
125 }
126 
clearFrameBufferCache(size_t clearBeforeFrame)127 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
128 {
129     // In some cases, like if the decoder was destroyed while animating, we
130     // can be asked to clear more frames than we currently have.
131     if (m_frameBufferCache.isEmpty())
132         return; // Nothing to do.
133 
134     // The "-1" here is tricky.  It does not mean that |clearBeforeFrame| is the
135     // last frame we wish to preserve, but rather that we never want to clear
136     // the very last frame in the cache: it's empty (so clearing it is
137     // pointless), it's partial (so we don't want to clear it anyway), or the
138     // cache could be enlarged with a future setData() call and it could be
139     // needed to construct the next frame (see comments below).  Callers can
140     // always use ImageSource::clear(true, ...) to completely free the memory in
141     // this case.
142     clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
143     const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
144 
145     // We need to preserve frames such that:
146     //   * We don't clear |end|
147     //   * We don't clear the frame we're currently decoding
148     //   * We don't clear any frame from which a future initFrameBuffer() call
149     //     will copy bitmap data
150     // All other frames can be cleared.  Because of the constraints on when
151     // ImageSource::clear() can be called (see ImageSource.h), we're guaranteed
152     // not to have non-empty frames after the frame we're currently decoding.
153     // So, scan backwards from |end| as follows:
154     //   * If the frame is empty, we're still past any frames we care about.
155     //   * If the frame is complete, but is DisposeOverwritePrevious, we'll
156     //     skip over it in future initFrameBuffer() calls.  We can clear it
157     //     unless it's |end|, and keep scanning.  For any other disposal method,
158     //     stop scanning, as we've found the frame initFrameBuffer() will need
159     //     next.
160     //   * If the frame is partial, we're decoding it, so don't clear it; if it
161     //     has a disposal method other than DisposeOverwritePrevious, stop
162     //     scanning, as we'll only need this frame when decoding the next one.
163     Vector<RGBA32Buffer>::iterator i(end);
164     for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) {
165         if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end))
166             i->clear();
167     }
168 
169     // Now |i| holds the last frame we need to preserve; clear prior frames.
170     for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
171         ASSERT(j->status() != RGBA32Buffer::FramePartial);
172         if (j->status() != RGBA32Buffer::FrameEmpty)
173             j->clear();
174     }
175 }
176 
177 // Feed data to the GIF reader.
decode(GIFQuery query,unsigned haltAtFrame)178 void GIFImageDecoder::decode(GIFQuery query, unsigned haltAtFrame)
179 {
180     if (m_failed)
181         return;
182 
183     m_failed = !m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame);
184 
185     if (m_failed)
186         m_reader.clear();
187 }
188 
189 // Callbacks from the GIF reader.
sizeNowAvailable(unsigned width,unsigned height)190 bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height)
191 {
192     if (!setSize(width, height))
193         return false;
194     prepareScaleDataIfNecessary();
195     return true;
196 }
197 
decodingHalted(unsigned bytesLeft)198 void GIFImageDecoder::decodingHalted(unsigned bytesLeft)
199 {
200     m_readOffset = m_data->size() - bytesLeft;
201 }
202 
initFrameBuffer(unsigned frameIndex)203 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
204 {
205     // Initialize the frame rect in our buffer.
206     const GIFFrameReader* frameReader = m_reader->frame_reader;
207     IntRect frameRect(frameReader->x_offset, frameReader->y_offset, frameReader->width, frameReader->height);
208 
209     // Make sure the frameRect doesn't extend past the bottom-right of the buffer.
210     if (frameRect.right() > size().width())
211         frameRect.setWidth(size().width() - frameReader->x_offset);
212     if (frameRect.bottom() > size().height())
213         frameRect.setHeight(size().height() - frameReader->y_offset);
214 
215     RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
216     int left = upperBoundScaledX(frameRect.x());
217     int right = lowerBoundScaledX(frameRect.right(), left);
218     int top = upperBoundScaledY(frameRect.y());
219     int bottom = lowerBoundScaledY(frameRect.bottom(), top);
220     buffer->setRect(IntRect(left, top, right - left, bottom - top));
221 
222     if (frameIndex == 0) {
223         // This is the first frame, so we're not relying on any previous data.
224         if (!buffer->setSize(scaledSize().width(), scaledSize().height())) {
225             m_failed = true;
226             return false;
227         }
228     } else {
229         // The starting state for this frame depends on the previous frame's
230         // disposal method.
231         //
232         // Frames that use the DisposeOverwritePrevious method are effectively
233         // no-ops in terms of changing the starting state of a frame compared to
234         // the starting state of the previous frame, so skip over them.  (If the
235         // first frame specifies this method, it will get treated like
236         // DisposeOverwriteBgcolor below and reset to a completely empty image.)
237         const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
238         RGBA32Buffer::FrameDisposalMethod prevMethod =
239             prevBuffer->disposalMethod();
240         while ((frameIndex > 0)
241                && (prevMethod == RGBA32Buffer::DisposeOverwritePrevious)) {
242             prevBuffer = &m_frameBufferCache[--frameIndex];
243             prevMethod = prevBuffer->disposalMethod();
244         }
245         ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete);
246 
247         if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) ||
248                 (prevMethod == RGBA32Buffer::DisposeKeep)) {
249             // Preserve the last frame as the starting state for this frame.
250             buffer->copyBitmapData(*prevBuffer);
251         } else {
252             // We want to clear the previous frame to transparent, without
253             // affecting pixels in the image outside of the frame.
254             const IntRect& prevRect = prevBuffer->rect();
255             const IntSize& bufferSize = scaledSize();
256             if ((frameIndex == 0)
257                 || prevRect.contains(IntRect(IntPoint(), bufferSize))) {
258                 // Clearing the first frame, or a frame the size of the whole
259                 // image, results in a completely empty image.
260                 if (!buffer->setSize(bufferSize.width(), bufferSize.height())) {
261                     m_failed = true;
262                     return false;
263                 }
264             } else {
265               // Copy the whole previous buffer, then clear just its frame.
266               buffer->copyBitmapData(*prevBuffer);
267               for (int y = prevRect.y(); y < prevRect.bottom(); ++y) {
268                   for (int x = prevRect.x(); x < prevRect.right(); ++x)
269                       buffer->setRGBA(x, y, 0, 0, 0, 0);
270               }
271               if ((prevRect.width() > 0) && (prevRect.height() > 0))
272                   buffer->setHasAlpha(true);
273             }
274         }
275     }
276 
277     // Update our status to be partially complete.
278     buffer->setStatus(RGBA32Buffer::FramePartial);
279 
280     // Reset the alpha pixel tracker for this frame.
281     m_currentBufferSawAlpha = false;
282     return true;
283 }
284 
haveDecodedRow(unsigned frameIndex,unsigned char * rowBuffer,unsigned char * rowEnd,unsigned rowNumber,unsigned repeatCount,bool writeTransparentPixels)285 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
286                                      unsigned char* rowBuffer,
287                                      unsigned char* rowEnd,
288                                      unsigned rowNumber,
289                                      unsigned repeatCount,
290                                      bool writeTransparentPixels)
291 {
292     const GIFFrameReader* frameReader = m_reader->frame_reader;
293     // The pixel data and coordinates supplied to us are relative to the frame's
294     // origin within the entire image size, i.e.
295     // (frameReader->x_offset, frameReader->y_offset).  There is no guarantee
296     // that (rowEnd - rowBuffer) == (size().width() - frameReader->x_offset), so
297     // we must ensure we don't run off the end of either the source data or the
298     // row's X-coordinates.
299     int xBegin = upperBoundScaledX(frameReader->x_offset);
300     int yBegin = upperBoundScaledY(frameReader->y_offset + rowNumber);
301     int xEnd = lowerBoundScaledX(std::min(xBegin + static_cast<int>(rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1;
302     int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1;
303     if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
304         return true;
305 
306     // Get the colormap.
307     const unsigned char* colorMap;
308     unsigned colorMapSize;
309     if (frameReader->is_local_colormap_defined) {
310         colorMap = frameReader->local_colormap;
311         colorMapSize = (unsigned)frameReader->local_colormap_size;
312     } else {
313         colorMap = m_reader->global_colormap;
314         colorMapSize = m_reader->global_colormap_size;
315     }
316     if (!colorMap)
317         return true;
318 
319     // Initialize the frame if necessary.
320     RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
321     if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
322         return false;
323 
324     // Write one row's worth of data into the frame.
325     for (int x = xBegin; x < xEnd; ++x) {
326         const unsigned char sourceValue = *(rowBuffer + (m_scaled ? m_scaledColumns[x] : x) - frameReader->x_offset);
327         if ((!frameReader->is_transparent || (sourceValue != frameReader->tpixel)) && (sourceValue < colorMapSize)) {
328             const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
329             buffer.setRGBA(x, yBegin, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
330         } else {
331             m_currentBufferSawAlpha = true;
332             // We may or may not need to write transparent pixels to the buffer.
333             // If we're compositing against a previous image, it's wrong, and if
334             // we're writing atop a cleared, fully transparent buffer, it's
335             // unnecessary; but if we're decoding an interlaced gif and
336             // displaying it "Haeberli"-style, we must write these for passes
337             // beyond the first, or the initial passes will "show through" the
338             // later ones.
339             if (writeTransparentPixels)
340                 buffer.setRGBA(x, yBegin, 0, 0, 0, 0);
341         }
342     }
343 
344     // Tell the frame to copy the row data if need be.
345     if (repeatCount > 1)
346         buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);
347 
348     return true;
349 }
350 
frameComplete(unsigned frameIndex,unsigned frameDuration,RGBA32Buffer::FrameDisposalMethod disposalMethod)351 void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
352 {
353     // Initialize the frame if necessary.  Some GIFs insert do-nothing frames,
354     // in which case we never reach haveDecodedRow() before getting here.
355     RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
356     if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
357         return;
358 
359     buffer.setStatus(RGBA32Buffer::FrameComplete);
360     buffer.setDuration(frameDuration);
361     buffer.setDisposalMethod(disposalMethod);
362 
363     if (!m_currentBufferSawAlpha) {
364         // The whole frame was non-transparent, so it's possible that the entire
365         // resulting buffer was non-transparent, and we can setHasAlpha(false).
366         if (buffer.rect().contains(IntRect(IntPoint(), scaledSize())))
367             buffer.setHasAlpha(false);
368         else if (frameIndex > 0) {
369             // Tricky case.  This frame does not have alpha only if everywhere
370             // outside its rect doesn't have alpha.  To know whether this is
371             // true, we check the start state of the frame -- if it doesn't have
372             // alpha, we're safe.
373             //
374             // First skip over prior DisposeOverwritePrevious frames (since they
375             // don't affect the start state of this frame) the same way we do in
376             // initFrameBuffer().
377             const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
378             while ((frameIndex > 0)
379                    && (prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious))
380                 prevBuffer = &m_frameBufferCache[--frameIndex];
381 
382             // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then
383             // we can say we have no alpha if that frame had no alpha.  But
384             // since in initFrameBuffer() we already copied that frame's alpha
385             // state into the current frame's, we need do nothing at all here.
386             //
387             // The only remaining case is a DisposeOverwriteBgcolor frame.  If
388             // it had no alpha, and its rect is contained in the current frame's
389             // rect, we know the current frame has no alpha.
390             if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor)
391                 && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect()))
392                 buffer.setHasAlpha(false);
393         }
394     }
395 }
396 
gifComplete()397 void GIFImageDecoder::gifComplete()
398 {
399     if (m_reader)
400         m_repetitionCount = m_reader->loop_count;
401     m_reader.clear();
402 }
403 
404 } // namespace WebCore
405