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 "core/platform/image-decoders/ImageDecoder.h"
     36 #include "wtf/CPU.h"
     37 
     38 namespace WebCore {
     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 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 usesAndMask);
     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 AndMaskState {
     98             None,
     99             NotYetDecoded,
    100             Decoding,
    101         };
    102         enum ProcessingResult {
    103             Success,
    104             Failure,
    105             InsufficientData,
    106         };
    107 
    108         // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE
    109         // structs, but with unnecessary entries removed.
    110         struct BitmapInfoHeader {
    111             uint32_t biSize;
    112             int32_t biWidth;
    113             int32_t biHeight;
    114             uint16_t biBitCount;
    115             CompressionType biCompression;
    116             uint32_t biClrUsed;
    117         };
    118         struct RGBTriple {
    119             uint8_t rgbBlue;
    120             uint8_t rgbGreen;
    121             uint8_t rgbRed;
    122         };
    123 
    124         inline uint16_t readUint16(int offset) const
    125         {
    126             return readUint16(m_data.get(), m_decodedOffset + offset);
    127         }
    128 
    129         inline uint32_t readUint32(int offset) const
    130         {
    131             return readUint32(m_data.get(), m_decodedOffset + offset);
    132         }
    133 
    134         // Determines the size of the BMP info header.  Returns true if the size
    135         // is valid.
    136         bool readInfoHeaderSize();
    137 
    138         // Processes the BMP info header.  Returns true if the info header could
    139         // be decoded.
    140         bool processInfoHeader();
    141 
    142         // Helper function for processInfoHeader() which does the actual reading
    143         // of header values from the byte stream.  Returns false on error.
    144         bool readInfoHeader();
    145 
    146         // Returns true if this is a Windows V4+ BMP.
    147         inline bool isWindowsV4Plus() const
    148         {
    149             // Windows V4 info header is 108 bytes.  V5 is 124 bytes.
    150             return (m_infoHeader.biSize == 108) || (m_infoHeader.biSize == 124);
    151         }
    152 
    153         // Returns false if consistency errors are found in the info header.
    154         bool isInfoHeaderValid() const;
    155 
    156         // For BI_BITFIELDS images, initializes the m_bitMasks[] and
    157         // m_bitOffsets[] arrays.  processInfoHeader() will initialize these for
    158         // other compression types where needed.
    159         bool processBitmasks();
    160 
    161         // For paletted images, allocates and initializes the m_colorTable[]
    162         // array.
    163         bool processColorTable();
    164 
    165         // Processes an RLE-encoded image.  Returns true if the entire image was
    166         // decoded.
    167         bool processRLEData();
    168 
    169         // Processes a set of non-RLE-compressed pixels.  Two cases:
    170         //   * inRLE = true: the data is inside an RLE-encoded bitmap.  Tries to
    171         //     process |numPixels| pixels on the current row.
    172         //   * inRLE = false: the data is inside a non-RLE-encoded bitmap.
    173         //     |numPixels| is ignored.  Expects |m_coord| to point at the
    174         //     beginning of the next row to be decoded.  Tries to process as
    175         //     many complete rows as possible.  Returns InsufficientData if
    176         //     there wasn't enough data to decode the whole image.
    177         //
    178         // This function returns a ProcessingResult instead of a bool so that it
    179         // can avoid calling m_parent->setFailed(), which could lead to memory
    180         // corruption since that will delete |this| but some callers still want
    181         // to access member variables after this returns.
    182         ProcessingResult processNonRLEData(bool inRLE, int numPixels);
    183 
    184         // Returns true if the current y-coordinate plus |numRows| would be past
    185         // the end of the image.  Here "plus" means "toward the end of the
    186         // image", so downwards for m_isTopDown images and upwards otherwise.
    187         inline bool pastEndOfImage(int numRows)
    188         {
    189             return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().height()) : ((m_coord.y() - numRows) < 0);
    190         }
    191 
    192         // Returns the pixel data for the current X coordinate in a uint32_t.
    193         // Assumes m_decodedOffset has been set to the beginning of the current
    194         // row.
    195         // NOTE: Only as many bytes of the return value as are needed to hold
    196         // the pixel data will actually be set.
    197         inline uint32_t readCurrentPixel(int bytesPerPixel) const
    198         {
    199             const int offset = m_coord.x() * bytesPerPixel;
    200             switch (bytesPerPixel) {
    201             case 2:
    202                 return readUint16(offset);
    203 
    204             case 3: {
    205                 // It doesn't matter that we never set the most significant byte
    206                 // of the return value here in little-endian mode, the caller
    207                 // won't read it.
    208                 uint32_t pixel;
    209                 memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
    210         #if CPU(BIG_ENDIAN)
    211                 pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24);
    212         #endif
    213                 return pixel;
    214             }
    215 
    216             case 4:
    217                 return readUint32(offset);
    218 
    219             default:
    220                 ASSERT_NOT_REACHED();
    221                 return 0;
    222             }
    223         }
    224 
    225         // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A)
    226         // in the given pixel data.
    227         inline unsigned getComponent(uint32_t pixel, int component) const
    228         {
    229             return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[component]) << m_bitShiftsLeft[component];
    230         }
    231 
    232         inline unsigned getAlpha(uint32_t pixel) const
    233         {
    234             // For images without alpha, return alpha of 0xff.
    235             return m_bitMasks[3] ? getComponent(pixel, 3) : 0xff;
    236         }
    237 
    238         // Sets the current pixel to the color given by |colorIndex|.  This also
    239         // increments the relevant local variables to move the current pixel
    240         // right by one.
    241         inline void setI(size_t colorIndex)
    242         {
    243             setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff);
    244         }
    245 
    246         // Like setI(), but with the individual component values specified.
    247         inline void setRGBA(unsigned red,
    248                             unsigned green,
    249                             unsigned blue,
    250                             unsigned alpha)
    251         {
    252             m_buffer->setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha);
    253             m_coord.move(1, 0);
    254         }
    255 
    256         // Fills pixels from the current X-coordinate up to, but not including,
    257         // |endCoord| with the color given by the individual components.  This
    258         // also increments the relevant local variables to move the current
    259         // pixel right to |endCoord|.
    260         inline void fillRGBA(int endCoord,
    261                              unsigned red,
    262                              unsigned green,
    263                              unsigned blue,
    264                              unsigned alpha)
    265         {
    266             while (m_coord.x() < endCoord)
    267                 setRGBA(red, green, blue, alpha);
    268         }
    269 
    270         // Resets the relevant local variables to start drawing at the left edge
    271         // of the "next" row, where "next" is above or below the current row
    272         // depending on the value of |m_isTopDown|.
    273         void moveBufferToNextRow();
    274 
    275         // The decoder that owns us.
    276         ImageDecoder* m_parent;
    277 
    278         // The destination for the pixel data.
    279         ImageFrame* m_buffer;
    280 
    281         // The file to decode.
    282         RefPtr<SharedBuffer> m_data;
    283 
    284         // An index into |m_data| representing how much we've already decoded.
    285         size_t m_decodedOffset;
    286 
    287         // The file offset at which the BMP info header starts.
    288         size_t m_headerOffset;
    289 
    290         // The file offset at which the actual image bits start.  When decoding
    291         // ICO files, this is set to 0, since it's not stored anywhere in a
    292         // header; the reader functions expect the image data to start
    293         // immediately after the header and (if necessary) color table.
    294         size_t m_imgDataOffset;
    295 
    296         // The BMP info header.
    297         BitmapInfoHeader m_infoHeader;
    298 
    299         // True if this is an OS/2 1.x (aka Windows 2.x) BMP.  The struct
    300         // layouts for this type of BMP are slightly different from the later,
    301         // more common formats.
    302         bool m_isOS21x;
    303 
    304         // True if this is an OS/2 2.x BMP.  The meanings of compression types 3
    305         // and 4 for this type of BMP differ from Windows V3+ BMPs.
    306         //
    307         // This will be falsely negative in some cases, but only ones where the
    308         // way we misinterpret the data is irrelevant.
    309         bool m_isOS22x;
    310 
    311         // True if the BMP is not vertically flipped, that is, the first line of
    312         // raster data in the file is the top line of the image.
    313         bool m_isTopDown;
    314 
    315         // These flags get set to false as we finish each processing stage.
    316         bool m_needToProcessBitmasks;
    317         bool m_needToProcessColorTable;
    318 
    319         // Masks/offsets for the color values for non-palette formats.  These
    320         // are bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B,
    321         // A.
    322         //
    323         // The right/left shift values are meant to be applied after the masks.
    324         // We need to right shift to compensate for the bitfields' offsets into
    325         // the 32 bits of pixel data, and left shift to scale the color values
    326         // up for fields with less than 8 bits of precision.  Sadly, we can't
    327         // just combine these into one shift value because the net shift amount
    328         // could go either direction.  (If only "<< -x" were equivalent to
    329         // ">> x"...)
    330         uint32_t m_bitMasks[4];
    331         int m_bitShiftsRight[4];
    332         int m_bitShiftsLeft[4];
    333 
    334         // The color palette, for paletted formats.
    335         size_t m_tableSizeInBytes;
    336         Vector<RGBTriple> m_colorTable;
    337 
    338         // The coordinate to which we've decoded the image.
    339         IntPoint m_coord;
    340 
    341         // Variables that track whether we've seen pixels with alpha values != 0
    342         // and == 0, respectively.  See comments in processNonRLEData() on how
    343         // these are used.
    344         bool m_seenNonZeroAlphaPixel;
    345         bool m_seenZeroAlphaPixel;
    346 
    347         // ICOs store a 1bpp "mask" immediately after the main bitmap image data
    348         // (and, confusingly, add its height to the biHeight value in the info
    349         // header, thus doubling it).  This variable tracks whether we have such
    350         // a mask and if we've started decoding it yet.
    351         AndMaskState m_andMaskState;
    352     };
    353 
    354 } // namespace WebCore
    355 
    356 #endif
    357