Changeset 44631 in webkit


Ignore:
Timestamp:
Jun 12, 2009 3:06:50 PM (15 years ago)
Author:
pkasting@chromium.org
Message:

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

Reviewed by Eric Seidel.

https://bugs.webkit.org/show_bug.cgi?id=25709 part seven
Update Skia's ImageDecoder.h with a few changes designed to reduce the
delta between specific implementations of ImageDecoder.h. Update
Cairo's ImageDecoder.h to sync up with the API changes in the Skia
version in the last two chage sets. Update Cairo's PNG/JPEG/GIF
decoders to use the APIs as well. All the Cairo image decoder changes
are direct copies of the Skia versions except ImageDecoder.h, which is
modified in the necessary ways for the differences between Cairo and
Skia.

  • platform/graphics/cairo/ImageSourceCairo.cpp: (WebCore::ImageSource::createFrameAtIndex): Use new RGBA32Buffer::asNewNativeImage() API.
  • platform/image-decoders/ImageDecoder.h: Sync up with Skia version. (WebCore::RGBA32Buffer::): (WebCore::RGBA32Buffer::RGBA32Buffer): (WebCore::RGBA32Buffer::clear): (WebCore::RGBA32Buffer::zeroFill): (WebCore::RGBA32Buffer::copyBitmapData): (WebCore::RGBA32Buffer::copyRowNTimes): (WebCore::RGBA32Buffer::setSize): (WebCore::RGBA32Buffer::asNewNativeImage): (WebCore::RGBA32Buffer::hasAlpha): (WebCore::RGBA32Buffer::disposalMethod): (WebCore::RGBA32Buffer::setHasAlpha): (WebCore::RGBA32Buffer::setDisposalMethod): (WebCore::RGBA32Buffer::setRGBA): (WebCore::RGBA32Buffer::operator=): (WebCore::RGBA32Buffer::width): (WebCore::RGBA32Buffer::height): (WebCore::RGBA32Buffer::getAddr):
  • platform/image-decoders/gif/GIFImageDecoder.cpp: Sync up with Skia version. (WebCore::GIFImageDecoder::initFrameBuffer): (WebCore::GIFImageDecoder::haveDecodedRow):
  • platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Sync up with Skia version. (WebCore::JPEGImageDecoder::outputScanlines):
  • platform/image-decoders/png/PNGImageDecoder.cpp: Sync up with Skia version. (WebCore::PNGImageDecoder::rowAvailable):
  • platform/image-decoders/skia/ImageDecoder.h: Add various typedefs or helper functions to minimize differences with Cairo version. Reorder functions slightly to match reordering of Cairo's m_hasAlpha variable, which I moved to increase readability. (WebCore::RGBA32Buffer::): (WebCore::RGBA32Buffer::copyRowNTimes): (WebCore::RGBA32Buffer::setSize): (WebCore::RGBA32Buffer::asNewNativeImage): (WebCore::RGBA32Buffer::hasAlpha): (WebCore::RGBA32Buffer::disposalMethod): (WebCore::RGBA32Buffer::setHasAlpha): (WebCore::RGBA32Buffer::setStatus): (WebCore::RGBA32Buffer::setDisposalMethod): (WebCore::RGBA32Buffer::setRGBA): (WebCore::RGBA32Buffer::operator=): (WebCore::RGBA32Buffer::width): (WebCore::RGBA32Buffer::height): (WebCore::RGBA32Buffer::getAddr):
  • platform/image-decoders/skia/JPEGImageDecoder.cpp: Add #include needed by JPEG headers on some platforms, plus comment.
