Changeset 58589 in webkit
- Timestamp:
- Apr 30, 2010 12:00:07 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r58586 r58589 1 2010-04-30 Peter Kasting <pkasting@google.com> 2 3 Reviewed by David Levin. 4 5 Make all image decoders set the "failed" bit if an image could not be 6 completely decoded, but no more data is coming. The ICO and BMP 7 decoders already did this. 8 https://bugs.webkit.org/show_bug.cgi?id=35411 9 10 "Failed" does not cause the image to not be displayed, it simply causes 11 us to not bother to try to decode again if future requests are made, and 12 for some decoders, lets the decoder clean up some of its temporary 13 objects. 14 15 No layout tests because this does not change the visible output of decoding in any way. 16 17 * platform/image-decoders/gif/GIFImageDecoder.cpp: 18 (WebCore::GIFImageDecoder::frameComplete): Return whether the frame could be marked as complete. 19 (WebCore::GIFImageDecoder::decode): Fail if read() needs more data (and thus returns false) and no more is coming. 20 * platform/image-decoders/gif/GIFImageDecoder.h: 21 * platform/image-decoders/gif/GIFImageReader.cpp: 22 (GIFImageReader::do_lzw): Instead of returning true for buffer underrun and false for failure, return false for both and set the failure flag on failure. 23 (GIFImageReader::read): Ditto. 24 * platform/image-decoders/gif/GIFImageReader.h: 25 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: 26 (WebCore::): 27 (WebCore::JPEGImageReader::decode): See do_lzw() comment above. 28 (WebCore::JPEGImageDecoder::decode): Fail if decode() needs more data (and thus returns false) and no more is coming. 29 * platform/image-decoders/jpeg/JPEGImageDecoder.h: 30 * platform/image-decoders/png/PNGImageDecoder.cpp: 31 (WebCore::PNGImageReader::decode): Return true for decode success, false for buffer underrun or decode failure, and set the failure flag on decode failure. 32 (WebCore::PNGImageDecoder::decode): See JPEGImageDecoder::decode() comment above. 33 * platform/image-decoders/png/PNGImageDecoder.h: 34 1 35 2010-04-30 Brady Eidson <beidson@apple.com> 2 36 -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r56007 r58589 236 236 } 237 237 238 voidGIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)238 bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod) 239 239 { 240 240 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, … … 242 242 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; 243 243 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) 244 return ;244 return false; // initFrameBuffer() has already called setFailed(). 245 245 246 246 buffer.setStatus(RGBA32Buffer::FrameComplete); … … 278 278 } 279 279 } 280 281 return true; 280 282 } 281 283 … … 295 297 m_reader.set(new GIFImageReader(this)); 296 298 297 if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame)) 299 // If we couldn't decode the image but we've received all the data, decoding 300 // has failed. 301 if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame) && isAllDataReceived()) 298 302 setFailed(); 299 303 -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
r56007 r58589 55 55 void decodingHalted(unsigned bytesLeft); 56 56 bool haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, unsigned repeatCount, bool writeTransparentPixels); 57 voidframeComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod);57 bool frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod); 58 58 void gifComplete(); 59 59 … … 61 61 // If the query is GIFFullQuery, decodes the image up to (but not 62 62 // including) |haltAtFrame|. Otherwise, decodes as much as is needed to 63 // answer the query, ignoring bitmap data. 63 // answer the query, ignoring bitmap data. If decoding fails but there 64 // is no more data coming, sets the "decode failure" flag. 64 65 void decode(unsigned haltAtFrame, GIFQuery); 65 66 -
trunk/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
r56007 r58589 291 291 if (code == (clear_code + 1)) { 292 292 /* end-of-stream should only appear after all image data */ 293 return !rows_remaining; 293 if (!rows_remaining) 294 return true; 295 return clientptr ? clientptr->setFailed() : false; 294 296 } 295 297 … … 309 311 310 312 if (stackp == stack + MAX_BITS) 311 return false;313 return clientptr ? clientptr->setFailed() : false; 312 314 } 313 315 … … 315 317 { 316 318 if (code >= MAX_BITS || code == prefix[code]) 317 return false;319 return clientptr ? clientptr->setFailed() : false; 318 320 319 321 // Even though suffix[] only holds characters through suffix[avail - 1], … … 325 327 326 328 if (stackp == stack + MAX_BITS) 327 return false;329 return clientptr ? clientptr->setFailed() : false; 328 330 } 329 331 … … 416 418 if (clientptr) 417 419 clientptr->decodingHalted(0); 418 return true;420 return false; 419 421 } 420 422 // Reset hold buffer count … … 441 443 { 442 444 case gif_lzw: 443 if (!do_lzw(q)) { 444 state = gif_error; 445 break; 446 } 445 if (!do_lzw(q)) 446 return false; // If do_lzw() encountered an error, it has already called 447 // clientptr->setFailed(). 447 448 GETN(1, gif_sub_block); 448 449 break; … … 455 456 // that our datasize is strictly less than the MAX_LZW_BITS value (12). 456 457 // This sets the largest possible codemask correctly at 4095. 457 if (datasize >= MAX_LZW_BITS) { 458 state = gif_error; 459 break; 460 } 458 if (datasize >= MAX_LZW_BITS) 459 return clientptr ? clientptr->setFailed() : false; 461 460 int clear_code = 1 << datasize; 462 if (clear_code >= MAX_BITS) { 463 state = gif_error; 464 break; 465 } 461 if (clear_code >= MAX_BITS) 462 return clientptr ? clientptr->setFailed() : false; 466 463 467 464 if (frame_reader) { … … 499 496 else if (!strncmp((char*)q, "GIF87a", 6)) 500 497 version = 87; 501 else { 502 state = gif_error; 503 break; 504 } 498 else 499 return clientptr ? clientptr->setFailed() : false; 505 500 GETN(7, gif_global_header); 506 501 } … … 587 582 } else { 588 583 /* No images decoded, there is nothing to display. */ 589 state = gif_error;584 return clientptr ? clientptr->setFailed() : false; 590 585 } 591 586 break; … … 715 710 } else { 716 711 // 0,3-7 are yet to be defined netscape extension codes 717 state = gif_error;712 return clientptr ? clientptr->setFailed() : false; 718 713 } 719 714 … … 756 751 height = screen_height; 757 752 width = screen_width; 758 if (!height || !width) { 759 state = gif_error; 760 break; 761 } 753 if (!height || !width) 754 return clientptr ? clientptr->setFailed() : false; 762 755 } 763 756 … … 795 788 } 796 789 797 if (!frame_reader->rowbuf) { 798 state = gif_oom; 799 break; 800 } 790 if (!frame_reader->rowbuf) 791 return clientptr ? clientptr->setFailed() : false; 801 792 if (screen_height < height) 802 793 screen_height = height; … … 839 830 delete []map; 840 831 map = new unsigned char[size]; 841 if (!map) { 842 state = gif_oom; 843 break; 844 } 832 if (!map) 833 return clientptr ? clientptr->setFailed() : false; 845 834 } 846 835 … … 894 883 895 884 // CALLBACK: The frame is now complete. 896 if (clientptr && frame_reader) 897 clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method); 885 if (clientptr && frame_reader && !clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method)) 886 return false; // frameComplete() has already called 887 // clientptr->setFailed(). 898 888 899 889 /* Clear state from this image */ … … 913 903 clientptr->gifComplete(); 914 904 return true; 915 916 // Handle out of memory errors917 case gif_oom:918 return false;919 920 // Handle general errors921 case gif_error:922 return false;923 905 924 906 // We shouldn't ever get here. … … 946 928 if (clientptr) 947 929 clientptr->decodingHalted(0); 948 return true;930 return false; 949 931 } -
trunk/WebCore/platform/image-decoders/gif/GIFImageReader.h
r54823 r58589 70 70 gif_skip_block, 71 71 gif_done, 72 gif_oom,73 gif_error,74 72 gif_comment_extension, 75 73 gif_application_extension, -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r56007 r58589 70 70 JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels 71 71 JPEG_DONE, 72 JPEG_SINK_NON_JPEG_TRAILER, // Some image files have a non-JPEG trailer73 72 JPEG_ERROR 74 73 }; … … 170 169 // We need to do the setjmp here. Otherwise bad things will happen 171 170 if (setjmp(m_err.setjmp_buffer)) { 172 m_state = JPEG_SINK_NON_JPEG_TRAILER;173 171 close(); 174 return false;172 return m_decoder->setFailed(); 175 173 } 176 174 … … 179 177 // Read file parameters with jpeg_read_header(). 180 178 if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED) 181 return true; // I/O suspension.179 return false; // I/O suspension. 182 180 183 181 // Let libjpeg take care of gray->RGB and YCbCr->RGB conversions. … … 195 193 break; 196 194 default: 197 return false;195 return m_decoder->setFailed(); 198 196 } 199 197 … … 215 213 // We can fill in the size now that the header is available. 216 214 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) 217 return false;215 return m_decoder->setFailed(); 218 216 219 217 if (m_decodingSizeOnly) { … … 238 236 // Start decompressor. 239 237 if (!jpeg_start_decompress(&m_info)) 240 return true; // I/O suspension.238 return false; // I/O suspension. 241 239 242 240 // If this is a progressive JPEG ... … … 248 246 249 247 if (!m_decoder->outputScanlines()) 250 return true; // I/O suspension.248 return false; // I/O suspension. 251 249 252 250 // If we've completed image output... … … 274 272 275 273 if (!jpeg_start_output(&m_info, scan)) 276 return true; // I/O suspension.274 return false; // I/O suspension. 277 275 } 278 276 … … 286 284 // the same scan. 287 285 m_info.output_scanline = 0xffffff; 288 return true; // I/O suspension.286 return false; // I/O suspension. 289 287 } 290 288 291 289 if (m_info.output_scanline == m_info.output_height) { 292 290 if (!jpeg_finish_output(&m_info)) 293 return true; // I/O suspension.291 return false; // I/O suspension. 294 292 295 293 if (jpeg_input_complete(&m_info) && (m_info.input_scan_number == m_info.output_scan_number)) … … 306 304 case JPEG_DONE: 307 305 // Finish decompression. 308 if (!jpeg_finish_decompress(&m_info)) 309 return true; // I/O suspension. 310 311 m_state = JPEG_SINK_NON_JPEG_TRAILER; 312 break; 306 return jpeg_finish_decompress(&m_info); 313 307 314 case JPEG_SINK_NON_JPEG_TRAILER:315 break;316 317 308 case JPEG_ERROR: 318 309 // We can get here if the constructor failed. … … 488 479 m_reader.set(new JPEGImageReader(this)); 489 480 490 if (!m_reader->decode(m_data->buffer(), onlySize)) 481 // If we couldn't decode the image but we've received all the data, decoding 482 // has failed. 483 if (!m_reader->decode(m_data->buffer(), onlySize) && isAllDataReceived()) 491 484 setFailed(); 492 485 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r56007 r58589 53 53 private: 54 54 // Decodes the image. If |onlySize| is true, stops decoding after 55 // calculating the image size. 55 // calculating the image size. If decoding fails but there is no more 56 // data coming, sets the "decode failure" flag. 56 57 void decode(bool onlySize); 57 58 -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r56007 r58589 120 120 unsigned currentBufferSize() const { return m_currentBufferSize; } 121 121 122 voiddecode(const SharedBuffer& data, bool sizeOnly)122 bool decode(const SharedBuffer& data, bool sizeOnly) 123 123 { 124 124 m_decodingSizeOnly = sizeOnly; … … 128 128 if (setjmp(m_png->jmpbuf)) { 129 129 close(); 130 decoder->setFailed(); 131 return; 130 return decoder->setFailed(); 132 131 } 133 132 … … 141 140 // (recursively) trigger additional decoding if we haven't. 142 141 if (sizeOnly ? decoder->ImageDecoder::isSizeAvailable() : decoder->isComplete()) 143 return; 144 } 145 if (!decoder->isComplete() && decoder->isAllDataReceived()) 146 decoder->pngComplete(); 142 return true; 143 } 144 return false; 147 145 } 148 146 … … 372 370 m_reader.set(new PNGImageReader(this)); 373 371 374 m_reader->decode(*m_data, onlySize); 372 // If we couldn't decode the image but we've received all the data, decoding 373 // has failed. 374 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) 375 setFailed(); 375 376 376 377 if (failed() || isComplete()) -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.h
r56007 r58589 58 58 private: 59 59 // Decodes the image. If |onlySize| is true, stops decoding after 60 // calculating the image size. 60 // calculating the image size. If decoding fails but there is no more 61 // data coming, sets the "decode failure" flag. 61 62 void decode(bool onlySize); 62 63
Note: See TracChangeset
for help on using the changeset viewer.