Line
Link Here
|
0 |
-- WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp |
0 |
++ WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp |
Lines 135-142
Link Here
|
135 |
// always use ImageSource::clear(true, ...) to completely free the memory in |
135 |
// always use ImageSource::clear(true, ...) to completely free the memory in |
136 |
// this case. |
136 |
// this case. |
137 |
clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1); |
137 |
clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1); |
138 |
const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame); |
138 |
|
139 |
|
|
|
140 |
// We need to preserve frames such that: |
139 |
// We need to preserve frames such that: |
141 |
// * We don't clear |end| |
140 |
// * We don't clear |end| |
142 |
// * We don't clear the frame we're currently decoding |
141 |
// * We don't clear the frame we're currently decoding |
Lines 155-171
Link Here
|
155 |
// * If the frame is partial, we're decoding it, so don't clear it; if it |
154 |
// * If the frame is partial, we're decoding it, so don't clear it; if it |
156 |
// has a disposal method other than DisposeOverwritePrevious, stop |
155 |
// has a disposal method other than DisposeOverwritePrevious, stop |
157 |
// scanning, as we'll only need this frame when decoding the next one. |
156 |
// scanning, as we'll only need this frame when decoding the next one. |
158 |
Vector<RGBA32Buffer>::iterator i(end); |
157 |
size_t i; |
159 |
for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) { |
158 |
for (i = clearBeforeFrame; i && ((m_frameBufferCache[i].status() == RGBA32Buffer::FrameEmpty) || (m_frameBufferCache[i].disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) { |
160 |
if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end)) |
159 |
if ((m_frameBufferCache[i].status() == RGBA32Buffer::FrameComplete) && (i != clearBeforeFrame)) |
161 |
i->clear(); |
160 |
m_frameBufferCache[i].clear(); |
162 |
} |
161 |
} |
163 |
|
162 |
|
164 |
// Now |i| holds the last frame we need to preserve; clear prior frames. |
163 |
// Now |i| holds the last frame we need to preserve; clear prior frames. |
165 |
for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) { |
164 |
for (size_t j = 0; j != i; ++j) { |
166 |
ASSERT(j->status() != RGBA32Buffer::FramePartial); |
165 |
ASSERT(m_frameBufferCache[j].status() != RGBA32Buffer::FramePartial); |
167 |
if (j->status() != RGBA32Buffer::FrameEmpty) |
166 |
if (m_frameBufferCache[j].status() != RGBA32Buffer::FrameEmpty) |
168 |
j->clear(); |
167 |
m_frameBufferCache[j].clear(); |
169 |
} |
168 |
} |
170 |
} |
169 |
} |
171 |
|
170 |
|
Lines 343-349
Link Here
|
343 |
|
342 |
|
344 |
if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) || (prevMethod == RGBA32Buffer::DisposeKeep)) { |
343 |
if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) || (prevMethod == RGBA32Buffer::DisposeKeep)) { |
345 |
// Preserve the last frame as the starting state for this frame. |
344 |
// Preserve the last frame as the starting state for this frame. |
346 |
if (!buffer->copyBitmapData(*prevBuffer)); |
345 |
if (!buffer->copyBitmapData(*prevBuffer)) |
347 |
return setFailed(); |
346 |
return setFailed(); |
348 |
} else { |
347 |
} else { |
349 |
// We want to clear the previous frame to transparent, without |
348 |
// We want to clear the previous frame to transparent, without |
Lines 357-363
Link Here
|
357 |
return setFailed(); |
356 |
return setFailed(); |
358 |
} else { |
357 |
} else { |
359 |
// Copy the whole previous buffer, then clear just its frame. |
358 |
// Copy the whole previous buffer, then clear just its frame. |
360 |
if (!buffer->copyBitmapData(*prevBuffer)); |
359 |
if (!buffer->copyBitmapData(*prevBuffer)) |
361 |
return setFailed(); |
360 |
return setFailed(); |
362 |
for (int y = prevRect.y(); y < prevRect.bottom(); ++y) { |
361 |
for (int y = prevRect.y(); y < prevRect.bottom(); ++y) { |
363 |
for (int x = prevRect.x(); x < prevRect.right(); ++x) |
362 |
for (int x = prevRect.x(); x < prevRect.right(); ++x) |
364 |
-- WebCore/platform/image-decoders/ImageDecoder.h |
363 |
++ WebCore/platform/image-decoders/ImageDecoder.h |
Lines 191-196
Link Here
|
191 |
// initializing the next frame. |
191 |
// initializing the next frame. |
192 |
}; |
192 |
}; |
193 |
|
193 |
|
|
|
194 |
class frameBufferCache { |
195 |
public: |
196 |
frameBufferCache() |
197 |
: m_size(0) |
198 |
, m_prev(NULL) |
199 |
, m_next(NULL) |
200 |
{ |
201 |
} |
202 |
|
203 |
bool isEmpty() const |
204 |
{ |
205 |
return m_size == 0; |
206 |
} |
207 |
|
208 |
const RGBA32Buffer& first() const |
209 |
{ |
210 |
return m_buffer; |
211 |
} |
212 |
|
213 |
RGBA32Buffer& first() |
214 |
{ |
215 |
return m_buffer; |
216 |
} |
217 |
|
218 |
RGBA32Buffer& operator [] (size_t n) |
219 |
{ |
220 |
return getItem(n)->m_buffer; |
221 |
} |
222 |
|
223 |
size_t size() |
224 |
{ |
225 |
return m_size; |
226 |
} |
227 |
|
228 |
void resize(size_t sz) |
229 |
{ |
230 |
if (sz == m_size) |
231 |
return; |
232 |
|
233 |
frameBufferCache* item = getLastItem(); |
234 |
|
235 |
if (sz > m_size) |
236 |
for (; m_size < sz; m_size++) { |
237 |
item->m_next = new frameBufferCache; |
238 |
item = item->m_next; |
239 |
} |
240 |
else |
241 |
for (; m_size > sz; m_size--) { |
242 |
item = item->m_prev; |
243 |
delete item->m_next; |
244 |
item->m_next = NULL; |
245 |
} |
246 |
} |
247 |
private: |
248 |
frameBufferCache* getItem(size_t n) |
249 |
{ |
250 |
frameBufferCache* item = this; |
251 |
|
252 |
for (size_t i = 0; i < n; i++) |
253 |
item = item->m_next; |
254 |
|
255 |
return item; |
256 |
} |
257 |
|
258 |
frameBufferCache* getLastItem() |
259 |
{ |
260 |
frameBufferCache* item = this; |
261 |
|
262 |
while (item->m_next) |
263 |
item = item->m_next; |
264 |
|
265 |
return item; |
266 |
} |
267 |
|
268 |
RGBA32Buffer m_buffer; |
269 |
|
270 |
size_t m_size; |
271 |
|
272 |
frameBufferCache* m_next; |
273 |
|
274 |
frameBufferCache* m_prev; |
275 |
}; |
276 |
|
194 |
// The ImageDecoder class represents a base class for specific image format |
277 |
// The ImageDecoder class represents a base class for specific image format |
195 |
// decoders (e.g., GIF, JPG, PNG, ICO) to derive from. All decoders decode |
278 |
// decoders (e.g., GIF, JPG, PNG, ICO) to derive from. All decoders decode |
196 |
// into RGBA32 format and the base class manages the RGBA32 frame cache. |
279 |
// into RGBA32 format and the base class manages the RGBA32 frame cache. |
Lines 325-331
Link Here
|
325 |
int scaledY(int origY, int searchStart = 0); |
408 |
int scaledY(int origY, int searchStart = 0); |
326 |
|
409 |
|
327 |
RefPtr<SharedBuffer> m_data; // The encoded data. |
410 |
RefPtr<SharedBuffer> m_data; // The encoded data. |
328 |
Vector<RGBA32Buffer> m_frameBufferCache; |
411 |
frameBufferCache m_frameBufferCache; |
329 |
bool m_scaled; |
412 |
bool m_scaled; |
330 |
Vector<int> m_scaledColumns; |
413 |
Vector<int> m_scaledColumns; |
331 |
Vector<int> m_scaledRows; |
414 |
Vector<int> m_scaledRows; |