Changeset 44553 in webkit
- Timestamp:
- Jun 9, 2009 7:23:06 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r44552 r44553 1 2009-06-09 Peter Kasting <pkasting@google.com> 2 3 Reviewed by Eric Seidel. 4 5 https://bugs.webkit.org/show_bug.cgi?id=25709 part four 6 Most of the remaining Cairo changes needed before merging Skia/Cairo 7 image decoders. Most of these involve plumbing more error detection and 8 handling (or, in some cases, merely the capability to detect errors, as 9 e.g. Skia detects and handles image allocation failure while Cairo 10 currently doesn't). There is also some general cleanup and 11 simplification; RGBA32Buffer::m_height and all associated functions have 12 been removed (set but never used) and some places now rely on superclass 13 implementations. 14 15 * platform/image-decoders/ImageDecoder.h: 16 (WebCore::RGBA32Buffer::RGBA32Buffer): Remove m_height, ensureHeight() and associated stuff 17 (WebCore::RGBA32Buffer::copyBitmapData): Add API function so refcounted backing stores (like Skia uses) can be used with GIFs 18 (WebCore::RGBA32Buffer::setSize): Zero-fill image to avoid garbage 19 (WebCore::RGBA32Buffer::height): Remove 20 (WebCore::RGBA32Buffer::ensureHeight): Remove 21 (WebCore::ImageDecoder::ImageDecoder): Keep member initialization in order, force subclasses to go through size() instead of accessing m_size directly 22 (WebCore::ImageDecoder::isSizeAvailable): Check that decoding hasn't failed 23 (WebCore::ImageDecoder::size): Check that decoding hasn't failed 24 (WebCore::ImageDecoder::setSize): Protect against integer overflow 25 (WebCore::ImageDecoder::isOverSize): Protect against integer overflow 26 * platform/image-decoders/gif/GIFImageDecoder.cpp: Remove prepEmptyFrameBuffer() 27 (WebCore::GIFImageDecoder::isSizeAvailable): Rely on superclass isSizeAvailable() for better failure handling 28 (WebCore::GIFImageDecoder::sizeNowAvailable): Add return values for better failure handling, rely on superclass setSize() for overflow protection 29 (WebCore::GIFImageDecoder::initFrameBuffer): Add return values for better failure handling, remove prepEmptyFrameBuffer(), use RGBA32Buffer::setSize() to handle potential allocation failures (won't happen with Cairo port, can in Skia), use RGBA32Buffer::copyBitmapData() so backing store can be refcounted internally (Cairo won't be, Skia is), rely on superclass size() for better failure handling 30 (WebCore::GIFImageDecoder::haveDecodedRow): Fix style violation, remove RGBA32Buffer::ensureHeight() 31 (WebCore::GIFImageDecoder::frameComplete): Remove RGBA32Buffer::ensureHeight() 32 * platform/image-decoders/gif/GIFImageDecoder.h: Remove prepEmptyFrameBuffer(), add return values for better failure handling 33 * platform/image-decoders/gif/GIFImageReader.cpp: 34 (GIFImageReader::do_lzw): Protect against array overflow, add comments 35 (GIFImageReader::read): Protect against array overflow, be more tolerant of bad data, better failure handling 36 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Remove MSVC-specific warning disable (bfulgham will move into build files) 37 (WebCore::JPEGImageReader::decode): Better failure handling 38 (WebCore::JPEGImageDecoder::isSizeAvailable): Rely on superclass isSizeAvailable() for better failure handling 39 (WebCore::JPEGImageDecoder::outputScanlines): Use RGBA32Buffer::setSize() to handle potential allocation failures (won't happen with Cairo port, can in Skia), rely on superclass size() for better failure handling, remove RGBA32Buffer::ensureHeight() 40 * platform/image-decoders/jpeg/JPEGImageDecoder.h: Rely on superclass setSize() for overflow protection 41 * platform/image-decoders/png/PNGImageDecoder.cpp: Remove MSVC-specific warning disable (bfulgham will move into build files) 42 (WebCore::PNGImageDecoder::PNGImageDecoder): Don't allocate a slot in the framebuffer cache until it's needed 43 (WebCore::PNGImageDecoder::isSizeAvailable): Rely on superclass isSizeAvailable() for better failure handling 44 (WebCore::PNGImageDecoder::frameBufferAtIndex): Don't allocate a slot in the framebuffer cache until it's needed 45 (WebCore::PNGImageDecoder::decode): Don't allocate a slot in the framebuffer cache until it's needed 46 (WebCore::PNGImageDecoder::decodingFailed): Fix style violation 47 (WebCore::PNGImageDecoder::headerAvailable): Rely on superclass isSizeAvailable() and setSize() for overflow protection and better failure handling 48 (WebCore::PNGImageDecoder::rowAvailable): Don't allocate a slot in the framebuffer cache until it's needed, use RGBA32Buffer::setSize() to handle potential allocation failures (won't happen with Cairo port, can in Skia), remove RGBA32Buffer::ensureHeight() 49 (WebCore::PNGImageDecoder::pngComplete): Don't allocate a slot in the framebuffer cache until it's needed 50 1 51 2009-06-09 Kevin Ollivier <kevino@theolliviers.com> 2 52 -
trunk/WebCore/platform/image-decoders/ImageDecoder.h
r44167 r44553 31 31 #include "PlatformString.h" 32 32 #include "SharedBuffer.h" 33 #include <wtf/Assertions.h> 34 #include <wtf/RefPtr.h> 33 35 #include <wtf/Vector.h> 34 36 … … 53 55 54 56 RGBA32Buffer() 55 : m_height(0) 56 , m_status(FrameEmpty) 57 : m_status(FrameEmpty) 57 58 , m_duration(0) 58 59 , m_disposalMethod(DisposeNotSpecified) … … 70 71 } 71 72 73 // This function creates a new copy of the image data in |other|, so the 74 // two images can be modified independently. 75 void copyBitmapData(const RGBA32Buffer& other) 76 { 77 if (this == &other) 78 return; 79 80 m_bytes = other.m_bytes; 81 m_hasAlpha = other.m_hasAlpha; 82 } 83 72 84 const RGBA32Array& bytes() const { return m_bytes; } 73 85 RGBA32Array& bytes() { return m_bytes; } 86 87 // Must be called before any pixels are written. Will return true on 88 // success, false if the memory allocation fails. 89 bool setSize(int width, int height) 90 { 91 // NOTE: This has no way to check for allocation failure if the 92 // requested size was too big... 93 m_bytes.resize(width * height); 94 95 // Clear the image. 96 m_bytes.fill(0); 97 m_hasAlpha = true; 98 99 return true; 100 } 101 74 102 const IntRect& rect() const { return m_rect; } 75 unsigned height() const { return m_height; }76 103 FrameStatus status() const { return m_status; } 77 104 unsigned duration() const { return m_duration; } … … 80 107 81 108 void setRect(const IntRect& r) { m_rect = r; } 82 void ensureHeight(unsigned rowIndex) { if (rowIndex > m_height) m_height = rowIndex; }83 109 void setStatus(FrameStatus s) { m_status = s; } 84 110 void setDuration(unsigned duration) { m_duration = duration; } … … 107 133 // This will always just be the entire buffer except for GIF frames 108 134 // whose original rect was smaller than the overall image size. 109 unsigned m_height; // The height (the number of rows we've fully decoded).110 135 FrameStatus m_status; // Whether or not this frame is completely finished decoding. 111 136 unsigned m_duration; // The animation delay. … … 120 145 public: 121 146 ImageDecoder() 122 : m_ sizeAvailable(false)123 , m_ failed(false)124 { 125 } 126 147 : m_failed(false) 148 , m_sizeAvailable(false) 149 { 150 } 151 127 152 virtual ~ImageDecoder() {} 128 153 … … 133 158 virtual void setData(SharedBuffer* data, bool allDataReceived) { m_data = data; } 134 159 135 // Whether or not the size information has been decoded yet. 136 virtual bool isSizeAvailable() const = 0; 160 // Whether or not the size information has been decoded yet. This default 161 // implementation just returns true if the size has been set and we have not 162 // seen a failure. Decoders may want to override this to lazily decode 163 // enough of the image to get the size. 164 virtual bool isSizeAvailable() const 165 { 166 return !m_failed && m_sizeAvailable; 167 } 137 168 138 169 // Requests the size. 139 virtual IntSize size() const { return m_size; } 170 virtual IntSize size() const 171 { 172 // Requesting the size of an invalid bitmap is meaningless. 173 ASSERT(!m_failed); 174 return m_size; 175 } 140 176 141 177 // The total number of frames for the image. Classes that support multiple frames … … 167 203 168 204 protected: 205 // Called by the image decoders to set their decoded size, this also check 206 // the size for validity. It will return true if the size was set, or false 207 // if there is an error. On error, the m_failed flag will be set and the 208 // caller should immediately stop decoding. 209 bool setSize(unsigned width, unsigned height) 210 { 211 if (isOverSize(width, height)) { 212 m_failed = true; 213 return false; 214 } 215 m_size = IntSize(width, height); 216 m_sizeAvailable = true; 217 return true; 218 } 219 169 220 RefPtr<SharedBuffer> m_data; // The encoded data. 170 221 Vector<RGBA32Buffer> m_frameBufferCache; 222 mutable bool m_failed; 223 224 private: 225 // Some code paths compute the size of the image as "width * height * 4" 226 // and return it as a (signed) int. Avoid overflow. 227 static bool isOverSize(unsigned width, unsigned height) 228 { 229 // width * height must not exceed (2 ^ 29) - 1, so that we don't 230 // overflow when we multiply by 4. 231 unsigned long long total_size = static_cast<unsigned long long>(width) 232 * static_cast<unsigned long long>(height); 233 return total_size > ((1 << 29) - 1); 234 } 235 236 IntSize m_size; 171 237 bool m_sizeAvailable; 172 mutable bool m_failed;173 IntSize m_size;174 238 }; 175 239 -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r44167 r44553 117 117 { 118 118 // If we have pending data to decode, send it to the GIF reader now. 119 if (! m_sizeAvailable&& m_reader) {119 if (!ImageDecoder::isSizeAvailable() && m_reader) { 120 120 if (m_failed) 121 121 return false; … … 126 126 } 127 127 128 return m_sizeAvailable;128 return ImageDecoder::isSizeAvailable(); 129 129 } 130 130 … … 252 252 253 253 // Callbacks from the GIF reader. 254 void GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height) 255 { 256 m_size = IntSize(width, height); 257 m_sizeAvailable = true; 254 bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height) 255 { 256 return setSize(width, height); 258 257 } 259 258 … … 263 262 } 264 263 265 voidGIFImageDecoder::initFrameBuffer(unsigned frameIndex)264 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) 266 265 { 267 266 // Initialize the frame rect in our buffer. … … 280 279 if (frameIndex == 0) { 281 280 // This is the first frame, so we're not relying on any previous data. 282 prepEmptyFrameBuffer(buffer); 281 if (!buffer->setSize(size().width(), size().height())) { 282 m_failed = true; 283 return false; 284 } 283 285 } else { 284 286 // The starting state for this frame depends on the previous frame's … … 303 305 (prevMethod == RGBA32Buffer::DisposeKeep)) { 304 306 // Preserve the last frame as the starting state for this frame. 305 buffer->bytes() = prevBuffer->bytes(); 306 buffer->setHasAlpha(prevBuffer->hasAlpha()); 307 buffer->copyBitmapData(*prevBuffer); 307 308 } else { 308 309 // We want to clear the previous frame to transparent, without … … 313 314 // Clearing the first frame, or a frame the size of the whole 314 315 // image, results in a completely empty image. 315 prepEmptyFrameBuffer(buffer); 316 if (!buffer->setSize(size().width(), size().height())) { 317 m_failed = true; 318 return false; 319 } 316 320 } else { 317 321 // Copy the whole previous buffer, then clear just its frame. 318 buffer->bytes() = prevBuffer->bytes(); 319 buffer->setHasAlpha(prevBuffer->hasAlpha()); 322 buffer->copyBitmapData(*prevBuffer); 320 323 for (int y = prevRect.y(); y < prevRect.bottom(); ++y) { 321 324 unsigned* const currentRow = 322 buffer->bytes().data() + (y * m_size.width());325 buffer->bytes().data() + (y * size().width()); 323 326 for (int x = prevRect.x(); x < prevRect.right(); ++x) 324 327 buffer->setRGBA(*(currentRow + x), 0, 0, 0, 0); … … 335 338 // Reset the alpha pixel tracker for this frame. 336 339 m_currentBufferSawAlpha = false; 337 } 338 339 void GIFImageDecoder::prepEmptyFrameBuffer(RGBA32Buffer* buffer) const 340 { 341 buffer->bytes().resize(size().width() * size().height()); 342 buffer->bytes().fill(0); 343 buffer->setHasAlpha(true); 340 return true; 344 341 } 345 342 … … 353 350 // Initialize the frame if necessary. 354 351 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; 355 if ( buffer.status() == RGBA32Buffer::FrameEmpty)356 initFrameBuffer(frameIndex);352 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) 353 return; 357 354 358 355 // Do nothing for bogus data. … … 405 402 // Copy the row |repeatCount|-1 times. 406 403 unsigned num = currDst - dst; 407 unsigned data _size = num * sizeof(unsigned);404 unsigned dataSize = num * sizeof(unsigned); 408 405 unsigned width = size().width(); 409 406 unsigned* end = buffer.bytes().data() + width * size().height(); … … 412 409 if (currDst + num > end) // Protect against a buffer overrun from a bogus repeatCount. 413 410 break; 414 memcpy(currDst, dst, data _size);411 memcpy(currDst, dst, dataSize); 415 412 currDst += width; 416 413 } 417 414 } 418 419 // Our partial height is rowNumber + 1, e.g., row 2 is the 3rd row, so that's a height of 3.420 // Adding in repeatCount - 1 to rowNumber + 1 works out to just be rowNumber + repeatCount.421 buffer.ensureHeight(rowNumber + repeatCount);422 415 } 423 416 … … 427 420 // in which case we never reach haveDecodedRow() before getting here. 428 421 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; 429 if (buffer.status() == RGBA32Buffer::FrameEmpty) 430 initFrameBuffer(frameIndex); 431 432 buffer.ensureHeight(m_size.height()); 422 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) 423 return; 424 433 425 buffer.setStatus(RGBA32Buffer::FrameComplete); 434 426 buffer.setDuration(frameDuration); -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
r44167 r44553 65 65 66 66 // Callbacks from the GIF reader. 67 voidsizeNowAvailable(unsigned width, unsigned height);67 bool sizeNowAvailable(unsigned width, unsigned height); 68 68 void decodingHalted(unsigned bytesLeft); 69 69 void haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, … … 74 74 private: 75 75 // Called to initialize the frame buffer with the given index, based on the 76 // previous frame's disposal method. 77 void initFrameBuffer(unsigned frameIndex); 78 79 // A helper for initFrameBuffer(), this sets the size of the buffer, and 80 // fills it with transparent pixels. 81 void prepEmptyFrameBuffer(RGBA32Buffer*) const; 76 // previous frame's disposal method. Returns true on success. On failure, 77 // this will mark the image as failed. 78 bool initFrameBuffer(unsigned frameIndex); 82 79 83 80 bool m_frameCountValid; -
trunk/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
r44167 r44553 312 312 while (code >= clear_code) 313 313 { 314 if (code == prefix[code])314 if (code >= MAX_BITS || code == prefix[code]) 315 315 return -1; 316 316 317 // Even though suffix[] only holds characters through suffix[avail - 1], 318 // allowing code >= avail here lets us be more tolerant of malformed 319 // data. As long as code < MAX_BITS, the only risk is a garbled image, 320 // which is no worse than refusing to display it. 317 321 *stackp++ = suffix[code]; 318 322 code = prefix[code]; … … 446 450 /* Initialize LZW parser/decoder */ 447 451 int datasize = *q; 448 if (datasize > MAX_LZW_BITS) { 452 // Since we use a codesize of 1 more than the datasize, we need to ensure 453 // that our datasize is strictly less than the MAX_LZW_BITS value (12). 454 // This sets the largest possible codemask correctly at 4095. 455 if (datasize >= MAX_LZW_BITS) { 449 456 state = gif_error; 450 457 break; … … 469 476 if (!frame_reader->suffix) 470 477 frame_reader->suffix = new unsigned char[MAX_BITS]; 478 // Clearing the whole suffix table lets us be more tolerant of bad data. 479 memset(frame_reader->suffix, 0, MAX_BITS); 471 480 for (int i = 0; i < frame_reader->clear_code; i++) 472 481 frame_reader->suffix[i] = i; … … 509 518 510 519 // CALLBACK: Inform the decoderplugin of our size. 511 if (clientptr )512 clientptr->sizeNowAvailable(screen_width, screen_height);520 if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) 521 return false; 513 522 514 523 screen_bgcolor = q[5]; … … 735 744 736 745 // CALLBACK: Inform the decoderplugin of our size. 737 if (clientptr )738 clientptr->sizeNowAvailable(screen_width, screen_height);746 if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) 747 return false; 739 748 } 740 749 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r44175 r44553 39 39 #include "JPEGImageDecoder.h" 40 40 #include <assert.h> 41 #include <stdio.h>42 41 43 42 extern "C" { 44 43 #include "jpeglib.h" 45 44 } 46 47 #if COMPILER(MSVC)48 // Remove warnings from warning level 4.49 #pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable50 #endif // COMPILER(MSVC)51 45 52 46 #include <setjmp.h> … … 220 214 221 215 // We can fill in the size now that the header is available. 222 m_decoder->setSize(m_info.image_width, m_info.image_height); 216 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) { 217 m_state = JPEG_ERROR; 218 return false; 219 } 223 220 224 221 if (m_decodingSizeOnly) { … … 415 412 { 416 413 // If we have pending data to decode, send it to the JPEG reader now. 417 if (! m_sizeAvailable&& m_reader) {414 if (!ImageDecoder::isSizeAvailable() && m_reader) { 418 415 if (m_failed) 419 416 return false; … … 424 421 } 425 422 426 return m_sizeAvailable;423 return ImageDecoder::isSizeAvailable(); 427 424 } 428 425 … … 464 461 RGBA32Buffer& buffer = m_frameBufferCache[0]; 465 462 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 466 // Let's resize our buffer now to the correct width/height. 467 RGBA32Array& bytes = buffer.bytes(); 468 bytes.resize(size().width() * size().height()); 463 // Let's resize our buffer now to the correct width/height. This will 464 // also initialize it to transparent. 465 if (!buffer.setSize(size().width(), size().height())) { 466 m_failed = true; 467 return false; 468 } 469 469 470 470 // Update our status to be partially complete. 471 471 buffer.setStatus(RGBA32Buffer::FramePartial); 472 buffer.setHasAlpha(false); 472 473 473 474 // For JPEGs, the frame always fills the entire image. 474 buffer.setRect(IntRect(0, 0, m_size.width(), m_size.height())); 475 476 // We don't have alpha (this is the default when the buffer is constructed). 475 buffer.setRect(IntRect(IntPoint(), size())); 477 476 } 478 477 … … 480 479 JSAMPARRAY samples = m_reader->samples(); 481 480 482 unsigned* dst = buffer.bytes().data() + info->output_scanline * m_size.width();481 unsigned* dst = buffer.bytes().data() + info->output_scanline * size().width(); 483 482 484 483 while (info->output_scanline < info->output_height) { … … 493 492 RGBA32Buffer::setRGBA(*dst++, r, g, b, 0xFF); 494 493 } 495 496 buffer.ensureHeight(info->output_scanline);497 494 } 498 495 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r44167 r44553 55 55 JPEGImageReader* reader() { return m_reader; } 56 56 57 void setSize(int width, int height) {58 if (!m_sizeAvailable) {59 m_sizeAvailable = true;60 m_size = IntSize(width, height);61 }62 }63 64 57 bool outputScanlines(); 65 58 void jpegComplete(); 66 59 67 60 private: 61 friend class JPEGImageReader; 68 62 mutable JPEGImageReader* m_reader; 69 63 }; -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r44167 r44553 41 41 #include "assert.h" 42 42 43 #if COMPILER(MSVC)44 // Remove warnings from warning level 4.45 #pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable46 #endif // COMPILER(MSVC)47 48 43 namespace WebCore { 49 44 … … 144 139 : m_reader(0) 145 140 { 146 m_frameBufferCache.resize(1);147 141 } 148 142 … … 170 164 { 171 165 // If we have pending data to decode, send it to the PNG reader now. 172 if (! m_sizeAvailable&& m_reader) {166 if (!ImageDecoder::isSizeAvailable() && m_reader) { 173 167 if (m_failed) 174 168 return false; … … 179 173 } 180 174 181 return m_sizeAvailable;175 return ImageDecoder::isSizeAvailable(); 182 176 } 183 177 … … 186 180 if (index) 187 181 return 0; 182 183 if (m_frameBufferCache.isEmpty()) 184 m_frameBufferCache.resize(1); 188 185 189 186 RGBA32Buffer& frame = m_frameBufferCache[0]; … … 202 199 m_reader->decode(m_data->buffer(), sizeOnly); 203 200 204 if (m_failed || ( m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) {201 if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) { 205 202 delete m_reader; 206 203 m_reader = 0; … … 227 224 } 228 225 229 void PNGImageDecoder::decodingFailed() { 226 void PNGImageDecoder::decodingFailed() 227 { 230 228 m_failed = true; 231 229 } … … 246 244 247 245 // We can fill in the size now that the header is available. 248 if (!m_sizeAvailable) { 249 m_sizeAvailable = true; 250 m_size = IntSize(width, height); 246 if (!ImageDecoder::isSizeAvailable()) { 247 if (!setSize(width, height)) { 248 // Size unreasonable, bail out. 249 longjmp(png->jmpbuf, 1); 250 return; 251 } 251 252 } 252 253 … … 314 315 void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int interlacePass) 315 316 { 317 if (m_frameBufferCache.isEmpty()) 318 return; 319 316 320 // Resize to the width and height of the image. 317 321 RGBA32Buffer& buffer = m_frameBufferCache[0]; 318 322 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 319 323 // Let's resize our buffer now to the correct width/height. 320 RGBA32Array& bytes = buffer.bytes(); 321 bytes.resize(size().width() * size().height()); 324 if (!buffer.setSize(size().width(), size().height())) { 325 // Error allocating the bitmap. We should not continue. 326 static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed(); 327 longjmp(reader()->pngPtr()->jmpbuf, 1); 328 return; 329 } 322 330 323 331 // Update our status to be partially complete. 324 332 buffer.setStatus(RGBA32Buffer::FramePartial); 333 buffer.setHasAlpha(false); 325 334 326 335 // For PNGs, the frame always fills the entire image. 327 buffer.setRect(IntRect( 0, 0, size().width(), size().height()));336 buffer.setRect(IntRect(IntPoint(), size())); 328 337 329 338 if (reader()->pngPtr()->interlaced) … … 389 398 } 390 399 } 391 392 buffer.ensureHeight(rowIndex + 1);393 400 } 394 401 … … 400 407 void PNGImageDecoder::pngComplete() 401 408 { 409 if (m_frameBufferCache.isEmpty()) 410 return; 411 402 412 // Hand back an appropriately sized buffer, even if the image ended up being empty. 403 413 RGBA32Buffer& buffer = m_frameBufferCache[0]; -
trunk/WebCore/platform/image-decoders/skia/GIFImageReader.cpp
r40173 r44553 519 519 520 520 // CALLBACK: Inform the decoderplugin of our size. 521 if (clientptr) { 522 if (!clientptr->sizeNowAvailable(screen_width, screen_height)) 523 return false; 524 } 521 if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) 522 return false; 525 523 526 524 screen_bgcolor = q[5]; … … 747 745 748 746 // CALLBACK: Inform the decoderplugin of our size. 749 if (clientptr )750 clientptr->sizeNowAvailable(screen_width, screen_height);747 if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) 748 return false; 751 749 } 752 750 -
trunk/WebCore/platform/image-decoders/skia/JPEGImageDecoder.cpp
r44545 r44553 474 474 475 475 // For JPEGs, the frame always fills the entire image. 476 buffer.setRect(IntRect( 0, 0, size().width(), size().height()));476 buffer.setRect(IntRect(IntPoint(), size())); 477 477 } 478 478 -
trunk/WebCore/platform/image-decoders/skia/PNGImageDecoder.cpp
r44545 r44553 335 335 336 336 // For PNGs, the frame always fills the entire image. 337 buffer.setRect(IntRect( 0, 0, size().width(), size().height()));337 buffer.setRect(IntRect(IntPoint(), size())); 338 338 339 339 if (reader()->pngPtr()->interlaced)
Note: See TracChangeset
for help on using the changeset viewer.