Changeset 44833 in webkit


Ignore:
Timestamp:
Jun 18, 2009 6:14:27 PM (15 years ago)
Author:
pkasting@chromium.org
Message:

2009-06-18 Peter Kasting <pkasting@google.com>

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=26460 part two
Attempt to minimize diff of following functional change by first landing
non-functional change to:

  • Make readUintX() public and static (since they will need to be once BMPImageReader is included in *ImageDecoder via composition rather than inheritance). Add wrappers in each class so callers can be simpler. In the next patch, these wrappers will be beefed up slightly and the callers will get even simpler.
  • Change direct setting of m_failed to use setFailed(), since in the next patch much of this code won't even have direct access to m_failed
  • Add a helper function in ICOImageDecoder to determine the image type instead of simply doing it inline
  • Rewrap lines that used to be <=80 cols and slipped over it during the original landing of these decoders
  • Other misc. changes, e.g. adding constructor definitions, reordering functions, changing RGBA32Buffer& to RGBA32Buffer*, etc. that have no functional effect but minimize the subsequent diff for readability
  • platform/image-decoders/bmp/BMPImageDecoder.cpp: (WebCore::BMPImageDecoder::BMPImageDecoder): (WebCore::BMPImageDecoder::processFileHeader):
  • platform/image-decoders/bmp/BMPImageDecoder.h: (WebCore::BMPImageDecoder::readUint32):
  • platform/image-decoders/bmp/BMPImageReader.cpp: (WebCore::BMPImageReader::decodeBMP): (WebCore::BMPImageReader::getInfoHeaderSize): (WebCore::BMPImageReader::processInfoHeader): (WebCore::BMPImageReader::readInfoHeader): (WebCore::BMPImageReader::processBitmasks): (WebCore::BMPImageReader::processColorTable): (WebCore::BMPImageReader::processRLEData): (WebCore::BMPImageReader::processNonRLEData):
  • platform/image-decoders/bmp/BMPImageReader.h: (WebCore::BMPImageReader::readUint16Helper): (WebCore::BMPImageReader::readUint32Helper): (WebCore::BMPImageReader::): (WebCore::BMPImageReader::readUint16): (WebCore::BMPImageReader::readUint32): (WebCore::BMPImageReader::readCurrentPixel): (WebCore::BMPImageReader::getComponent): (WebCore::BMPImageReader::setI): (WebCore::BMPImageReader::setRGBA): (WebCore::BMPImageReader::fillRGBA):
  • platform/image-decoders/ico/ICOImageDecoder.cpp: (WebCore::ICOImageDecoder::ICOImageDecoder): (WebCore::ICOImageDecoder::isSizeAvailable): (WebCore::ICOImageDecoder::size): (WebCore::ICOImageDecoder::decodeImage): (WebCore::ICOImageDecoder::processDirectory): (WebCore::ICOImageDecoder::processDirectoryEntries): (WebCore::ICOImageDecoder::isBetterEntry): (WebCore::ICOImageDecoder::processImageType):
  • platform/image-decoders/ico/ICOImageDecoder.h: (WebCore::ICOImageDecoder::readUint16): (WebCore::ICOImageDecoder::readUint32):