Location:
trunk/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r44630 r44631  
     12009-06-11  Peter Kasting  <pkasting@google.com>
     2
     3        Reviewed by Eric Seidel.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=25709 part seven
     6        Update Skia's ImageDecoder.h with a few changes designed to reduce the
     7        delta between specific implementations of ImageDecoder.h.  Update
     8        Cairo's ImageDecoder.h to sync up with the API changes in the Skia
     9        version in the last two chage sets.  Update Cairo's PNG/JPEG/GIF
     10        decoders to use the APIs as well.  All the Cairo image decoder changes
     11        are direct copies of the Skia versions except ImageDecoder.h, which is
     12        modified in the necessary ways for the differences between Cairo and
     13        Skia.
     14
     15        * platform/graphics/cairo/ImageSourceCairo.cpp:
     16        (WebCore::ImageSource::createFrameAtIndex): Use new RGBA32Buffer::asNewNativeImage() API.
     17        * platform/image-decoders/ImageDecoder.h: Sync up with Skia version.
     18        (WebCore::RGBA32Buffer::):
     19        (WebCore::RGBA32Buffer::RGBA32Buffer):
     20        (WebCore::RGBA32Buffer::clear):
     21        (WebCore::RGBA32Buffer::zeroFill):
     22        (WebCore::RGBA32Buffer::copyBitmapData):
     23        (WebCore::RGBA32Buffer::copyRowNTimes):
     24        (WebCore::RGBA32Buffer::setSize):
     25        (WebCore::RGBA32Buffer::asNewNativeImage):
     26        (WebCore::RGBA32Buffer::hasAlpha):
     27        (WebCore::RGBA32Buffer::disposalMethod):
     28        (WebCore::RGBA32Buffer::setHasAlpha):
     29        (WebCore::RGBA32Buffer::setDisposalMethod):
     30        (WebCore::RGBA32Buffer::setRGBA):
     31        (WebCore::RGBA32Buffer::operator=):
     32        (WebCore::RGBA32Buffer::width):
     33        (WebCore::RGBA32Buffer::height):
     34        (WebCore::RGBA32Buffer::getAddr):
     35        * platform/image-decoders/gif/GIFImageDecoder.cpp: Sync up with Skia version.
     36        (WebCore::GIFImageDecoder::initFrameBuffer):
     37        (WebCore::GIFImageDecoder::haveDecodedRow):
     38        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Sync up with Skia version.
     39        (WebCore::JPEGImageDecoder::outputScanlines):
     40        * platform/image-decoders/png/PNGImageDecoder.cpp: Sync up with Skia version.
     41        (WebCore::PNGImageDecoder::rowAvailable):
     42        * platform/image-decoders/skia/ImageDecoder.h: Add various typedefs or helper functions to minimize differences with Cairo version.  Reorder functions slightly to match reordering of Cairo's m_hasAlpha variable, which I moved to increase readability.
     43        (WebCore::RGBA32Buffer::):
     44        (WebCore::RGBA32Buffer::copyRowNTimes):
     45        (WebCore::RGBA32Buffer::setSize):
     46        (WebCore::RGBA32Buffer::asNewNativeImage):
     47        (WebCore::RGBA32Buffer::hasAlpha):
     48        (WebCore::RGBA32Buffer::disposalMethod):
     49        (WebCore::RGBA32Buffer::setHasAlpha):
     50        (WebCore::RGBA32Buffer::setStatus):
     51        (WebCore::RGBA32Buffer::setDisposalMethod):
     52        (WebCore::RGBA32Buffer::setRGBA):
     53        (WebCore::RGBA32Buffer::operator=):
     54        (WebCore::RGBA32Buffer::width):
     55        (WebCore::RGBA32Buffer::height):
     56        (WebCore::RGBA32Buffer::getAddr):
     57        * platform/image-decoders/skia/JPEGImageDecoder.cpp: Add #include needed by JPEG headers on some platforms, plus comment.
     58
    1592009-06-12  Brent Fulgham  <bfulgham@webkit.org>
    260
  • trunk/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp

    r44539 r44631  
    194194        return 0;
    195195
    196     return cairo_image_surface_create_for_data((unsigned char*)buffer->bytes().data(),
    197                                                CAIRO_FORMAT_ARGB32,
    198                                                size().width(),
    199                                                size().height(),
    200                                                size().width()*4);
     196    return buffer->asNewNativeImage();
    201197}
    202198
  • trunk/WebCore/platform/image-decoders/ImageDecoder.h

    r44597 r44631  
    3131#include "PlatformString.h"
    3232#include "SharedBuffer.h"
     33#include <cairo.h>
    3334#include <wtf/Assertions.h>
    3435#include <wtf/RefPtr.h>
     
    3637
    3738namespace WebCore {
    38 
    39     typedef Vector<unsigned> RGBA32Array;
    4039
    4140    // The RGBA32Buffer object represents the decoded image data in RGBA32 format.  This buffer is what all
     
    4443    public:
    4544        enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
    46 
    4745        enum FrameDisposalMethod {
    4846            // If you change the numeric values of these, make sure you audit all
     
    5351            DisposeOverwritePrevious,  // Clear frame to previous framebuffer contents
    5452        };
     53        typedef unsigned PixelData;
    5554
    5655        RGBA32Buffer()
    57             : m_status(FrameEmpty)
     56            : m_hasAlpha(false)
     57            , m_status(FrameEmpty)
    5858            , m_duration(0)
    5959            , m_disposalMethod(DisposeNotSpecified)
    60             , m_hasAlpha(false)
    6160        {
    6261        }
    6362
    64         void clear() {
    65           m_bytes.clear();
    66           m_status = FrameEmpty;
    67           // NOTE: Do not reset other members here; clearFrameBufferCache() calls
    68           // this to free the bitmap data, but other functions like
    69           // initFrameBuffer() and frameComplete() may still need to read other
    70           // metadata out of this frame later.
     63        // This exists because ImageDecoder keeps a Vector<RGBA32Buffer>, and
     64        // Vector requires this constructor.
     65        RGBA32Buffer(const RGBA32Buffer& other)
     66        {
     67            operator=(other);
     68        }
     69
     70        void clear()
     71        {
     72            m_bytes.clear();
     73            m_status = FrameEmpty;
     74            // NOTE: Do not reset other members here; clearFrameBufferCache()
     75            // calls this to free the bitmap data, but other functions like
     76            // initFrameBuffer() and frameComplete() may still need to read
     77            // other metadata out of this frame later.
     78        }
     79
     80        void zeroFill()
     81        {
     82            m_bytes.fill(0);
     83            m_hasAlpha = true;
    7184        }
    7285
     
    7992
    8093            m_bytes = other.m_bytes;
    81             m_hasAlpha = other.m_hasAlpha;
    82         }
    83 
    84         const RGBA32Array& bytes() const { return m_bytes; }
    85         RGBA32Array& bytes() { return m_bytes; }
     94            setHasAlpha(other.m_hasAlpha);
     95        }
     96
     97        // This function copies [(startX, startY), (endX, startY)) to the same
     98        // X-coordinates on each subsequent row up to but not including endY.
     99        //
     100        // NOTE: This function does not sanity-check its arguments!  Callers
     101        // MUST not pass invalid values or this will corrupt memory.
     102        void copyRowNTimes(int startX, int endX, int startY, int endY)
     103        {
     104            ASSERT(startX < width());
     105            ASSERT(endX <= width());
     106            ASSERT(startY < height());
     107            ASSERT(endY <= height());
     108            const int rowBytes = (endX - startX) * sizeof(PixelData);
     109            const PixelData* const startAddr = getAddr(startX, startY);
     110            for (int destY = startY + 1; destY < endY; ++destY)
     111                memcpy(getAddr(startX, endY), startAddr, rowBytes);
     112        }
    86113
    87114        // Must be called before any pixels are written. Will return true on
     
    92119            // requested size was too big...
    93120            m_bytes.resize(width * height);
    94 
    95             // Clear the image.
    96             m_bytes.fill(0);
    97             m_hasAlpha = true;
     121            m_size = IntSize(width, height);
     122
     123            // Zero the image.
     124            zeroFill();
    98125
    99126            return true;
    100127        }
    101128
     129        // To be used by ImageSource::createFrameAtIndex().  Returns a pointer
     130        // to the underlying native image data.  This pointer will be owned by
     131        // the BitmapImage and freed in FrameData::clear().
     132        NativeImagePtr asNewNativeImage() const
     133        {
     134            return cairo_image_surface_create_for_data(
     135                reinterpret_cast<unsigned char*>(const_cast<PixelData*>(
     136                    m_bytes.data())), CAIRO_FORMAT_ARGB32, width(), height(),
     137                width() * sizeof(PixelData));
     138        }
     139
     140        bool hasAlpha() const { return m_hasAlpha; }
    102141        const IntRect& rect() const { return m_rect; }
    103142        FrameStatus status() const { return m_status; }
    104143        unsigned duration() const { return m_duration; }
    105144        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
    106         bool hasAlpha() const { return m_hasAlpha; }
    107 
     145
     146        void setHasAlpha(bool alpha) { m_hasAlpha = alpha; }
    108147        void setRect(const IntRect& r) { m_rect = r; }
    109148        void setStatus(FrameStatus s) { m_status = s; }
    110149        void setDuration(unsigned duration) { m_duration = duration; }
    111150        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
    112         void setHasAlpha(bool alpha) { m_hasAlpha = alpha; }
    113 
    114         static void setRGBA(unsigned& pos, unsigned r, unsigned g, unsigned b, unsigned a)
     151
     152        inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
     153        {
     154            setRGBA(getAddr(x, y), r, g, b, a);
     155        }
     156
     157    private:
     158        // Initialize with another buffer.  This function doesn't create a new copy
     159        // of the image data, it only increases the refcount of the existing bitmap.
     160        //
     161        // Normal callers should not generally be using this function.  If you want
     162        // to create a copy on which you can modify the image data independently,
     163        // use copyBitmapData() instead.
     164        RGBA32Buffer& operator=(const RGBA32Buffer& other)
     165        {
     166            if (this == &other)
     167                return *this;
     168
     169            m_bytes = other.m_bytes;
     170            m_size = other.m_size;
     171            setHasAlpha(other.hasAlpha());
     172            setRect(other.rect());
     173            setStatus(other.status());
     174            setDuration(other.duration());
     175            setDisposalMethod(other.disposalMethod());
     176            return *this;
     177        }
     178
     179        inline int width() const { return m_size.width(); }
     180        inline int height() const { return m_size.height(); }
     181
     182        inline PixelData* getAddr(int x, int y)
     183        {
     184            return m_bytes.data() + (y * width()) + x;
     185        }
     186
     187        inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
    115188        {
    116189            // We store this data pre-multiplied.
    117190            if (a == 0)
    118                 pos = 0;
     191                *dest = 0;
    119192            else {
    120193                if (a < 255) {
     
    124197                    b = static_cast<unsigned>(b * alphaPercent);
    125198                }
    126                 pos = (a << 24 | r << 16 | g << 8 | b);
     199                *dest = (a << 24 | r << 16 | g << 8 | b);
    127200            }
    128201        }
    129202
    130     private:
    131         RGBA32Array m_bytes;
    132         IntRect m_rect;    // The rect of the original specified frame within the overall buffer.
    133                            // This will always just be the entire buffer except for GIF frames
    134                            // whose original rect was smaller than the overall image size.
     203        Vector<PixelData> m_bytes;
     204        IntSize m_size;       // The size of the buffer.  This should be the
     205                              // same as ImageDecoder::m_size.
     206        bool m_hasAlpha;      // Whether or not any of the pixels in the buffer have transparency.
     207        IntRect m_rect;       // The rect of the original specified frame within the overall buffer.
     208                              // This will always just be the entire buffer except for GIF frames
     209                              // whose original rect was smaller than the overall image size.
    135210        FrameStatus m_status; // Whether or not this frame is completely finished decoding.
    136         unsigned m_duration; // The animation delay.
    137         FrameDisposalMethod m_disposalMethod; // What to do with this frame's data when initializing the next frame.
    138         bool m_hasAlpha; // Whether or not any of the pixels in the buffer have transparency.
     211        unsigned m_duration;  // The animation delay.
     212        FrameDisposalMethod m_disposalMethod;
     213                              // What to do with this frame's data when initializing the next frame.
    139214    };
    140215
  • trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp

    r44597 r44631  
    322322              buffer->copyBitmapData(*prevBuffer);
    323323              for (int y = prevRect.y(); y < prevRect.bottom(); ++y) {
    324                   unsigned* const currentRow =
    325                       buffer->bytes().data() + (y * size().width());
    326324                  for (int x = prevRect.x(); x < prevRect.right(); ++x)
    327                       buffer->setRGBA(*(currentRow + x), 0, 0, 0, 0);
     325                      buffer->setRGBA(x, y, 0, 0, 0, 0);
    328326              }
    329327              if ((prevRect.width() > 0) && (prevRect.height() > 0))
     
    342340
    343341void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
    344                                      unsigned char* rowBuffer,   // Pointer to single scanline temporary buffer
     342                                     unsigned char* rowBuffer,
    345343                                     unsigned char* rowEnd,
    346                                      unsigned rowNumber,  // The row index
    347                                      unsigned repeatCount,  // How many times to repeat the row
     344                                     unsigned rowNumber,
     345                                     unsigned repeatCount,
    348346                                     bool writeTransparentPixels)
    349347{
    350     // Initialize the frame if necessary.
    351     RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
    352     if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
    353         return;
    354 
    355     // Do nothing for bogus data.
    356     if (rowBuffer == 0 || static_cast<int>(m_reader->frameYOffset() + rowNumber) >= size().height())
    357         return;
    358 
     348    // The pixel data and coordinates supplied to us are relative to the frame's
     349    // origin within the entire image size, i.e.
     350    // (m_reader->frameXOffset(), m_reader->frameYOffset()).
     351    int x = m_reader->frameXOffset();
     352    const int y = m_reader->frameYOffset() + rowNumber;
     353
     354    // Sanity-check the arguments.
     355    if ((rowBuffer == 0) || (y >= size().height()))
     356        return;
     357
     358    // Get the colormap.
    359359    unsigned colorMapSize;
    360360    unsigned char* colorMap;
     
    363363        return;
    364364
    365     // The buffers that we draw are the entire image's width and height, so a final output frame is
    366     // width * height RGBA32 values in size.
    367     //
    368     // A single GIF frame, however, can be smaller than the entire image, i.e., it can represent some sub-rectangle
    369     // within the overall image.  The rows we are decoding are within this
    370     // sub-rectangle.  This means that if the GIF frame's sub-rectangle is (x,y,w,h) then row 0 is really row
    371     // y, and each row goes from x to x+w.
    372     unsigned dstPos = (m_reader->frameYOffset() + rowNumber) * size().width() + m_reader->frameXOffset();
    373     unsigned* dst = buffer.bytes().data() + dstPos;
    374     unsigned* dstEnd = dst + size().width() - m_reader->frameXOffset();
    375     unsigned* currDst = dst;
    376     unsigned char* currentRowByte = rowBuffer;
    377 
    378     while (currentRowByte != rowEnd && currDst < dstEnd) {
    379         if ((!m_reader->isTransparent() || *currentRowByte != m_reader->transparentPixel()) && *currentRowByte < colorMapSize) {
    380             unsigned colorIndex = *currentRowByte * 3;
    381             unsigned red = colorMap[colorIndex];
    382             unsigned green = colorMap[colorIndex + 1];
    383             unsigned blue = colorMap[colorIndex + 2];
    384             RGBA32Buffer::setRGBA(*currDst, red, green, blue, 255);
     365    // Initialize the frame if necessary.
     366    RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
     367    if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
     368        return;
     369
     370    // Write one row's worth of data into the frame.  There is no guarantee that
     371    // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
     372    // we must ensure we don't run off the end of either the source data or the
     373    // row's X-coordinates.
     374    for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < size().width()); ++sourceAddr, ++x) {
     375        const unsigned char sourceValue = *sourceAddr;
     376        if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) {
     377            const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
     378            buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
    385379        } else {
    386380            m_currentBufferSawAlpha = true;
     
    393387            // later ones.
    394388            if (writeTransparentPixels)
    395                 RGBA32Buffer::setRGBA(*currDst, 0, 0, 0, 0);
    396         }
    397         currDst++;
    398         currentRowByte++;
    399     }
    400 
    401     if (repeatCount > 1) {
    402         // Copy the row |repeatCount|-1 times.
    403         unsigned num = currDst - dst;
    404         unsigned dataSize = num * sizeof(unsigned);
    405         unsigned width = size().width();
    406         unsigned* end = buffer.bytes().data() + width * size().height();
    407         currDst = dst + width;
    408         for (unsigned i = 1; i < repeatCount; i++) {
    409             if (currDst + num > end) // Protect against a buffer overrun from a bogus repeatCount.
    410                 break;
    411             memcpy(currDst, dst, dataSize);
    412             currDst += width;
    413         }
    414     }
     389                buffer.setRGBA(x, y, 0, 0, 0, 0);
     390        }
     391    }
     392
     393    // Tell the frame to copy the row data if need be.
     394    if (repeatCount > 1)
     395        buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height()));
    415396}
    416397
  • trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

    r44597 r44631  
    3939#include "JPEGImageDecoder.h"
    4040#include <assert.h>
    41 #include <stdio.h>
     41#include <stdio.h>  // Needed by jpeglib.h for FILE.
    4242
    4343extern "C" {
     
    476476    JSAMPARRAY samples = m_reader->samples();
    477477
    478     unsigned* dst = buffer.bytes().data() + info->output_scanline * size().width();
    479    
    480478    while (info->output_scanline < info->output_height) {
    481479        /* Request one scanline.  Returns 0 or 1 scanlines. */
     
    487485            unsigned g = *j1++;
    488486            unsigned b = *j1++;
    489             RGBA32Buffer::setRGBA(*dst++, r, g, b, 0xFF);
     487            // read_scanlines has increased the scanline counter, so we
     488            // actually mean the previous one.
     489            buffer.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF);
    490490        }
    491491    }
  • trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp

    r44597 r44631  
    381381    // Copy the data into our buffer.
    382382    int width = size().width();
    383     unsigned* dst = buffer.bytes().data() + rowIndex * width;
    384383    bool sawAlpha = false;
    385384    for (int x = 0; x < width; x++) {
     
    388387        unsigned blue = *row++;
    389388        unsigned alpha = (hasAlpha ? *row++ : 255);
    390         RGBA32Buffer::setRGBA(*dst++, red, green, blue, alpha);
     389        buffer.setRGBA(x, rowIndex, red, green, blue, alpha);
    391390        if (!sawAlpha && alpha < 255) {
    392391            sawAlpha = true;
  • trunk/WebCore/platform/image-decoders/skia/ImageDecoder.h

    r44597 r44631  
    4646    public:
    4747        enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
    48 
    4948        enum FrameDisposalMethod {
    5049            // If you change the numeric values of these, make sure you audit all
     
    5554            DisposeOverwritePrevious,  // Clear frame to previous framebuffer contents
    5655        };
     56        typedef uint32_t PixelData;
    5757
    5858        RGBA32Buffer()
     
    6565        // This constructor doesn't create a new copy of the image data, it only
    6666        // increases the ref count of the existing bitmap.
     67        //
     68        // This exists because ImageDecoder keeps a Vector<RGBA32Buffer>, and
     69        // Vector requires this constructor.
    6770        RGBA32Buffer(const RGBA32Buffer& other)
    6871        {
     
    7073        }
    7174
    72         ~RGBA32Buffer()
    73         {
    74         }
    75 
     75        void clear()
     76        {
     77            m_bitmap.reset();
     78            m_status = FrameEmpty;
     79            // NOTE: Do not reset other members here; clearFrameBufferCache()
     80            // calls this to free the bitmap data, but other functions like
     81            // initFrameBuffer() and frameComplete() may still need to read
     82            // other metadata out of this frame later.
     83        }
     84
     85        void zeroFill()
     86        {
     87            m_bitmap.eraseARGB(0, 0, 0, 0);
     88        }
     89
     90        // This function creates a new copy of the image data in |other|, so the
     91        // two images can be modified independently.
     92        void copyBitmapData(const RGBA32Buffer& other)
     93        {
     94            if (this == &other)
     95                return;
     96
     97            m_bitmap.reset();
     98            const NativeImageSkia& otherBitmap = other.m_bitmap;
     99            otherBitmap.copyTo(&m_bitmap, otherBitmap.config());
     100        }
     101
     102        // This function copies [(startX, startY), (endX, startY)) to the same
     103        // X-coordinates on each subsequent row up to but not including endY.
     104        //
     105        // NOTE: This function does not sanity-check its arguments!  Callers
     106        // MUST not pass invalid values or this will corrupt memory.
     107        void copyRowNTimes(int startX, int endX, int startY, int endY)
     108        {
     109            ASSERT(startX < width());
     110            ASSERT(endX <= width());
     111            ASSERT(startY < height());
     112            ASSERT(endY <= height());
     113            const int rowBytes = (endX - startX) * sizeof(PixelData);
     114            const PixelData* const startAddr = getAddr(startX, startY);
     115            for (int destY = startY + 1; destY < endY; ++destY)
     116                memcpy(getAddr(startX, startY), startAddr, rowBytes);
     117        }
     118
     119        // Must be called before any pixels are written. Will return true on
     120        // success, false if the memory allocation fails.
     121        bool setSize(int width, int height)
     122        {
     123            // This function should only be called once, it will leak memory
     124            // otherwise.
     125            ASSERT(width() == 0 && height() == 0);
     126            m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
     127            if (!m_bitmap.allocPixels()) {
     128                // Allocation failure, maybe the bitmap was too big.
     129                setStatus(FrameComplete);
     130                return false;
     131            }
     132
     133            // Zero the image.
     134            zeroFill();
     135
     136            return true;
     137        }
     138
     139        // To be used by ImageSource::createFrameAtIndex().  Returns a pointer
     140        // to the underlying native image data.  This pointer will be owned by
     141        // the BitmapImage and freed in FrameData::clear().
     142        NativeImagePtr asNewNativeImage() const
     143        {
     144            return new NativeImageSkia(m_bitmap);
     145        }
     146
     147        bool hasAlpha() const { return !m_bitmap.isOpaque(); }
     148        const IntRect& rect() const { return m_rect; }
     149        FrameStatus status() const { return m_status; }
     150        unsigned duration() const { return m_duration; }
     151        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
     152
     153        void setHasAlpha(bool alpha) { m_bitmap.setIsOpaque(!alpha); }
     154        void setRect(const IntRect& r) { m_rect = r; }
     155        void setStatus(FrameStatus s)
     156        {
     157            m_status = s;
     158            if (s == FrameComplete)
     159                m_bitmap.setDataComplete();  // Tell the bitmap it's done.
     160        }
     161        void setDuration(unsigned duration) { m_duration = duration; }
     162        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
     163
     164        inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
     165        {
     166            setRGBA(getAddr(x, y), r, g, b, a);
     167        }
     168
     169    private:
    76170        // Initialize with another buffer.  This function doesn't create a new copy
    77171        // of the image data, it only increases the refcount of the existing bitmap.
     
    96190        }
    97191
    98         void clear()
    99         {
    100             m_bitmap.reset();
    101             m_status = FrameEmpty;
    102             // NOTE: Do not reset other members here; clearFrameBufferCache()
    103             // calls this to free the bitmap data, but other functions like
    104             // initFrameBuffer() and frameComplete() may still need to read
    105             // other metadata out of this frame later.
    106         }
    107 
    108         void zeroFill()
    109         {
    110             m_bitmap.eraseARGB(0, 0, 0, 0);
    111         }
    112 
    113         // This function creates a new copy of the image data in |other|, so the
    114         // two images can be modified independently.
    115         void copyBitmapData(const RGBA32Buffer& other)
    116         {
    117             if (this == &other)
    118                 return;
    119 
    120             m_bitmap.reset();
    121             const NativeImageSkia& otherBitmap = other.m_bitmap;
    122             otherBitmap.copyTo(&m_bitmap, otherBitmap.config());
    123         }
    124 
    125         // This function copies [(startX, startY), (endX, startY)) to the same
    126         // X-coordinates on each subsequent row up to but not including endY.
    127         //
    128         // NOTE: This function does not sanity-check its arguments!  Callers
    129         // MUST not pass invalid values or this will corrupt memory.
    130         void copyRowNTimes(int startX, int endX, int startY, int endY)
    131         {
    132             ASSERT(startX < m_bitmap.width());
    133             ASSERT(endX <= m_bitmap.width());
    134             ASSERT(startY < m_bitmap.height());
    135             ASSERT(endY <= m_bitmap.height());
    136             const int rowBytes = (endX - startX) * sizeof(uint32_t);
    137             const uint32_t* const startAddr = m_bitmap.getAddr32(startX, startY);
    138             for (int destY = startY + 1; destY < endY; ++destY)
    139                 memcpy(m_bitmap.getAddr32(startX, destY), startAddr, rowBytes);
    140         }
    141 
    142         // Must be called before any pixels are written. Will return true on
    143         // success, false if the memory allocation fails.
    144         bool setSize(int width, int height)
    145         {
    146             // This function should only be called once, it will leak memory
    147             // otherwise.
    148             ASSERT(m_bitmap.width() == 0 && m_bitmap.height() == 0);
    149             m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
    150             if (!m_bitmap.allocPixels()) {
    151                 // Allocation failure, maybe the bitmap was too big.
    152                 setStatus(FrameComplete);
    153                 return false;
    154             }
    155 
    156             // Zero the image.
    157             zeroFill();
    158 
    159             return true;
    160         }
    161 
    162         // To be used by ImageSource::createFrameAtIndex().  Returns a pointer
    163         // to the underlying native image data.  This pointer will be owned by
    164         // the BitmapImage and freed in FrameData::clear().
    165         NativeImagePtr asNewNativeImage()
    166         {
    167             return new NativeImageSkia(m_bitmap);
    168         }
    169 
    170         const IntRect& rect() const { return m_rect; }
    171         FrameStatus status() const { return m_status; }
    172         unsigned duration() const { return m_duration; }
    173         FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
    174         bool hasAlpha() const { return !m_bitmap.isOpaque(); }
    175 
    176         void setRect(const IntRect& r) { m_rect = r; }
    177         void setStatus(FrameStatus s)
    178         {
    179             if (s == FrameComplete)
    180                 m_bitmap.setDataComplete();  // Tell the bitmap it's done.
    181             m_status = s;
    182         }
    183         void setDuration(unsigned duration) { m_duration = duration; }
    184         void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
    185         void setHasAlpha(bool alpha) { m_bitmap.setIsOpaque(!alpha); }
    186 
    187         void setRGBA(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
    188         {
    189             uint32_t* const dest = m_bitmap.getAddr32(x, y);
    190 
     192        inline int width() const { return m_bitmap.width(); }
     193        inline int height() const { return m_bitmap.height(); }
     194
     195        inline PixelData* getAddr(int x, int y)
     196        {
     197            return m_bitmap.getAddr32(x, y);
     198        }
     199
     200        inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
     201        {
    191202            // We store this data pre-multiplied.
    192203            if (a == 0)
     
    203214        }
    204215
    205     private:
    206216        NativeImageSkia m_bitmap;
    207         IntRect m_rect;    // The rect of the original specified frame within the overall buffer.
    208                            // This will always just be the entire buffer except for GIF frames
    209                            // whose original rect was smaller than the overall image size.
     217        IntRect m_rect;       // The rect of the original specified frame within the overall buffer.
     218                              // This will always just be the entire buffer except for GIF frames
     219                              // whose original rect was smaller than the overall image size.
    210220        FrameStatus m_status; // Whether or not this frame is completely finished decoding.
    211         unsigned m_duration; // The animation delay.
    212         FrameDisposalMethod m_disposalMethod; // What to do with this frame's data when initializing the next frame.
     221        unsigned m_duration;  // The animation delay.
     222        FrameDisposalMethod m_disposalMethod;
     223                              // What to do with this frame's data when initializing the next frame.
    213224    };
    214225
  • trunk/WebCore/platform/image-decoders/skia/JPEGImageDecoder.cpp

    r44597 r44631  
    4040#include "JPEGImageDecoder.h"
    4141#include <assert.h>
     42#include <stdio.h>  // Needed by jpeglib.h for FILE.
    4243
    4344extern "C" {
Note: See TracChangeset for help on using the changeset viewer.