| OLD | NEW |
| (Empty) |
| 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 #ifndef PNGImageReader_h | |
| 27 #define PNGImageReader_h | |
| 28 | |
| 29 #include "platform/PlatformExport.h" | |
| 30 #include "platform/geometry/IntRect.h" | |
| 31 #include "platform/image-decoders/ImageFrame.h" | |
| 32 #include "platform/wtf/Allocator.h" | |
| 33 #include "platform/wtf/PtrUtil.h" | |
| 34 #include "platform/wtf/Vector.h" | |
| 35 #include "png.h" | |
| 36 | |
| 37 #if !defined(PNG_LIBPNG_VER_MAJOR) || !defined(PNG_LIBPNG_VER_MINOR) | |
| 38 #error version error: compile against a versioned libpng. | |
| 39 #endif | |
| 40 | |
| 41 #if PNG_LIBPNG_VER_MAJOR > 1 || \ | |
| 42 (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 4) | |
| 43 #define JMPBUF(png_ptr) png_jmpbuf(png_ptr) | |
| 44 #else | |
| 45 #define JMPBUF(png_ptr) png_ptr->jmpbuf | |
| 46 #endif | |
| 47 | |
| 48 namespace blink { | |
| 49 | |
| 50 class FastSharedBufferReader; | |
| 51 class PNGImageDecoder; | |
| 52 class SegmentReader; | |
| 53 | |
| 54 class PLATFORM_EXPORT PNGImageReader final { | |
| 55 USING_FAST_MALLOC(PNGImageReader); | |
| 56 WTF_MAKE_NONCOPYABLE(PNGImageReader); | |
| 57 | |
| 58 public: | |
| 59 PNGImageReader(PNGImageDecoder*, size_t initial_offset); | |
| 60 ~PNGImageReader(); | |
| 61 | |
| 62 struct FrameInfo { | |
| 63 // The offset where the frame data of this frame starts. | |
| 64 size_t start_offset; | |
| 65 // The number of bytes that contain frame data, starting at start_offset. | |
| 66 size_t byte_length; | |
| 67 size_t duration; | |
| 68 IntRect frame_rect; | |
| 69 ImageFrame::DisposalMethod disposal_method; | |
| 70 ImageFrame::AlphaBlendSource alpha_blend; | |
| 71 }; | |
| 72 | |
| 73 enum class ParseQuery { kSize, kMetaData }; | |
| 74 | |
| 75 bool Parse(SegmentReader&, ParseQuery); | |
| 76 | |
| 77 // Returns false on a fatal error. | |
| 78 bool Decode(SegmentReader&, size_t); | |
| 79 const FrameInfo& GetFrameInfo(size_t) const; | |
| 80 | |
| 81 // Number of complete frames parsed so far; includes frame 0 even if partial. | |
| 82 size_t FrameCount() const { return frame_info_.size(); } | |
| 83 | |
| 84 bool ParseCompleted() const { return parse_completed_; }; | |
| 85 | |
| 86 bool FrameIsReceivedAtIndex(size_t index) const { | |
| 87 if (!index) | |
| 88 return FirstFrameFullyReceived(); | |
| 89 return index < FrameCount(); | |
| 90 } | |
| 91 | |
| 92 void ClearDecodeState(size_t); | |
| 93 | |
| 94 png_structp PngPtr() const { return png_; } | |
| 95 png_infop InfoPtr() const { return info_; } | |
| 96 | |
| 97 png_bytep InterlaceBuffer() const { return interlace_buffer_.get(); } | |
| 98 void CreateInterlaceBuffer(int size) { | |
| 99 interlace_buffer_ = WrapArrayUnique(new png_byte[size]); | |
| 100 } | |
| 101 void ClearInterlaceBuffer() { interlace_buffer_.reset(); } | |
| 102 | |
| 103 private: | |
| 104 png_structp png_; | |
| 105 png_infop info_; | |
| 106 png_uint_32 width_; | |
| 107 png_uint_32 height_; | |
| 108 | |
| 109 PNGImageDecoder* decoder_; | |
| 110 | |
| 111 // The offset in the stream where the PNG image starts. | |
| 112 const size_t initial_offset_; | |
| 113 // How many bytes have been read during parsing. | |
| 114 size_t read_offset_; | |
| 115 size_t progressive_decode_offset_; | |
| 116 size_t idat_offset_; | |
| 117 | |
| 118 bool idat_is_part_of_animation_; | |
| 119 // All IDAT chunks must precede the first fdAT chunk, and all fdAT chunks | |
| 120 // should be separated from the IDAT chunks by an fcTL chunk. So this is true | |
| 121 // until the first fcTL chunk after an IDAT chunk. After that, only fdAT | |
| 122 // chunks are expected. | |
| 123 bool expect_idats_; | |
| 124 bool is_animated_; | |
| 125 bool parsed_signature_; | |
| 126 bool parsed_ihdr_; | |
| 127 bool parse_completed_; | |
| 128 uint32_t reported_frame_count_; | |
| 129 uint32_t next_sequence_number_; | |
| 130 // True when an fcTL has been parsed but not its corresponding fdAT or IDAT | |
| 131 // chunk. Consecutive fcTLs is an error. | |
| 132 bool fctl_needs_dat_chunk_; | |
| 133 bool ignore_animation_; | |
| 134 | |
| 135 std::unique_ptr<png_byte[]> interlace_buffer_; | |
| 136 | |
| 137 // Value used for the byte_length of a FrameInfo struct to indicate that it is | |
| 138 // the first frame and its byte_length is not yet known. 1 is a safe value | |
| 139 // since the byte_length field of a frame is at least 12. | |
| 140 static constexpr size_t kFirstFrameIndicator = 1; | |
| 141 | |
| 142 // Stores information about a frame until it can be pushed to |frame_info| | |
| 143 // once all the frame data has been read from the stream. | |
| 144 FrameInfo new_frame_; | |
| 145 Vector<FrameInfo, 1> frame_info_; | |
| 146 | |
| 147 size_t ProcessData(const FastSharedBufferReader&, | |
| 148 size_t offset, | |
| 149 size_t length); | |
| 150 // Returns false on a fatal error. | |
| 151 bool ParseSize(const FastSharedBufferReader&); | |
| 152 // Returns false on an error. | |
| 153 bool ParseFrameInfo(const png_byte* data); | |
| 154 bool ShouldDecodeWithNewPNG(size_t) const; | |
| 155 void StartFrameDecoding(const FastSharedBufferReader&, size_t); | |
| 156 // Returns whether the frame was completely decoded. | |
| 157 bool ProgressivelyDecodeFirstFrame(const FastSharedBufferReader&); | |
| 158 void DecodeFrame(const FastSharedBufferReader&, size_t); | |
| 159 void ProcessFdatChunkAsIdat(png_uint_32 fdat_length); | |
| 160 // Returns false on a fatal error. | |
| 161 bool CheckSequenceNumber(const png_byte* position); | |
| 162 bool FirstFrameFullyReceived() const { | |
| 163 return !frame_info_.IsEmpty() && | |
| 164 frame_info_[0].byte_length != kFirstFrameIndicator; | |
| 165 } | |
| 166 }; | |
| 167 | |
| 168 } // namespace blink | |
| 169 | |
| 170 #endif | |
| OLD | NEW |