Location:
trunk/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r44832 r44833  
     12009-06-18  Peter Kasting  <pkasting@google.com>
     2
     3        Reviewed by Eric Seidel.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=26460 part two
     6        Attempt to minimize diff of following functional change by first landing
     7        non-functional change to:
     8        * Make readUintX() public and static (since they will need to be once
     9          BMPImageReader is included in *ImageDecoder via composition rather
     10          than inheritance).  Add wrappers in each class so callers can be
     11          simpler.  In the next patch, these wrappers will be beefed up slightly
     12          and the callers will get even simpler.
     13        * Change direct setting of m_failed to use setFailed(), since in the
     14          next patch much of this code won't even have direct access to m_failed
     15        * Add a helper function in ICOImageDecoder to determine the image type
     16          instead of simply doing it inline
     17        * Rewrap lines that used to be <=80 cols and slipped over it during the
     18          original landing of these decoders
     19        * Other misc. changes, e.g. adding constructor definitions, reordering
     20          functions, changing RGBA32Buffer& to RGBA32Buffer*, etc. that have no
     21          functional effect but minimize the subsequent diff for readability
     22
     23
     24        * platform/image-decoders/bmp/BMPImageDecoder.cpp:
     25        (WebCore::BMPImageDecoder::BMPImageDecoder):
     26        (WebCore::BMPImageDecoder::processFileHeader):
     27        * platform/image-decoders/bmp/BMPImageDecoder.h:
     28        (WebCore::BMPImageDecoder::readUint32):
     29        * platform/image-decoders/bmp/BMPImageReader.cpp:
     30        (WebCore::BMPImageReader::decodeBMP):
     31        (WebCore::BMPImageReader::getInfoHeaderSize):
     32        (WebCore::BMPImageReader::processInfoHeader):
     33        (WebCore::BMPImageReader::readInfoHeader):
     34        (WebCore::BMPImageReader::processBitmasks):
     35        (WebCore::BMPImageReader::processColorTable):
     36        (WebCore::BMPImageReader::processRLEData):
     37        (WebCore::BMPImageReader::processNonRLEData):
     38        * platform/image-decoders/bmp/BMPImageReader.h:
     39        (WebCore::BMPImageReader::readUint16Helper):
     40        (WebCore::BMPImageReader::readUint32Helper):
     41        (WebCore::BMPImageReader::):
     42        (WebCore::BMPImageReader::readUint16):
     43        (WebCore::BMPImageReader::readUint32):
     44        (WebCore::BMPImageReader::readCurrentPixel):
     45        (WebCore::BMPImageReader::getComponent):
     46        (WebCore::BMPImageReader::setI):
     47        (WebCore::BMPImageReader::setRGBA):
     48        (WebCore::BMPImageReader::fillRGBA):
     49        * platform/image-decoders/ico/ICOImageDecoder.cpp:
     50        (WebCore::ICOImageDecoder::ICOImageDecoder):
     51        (WebCore::ICOImageDecoder::isSizeAvailable):
     52        (WebCore::ICOImageDecoder::size):
     53        (WebCore::ICOImageDecoder::decodeImage):
     54        (WebCore::ICOImageDecoder::processDirectory):
     55        (WebCore::ICOImageDecoder::processDirectoryEntries):
     56        (WebCore::ICOImageDecoder::isBetterEntry):
     57        (WebCore::ICOImageDecoder::processImageType):
     58        * platform/image-decoders/ico/ICOImageDecoder.h:
     59        (WebCore::ICOImageDecoder::readUint16):
     60        (WebCore::ICOImageDecoder::readUint32):
     61
    1622009-06-18  Peter Kasting  <pkasting@google.com>
    263
  • trunk/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp

    r44634 r44833  
    3939static const size_t sizeOfFileHeader = 14;
    4040
     41BMPImageDecoder::BMPImageDecoder()
     42    : BMPImageReader()
     43{
     44}
     45
    4146void BMPImageDecoder::decodeImage(SharedBuffer* data)
    4247{
     
    7479        */
    7580    };
    76     if (fileType != BMAP)
    77         m_failed = true;
     81    if (fileType != BMAP) {
     82        setFailed();
     83        return false;
     84    }
    7885
    79     return !m_failed;
     86    return true;
    8087}
    8188
  • trunk/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h

    r44634 r44833  
    3939    class BMPImageDecoder : public BMPImageReader {
    4040    public:
     41        BMPImageDecoder();
     42
    4143        virtual String filenameExtension() const { return "bmp"; }
    4244
     
    4547
    4648    private:
     49        inline uint32_t readUint32(SharedBuffer* data, int offset) const
     50        {
     51            return readUint32Helper(data, m_decodedOffset + offset);
     52        }
     53
    4754        // Processes the file header at the beginning of the data.  Returns true if
    4855        // the file header could be decoded.
  • trunk/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp

    r44654 r44833  
    9393}
    9494
    95 void BMPImageReader::decodeBMP(SharedBuffer* data)
     95bool BMPImageReader::decodeBMP(SharedBuffer* data)
    9696{
    9797    // Calculate size of info header.
    9898    if (!m_infoHeader.biSize && !getInfoHeaderSize(data))
    99         return;
     99        return false;
    100100
    101101    // Read and process info header.
    102102    if ((m_decodedOffset < (m_headerOffset + m_infoHeader.biSize))
    103103        && !processInfoHeader(data))
    104         return;
     104        return false;
    105105
    106106    // Read and process the bitmasks, if needed.
    107107    if (m_needToProcessBitmasks && !processBitmasks(data))
    108         return;
     108        return false;
    109109
    110110    // Read and process the color table, if needed.
    111111    if (m_needToProcessColorTable && !processColorTable(data))
    112         return;
     112        return false;
    113113
    114114    // Initialize the framebuffer if needed.
    115     RGBA32Buffer& buffer = m_frameBufferCache.first();
    116     if (buffer.status() == RGBA32Buffer::FrameEmpty) {
    117         if (!buffer.setSize(size().width(), size().height())) {
     115    RGBA32Buffer* buffer = &m_frameBufferCache.first();
     116    if (buffer->status() == RGBA32Buffer::FrameEmpty) {
     117        if (!buffer->setSize(size().width(), size().height())) {
    118118            // Unable to allocate.
    119             m_failed = true;
    120             return;
    121         }
    122         buffer.setStatus(RGBA32Buffer::FramePartial);
     119            setFailed();
     120            return false;
     121        }
     122        buffer->setStatus(RGBA32Buffer::FramePartial);
    123123        // setSize() calls eraseARGB(), which resets the alpha flag, so we force
    124124        // it back to false here.  We'll set it true below in all cases where
    125125        // these 0s could actually show through.
    126         buffer.setHasAlpha(false);
     126        buffer->setHasAlpha(false);
    127127
    128128        // For BMPs, the frame always fills the entire image.
    129         buffer.setRect(IntRect(IntPoint(), size()));
     129        buffer->setRect(IntRect(IntPoint(), size()));
    130130
    131131        if (!m_isTopDown)
     
    139139            || (m_infoHeader.biCompression == RLE24)) {
    140140            if (!processRLEData(data))
    141                 return;
     141                return false;
    142142        } else if (!processNonRLEData(data, false, 0))
    143             return;
     143            return false;
    144144    }
    145145
    146146    // If the image has an AND mask and there was no alpha data, process the
    147147    // mask.
    148     if ((m_andMaskState == NotYetDecoded) && !buffer.hasAlpha()) {
     148    if ((m_andMaskState == NotYetDecoded) && !buffer->hasAlpha()) {
    149149        // Reset decoding coordinates to start of image.
    150150        m_coord.setX(0);
     
    157157    }
    158158    if ((m_andMaskState == Decoding) && !processNonRLEData(data, false, 0))
    159         return;
     159        return false;
    160160
    161161    // Done!
    162     buffer.setStatus(RGBA32Buffer::FrameComplete);
     162    buffer->setStatus(RGBA32Buffer::FrameComplete);
     163    return true;
    163164}
    164165
     
    180181        || (m_imgDataOffset
    181182            && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize)))) {
    182         m_failed = true;
     183        setFailed();
    183184        return false;
    184185    }
     
    196197                 || (m_infoHeader.biSize == 46)))
    197198        m_isOS22x = true;
    198     else
    199         m_failed = true;
    200 
    201     return !m_failed;
     199    else {
     200        setFailed();
     201        return false;
     202    }
     203
     204    return true;
    202205}
    203206
     
    214217    // Sanity-check header values.
    215218    if (!isInfoHeaderValid()) {
    216         m_failed = true;
     219        setFailed();
    217220        return false;
    218221    }
     
    220223    // Make our size available to the caller.
    221224    if (!setSize(m_infoHeader.biWidth, m_infoHeader.biHeight)) {
    222         m_failed = true;
     225        setFailed();
    223226        return false;
    224227    }
     
    285288        } else if (biCompression > 5) {
    286289            // Some type we don't understand.
    287             m_failed = true;
     290            setFailed();
    288291            return false;
    289292        } else
    290             m_infoHeader.biCompression = static_cast<CompressionType>(biCompression);
     293            m_infoHeader.biCompression =
     294                static_cast<CompressionType>(biCompression);
    291295    }
    292296
     
    472476        // Fail if we don't have enough file space for the bitmasks.
    473477        static const size_t SIZEOF_BITMASKS = 12;
    474         if (((m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS) < (m_headerOffset + m_infoHeader.biSize))
    475             || (m_imgDataOffset && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS)))) {
    476             m_failed = true;
     478        if (((m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS) <
     479                (m_headerOffset + m_infoHeader.biSize))
     480            || (m_imgDataOffset && (m_imgDataOffset <
     481                (m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS)))) {
     482            setFailed();
    477483            return false;
    478484        }
     
    502508        // data (for example, bits 25-31 in a 24-bit RGB format).
    503509        if (m_infoHeader.biBitCount < 32)
    504             m_bitMasks[i] &= ((static_cast<uint32_t>(1) << m_infoHeader.biBitCount) - 1);
     510            m_bitMasks[i] &=
     511                ((static_cast<uint32_t>(1) << m_infoHeader.biBitCount) - 1);
    505512
    506513        // For empty masks (common on the alpha channel, especially after the
     
    516523        for (int j = 0; j < i; ++j) {
    517524            if (tempMask & m_bitMasks[j]) {
    518                 m_failed = true;
     525                setFailed();
    519526                return false;
    520527            }
     
    531538        // Make sure bitmask is contiguous.
    532539        if (tempMask) {
    533             m_failed = true;
     540            setFailed();
    534541            return false;
    535542        }
     
    551558
    552559    // Fail if we don't have enough file space for the color table.
    553     if (((m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes) < (m_headerOffset + m_infoHeader.biSize))
    554         || (m_imgDataOffset && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes)))) {
    555         m_failed = true;
     560    if (((m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes) <
     561            (m_headerOffset + m_infoHeader.biSize))
     562        || (m_imgDataOffset && (m_imgDataOffset <
     563            (m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes)))) {
     564        setFailed();
    556565        return false;
    557566    }
     
    607616    // Impossible to decode row-at-a-time, so just do things as a stream of
    608617    // bytes.
    609     RGBA32Buffer& buffer = m_frameBufferCache.first();
     618    RGBA32Buffer* buffer = &m_frameBufferCache.first();
    610619    while (true) {
    611620        // Every entry takes at least two bytes; bail if there isn't enough
     
    619628        const uint8_t code = data->data()[m_decodedOffset + 1];
    620629        if (((count != 0) || (code != 1)) && pastEndOfImage(0)) {
    621             m_failed = true;
     630            setFailed();
    622631            return false;
    623632        }
     
    629638                // Skip any remaining pixels in this row.
    630639                if (m_coord.x() < size().width())
    631                     buffer.setHasAlpha(true);
     640                    buffer->setHasAlpha(true);
    632641                moveBufferToNextRow();
    633642
     
    638647                // Skip any remaining pixels in the image.
    639648                if ((m_coord.x() < size().width())
    640                     || (m_isTopDown ? (m_coord.y() < (size().height() - 1)) : (m_coord.y() > 0)))
    641                     buffer.setHasAlpha(true);
     649                    || (m_isTopDown
     650                        ? (m_coord.y() < (size().height() - 1))
     651                        : (m_coord.y() > 0)))
     652                    buffer->setHasAlpha(true);
    642653                return true;
    643654
     
    653664                const uint8_t dy = data->data()[m_decodedOffset + 3];
    654665                if ((dx != 0) || (dy != 0))
    655                     buffer.setHasAlpha(true);
     666                    buffer->setHasAlpha(true);
    656667                if (((m_coord.x() + dx) > size().width()) ||
    657668                    pastEndOfImage(dy)) {
    658                     m_failed = true;
     669                    setFailed();
    659670                    return false;
    660671                }
     
    706717                if ((colorIndexes[0] >= m_infoHeader.biClrUsed)
    707718                    || (colorIndexes[1] >= m_infoHeader.biClrUsed)) {
    708                     m_failed = true;
     719                    setFailed();
    709720                    return false;
    710721                }
     
    731742    const int endX = m_coord.x() + numPixels;
    732743    if (endX > size().width()) {
    733         m_failed = true;
     744        setFailed();
    734745        return false;
    735746    }
     
    749760    // Decode as many rows as we can.  (For RLE, where we only want to decode
    750761    // one row, we've already checked that this condition is true.)
    751     RGBA32Buffer& buffer = m_frameBufferCache.first();
     762    RGBA32Buffer* buffer = &m_frameBufferCache.first();
    752763    while (!pastEndOfImage(0)) {
    753764        // Bail if we don't have enough data for the desired number of pixels.
     
    762773            for (size_t byte = 0; byte < unpaddedNumBytes; ++byte) {
    763774                uint8_t pixelData = data->data()[m_decodedOffset + byte];
    764                 for (size_t pixel = 0; (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) {
     775                for (size_t pixel = 0;
     776                     (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) {
    765777                    const size_t colorIndex =
    766778                        (pixelData >> (8 - m_infoHeader.biBitCount)) & mask;
     
    773785                        if (colorIndex) {
    774786                            setRGBA(0, 0, 0, 0);
    775                             buffer.setHasAlpha(true);
     787                            buffer->setHasAlpha(true);
    776788                        } else
    777789                            m_coord.move(1, 0);
    778790                    } else {
    779791                        if (colorIndex >= m_infoHeader.biClrUsed) {
    780                             m_failed = true;
     792                            setFailed();
    781793                            return false;
    782794                        }
     
    807819                    m_seenNonZeroAlphaPixel = true;
    808820                    if (m_seenZeroAlphaPixel) {
    809                         buffer.zeroFill();
     821                        buffer->zeroFill();
    810822                        m_seenZeroAlphaPixel = false;
    811823                    } else if (alpha != 255)
    812                         buffer.setHasAlpha(true);
     824                        buffer->setHasAlpha(true);
    813825                }
    814826
  • trunk/WebCore/platform/image-decoders/bmp/BMPImageReader.h

    r44634 r44833  
    5151        virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
    5252
     53        // Read a value from |data[offset]|, converting from little to native
     54        // endianness.
     55        static inline uint16_t readUint16Helper(SharedBuffer* data, int offset)
     56        {
     57            uint16_t result;
     58            memcpy(&result, &data->data()[offset], 2);
     59        #if PLATFORM(BIG_ENDIAN)
     60            result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
     61        #endif
     62            return result;
     63        }
     64
     65        static inline uint32_t readUint32Helper(SharedBuffer* data, int offset)
     66        {
     67            uint32_t result;
     68            memcpy(&result, &data->data()[offset], 4);
     69        #if PLATFORM(BIG_ENDIAN)
     70            result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) |
     71                ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
     72        #endif
     73            return result;
     74        }
     75
    5376    protected:
    5477        enum AndMaskState {
     
    5881        };
    5982
    60         // Decodes a single BMP, starting with an info header.
    61         void decodeBMP(SharedBuffer* data);
    62 
    63         // Read a value from |data[m_decodedOffset + additionalOffset]|, converting
    64         // from little to native endianness.
    65         inline uint16_t readUint16(SharedBuffer* data, int additionalOffset) const
    66         {
    67             uint16_t result;
    68             memcpy(&result, &data->data()[m_decodedOffset + additionalOffset], 2);
    69         #if PLATFORM(BIG_ENDIAN)
    70             result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
    71         #endif
    72             return result;
    73         }
    74 
    75         inline uint32_t readUint32(SharedBuffer* data, int additionalOffset) const
    76         {
    77             uint32_t result;
    78             memcpy(&result, &data->data()[m_decodedOffset + additionalOffset], 4);
    79         #if PLATFORM(BIG_ENDIAN)
    80             result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) |
    81                 ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
    82         #endif
    83             return result;
    84         }
     83        // Does the actual decoding.  Returns whether decoding succeeded.
     84        bool decodeBMP(SharedBuffer* data);
    8585
    8686        // An index into |m_data| representing how much we've already decoded.
     
    9090        size_t m_headerOffset;
    9191
    92         // The file offset at which the actual image bits start.  When decoding ICO
    93         // files, this is set to 0, since it's not stored anywhere in a header; the
    94         // reader functions expect the image data to start immediately after the
    95         // header and (if necessary) color table.
     92        // The file offset at which the actual image bits start.  When decoding
     93        // ICO files, this is set to 0, since it's not stored anywhere in a
     94        // header; the reader functions expect the image data to start
     95        // immediately after the header and (if necessary) color table.
    9696        size_t m_imgDataOffset;
    9797
    9898        // ICOs store a 1bpp "mask" immediately after the main bitmap image data
    9999        // (and, confusingly, add its height to the biHeight value in the info
    100         // header, thus doubling it).  This variable tracks whether we have such a
    101         // mask and if we've started decoding it yet.
     100        // header, thus doubling it).  This variable tracks whether we have such
     101        // a mask and if we've started decoding it yet.
    102102        AndMaskState m_andMaskState;
    103103
    104104    private:
    105         // The various BMP compression types.  We don't currently decode all these.
     105        // The various BMP compression types.  We don't currently decode all
     106        // these.
    106107        enum CompressionType {
    107108            // Universal types
     
    118119        };
    119120
    120         // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE structs,
    121         // but with unnecessary entries removed.
     121        // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE
     122        // structs, but with unnecessary entries removed.
    122123        struct BitmapInfoHeader {
    123124            uint32_t biSize;
     
    134135        };
    135136
    136         // Determines the size of the BMP info header.  Returns true if the size is
    137         // valid.
     137        inline uint16_t readUint16(SharedBuffer* data, int offset) const
     138        {
     139            return readUint16Helper(data, m_decodedOffset + offset);
     140        }
     141
     142        inline uint32_t readUint32(SharedBuffer* data, int offset) const
     143        {
     144            return readUint32Helper(data, m_decodedOffset + offset);
     145        }
     146
     147        // Determines the size of the BMP info header.  Returns true if the size
     148        // is valid.
    138149        bool getInfoHeaderSize(SharedBuffer* data);
    139150
    140         // Processes the BMP info header.  Returns true if the info header could be
    141         // decoded.
     151        // Processes the BMP info header.  Returns true if the info header could
     152        // be decoded.
    142153        bool processInfoHeader(SharedBuffer* data);
    143154
    144         // Helper function for processInfoHeader() which does the actual reading of
    145         // header values from the byte stream.  Returns false on error.
     155        // Helper function for processInfoHeader() which does the actual reading
     156        // of header values from the byte stream.  Returns false on error.
    146157        bool readInfoHeader(SharedBuffer* data);
    147158
     
    156167        bool isInfoHeaderValid() const;
    157168
    158         // For BI_BITFIELDS images, initializes the m_bitMasks[] and m_bitOffsets[]
    159         // arrays.  processInfoHeader() will initialize these for other compression
    160         // types where needed.
     169        // For BI_BITFIELDS images, initializes the m_bitMasks[] and
     170        // m_bitOffsets[] arrays.  processInfoHeader() will initialize these for
     171        // other compression types where needed.
    161172        bool processBitmasks(SharedBuffer* data);
    162173
    163         // For paletted images, allocates and initializes the m_colorTable[] array.
     174        // For paletted images, allocates and initializes the m_colorTable[]
     175        // array.
    164176        bool processColorTable(SharedBuffer* data);
    165177
     
    173185        //     success.
    174186        //   * inRLE = false: the data is inside a non-RLE-encoded bitmap.
    175         //     |numPixels| is ignored.  Expects |m_coord| to point at the beginning
    176         //     of the next row to be decoded.  Tries to process as many complete
    177         //     rows as possible.  Returns true if the whole image was decoded.
     187        //     |numPixels| is ignored.  Expects |m_coord| to point at the
     188        //     beginning of the next row to be decoded.  Tries to process as
     189        //     many complete rows as possible.  Returns true if the whole image
     190        //     was decoded.
    178191        bool processNonRLEData(SharedBuffer* data, bool inRLE, int numPixels);
    179192
    180193        // Returns true if the current y-coordinate plus |numRows| would be past
    181         // the end of the image.  Here "plus" means "toward the end of the image",
    182         // so downwards for m_isTopDown images and upwards otherwise.
     194        // the end of the image.  Here "plus" means "toward the end of the
     195        // image", so downwards for m_isTopDown images and upwards otherwise.
    183196        inline bool pastEndOfImage(int numRows)
    184197        {
     
    191204        // Assumes m_decodedOffset has been set to the beginning of the current
    192205        // row.
    193         // NOTE: Only as many bytes of the return value as are needed to hold the
    194         // pixel data will actually be set.
     206        // NOTE: Only as many bytes of the return value as are needed to hold
     207        // the pixel data will actually be set.
    195208        inline uint32_t readCurrentPixel(SharedBuffer* data, int bytesPerPixel) const
    196209        {
     
    201214
    202215            case 3: {
    203                 // It doesn't matter that we never set the most significant byte of
    204                 // the return value here in little-endian mode, the caller won't
    205                 // read it.
     216                // It doesn't matter that we never set the most significant byte
     217                // of the return value here in little-endian mode, the caller
     218                // won't read it.
    206219                uint32_t pixel;
    207220                memcpy(&pixel,
     
    223236        }
    224237
    225         // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A) in
    226         // the given pixel data.
     238        // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A)
     239        // in the given pixel data.
    227240        inline unsigned getComponent(uint32_t pixel, int component) const
    228241        {
    229             return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[component])
    230                 << m_bitShiftsLeft[component];
     242            return ((pixel & m_bitMasks[component]) >>
     243                m_bitShiftsRight[component]) << m_bitShiftsLeft[component];
    231244        }
    232245
     
    241254
    242255        // Sets the current pixel to the color given by |colorIndex|.  This also
    243         // increments the relevant local variables to move the current pixel right
    244         // by one.
     256        // increments the relevant local variables to move the current pixel
     257        // right by one.
    245258        inline void setI(size_t colorIndex)
    246259        {
    247             setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen,
     260            setRGBA(m_colorTable[colorIndex].rgbRed,
     261                    m_colorTable[colorIndex].rgbGreen,
    248262                    m_colorTable[colorIndex].rgbBlue, 0xff);
    249263        }
    250264
    251265        // Like setI(), but with the individual component values specified.
    252         inline void setRGBA(unsigned red, unsigned green, unsigned blue, unsigned alpha)
     266        inline void setRGBA(unsigned red,
     267                            unsigned green,
     268                            unsigned blue,
     269                            unsigned alpha)
    253270        {
    254271            m_frameBufferCache.first().setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha);
     
    257274
    258275        // Fills pixels from the current X-coordinate up to, but not including,
    259         // |endCoord| with the color given by the individual components.  This also
    260         // increments the relevant local variables to move the current pixel right
    261         // to |endCoord|.
    262         inline void fillRGBA(int endCoord, unsigned red, unsigned green, unsigned blue, unsigned alpha)
     276        // |endCoord| with the color given by the individual components.  This
     277        // also increments the relevant local variables to move the current
     278        // pixel right to |endCoord|.
     279        inline void fillRGBA(int endCoord,
     280                             unsigned red,
     281                             unsigned green,
     282                             unsigned blue,
     283                             unsigned alpha)
    263284        {
    264285            while (m_coord.x() < endCoord)
     
    266287        }
    267288
    268         // Resets the relevant local variables to start drawing at the left edge of
    269         // the "next" row, where "next" is above or below the current row depending
    270         // on the value of |m_isTopDown|.
     289        // Resets the relevant local variables to start drawing at the left edge
     290        // of the "next" row, where "next" is above or below the current row
     291        // depending on the value of |m_isTopDown|.
    271292        void moveBufferToNextRow();
    272293
     
    274295        BitmapInfoHeader m_infoHeader;
    275296
    276         // True if this is an OS/2 1.x (aka Windows 2.x) BMP.  The struct layouts
    277         // for this type of BMP are slightly different from the later, more common
    278         // formats.
     297        // True if this is an OS/2 1.x (aka Windows 2.x) BMP.  The struct
     298        // layouts for this type of BMP are slightly different from the later,
     299        // more common formats.
    279300        bool m_isOS21x;
    280301
     
    282303        // and 4 for this type of BMP differ from Windows V3+ BMPs.
    283304        //
    284         // This will be falsely negative in some cases, but only ones where the way
    285         // we misinterpret the data is irrelevant.
     305        // This will be falsely negative in some cases, but only ones where the
     306        // way we misinterpret the data is irrelevant.
    286307        bool m_isOS22x;
    287308
     
    294315        bool m_needToProcessColorTable;
    295316
    296         // Masks/offsets for the color values for non-palette formats.  These are
    297         // bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, A.
     317        // Masks/offsets for the color values for non-palette formats.  These
     318        // are bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B,
     319        // A.
    298320        //
    299321        // The right/left shift values are meant to be applied after the masks.
    300         // We need to right shift to compensate for the bitfields' offsets into the
    301         // 32 bits of pixel data, and left shift to scale the color values up for
    302         // fields with less than 8 bits of precision.  Sadly, we can't just combine
    303         // these into one shift value because the net shift amount could go either
    304         // direction.  (If only "<< -x" were equivalent to ">> x"...)
     322        // We need to right shift to compensate for the bitfields' offsets into
     323        // the 32 bits of pixel data, and left shift to scale the color values
     324        // up for fields with less than 8 bits of precision.  Sadly, we can't
     325        // just combine these into one shift value because the net shift amount
     326        // could go either direction.  (If only "<< -x" were equivalent to
     327        // ">> x"...)
    305328        uint32_t m_bitMasks[4];
    306329        int m_bitShiftsRight[4];
  • trunk/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp

    r44825 r44833  
    4040static const size_t sizeOfDirEntry = 16;
    4141
     42ICOImageDecoder::ICOImageDecoder(const IntSize& preferredIconSize)
     43    : BMPImageReader()
     44    , m_preferredIconSize(preferredIconSize)
     45    , m_imageType(Unknown)
     46{
     47    m_andMaskState = NotYetDecoded;
     48}
     49
     50bool ICOImageDecoder::isSizeAvailable()
     51{
     52    return (m_imageType == PNG) ?
     53        m_pngDecoder.isSizeAvailable() : BMPImageReader::isSizeAvailable();
     54}
     55
     56IntSize ICOImageDecoder::size() const
     57{
     58    return (m_imageType == PNG) ? m_pngDecoder.size() : BMPImageReader::size();
     59}
     60
    4261void ICOImageDecoder::decodeImage(SharedBuffer* data)
    4362{
     
    4766
    4867    // Read and process directory entries.
    49     if ((m_decodedOffset < (sizeOfDirectory + (m_directory.idCount * sizeOfDirEntry)))
     68    if ((m_decodedOffset <
     69            (sizeOfDirectory + (m_directory.idCount * sizeOfDirEntry)))
    5070        && !processDirectoryEntries(data))
    5171        return;
    5272
    53     // Check if this entry is a PNG; we need 4 bytes to check the magic number.
    54     if (m_imageType == Unknown) {
    55         if (data->size() < (m_dirEntry.dwImageOffset + 4))
    56             return;
    57         m_imageType =
    58             strncmp(&data->data()[m_dirEntry.dwImageOffset], "\x89PNG", 4) ?
    59             BMP : PNG;
    60     }
     73    // Get the image type.
     74    if ((m_imageType == Unknown) && !processImageType(data))
     75        return;
    6176
    6277    // Decode selected entry.
     
    8196}
    8297
    83 bool ICOImageDecoder::isSizeAvailable()
    84 {
    85     return (m_imageType == PNG) ? m_pngDecoder.isSizeAvailable() :
    86         BMPImageReader::isSizeAvailable();
    87 }
    88 
    89 IntSize ICOImageDecoder::size() const
    90 {
    91     return (m_imageType == PNG) ? m_pngDecoder.size() : BMPImageReader::size();
    92 }
    93 
    9498bool ICOImageDecoder::processDirectory(SharedBuffer* data)
    9599{
     
    110114    if (((fileType != ICON) && (fileType != CURSOR)) ||
    111115            (m_directory.idCount == 0))
    112         m_failed = true;
    113 
    114     return !m_failed;
     116        setFailed();
     117
     118    return !failed();
    115119}
    116120
     
    119123    // Read directory entries.
    120124    ASSERT(m_decodedOffset == sizeOfDirectory);
    121     if ((m_decodedOffset > data->size()) || (data->size() - m_decodedOffset) <
    122             (m_directory.idCount * sizeOfDirEntry))
     125    if ((m_decodedOffset > data->size())
     126        || ((data->size() - m_decodedOffset) <
     127            (m_directory.idCount * sizeOfDirEntry)))
    123128        return false;
    124129    for (int i = 0; i < m_directory.idCount; ++i) {
     
    134139    if ((m_dirEntry.dwImageOffset < m_decodedOffset) ||
    135140            ((m_dirEntry.dwImageOffset + 4) < m_dirEntry.dwImageOffset)) {
    136       m_failed = true;
     141      setFailed();
    137142      return false;
    138143    }
     
    190195        // better.
    191196        if (entryArea != dirEntryArea) {
    192             return (entryArea < dirEntryArea)
    193                 && (entryArea >= (m_preferredIconSize.width() * m_preferredIconSize.height()));
     197            return (entryArea < dirEntryArea) && (entryArea >=
     198                (m_preferredIconSize.width() * m_preferredIconSize.height()));
    194199        }
    195200    }
     
    201206    // Higher bit-depth icons are better.
    202207    return (entry.wBitCount > m_dirEntry.wBitCount);
     208}
     209
     210bool ICOImageDecoder::processImageType(SharedBuffer* data)
     211{
     212    // Check if this entry is a BMP or a PNG; we need 4 bytes to check the magic
     213    // number.
     214    ASSERT(m_decodedOffset == m_dirEntry.dwImageOffset);
     215    if ((m_decodedOffset > data->size())
     216        || ((data->size() - m_decodedOffset) < 4))
     217        return false;
     218    m_imageType =
     219        strncmp(&data->data()[m_decodedOffset], "\x89PNG", 4) ? BMP : PNG;
     220    return true;
    203221}
    204222
  • trunk/WebCore/platform/image-decoders/ico/ICOImageDecoder.h

    r44825 r44833  
    4141    public:
    4242        // See comments on |m_preferredIconSize| below.
    43         ICOImageDecoder(const IntSize& preferredIconSize)
    44             : m_preferredIconSize(preferredIconSize)
    45             , m_imageType(Unknown)
    46         {
    47             m_andMaskState = NotYetDecoded;
    48         }
     43        ICOImageDecoder(const IntSize& preferredIconSize);
    4944
     45        // ImageDecoder
    5046        virtual String filenameExtension() const { return "ico"; }
     47        virtual bool isSizeAvailable();
     48        virtual IntSize size() const;
    5149
    5250        // BMPImageReader
    5351        virtual void decodeImage(SharedBuffer* data);
    5452        virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
    55 
    56         // ImageDecoder
    57         virtual bool isSizeAvailable();
    58         virtual IntSize size() const;
    5953
    6054    private:
     
    7771        };
    7872
    79         // Processes the ICONDIR at the beginning of the data.  Returns true if the
    80         // directory could be decoded.
     73        inline uint16_t readUint16(SharedBuffer* data, int offset) const
     74        {
     75            return readUint16Helper(data, m_decodedOffset + offset);
     76        }
     77
     78        inline uint32_t readUint32(SharedBuffer* data, int offset) const
     79        {
     80            return readUint32Helper(data, m_decodedOffset + offset);
     81        }
     82
     83        // Processes the ICONDIR at the beginning of the data.  Returns true if
     84        // the directory could be decoded.
    8185        bool processDirectory(SharedBuffer*);
    8286
    8387        // Processes the ICONDIRENTRY records after the directory.  Keeps the
    84         // "best" entry as the one we'll decode.  Returns true if the entries could
    85         // be decoded.
     88        // "best" entry as the one we'll decode.  Returns true if the entries
     89        // could be decoded.
    8690        bool processDirectoryEntries(SharedBuffer*);
    8791
    88         // Reads and returns a directory entry from the current offset into |data|.
     92        // Reads and returns a directory entry from the current offset into
     93        // |data|.
    8994        IconDirectoryEntry readDirectoryEntry(SharedBuffer*);
    9095
     
    9297        // Larger sizes, or greater bitdepths at the same size, are preferable.
    9398        bool isBetterEntry(const IconDirectoryEntry&) const;
     99
     100        // Determines whether the desired entry is a BMP or PNG.  Returns true
     101        // if the type could be determined.
     102        bool processImageType(SharedBuffer*);
    94103
    95104        // Called when the image to be decoded is a PNG rather than a BMP.
Note: See TracChangeset for help on using the changeset viewer.