• 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 
32 class GIFImageDecoderPrivate {
33 public:
GIFImageDecoderPrivate(GIFImageDecoder * decoder=0)34     GIFImageDecoderPrivate(GIFImageDecoder* decoder = 0)
35         : m_reader(decoder)
36         , m_readOffset(0)
37     {
38     }
39 
~GIFImageDecoderPrivate()40     ~GIFImageDecoderPrivate()
41     {
42         m_reader.close();
43     }
44 
decode(SharedBuffer * data,GIFImageDecoder::GIFQuery query=GIFImageDecoder::GIFFullQuery,unsigned int haltFrame=-1)45     bool decode(SharedBuffer* data,
46                 GIFImageDecoder::GIFQuery query = GIFImageDecoder::GIFFullQuery,
47                 unsigned int haltFrame = -1)
48     {
49         return m_reader.read((const unsigned char*)data->data() + m_readOffset, data->size() - m_readOffset,
50                              query,
51                              haltFrame);
52     }
53 
frameCount() const54     unsigned frameCount() const { return m_reader.images_count; }
repetitionCount() const55     int repetitionCount() const { return m_reader.loop_count; }
56 
setReadOffset(unsigned o)57     void setReadOffset(unsigned o) { m_readOffset = o; }
58 
isTransparent() const59     bool isTransparent() const { return m_reader.frame_reader->is_transparent; }
60 
getColorMap(unsigned char * & map,unsigned & size) const61     void getColorMap(unsigned char*& map, unsigned& size) const
62     {
63         if (m_reader.frame_reader->is_local_colormap_defined) {
64             map = m_reader.frame_reader->local_colormap;
65             size = (unsigned)m_reader.frame_reader->local_colormap_size;
66         } else {
67             map = m_reader.global_colormap;
68             size = m_reader.global_colormap_size;
69         }
70     }
71 
frameXOffset() const72     unsigned frameXOffset() const { return m_reader.frame_reader->x_offset; }
frameYOffset() const73     unsigned frameYOffset() const { return m_reader.frame_reader->y_offset; }
frameWidth() const74     unsigned frameWidth() const { return m_reader.frame_reader->width; }
frameHeight() const75     unsigned frameHeight() const { return m_reader.frame_reader->height; }
76 
transparentPixel() const77     int transparentPixel() const { return m_reader.frame_reader->tpixel; }
78 
duration() const79     unsigned duration() const { return m_reader.frame_reader->delay_time; }
80 
81 private:
82     GIFImageReader m_reader;
83     unsigned m_readOffset;
84 };
85 
GIFImageDecoder()86 GIFImageDecoder::GIFImageDecoder()
87     : m_frameCountValid(true)
88     , m_repetitionCount(cAnimationLoopOnce)
89     , m_reader(0)
90 {
91 }
92 
~GIFImageDecoder()93 GIFImageDecoder::~GIFImageDecoder()
94 {
95     delete m_reader;
96 }
97 
98 // Take the data and store it.
setData(SharedBuffer * data,bool allDataReceived)99 void GIFImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
100 {
101     if (m_failed)
102         return;
103 
104     // Cache our new data.
105     ImageDecoder::setData(data, allDataReceived);
106 
107     // Our frame count is now unknown.
108     m_frameCountValid = false;
109 
110     // Create the GIF reader.
111     if (!m_reader && !m_failed)
112         m_reader = new GIFImageDecoderPrivate(this);
113 }
114 
115 // Whether or not the size information has been decoded yet.
isSizeAvailable()116 bool GIFImageDecoder::isSizeAvailable()
117 {
118     if (!ImageDecoder::isSizeAvailable() && !failed() && m_reader)
119          decode(GIFSizeQuery, 0);
120 
121     return ImageDecoder::isSizeAvailable();
122 }
123 
124 // The total number of frames for the image.  Will scan the image data for the answer
125 // (without necessarily decoding all of the individual frames).
frameCount()126 size_t GIFImageDecoder::frameCount()
127 {
128     // If the decoder had an earlier error, we will just return what we had decoded
129     // so far.
130     if (!m_frameCountValid) {
131         // FIXME: Scanning all the data has O(n^2) behavior if the data were to come in really
132         // slowly.  Might be interesting to try to clone our existing read session to preserve
133         // state, but for now we just crawl all the data.  Note that this is no worse than what
134         // ImageIO does on Mac right now (it also crawls all the data again).
135         GIFImageDecoderPrivate reader;
136         // This function may fail, but we want to keep any partial data it may
137         // have decoded, so don't mark it is invalid. If there is an overflow
138         // or some serious error, m_failed will have gotten set for us.
139         reader.decode(m_data.get(), GIFFrameCountQuery);
140         m_frameCountValid = true;
141         m_frameBufferCache.resize(reader.frameCount());
142     }
143 
144     return m_frameBufferCache.size();
145 }
146 
147 // The number of repetitions to perform for an animation loop.
repetitionCount() const148 int GIFImageDecoder::repetitionCount() const
149 {
150     // This value can arrive at any point in the image data stream.  Most GIFs
151     // in the wild declare it near the beginning of the file, so it usually is
152     // set by the time we've decoded the size, but (depending on the GIF and the
153     // packets sent back by the webserver) not always.  Our caller is
154     // responsible for waiting until image decoding has finished to ask this if
155     // it needs an authoritative answer.  In the meantime, we should default to
156     // "loop once".
157     if (m_reader) {
158         // Added wrinkle: ImageSource::clear() may destroy the reader, making
159         // the result from the reader _less_ authoritative on future calls.  To
160         // detect this, the reader returns cLoopCountNotSeen (-2) instead of
161         // cAnimationLoopOnce (-1) when its current incarnation hasn't actually
162         // seen a loop count yet; in this case we return our previously-cached
163         // value.
164         const int repetitionCount = m_reader->repetitionCount();
165         if (repetitionCount != cLoopCountNotSeen)
166             m_repetitionCount = repetitionCount;
167     }
168     return m_repetitionCount;
169 }
170 
frameBufferAtIndex(size_t index)171 RGBA32Buffer* GIFImageDecoder::frameBufferAtIndex(size_t index)
172 {
173     if (index >= frameCount())
174         return 0;
175 
176     RGBA32Buffer& frame = m_frameBufferCache[index];
177     if (frame.status() != RGBA32Buffer::FrameComplete && m_reader)
178         decode(GIFFullQuery, index + 1); // Decode this frame.
179     return &frame;
180 }
181 
clearFrameBufferCache(size_t clearBeforeFrame)182 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
183 {
184     // In some cases, like if the decoder was destroyed while animating, we
185     // can be asked to clear more frames than we currently have.
186     if (m_frameBufferCache.isEmpty())
187         return; // Nothing to do.
188 
189     // The "-1" here is tricky.  It does not mean that |clearBeforeFrame| is the
190     // last frame we wish to preserve, but rather that we never want to clear
191     // the very last frame in the cache: it's empty (so clearing it is
192     // pointless), it's partial (so we don't want to clear it anyway), or the
193     // cache could be enlarged with a future setData() call and it could be
194     // needed to construct the next frame (see comments below).  Callers can
195     // always use ImageSource::clear(true, ...) to completely free the memory in
196     // this case.
197     clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
198     const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
199 
200     // We need to preserve frames such that:
201     //   * We don't clear |end|
202     //   * We don't clear the frame we're currently decoding
203     //   * We don't clear any frame from which a future initFrameBuffer() call
204     //     will copy bitmap data
205     // All other frames can be cleared.  Because of the constraints on when
206     // ImageSource::clear() can be called (see ImageSource.h), we're guaranteed
207     // not to have non-empty frames after the frame we're currently decoding.
208     // So, scan backwards from |end| as follows:
209     //   * If the frame is empty, we're still past any frames we care about.
210     //   * If the frame is complete, but is DisposeOverwritePrevious, we'll
211     //     skip over it in future initFrameBuffer() calls.  We can clear it
212     //     unless it's |end|, and keep scanning.  For any other disposal method,
213     //     stop scanning, as we've found the frame initFrameBuffer() will need
214     //     next.
215     //   * If the frame is partial, we're decoding it, so don't clear it; if it
216     //     has a disposal method other than DisposeOverwritePrevious, stop
217     //     scanning, as we'll only need this frame when decoding the next one.
218     Vector<RGBA32Buffer>::iterator i(end);
219     for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) {
220         if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end))
221             i->clear();
222     }
223 
224     // Now |i| holds the last frame we need to preserve; clear prior frames.
225     for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
226         ASSERT(j->status() != RGBA32Buffer::FramePartial);
227         if (j->status() != RGBA32Buffer::FrameEmpty)
228             j->clear();
229     }
230 }
231 
232 // Feed data to the GIF reader.
decode(GIFQuery query,unsigned haltAtFrame)233 void GIFImageDecoder::decode(GIFQuery query, unsigned haltAtFrame)
234 {
235     if (m_failed)
236         return;
237 
238     m_failed = !m_reader->decode(m_data.get(), query, haltAtFrame);
239 
240     if (m_failed) {
241         delete m_reader;
242         m_reader = 0;
243     }
244 }
245 
246 // Callbacks from the GIF reader.
sizeNowAvailable(unsigned width,unsigned height)247 bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height)
248 {
249     return setSize(width, height);
250 }
251 
decodingHalted(unsigned bytesLeft)252 void GIFImageDecoder::decodingHalted(unsigned bytesLeft)
253 {
254     m_reader->setReadOffset(m_data->size() - bytesLeft);
255 }
256 
initFrameBuffer(unsigned frameIndex)257 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
258 {
259     // Initialize the frame rect in our buffer.
260     IntRect frameRect(m_reader->frameXOffset(), m_reader->frameYOffset(),
261                       m_reader->frameWidth(), m_reader->frameHeight());
262 
263     // Make sure the frameRect doesn't extend past the bottom-right of the buffer.
264     if (frameRect.right() > size().width())
265         frameRect.setWidth(size().width() - m_reader->frameXOffset());
266     if (frameRect.bottom() > size().height())
267         frameRect.setHeight(size().height() - m_reader->frameYOffset());
268 
269     RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
270     buffer->setRect(frameRect);
271 
272     if (frameIndex == 0) {
273         // This is the first frame, so we're not relying on any previous data.
274         if (!buffer->setSize(size().width(), size().height())) {
275             m_failed = true;
276             return false;
277         }
278     } else {
279         // The starting state for this frame depends on the previous frame's
280         // disposal method.
281         //
282         // Frames that use the DisposeOverwritePrevious method are effectively
283         // no-ops in terms of changing the starting state of a frame compared to
284         // the starting state of the previous frame, so skip over them.  (If the
285         // first frame specifies this method, it will get treated like
286         // DisposeOverwriteBgcolor below and reset to a completely empty image.)
287         const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
288         RGBA32Buffer::FrameDisposalMethod prevMethod =
289             prevBuffer->disposalMethod();
290         while ((frameIndex > 0)
291                && (prevMethod == RGBA32Buffer::DisposeOverwritePrevious)) {
292             prevBuffer = &m_frameBufferCache[--frameIndex];
293             prevMethod = prevBuffer->disposalMethod();
294         }
295         ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete);
296 
297         if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) ||
298                 (prevMethod == RGBA32Buffer::DisposeKeep)) {
299             // Preserve the last frame as the starting state for this frame.
300             buffer->copyBitmapData(*prevBuffer);
301         } else {
302             // We want to clear the previous frame to transparent, without
303             // affecting pixels in the image outside of the frame.
304             const IntRect& prevRect = prevBuffer->rect();
305             if ((frameIndex == 0)
306                 || prevRect.contains(IntRect(IntPoint(), size()))) {
307                 // Clearing the first frame, or a frame the size of the whole
308                 // image, results in a completely empty image.
309                 if (!buffer->setSize(size().width(), size().height())) {
310                     m_failed = true;
311                     return false;
312                 }
313             } else {
314               // Copy the whole previous buffer, then clear just its frame.
315               buffer->copyBitmapData(*prevBuffer);
316               for (int y = prevRect.y(); y < prevRect.bottom(); ++y) {
317                   for (int x = prevRect.x(); x < prevRect.right(); ++x)
318                       buffer->setRGBA(x, y, 0, 0, 0, 0);
319               }
320               if ((prevRect.width() > 0) && (prevRect.height() > 0))
321                   buffer->setHasAlpha(true);
322             }
323         }
324     }
325 
326     // Update our status to be partially complete.
327     buffer->setStatus(RGBA32Buffer::FramePartial);
328 
329     // Reset the alpha pixel tracker for this frame.
330     m_currentBufferSawAlpha = false;
331     return true;
332 }
333 
haveDecodedRow(unsigned frameIndex,unsigned char * rowBuffer,unsigned char * rowEnd,unsigned rowNumber,unsigned repeatCount,bool writeTransparentPixels)334 void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
335                                      unsigned char* rowBuffer,
336                                      unsigned char* rowEnd,
337                                      unsigned rowNumber,
338                                      unsigned repeatCount,
339                                      bool writeTransparentPixels)
340 {
341     // The pixel data and coordinates supplied to us are relative to the frame's
342     // origin within the entire image size, i.e.
343     // (m_reader->frameXOffset(), m_reader->frameYOffset()).
344     int x = m_reader->frameXOffset();
345     const int y = m_reader->frameYOffset() + rowNumber;
346 
347     // Sanity-check the arguments.
348     if ((rowBuffer == 0) || (y >= size().height()))
349         return;
350 
351     // Get the colormap.
352     unsigned colorMapSize;
353     unsigned char* colorMap;
354     m_reader->getColorMap(colorMap, colorMapSize);
355     if (!colorMap)
356         return;
357 
358     // Initialize the frame if necessary.
359     RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
360     if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
361         return;
362 
363     // Write one row's worth of data into the frame.  There is no guarantee that
364     // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
365     // we must ensure we don't run off the end of either the source data or the
366     // row's X-coordinates.
367     for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < size().width()); ++sourceAddr, ++x) {
368         const unsigned char sourceValue = *sourceAddr;
369         if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) {
370             const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
371             buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
372         } else {
373             m_currentBufferSawAlpha = true;
374             // We may or may not need to write transparent pixels to the buffer.
375             // If we're compositing against a previous image, it's wrong, and if
376             // we're writing atop a cleared, fully transparent buffer, it's
377             // unnecessary; but if we're decoding an interlaced gif and
378             // displaying it "Haeberli"-style, we must write these for passes
379             // beyond the first, or the initial passes will "show through" the
380             // later ones.
381             if (writeTransparentPixels)
382                 buffer.setRGBA(x, y, 0, 0, 0, 0);
383         }
384     }
385 
386     // Tell the frame to copy the row data if need be.
387     if (repeatCount > 1)
388         buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height()));
389 }
390 
frameComplete(unsigned frameIndex,unsigned frameDuration,RGBA32Buffer::FrameDisposalMethod disposalMethod)391 void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
392 {
393     // Initialize the frame if necessary.  Some GIFs insert do-nothing frames,
394     // in which case we never reach haveDecodedRow() before getting here.
395     RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
396     if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
397         return;
398 
399     buffer.setStatus(RGBA32Buffer::FrameComplete);
400     buffer.setDuration(frameDuration);
401     buffer.setDisposalMethod(disposalMethod);
402 
403     if (!m_currentBufferSawAlpha) {
404         // The whole frame was non-transparent, so it's possible that the entire
405         // resulting buffer was non-transparent, and we can setHasAlpha(false).
406         if (buffer.rect().contains(IntRect(IntPoint(), size())))
407             buffer.setHasAlpha(false);
408         else if (frameIndex > 0) {
409             // Tricky case.  This frame does not have alpha only if everywhere
410             // outside its rect doesn't have alpha.  To know whether this is
411             // true, we check the start state of the frame -- if it doesn't have
412             // alpha, we're safe.
413             //
414             // First skip over prior DisposeOverwritePrevious frames (since they
415             // don't affect the start state of this frame) the same way we do in
416             // initFrameBuffer().
417             const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
418             while ((frameIndex > 0)
419                    && (prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious))
420                 prevBuffer = &m_frameBufferCache[--frameIndex];
421 
422             // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then
423             // we can say we have no alpha if that frame had no alpha.  But
424             // since in initFrameBuffer() we already copied that frame's alpha
425             // state into the current frame's, we need do nothing at all here.
426             //
427             // The only remaining case is a DisposeOverwriteBgcolor frame.  If
428             // it had no alpha, and its rect is contained in the current frame's
429             // rect, we know the current frame has no alpha.
430             if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor)
431                 && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect()))
432                 buffer.setHasAlpha(false);
433         }
434     }
435 }
436 
gifComplete()437 void GIFImageDecoder::gifComplete()
438 {
439     if (m_reader)
440         m_repetitionCount = m_reader->repetitionCount();
441     delete m_reader;
442     m_reader = 0;
443 }
444 
445 } // namespace WebCore
446