| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2008, 2009, Google 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 are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #ifndef BMPImageReader_h | |
| 32 #define BMPImageReader_h | |
| 33 | |
| 34 #include <stdint.h> | |
| 35 #include "platform/image-decoders/FastSharedBufferReader.h" | |
| 36 #include "platform/image-decoders/ImageDecoder.h" | |
| 37 #include "platform/wtf/Allocator.h" | |
| 38 #include "platform/wtf/CPU.h" | |
| 39 #include "platform/wtf/Noncopyable.h" | |
| 40 | |
| 41 namespace blink { | |
| 42 | |
| 43 // This class decodes a BMP image. It is used in the BMP and ICO decoders, | |
| 44 // which wrap it in the appropriate code to read file headers, etc. | |
| 45 class PLATFORM_EXPORT BMPImageReader final { | |
| 46 USING_FAST_MALLOC(BMPImageReader); | |
| 47 WTF_MAKE_NONCOPYABLE(BMPImageReader); | |
| 48 | |
| 49 public: | |
| 50 // Read a value from |buffer|, converting to an int assuming little | |
| 51 // endianness | |
| 52 static inline uint16_t ReadUint16(const char* buffer) { | |
| 53 return *reinterpret_cast<const uint16_t*>(buffer); | |
| 54 } | |
| 55 | |
| 56 static inline uint32_t ReadUint32(const char* buffer) { | |
| 57 return *reinterpret_cast<const uint32_t*>(buffer); | |
| 58 } | |
| 59 | |
| 60 // |parent| is the decoder that owns us. | |
| 61 // |start_offset| points to the start of the BMP within the file. | |
| 62 // |buffer| points at an empty ImageFrame that we'll initialize and | |
| 63 // fill with decoded data. | |
| 64 BMPImageReader(ImageDecoder* parent, | |
| 65 size_t decoded_and_header_offset, | |
| 66 size_t img_data_offset, | |
| 67 bool is_in_ico); | |
| 68 | |
| 69 void SetBuffer(ImageFrame* buffer) { buffer_ = buffer; } | |
| 70 void SetData(SegmentReader* data) { | |
| 71 data_ = data; | |
| 72 fast_reader_.SetData(data); | |
| 73 } | |
| 74 | |
| 75 // Does the actual decoding. If |only_size| is true, decoding only | |
| 76 // progresses as far as necessary to get the image size. Returns | |
| 77 // whether decoding succeeded. | |
| 78 bool DecodeBMP(bool only_size); | |
| 79 | |
| 80 private: | |
| 81 friend class PixelChangedScoper; | |
| 82 | |
| 83 // Helper for DecodeBMP() which will call either ProcessRLEData() or | |
| 84 // ProcessNonRLEData(), depending on the value of |non_rle|, call any | |
| 85 // appropriate notifications to deal with the result, then return whether | |
| 86 // decoding succeeded. | |
| 87 bool DecodePixelData(bool non_rle); | |
| 88 | |
| 89 // The various BMP compression types. We don't currently decode all | |
| 90 // these. | |
| 91 enum CompressionType { | |
| 92 // Universal types | |
| 93 RGB = 0, | |
| 94 RLE8 = 1, | |
| 95 RLE4 = 2, | |
| 96 // Windows V3+ only | |
| 97 BITFIELDS = 3, | |
| 98 JPEG = 4, | |
| 99 PNG = 5, | |
| 100 // OS/2 2.x-only | |
| 101 HUFFMAN1D, // Stored in file as 3 | |
| 102 RLE24, // Stored in file as 4 | |
| 103 }; | |
| 104 enum ProcessingResult { | |
| 105 kSuccess, | |
| 106 kFailure, | |
| 107 kInsufficientData, | |
| 108 }; | |
| 109 | |
| 110 // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE | |
| 111 // structs, but with unnecessary entries removed. | |
| 112 struct BitmapInfoHeader { | |
| 113 DISALLOW_NEW(); | |
| 114 uint32_t bi_size; | |
| 115 int32_t bi_width; | |
| 116 int32_t bi_height; | |
| 117 uint16_t bi_bit_count; | |
| 118 CompressionType bi_compression; | |
| 119 uint32_t bi_clr_used; | |
| 120 }; | |
| 121 struct RGBTriple { | |
| 122 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
| 123 uint8_t rgb_blue; | |
| 124 uint8_t rgb_green; | |
| 125 uint8_t rgb_red; | |
| 126 }; | |
| 127 | |
| 128 inline uint8_t ReadUint8(size_t offset) const { | |
| 129 return fast_reader_.GetOneByte(decoded_offset_ + offset); | |
| 130 } | |
| 131 | |
| 132 inline uint16_t ReadUint16(int offset) const { | |
| 133 char buffer[2]; | |
| 134 const char* data = | |
| 135 fast_reader_.GetConsecutiveData(decoded_offset_ + offset, 2, buffer); | |
| 136 return ReadUint16(data); | |
| 137 } | |
| 138 | |
| 139 inline uint32_t ReadUint32(int offset) const { | |
| 140 char buffer[4]; | |
| 141 const char* data = | |
| 142 fast_reader_.GetConsecutiveData(decoded_offset_ + offset, 4, buffer); | |
| 143 return ReadUint32(data); | |
| 144 } | |
| 145 | |
| 146 // Determines the size of the BMP info header. Returns true if the size | |
| 147 // is valid. | |
| 148 bool ReadInfoHeaderSize(); | |
| 149 | |
| 150 // Processes the BMP info header. Returns true if the info header could | |
| 151 // be decoded. | |
| 152 bool ProcessInfoHeader(); | |
| 153 | |
| 154 // Helper function for ProcessInfoHeader() which does the actual reading | |
| 155 // of header values from the byte stream. Returns false on error. | |
| 156 bool ReadInfoHeader(); | |
| 157 | |
| 158 // Returns true if this is a Windows V4+ BMP. | |
| 159 inline bool IsWindowsV4Plus() const { | |
| 160 // Windows V4 info header is 108 bytes. V5 is 124 bytes. | |
| 161 return (info_header_.bi_size == 108) || (info_header_.bi_size == 124); | |
| 162 } | |
| 163 | |
| 164 // Returns false if consistency errors are found in the info header. | |
| 165 bool IsInfoHeaderValid() const; | |
| 166 | |
| 167 // For BI_BITFIELDS images, initializes the bit_masks_[] and | |
| 168 // bit_offsets_[] arrays. ProcessInfoHeader() will initialize these for | |
| 169 // other compression types where needed. | |
| 170 bool ProcessBitmasks(); | |
| 171 | |
| 172 // For paletted images, allocates and initializes the color_table_[] | |
| 173 // array. | |
| 174 bool ProcessColorTable(); | |
| 175 | |
| 176 // The next two functions return a ProcessingResult instead of a bool so | |
| 177 // they can avoid calling parent_->SetFailed(), which could lead to memory | |
| 178 // corruption since that will delete |this| but some callers still want | |
| 179 // to access member variables after they return. | |
| 180 | |
| 181 // Processes an RLE-encoded image. | |
| 182 ProcessingResult ProcessRLEData(); | |
| 183 | |
| 184 // Processes a set of non-RLE-compressed pixels. Two cases: | |
| 185 // * in_rle = true: the data is inside an RLE-encoded bitmap. Tries to | |
| 186 // process |num_pixels| pixels on the current row. | |
| 187 // * in_rle = false: the data is inside a non-RLE-encoded bitmap. | |
| 188 // |num_pixels| is ignored. Expects |coord_| to point at the | |
| 189 // beginning of the next row to be decoded. Tries to process as | |
| 190 // many complete rows as possible. Returns InsufficientData if | |
| 191 // there wasn't enough data to decode the whole image. | |
| 192 ProcessingResult ProcessNonRLEData(bool in_rle, int num_pixels); | |
| 193 | |
| 194 // Returns true if the current y-coordinate plus |num_rows| would be past | |
| 195 // the end of the image. Here "plus" means "toward the end of the | |
| 196 // image", so downwards for is_top_down_ images and upwards otherwise. | |
| 197 inline bool PastEndOfImage(int num_rows) { | |
| 198 return is_top_down_ ? ((coord_.Y() + num_rows) >= parent_->Size().Height()) | |
| 199 : ((coord_.Y() - num_rows) < 0); | |
| 200 } | |
| 201 | |
| 202 // Returns the pixel data for the current X coordinate in a uint32_t. | |
| 203 // Assumes decoded_offset has been set to the beginning of the current | |
| 204 // row. | |
| 205 // NOTE: Only as many bytes of the return value as are needed to hold | |
| 206 // the pixel data will actually be set. | |
| 207 inline uint32_t ReadCurrentPixel(int bytes_per_pixel) const { | |
| 208 // We need at most 4 bytes, starting at decoded_offset_ + offset. | |
| 209 char buffer[4]; | |
| 210 const int offset = coord_.X() * bytes_per_pixel; | |
| 211 const char* encoded_pixel = fast_reader_.GetConsecutiveData( | |
| 212 decoded_offset_ + offset, bytes_per_pixel, buffer); | |
| 213 switch (bytes_per_pixel) { | |
| 214 case 2: | |
| 215 return ReadUint16(encoded_pixel); | |
| 216 | |
| 217 case 3: { | |
| 218 // It doesn't matter that we never set the most significant byte | |
| 219 // of the return value, the caller won't read it. | |
| 220 uint32_t pixel; | |
| 221 memcpy(&pixel, encoded_pixel, 3); | |
| 222 return pixel; | |
| 223 } | |
| 224 | |
| 225 case 4: | |
| 226 return ReadUint32(encoded_pixel); | |
| 227 | |
| 228 default: | |
| 229 NOTREACHED(); | |
| 230 return 0; | |
| 231 } | |
| 232 } | |
| 233 | |
| 234 // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A) | |
| 235 // in the given pixel data. | |
| 236 inline unsigned GetComponent(uint32_t pixel, int component) const { | |
| 237 uint8_t value = | |
| 238 (pixel & bit_masks_[component]) >> bit_shifts_right_[component]; | |
| 239 return lookup_table_addresses_[component] | |
| 240 ? lookup_table_addresses_[component][value] | |
| 241 : value; | |
| 242 } | |
| 243 | |
| 244 inline unsigned GetAlpha(uint32_t pixel) const { | |
| 245 // For images without alpha, return alpha of 0xff. | |
| 246 return bit_masks_[3] ? GetComponent(pixel, 3) : 0xff; | |
| 247 } | |
| 248 | |
| 249 // Sets the current pixel to the color given by |color_index|. This also | |
| 250 // increments the relevant local variables to move the current pixel | |
| 251 // right by one. | |
| 252 inline void SetI(size_t color_index) { | |
| 253 SetRGBA(color_table_[color_index].rgb_red, | |
| 254 color_table_[color_index].rgb_green, | |
| 255 color_table_[color_index].rgb_blue, 0xff); | |
| 256 } | |
| 257 | |
| 258 // Like SetI(), but with the individual component values specified. | |
| 259 inline void SetRGBA(unsigned red, | |
| 260 unsigned green, | |
| 261 unsigned blue, | |
| 262 unsigned alpha) { | |
| 263 buffer_->SetRGBA(coord_.X(), coord_.Y(), red, green, blue, alpha); | |
| 264 coord_.Move(1, 0); | |
| 265 } | |
| 266 | |
| 267 // Fills pixels from the current X-coordinate up to, but not including, | |
| 268 // |end_coord| with the color given by the individual components. This | |
| 269 // also increments the relevant local variables to move the current | |
| 270 // pixel right to |end_coord|. | |
| 271 inline void FillRGBA(int end_coord, | |
| 272 unsigned red, | |
| 273 unsigned green, | |
| 274 unsigned blue, | |
| 275 unsigned alpha) { | |
| 276 while (coord_.X() < end_coord) | |
| 277 SetRGBA(red, green, blue, alpha); | |
| 278 } | |
| 279 | |
| 280 // Resets the relevant local variables to start drawing at the left edge | |
| 281 // of the "next" row, where "next" is above or below the current row | |
| 282 // depending on the value of |is_top_down_|. | |
| 283 void MoveBufferToNextRow(); | |
| 284 | |
| 285 // The decoder that owns us. | |
| 286 ImageDecoder* parent_; | |
| 287 | |
| 288 // The destination for the pixel data. | |
| 289 ImageFrame* buffer_; | |
| 290 | |
| 291 // The file to decode. | |
| 292 RefPtr<SegmentReader> data_; | |
| 293 FastSharedBufferReader fast_reader_; | |
| 294 | |
| 295 // An index into |data_| representing how much we've already decoded. | |
| 296 size_t decoded_offset_; | |
| 297 | |
| 298 // The file offset at which the BMP info header starts. | |
| 299 size_t header_offset_; | |
| 300 | |
| 301 // The file offset at which the actual image bits start. When decoding | |
| 302 // ICO files, this is set to 0, since it's not stored anywhere in a | |
| 303 // header; the reader functions expect the image data to start | |
| 304 // immediately after the header and (if necessary) color table. | |
| 305 size_t img_data_offset_; | |
| 306 | |
| 307 // The BMP info header. | |
| 308 BitmapInfoHeader info_header_; | |
| 309 | |
| 310 // True if this is an OS/2 1.x (aka Windows 2.x) BMP. The struct | |
| 311 // layouts for this type of BMP are slightly different from the later, | |
| 312 // more common formats. | |
| 313 bool is_os21x_; | |
| 314 | |
| 315 // True if this is an OS/2 2.x BMP. The meanings of compression types 3 | |
| 316 // and 4 for this type of BMP differ from Windows V3+ BMPs. | |
| 317 // | |
| 318 // This will be falsely negative in some cases, but only ones where the | |
| 319 // way we misinterpret the data is irrelevant. | |
| 320 bool is_os22x_; | |
| 321 | |
| 322 // True if the BMP is not vertically flipped, that is, the first line of | |
| 323 // raster data in the file is the top line of the image. | |
| 324 bool is_top_down_; | |
| 325 | |
| 326 // These flags get set to false as we finish each processing stage. | |
| 327 bool need_to_process_bitmasks_; | |
| 328 bool need_to_process_color_table_; | |
| 329 | |
| 330 // Masks/offsets for the color values for non-palette formats. These are | |
| 331 // bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, A. | |
| 332 // These are uninitialized (and ignored) for images with less than 16bpp. | |
| 333 uint32_t bit_masks_[4]; | |
| 334 | |
| 335 // Right shift values, meant to be applied after the masks. We need to shift | |
| 336 // the bitfield values down from their offsets into the 32 bits of pixel | |
| 337 // data, as well as truncate the least significant bits of > 8-bit fields. | |
| 338 int bit_shifts_right_[4]; | |
| 339 | |
| 340 // We use a lookup table to convert < 8-bit values into 8-bit values. The | |
| 341 // values in the table are "round(val * 255.0 / ((1 << n) - 1))" for an | |
| 342 // n-bit source value. These elements are set to 0 for 8-bit sources. | |
| 343 const uint8_t* lookup_table_addresses_[4]; | |
| 344 | |
| 345 // The color palette, for paletted formats. | |
| 346 Vector<RGBTriple> color_table_; | |
| 347 | |
| 348 // The coordinate to which we've decoded the image. | |
| 349 IntPoint coord_; | |
| 350 | |
| 351 // Variables that track whether we've seen pixels with alpha values != 0 | |
| 352 // and == 0, respectively. See comments in ProcessNonRLEData() on how | |
| 353 // these are used. | |
| 354 bool seen_non_zero_alpha_pixel_; | |
| 355 bool seen_zero_alpha_pixel_; | |
| 356 | |
| 357 // BMPs-in-ICOs have a few differences from standalone BMPs, so we need to | |
| 358 // know if we're in an ICO container. | |
| 359 bool is_in_ico_; | |
| 360 | |
| 361 // ICOs store a 1bpp "mask" immediately after the main bitmap image data | |
| 362 // (and, confusingly, add its height to the biHeight value in the info | |
| 363 // header, thus doubling it). If |is_in_ico_| is true, this variable tracks | |
| 364 // whether we've begun decoding this mask yet. | |
| 365 bool decoding_and_mask_; | |
| 366 }; | |
| 367 | |
| 368 } // namespace blink | |
| 369 | |
| 370 #endif | |
| OLD | NEW |