Home | History | Annotate | Download | only in bmp
      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/ImageDecoder.h"
     36 #include "wtf/CPU.h"
     37 
     38 namespace blink {
     39 
     40 // This class decodes a BMP image.  It is used in the BMP and ICO decoders,
     41 // which wrap it in the appropriate code to read file headers, etc.
     42 class PLATFORM_EXPORT BMPImageReader {
     43     WTF_MAKE_FAST_ALLOCATED;
     44 public:
     45     // Read a value from |data[offset]|, converting from little to native
     46     // endianness.
     47     static inline uint16_t readUint16(SharedBuffer* data, int offset)
     48     {
     49         uint16_t result;
     50         memcpy(&result, &data->data()[offset], 2);
     51     #if CPU(BIG_ENDIAN)
     52         result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
     53     #endif
     54         return result;
     55     }
     56 
     57     static inline uint32_t readUint32(SharedBuffer* data, int offset)
     58     {
     59         uint32_t result;
     60         memcpy(&result, &data->data()[offset], 4);
     61     #if CPU(BIG_ENDIAN)
     62         result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
     63     #endif
     64         return result;
     65     }
     66 
     67     // |parent| is the decoder that owns us.
     68     // |startOffset| points to the start of the BMP within the file.
     69     // |buffer| points at an empty ImageFrame that we'll initialize and
     70     // fill with decoded data.
     71     BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO);
     72 
     73     void setBuffer(ImageFrame* buffer) { m_buffer = buffer; }
     74     void setData(SharedBuffer* data) { m_data = data; }
     75 
     76     // Does the actual decoding.  If |onlySize| is true, decoding only
     77     // progresses as far as necessary to get the image size.  Returns
     78     // whether decoding succeeded.
     79     bool decodeBMP(bool onlySize);
     80 
     81 private:
     82     // The various BMP compression types.  We don't currently decode all
     83     // these.
     84     enum CompressionType {
     85         // Universal types
     86         RGB = 0,
     87         RLE8 = 1,
     88         RLE4 = 2,
     89         // Windows V3+ only
     90         BITFIELDS = 3,
     91         JPEG = 4,
     92         PNG = 5,
     93         // OS/2 2.x-only
     94         HUFFMAN1D,  // Stored in file as 3
     95         RLE24,      // Stored in file as 4
     96     };
     97     enum ProcessingResult {
     98         Success,
     99         Failure,
    100         InsufficientData,
    101     };
    102 
    103     // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE
    104     // structs, but with unnecessary entries removed.
    105     struct BitmapInfoHeader {
    106         uint32_t biSize;
    107         int32_t biWidth;
    108         int32_t biHeight;
    109         uint16_t biBitCount;
    110         CompressionType biCompression;
    111         uint32_t biClrUsed;
    112     };
    113     struct RGBTriple {
    114         uint8_t rgbBlue;
    115         uint8_t rgbGreen;
    116         uint8_t rgbRed;
    117     };
    118 
    119     inline uint16_t readUint16(int offset) const
    120     {
    121         return readUint16(m_data.get(), m_decodedOffset + offset);
    122     }
    123 
    124     inline uint32_t readUint32(int offset) const
    125     {
    126         return readUint32(m_data.get(), m_decodedOffset + offset);
    127     }
    128 
    129     // Determines the size of the BMP info header.  Returns true if the size
    130     // is valid.
    131     bool readInfoHeaderSize();
    132 
    133     // Processes the BMP info header.  Returns true if the info header could
    134     // be decoded.
    135     bool processInfoHeader();
    136 
    137     // Helper function for processInfoHeader() which does the actual reading
    138     // of header values from the byte stream.  Returns false on error.
    139     bool readInfoHeader();
    140 
    141     // Returns true if this is a Windows V4+ BMP.
    142     inline bool isWindowsV4Plus() const
    143     {
    144         // Windows V4 info header is 108 bytes.  V5 is 124 bytes.
    145         return (m_infoHeader.biSize == 108) || (m_infoHeader.biSize == 124);
    146     }
    147 
    148     // Returns false if consistency errors are found in the info header.
    149     bool isInfoHeaderValid() const;
    150 
    151     // For BI_BITFIELDS images, initializes the m_bitMasks[] and
    152     // m_bitOffsets[] arrays.  processInfoHeader() will initialize these for
    153     // other compression types where needed.
    154     bool processBitmasks();
    155 
    156     // For paletted images, allocates and initializes the m_colorTable[]
    157     // array.
    158     bool processColorTable();
    159 
    160     // Processes an RLE-encoded image.  Returns true if the entire image was
    161     // decoded.
    162     bool processRLEData();
    163 
    164     // Processes a set of non-RLE-compressed pixels.  Two cases:
    165     //   * inRLE = true: the data is inside an RLE-encoded bitmap.  Tries to
    166     //     process |numPixels| pixels on the current row.
    167     //   * inRLE = false: the data is inside a non-RLE-encoded bitmap.
    168     //     |numPixels| is ignored.  Expects |m_coord| to point at the
    169     //     beginning of the next row to be decoded.  Tries to process as
    170     //     many complete rows as possible.  Returns InsufficientData if
    171     //     there wasn't enough data to decode the whole image.
    172     //
    173     // This function returns a ProcessingResult instead of a bool so that it
    174     // can avoid calling m_parent->setFailed(), which could lead to memory
    175     // corruption since that will delete |this| but some callers still want
    176     // to access member variables after this returns.
    177     ProcessingResult processNonRLEData(bool inRLE, int numPixels);
    178 
    179     // Returns true if the current y-coordinate plus |numRows| would be past
    180     // the end of the image.  Here "plus" means "toward the end of the
    181     // image", so downwards for m_isTopDown images and upwards otherwise.
    182     inline bool pastEndOfImage(int numRows)
    183     {
    184         return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().height()) : ((m_coord.y() - numRows) < 0);
    185     }
    186 
    187     // Returns the pixel data for the current X coordinate in a uint32_t.
    188     // Assumes m_decodedOffset has been set to the beginning of the current
    189     // row.
    190     // NOTE: Only as many bytes of the return value as are needed to hold
    191     // the pixel data will actually be set.
    192     inline uint32_t readCurrentPixel(int bytesPerPixel) const
    193     {
    194         const int offset = m_coord.x() * bytesPerPixel;
    195         switch (bytesPerPixel) {
    196         case 2:
    197             return readUint16(offset);
    198 
    199         case 3: {
    200             // It doesn't matter that we never set the most significant byte
    201             // of the return value here in little-endian mode, the caller
    202             // won't read it.
    203             uint32_t pixel;
    204             memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
    205     #if CPU(BIG_ENDIAN)
    206             pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24);
    207     #endif
    208             return pixel;
    209         }
    210 
    211         case 4:
    212             return readUint32(offset);
    213 
    214         default:
    215             ASSERT_NOT_REACHED();
    216             return 0;
    217         }
    218     }
    219 
    220     // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A)
    221     // in the given pixel data.
    222     inline unsigned getComponent(uint32_t pixel, int component) const
    223     {
    224         uint8_t value = (pixel & m_bitMasks[component]) >> m_bitShiftsRight[component];
    225         return m_lookupTableAddresses[component] ? m_lookupTableAddresses[component][value] : value;
    226     }
    227 
    228     inline unsigned getAlpha(uint32_t pixel) const
    229     {
    230         // For images without alpha, return alpha of 0xff.
    231         return m_bitMasks[3] ? getComponent(pixel, 3) : 0xff;
    232     }
    233 
    234     // Sets the current pixel to the color given by |colorIndex|.  This also
    235     // increments the relevant local variables to move the current pixel
    236     // right by one.
    237     inline void setI(size_t colorIndex)
    238     {
    239         setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff);
    240     }
    241 
    242     // Like setI(), but with the individual component values specified.
    243     inline void setRGBA(unsigned red,
    244                         unsigned green,
    245                         unsigned blue,
    246                         unsigned alpha)
    247     {
    248         m_buffer->setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha);
    249         m_coord.move(1, 0);
    250     }
    251 
    252     // Fills pixels from the current X-coordinate up to, but not including,
    253     // |endCoord| with the color given by the individual components.  This
    254     // also increments the relevant local variables to move the current
    255     // pixel right to |endCoord|.
    256     inline void fillRGBA(int endCoord,
    257                          unsigned red,
    258                          unsigned green,
    259                          unsigned blue,
    260                          unsigned alpha)
    261     {
    262         while (m_coord.x() < endCoord)
    263             setRGBA(red, green, blue, alpha);
    264     }
    265 
    266     // Resets the relevant local variables to start drawing at the left edge
    267     // of the "next" row, where "next" is above or below the current row
    268     // depending on the value of |m_isTopDown|.
    269     void moveBufferToNextRow();
    270 
    271     // The decoder that owns us.
    272     ImageDecoder* m_parent;
    273 
    274     // The destination for the pixel data.
    275     ImageFrame* m_buffer;
    276 
    277     // The file to decode.
    278     RefPtr<SharedBuffer> m_data;
    279 
    280     // An index into |m_data| representing how much we've already decoded.
    281     size_t m_decodedOffset;
    282 
    283     // The file offset at which the BMP info header starts.
    284     size_t m_headerOffset;
    285 
    286     // The file offset at which the actual image bits start.  When decoding
    287     // ICO files, this is set to 0, since it's not stored anywhere in a
    288     // header; the reader functions expect the image data to start
    289     // immediately after the header and (if necessary) color table.
    290     size_t m_imgDataOffset;
    291 
    292     // The BMP info header.
    293     BitmapInfoHeader m_infoHeader;
    294 
    295     // True if this is an OS/2 1.x (aka Windows 2.x) BMP.  The struct
    296     // layouts for this type of BMP are slightly different from the later,
    297     // more common formats.
    298     bool m_isOS21x;
    299 
    300     // True if this is an OS/2 2.x BMP.  The meanings of compression types 3
    301     // and 4 for this type of BMP differ from Windows V3+ BMPs.
    302     //
    303     // This will be falsely negative in some cases, but only ones where the
    304     // way we misinterpret the data is irrelevant.
    305     bool m_isOS22x;
    306 
    307     // True if the BMP is not vertically flipped, that is, the first line of
    308     // raster data in the file is the top line of the image.
    309     bool m_isTopDown;
    310 
    311     // These flags get set to false as we finish each processing stage.
    312     bool m_needToProcessBitmasks;
    313     bool m_needToProcessColorTable;
    314 
    315     // Masks/offsets for the color values for non-palette formats. These are
    316     // bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, A.
    317     uint32_t m_bitMasks[4];
    318 
    319     // Right shift values, meant to be applied after the masks. We need to shift
    320     // the bitfield values down from their offsets into the 32 bits of pixel
    321     // data, as well as truncate the least significant bits of > 8-bit fields.
    322     int m_bitShiftsRight[4];
    323 
    324     // We use a lookup table to convert < 8-bit values into 8-bit values. The
    325     // values in the table are "round(val * 255.0 / ((1 << n) - 1))" for an
    326     // n-bit source value. These elements are set to 0 for 8-bit sources.
    327     const uint8_t* m_lookupTableAddresses[4];
    328 
    329     // The color palette, for paletted formats.
    330     Vector<RGBTriple> m_colorTable;
    331 
    332     // The coordinate to which we've decoded the image.
    333     IntPoint m_coord;
    334 
    335     // Variables that track whether we've seen pixels with alpha values != 0
    336     // and == 0, respectively.  See comments in processNonRLEData() on how
    337     // these are used.
    338     bool m_seenNonZeroAlphaPixel;
    339     bool m_seenZeroAlphaPixel;
    340 
    341     // BMPs-in-ICOs have a few differences from standalone BMPs, so we need to
    342     // know if we're in an ICO container.
    343     bool m_isInICO;
    344 
    345     // ICOs store a 1bpp "mask" immediately after the main bitmap image data
    346     // (and, confusingly, add its height to the biHeight value in the info
    347     // header, thus doubling it). If |m_isInICO| is true, this variable tracks
    348     // whether we've begun decoding this mask yet.
    349     bool m_decodingAndMask;
    350 };
    351 
    352 } // namespace blink
    353 
    354 #endif
    355