Changeset 44573 in webkit
- Timestamp:
- Jun 10, 2009 10:46:51 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r44571 r44573 1 2009-06-10 Peter Kasting <pkasting@google.com> 2 3 Reviewed by Eric Seidel. 4 5 https://bugs.webkit.org/show_bug.cgi?id=25709 part five 6 Rewrite users of ImageDecoder.h to use "safe" API calls, Skia side. 7 This tweaks the RGBA32Buffer interfaces to be implementable by Cairo as 8 well and modifies Skia's usage of those interfaces accordingly. Once a 9 similar change lands on the Cairo side, the Skia and Cairo decoders 10 should be identical except for the implementation of RGBA32Buffer. 11 12 * platform/graphics/skia/ImageSourceSkia.cpp: 13 (WebCore::ImageSource::createFrameAtIndex): Use new RGBA32Buffer::asNewNativeImage() function. 14 * platform/image-decoders/skia/BMPImageReader.cpp: 15 (WebCore::BMPImageReader::processNonRLEData): Use new RGBA32Buffer::zeroFill() function. 16 * platform/image-decoders/skia/GIFImageDecoder.cpp: 17 (WebCore::GIFImageDecoder::haveDecodedRow): Rewrite to use RGBA32Buffer::setRGBA(x, y, ...) calls as well as other RGBA32Buffer interface calls instead of knowing the underlying types inside the buffer; also try and add clarity. 18 * platform/image-decoders/skia/ImageDecoder.h: Removed bitmap(), width(), and height(). 19 (WebCore::RGBA32Buffer::zeroFill): Added. 20 (WebCore::RGBA32Buffer::copyBitmapData): Avoid using bitmap(), which is going away. 21 (WebCore::RGBA32Buffer::copyRowNTimes): Added. 22 (WebCore::RGBA32Buffer::setSize): Use new zeroFill() function. 23 (WebCore::RGBA32Buffer::asNewNativeImage): Added. 24 (WebCore::RGBA32Buffer::setRGBA): Condensed two versions into one that takes coordinates instead of a raw pointer. 25 1 26 2009-06-10 Xan Lopez <xlopez@igalia.com> 2 27 -
trunk/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
r40410 r44573 186 186 187 187 // Copy the bitmap. The pixel data is refcounted internally by SkBitmap, so 188 // this doesn't cost much. This pointer will be owned by the BitmapImage 189 // and freed in FrameData::clear(). 190 return new NativeImageSkia(buffer->bitmap()); 188 // this doesn't cost much. 189 return buffer->asNewNativeImage(); 191 190 } 192 191 -
trunk/WebCore/platform/image-decoders/skia/BMPImageReader.cpp
r40173 r44573 804 804 m_seenNonZeroAlphaPixel = true; 805 805 if (m_seenZeroAlphaPixel) { 806 // The eraseARGB() call here also sets "hasAlpha" true. 807 m_frameBufferCache.first().bitmap().eraseARGB(0, 0, 0, 808 0); 806 m_frameBufferCache.first().zeroFill(); 809 807 m_seenZeroAlphaPixel = false; 810 808 } else if (alpha != 255) -
trunk/WebCore/platform/image-decoders/skia/GIFImageDecoder.cpp
r44545 r44573 341 341 342 342 void GIFImageDecoder::haveDecodedRow(unsigned frameIndex, 343 unsigned char* rowBuffer, // Pointer to single scanline temporary buffer343 unsigned char* rowBuffer, 344 344 unsigned char* rowEnd, 345 unsigned rowNumber, // The row index346 unsigned repeatCount, // How many times to repeat the row345 unsigned rowNumber, 346 unsigned repeatCount, 347 347 bool writeTransparentPixels) 348 348 { 349 // Initialize the frame if necessary. 350 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; 351 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) 352 return; 353 354 // Do nothing for bogus data. 355 if (rowBuffer == 0 || static_cast<int>(m_reader->frameYOffset() + rowNumber) >= size().height()) 356 return; 357 349 // The pixel data and coordinates supplied to us are relative to the frame's 350 // origin within the entire image size, i.e. 351 // (m_reader->frameXOffset(), m_reader->frameYOffset()). 352 int x = m_reader->frameXOffset(); 353 const int y = m_reader->frameYOffset() + rowNumber; 354 355 // Sanity-check the arguments. 356 if ((rowBuffer == 0) || (y >= size().height())) 357 return; 358 359 // Get the colormap. 358 360 unsigned colorMapSize; 359 361 unsigned char* colorMap; … … 362 364 return; 363 365 364 // The buffers that we draw are the entire image's width and height, so a final output frame is 365 // width * height RGBA32 values in size. 366 // 367 // A single GIF frame, however, can be smaller than the entire image, i.e., it can represent some sub-rectangle 368 // within the overall image. The rows we are decoding are within this 369 // sub-rectangle. This means that if the GIF frame's sub-rectangle is (x,y,w,h) then row 0 is really row 370 // y, and each row goes from x to x+w. 371 unsigned dstPos = (m_reader->frameYOffset() + rowNumber) * size().width() + m_reader->frameXOffset(); 372 unsigned* dst = buffer.bitmap().getAddr32(0, 0) + dstPos; 373 unsigned* dstEnd = dst + size().width() - m_reader->frameXOffset(); 374 unsigned* currDst = dst; 375 unsigned char* currentRowByte = rowBuffer; 376 377 while (currentRowByte != rowEnd && currDst < dstEnd) { 378 if ((!m_reader->isTransparent() || *currentRowByte != m_reader->transparentPixel()) && *currentRowByte < colorMapSize) { 379 unsigned colorIndex = *currentRowByte * 3; 380 unsigned red = colorMap[colorIndex]; 381 unsigned green = colorMap[colorIndex + 1]; 382 unsigned blue = colorMap[colorIndex + 2]; 383 RGBA32Buffer::setRGBA(currDst, red, green, blue, 255); 366 // Initialize the frame if necessary. 367 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; 368 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) 369 return; 370 371 // Write one row's worth of data into the frame. There is no guarantee that 372 // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so 373 // we must ensure we don't run off the end of either the source data or the 374 // row's X-coordinates. 375 for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < size().width()); ++sourceAddr, ++x) { 376 const unsigned char sourceValue = *sourceAddr; 377 if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) { 378 const size_t colorIndex = static_cast<size_t>(sourceValue) * 3; 379 buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255); 384 380 } else { 385 381 m_currentBufferSawAlpha = true; … … 392 388 // later ones. 393 389 if (writeTransparentPixels) 394 RGBA32Buffer::setRGBA(currDst, 0, 0, 0, 0); 395 } 396 currDst++; 397 currentRowByte++; 398 } 399 400 if (repeatCount > 1) { 401 // Copy the row |repeatCount|-1 times. 402 unsigned num = currDst - dst; 403 unsigned dataSize = num * sizeof(unsigned); 404 unsigned width = size().width(); 405 unsigned* end = buffer.bitmap().getAddr32(0, 0) + width * size().height(); 406 currDst = dst + width; 407 for (unsigned i = 1; i < repeatCount; i++) { 408 if (currDst + num > end) // Protect against a buffer overrun from a bogus repeatCount. 409 break; 410 memcpy(currDst, dst, dataSize); 411 currDst += width; 412 } 413 } 390 buffer.setRGBA(x, y, 0, 0, 0, 0); 391 } 392 } 393 394 // Tell the frame to copy the row data if need be. 395 if (repeatCount > 1) 396 buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height())); 414 397 } 415 398 -
trunk/WebCore/platform/image-decoders/skia/ImageDecoder.h
r44545 r44573 106 106 } 107 107 108 void zeroFill() 109 { 110 m_bitmap.eraseARGB(0, 0, 0, 0); 111 } 112 108 113 // This function creates a new copy of the image data in |other|, so the 109 114 // two images can be modified independently. … … 114 119 115 120 m_bitmap.reset(); 116 const NativeImageSkia& otherBitmap = other. bitmap();121 const NativeImageSkia& otherBitmap = other.m_bitmap; 117 122 otherBitmap.copyTo(&m_bitmap, otherBitmap.config()); 118 123 } 119 124 120 NativeImageSkia& bitmap() { return m_bitmap; } 121 const NativeImageSkia& bitmap() const { return m_bitmap; } 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 } 122 141 123 142 // Must be called before any pixels are written. Will return true on … … 135 154 } 136 155 137 // Clearthe image.138 m_bitmap.eraseARGB(0, 0, 0, 0);156 // Zero the image. 157 zeroFill(); 139 158 140 159 return true; 141 160 } 142 161 143 int width() const { return m_bitmap.width(); } 144 int height() const { return m_bitmap.height(); } 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 } 145 169 146 170 const IntRect& rect() const { return m_rect; } … … 161 185 void setHasAlpha(bool alpha) { m_bitmap.setIsOpaque(!alpha); } 162 186 163 static void setRGBA(uint32_t* dest, uint8_t r, uint8_t g, uint8_t b, uint8_t a) 164 { 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 165 191 // We store this data pre-multiplied. 166 192 if (a == 0) … … 177 203 } 178 204 179 void setRGBA(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a)180 {181 setRGBA(m_bitmap.getAddr32(x, y), r, g, b, a);182 }183 184 205 private: 185 206 NativeImageSkia m_bitmap;
Note: See TracChangeset
for help on using the changeset viewer.