Changeset 44631 in webkit
- Timestamp:
- Jun 12, 2009 3:06:50 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r44630 r44631 1 2009-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 1 59 2009-06-12 Brent Fulgham <bfulgham@webkit.org> 2 60 -
trunk/WebCore/platform/graphics/cairo/ImageSourceCairo.cpp
r44539 r44631 194 194 return 0; 195 195 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(); 201 197 } 202 198 -
trunk/WebCore/platform/image-decoders/ImageDecoder.h
r44597 r44631 31 31 #include "PlatformString.h" 32 32 #include "SharedBuffer.h" 33 #include <cairo.h> 33 34 #include <wtf/Assertions.h> 34 35 #include <wtf/RefPtr.h> … … 36 37 37 38 namespace WebCore { 38 39 typedef Vector<unsigned> RGBA32Array;40 39 41 40 // The RGBA32Buffer object represents the decoded image data in RGBA32 format. This buffer is what all … … 44 43 public: 45 44 enum FrameStatus { FrameEmpty, FramePartial, FrameComplete }; 46 47 45 enum FrameDisposalMethod { 48 46 // If you change the numeric values of these, make sure you audit all … … 53 51 DisposeOverwritePrevious, // Clear frame to previous framebuffer contents 54 52 }; 53 typedef unsigned PixelData; 55 54 56 55 RGBA32Buffer() 57 : m_status(FrameEmpty) 56 : m_hasAlpha(false) 57 , m_status(FrameEmpty) 58 58 , m_duration(0) 59 59 , m_disposalMethod(DisposeNotSpecified) 60 , m_hasAlpha(false)61 60 { 62 61 } 63 62 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; 71 84 } 72 85 … … 79 92 80 93 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 } 86 113 87 114 // Must be called before any pixels are written. Will return true on … … 92 119 // requested size was too big... 93 120 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(); 98 125 99 126 return true; 100 127 } 101 128 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; } 102 141 const IntRect& rect() const { return m_rect; } 103 142 FrameStatus status() const { return m_status; } 104 143 unsigned duration() const { return m_duration; } 105 144 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } 106 bool hasAlpha() const { return m_hasAlpha; } 107 145 146 void setHasAlpha(bool alpha) { m_hasAlpha = alpha; } 108 147 void setRect(const IntRect& r) { m_rect = r; } 109 148 void setStatus(FrameStatus s) { m_status = s; } 110 149 void setDuration(unsigned duration) { m_duration = duration; } 111 150 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) 115 188 { 116 189 // We store this data pre-multiplied. 117 190 if (a == 0) 118 pos= 0;191 *dest = 0; 119 192 else { 120 193 if (a < 255) { … … 124 197 b = static_cast<unsigned>(b * alphaPercent); 125 198 } 126 pos= (a << 24 | r << 16 | g << 8 | b);199 *dest = (a << 24 | r << 16 | g << 8 | b); 127 200 } 128 201 } 129 202 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. 135 210 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. 139 214 }; 140 215 -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r44597 r44631 322 322 buffer->copyBitmapData(*prevBuffer); 323 323 for (int y = prevRect.y(); y < prevRect.bottom(); ++y) { 324 unsigned* const currentRow =325 buffer->bytes().data() + (y * size().width());326 324 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); 328 326 } 329 327 if ((prevRect.width() > 0) && (prevRect.height() > 0)) … … 342 340 343 341 void GIFImageDecoder::haveDecodedRow(unsigned frameIndex, 344 unsigned char* rowBuffer, // Pointer to single scanline temporary buffer342 unsigned char* rowBuffer, 345 343 unsigned char* rowEnd, 346 unsigned rowNumber, // The row index347 unsigned repeatCount, // How many times to repeat the row344 unsigned rowNumber, 345 unsigned repeatCount, 348 346 bool writeTransparentPixels) 349 347 { 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. 359 359 unsigned colorMapSize; 360 360 unsigned char* colorMap; … … 363 363 return; 364 364 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); 385 379 } else { 386 380 m_currentBufferSawAlpha = true; … … 393 387 // later ones. 394 388 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())); 415 396 } 416 397 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r44597 r44631 39 39 #include "JPEGImageDecoder.h" 40 40 #include <assert.h> 41 #include <stdio.h> 41 #include <stdio.h> // Needed by jpeglib.h for FILE. 42 42 43 43 extern "C" { … … 476 476 JSAMPARRAY samples = m_reader->samples(); 477 477 478 unsigned* dst = buffer.bytes().data() + info->output_scanline * size().width();479 480 478 while (info->output_scanline < info->output_height) { 481 479 /* Request one scanline. Returns 0 or 1 scanlines. */ … … 487 485 unsigned g = *j1++; 488 486 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); 490 490 } 491 491 } -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r44597 r44631 381 381 // Copy the data into our buffer. 382 382 int width = size().width(); 383 unsigned* dst = buffer.bytes().data() + rowIndex * width;384 383 bool sawAlpha = false; 385 384 for (int x = 0; x < width; x++) { … … 388 387 unsigned blue = *row++; 389 388 unsigned alpha = (hasAlpha ? *row++ : 255); 390 RGBA32Buffer::setRGBA(*dst++, red, green, blue, alpha);389 buffer.setRGBA(x, rowIndex, red, green, blue, alpha); 391 390 if (!sawAlpha && alpha < 255) { 392 391 sawAlpha = true; -
trunk/WebCore/platform/image-decoders/skia/ImageDecoder.h
r44597 r44631 46 46 public: 47 47 enum FrameStatus { FrameEmpty, FramePartial, FrameComplete }; 48 49 48 enum FrameDisposalMethod { 50 49 // If you change the numeric values of these, make sure you audit all … … 55 54 DisposeOverwritePrevious, // Clear frame to previous framebuffer contents 56 55 }; 56 typedef uint32_t PixelData; 57 57 58 58 RGBA32Buffer() … … 65 65 // This constructor doesn't create a new copy of the image data, it only 66 66 // increases the ref count of the existing bitmap. 67 // 68 // This exists because ImageDecoder keeps a Vector<RGBA32Buffer>, and 69 // Vector requires this constructor. 67 70 RGBA32Buffer(const RGBA32Buffer& other) 68 71 { … … 70 73 } 71 74 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: 76 170 // Initialize with another buffer. This function doesn't create a new copy 77 171 // of the image data, it only increases the refcount of the existing bitmap. … … 96 190 } 97 191 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 { 191 202 // We store this data pre-multiplied. 192 203 if (a == 0) … … 203 214 } 204 215 205 private:206 216 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 frames209 // 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. 210 220 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. 213 224 }; 214 225 -
trunk/WebCore/platform/image-decoders/skia/JPEGImageDecoder.cpp
r44597 r44631 40 40 #include "JPEGImageDecoder.h" 41 41 #include <assert.h> 42 #include <stdio.h> // Needed by jpeglib.h for FILE. 42 43 43 44 extern "C" {
Note: See TracChangeset
for help on using the changeset viewer.