OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2008-2009 Torch Mobile, Inc. | 2 * Copyright (C) 2008-2009 Torch Mobile, Inc. |
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 int ImageDecoder::lowerBoundScaledY(int origY, int searchStart) | 220 int ImageDecoder::lowerBoundScaledY(int origY, int searchStart) |
221 { | 221 { |
222 return getScaledValue<LowerBound>(m_scaledRows, origY, searchStart); | 222 return getScaledValue<LowerBound>(m_scaledRows, origY, searchStart); |
223 } | 223 } |
224 | 224 |
225 int ImageDecoder::scaledY(int origY, int searchStart) | 225 int ImageDecoder::scaledY(int origY, int searchStart) |
226 { | 226 { |
227 return getScaledValue<Exact>(m_scaledRows, origY, searchStart); | 227 return getScaledValue<Exact>(m_scaledRows, origY, searchStart); |
228 } | 228 } |
229 | 229 |
230 void ImageDecoder::clearFrameBufferCache(size_t clearExceptFrame) | |
Alpha Left Google
2013/05/22 20:18:09
I'm not sure you should move this to the base clas
Xianzhu
2013/05/22 23:43:29
I thought as the disposal methods are defined in c
| |
231 { | |
232 // Don't clear if there is no or only one frame. | |
233 if (m_frameBufferCache.size() <= 1) | |
234 return; | |
235 | |
236 // We need to preserve frames such that: | |
237 // 1. We don't clear |clearExceptFrame|; | |
238 // 2. We don't clear any frame from which a future initFrameBuffer() call | |
239 // will copy bitmap data. | |
240 // 3. We don't clear empty frames or the frame we're currently decoding; | |
241 // All other frames can be cleared. | |
242 size_t frameToBeRequired; | |
243 if (clearExceptFrame < m_frameBufferCache.size() && m_frameBufferCache[clear ExceptFrame].status() == ImageFrame::FrameEmpty) { | |
244 frameToBeRequired = clearExceptFrame; | |
245 do { | |
246 frameToBeRequired = m_frameBufferCache[frameToBeRequired].requiredPr eviousFrameIndex(); | |
247 } while (frameToBeRequired != notFound && m_frameBufferCache[frameToBeRe quired].status() != ImageFrame::FrameComplete); | |
Xianzhu
2013/05/22 23:43:29
Changed the above condition to ...== ImageFrame::F
| |
248 } else { | |
249 // initFrameBuffer() has already been called for this frame. | |
250 frameToBeRequired = notFound; | |
251 } | |
252 | |
253 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { | |
254 if (i == clearExceptFrame || i == frameToBeRequired) // 1 and 2. | |
255 continue; | |
256 | |
257 ImageFrame& frame = m_frameBufferCache[i]; | |
258 if (frame.status() == ImageFrame::FrameComplete) // 3. | |
Alpha Left Google
2013/05/22 20:18:09
Using this condition you'll hit a corner case wher
Xianzhu
2013/05/22 23:43:29
Changed to clear partial frames. However, I'm not
Xianzhu
2013/05/23 00:33:49
Never mind this question. I know the answer now :)
| |
259 frame.clearPixelData(); | |
260 } | |
261 } | |
262 | |
263 size_t ImageDecoder::findRequiredPreviousFrame(size_t frameIndex) | |
264 { | |
265 if (!frameIndex) { | |
266 // The first frame doesn't rely on any previous data. | |
267 return notFound; | |
268 } | |
269 | |
270 // The starting state for this frame depends on the previous frame's | |
271 // disposal method. | |
272 // | |
273 // Frames that use the DisposeOverwritePrevious method are effectively | |
274 // no-ops in terms of changing the starting state of a frame compared to | |
275 // the starting state of the previous frame, so skip over them. (If the | |
276 // first frame specifies this method, it will get treated like | |
277 // DisposeOverwriteBgcolor below and reset to a completely empty image.) | |
278 size_t prevFrame = frameIndex - 1; | |
279 const ImageFrame* prevBuffer = &m_frameBufferCache[prevFrame]; | |
280 ImageFrame::FrameDisposalMethod prevMethod = prevBuffer->disposalMethod(); | |
281 while (prevFrame && (prevMethod == ImageFrame::DisposeOverwritePrevious)) { | |
282 prevBuffer = &m_frameBufferCache[--prevFrame]; | |
283 prevMethod = prevBuffer->disposalMethod(); | |
284 } | |
285 | |
286 if (prevMethod == ImageFrame::DisposeNotSpecified || prevMethod == ImageFram e::DisposeKeep) { | |
287 // prevFrame will be used as the starting state for this frame. | |
288 return prevFrame; | |
289 } | |
290 | |
291 if (!prevFrame) { | |
292 // The first frame whose disposal method is DisposeOverwriteBgColor or | |
293 // DisposeOverritePrevious will be reset to background despite its size. | |
294 return notFound; | |
295 } | |
296 | |
297 ASSERT(prevMethod == ImageFrame::DisposeOverwriteBgcolor); | |
298 const IntRect& prevRect = prevBuffer->originalFrameRect(); | |
299 const IntSize& bufferSize = scaledSize(); | |
300 if (prevRect.contains(IntRect(IntPoint(), scaledSize()))) { | |
301 // prevFrame covering the whole image will be reset to background, | |
302 return notFound; | |
303 } | |
304 | |
305 // prevFrame only clears part of the image to background, so it contributes | |
306 // to the starting state of this frame. | |
307 return prevFrame; | |
308 } | |
309 | |
230 } // namespace WebCore | 310 } // namespace WebCore |
OLD | NEW |