Changeset 53309 in webkit
- Timestamp:
- Jan 14, 2010 5:45:23 PM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r53308 r53309 1 2010-01-14 Peter Kasting <pkasting@google.com> 2 3 Reviewed by Adam Barth. 4 5 Simplify image decoders by making downsampling functions available at 6 all times, allowing much duplicated logic to be collapsed. 7 https://bugs.webkit.org/show_bug.cgi?id=28751 8 9 * platform/graphics/ImageSource.cpp: 10 (WebCore::ImageSource::setData): 11 * platform/image-decoders/ImageDecoder.cpp: 12 (WebCore::ImageDecoder::prepareScaleDataIfNecessary): 13 * platform/image-decoders/ImageDecoder.h: 14 (WebCore::ImageDecoder::ImageDecoder): 15 (WebCore::ImageDecoder::scaledSize): 16 (WebCore::ImageDecoder::setMaxNumPixels): 17 * platform/image-decoders/gif/GIFImageDecoder.cpp: 18 (WebCore::GIFImageDecoder::sizeNowAvailable): 19 (WebCore::GIFImageDecoder::initFrameBuffer): 20 (WebCore::GIFImageDecoder::haveDecodedRow): 21 (WebCore::GIFImageDecoder::frameComplete): 22 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: 23 (WebCore::JPEGImageDecoder::setSize): 24 (WebCore::JPEGImageDecoder::outputScanlines): 25 * platform/image-decoders/jpeg/JPEGImageDecoder.h: 26 * platform/image-decoders/png/PNGImageDecoder.cpp: 27 (WebCore::PNGImageDecoder::headerAvailable): 28 (WebCore::PNGImageDecoder::rowAvailable): 29 1 30 2010-01-14 Jian Li <jianli@chromium.org> 2 31 -
trunk/WebCore/platform/graphics/ImageSource.cpp
r52102 r53309 34 34 #else 35 35 #include "ImageDecoder.h" 36 #endif37 38 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)39 #ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS40 #define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024)41 #endif42 36 #endif 43 37 … … 82 76 m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data)); 83 77 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 78 #ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS 79 #define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024) 80 #endif 84 81 if (m_decoder) 85 82 m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS); -
trunk/WebCore/platform/image-decoders/ImageDecoder.cpp
r53152 r53309 24 24 #include "ImageDecoder.h" 25 25 26 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)27 26 #include <algorithm> 28 # endif27 #include <cmath> 29 28 30 29 #include "BMPImageDecoder.h" … … 185 184 #endif 186 185 187 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)188 189 186 namespace { 190 187 … … 211 208 template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, int valueToMatch, int searchStart) 212 209 { 210 if (scaledValues.isEmpty()) 211 return valueToMatch; 212 213 213 const int* dataStart = scaledValues.data(); 214 214 const int* dataEnd = dataStart + scaledValues.size(); … … 229 229 void ImageDecoder::prepareScaleDataIfNecessary() 230 230 { 231 int width = m_size.width();232 int height = m_size.height();231 int width = size().width(); 232 int height = size().height(); 233 233 int numPixels = height * width; 234 if (m_maxNumPixels <= 0 || numPixels <= m_maxNumPixels) { 234 if (m_maxNumPixels > 0 && numPixels > m_maxNumPixels) { 235 m_scaled = true; 236 double scale = sqrt(m_maxNumPixels / (double)numPixels); 237 fillScaledValues(m_scaledColumns, scale, width); 238 fillScaledValues(m_scaledRows, scale, height); 239 } else if (m_scaled) { 235 240 m_scaled = false; 236 return; 237 } 238 239 m_scaled = true; 240 double scale = sqrt(m_maxNumPixels / (double)numPixels); 241 fillScaledValues(m_scaledColumns, scale, width); 242 fillScaledValues(m_scaledRows, scale, height); 241 m_scaledColumns.clear(); 242 m_scaledRows.clear(); 243 } 243 244 } 244 245 … … 268 269 } 269 270 270 #endif // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 271 272 } 271 } -
trunk/WebCore/platform/image-decoders/ImageDecoder.h
r53148 r53309 131 131 } 132 132 133 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)134 const IntRect& scaledRect() const { return m_scaledRect; }135 void setScaledRect(const IntRect& r) { m_scaledRect = r; }136 #endif137 138 133 #if PLATFORM(QT) 139 134 void setDecodedImage(const QImage& image); … … 193 188 FrameDisposalMethod m_disposalMethod; 194 189 // What to do with this frame's data when initializing the next frame. 195 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)196 IntRect m_scaledRect;197 #endif198 190 }; 199 191 … … 208 200 // images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet) 209 201 ImageDecoder() 210 : m_failed(false) 202 : m_scaled(false) 203 , m_failed(false) 211 204 , m_sizeAvailable(false) 212 205 , m_isAllDataReceived(false) 213 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)214 206 , m_maxNumPixels(-1) 215 , m_scaled(false)216 #endif217 207 { 218 208 } … … 251 241 ASSERT(!m_failed); 252 242 return m_size; 243 } 244 245 IntSize scaledSize() const 246 { 247 return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size(); 253 248 } 254 249 … … 308 303 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 309 304 void setMaxNumPixels(int m) { m_maxNumPixels = m; } 310 IntSize scaledSize() const { return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : m_size; }311 305 #endif 312 306 313 307 protected: 314 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)315 308 void prepareScaleDataIfNecessary(); 316 309 int upperBoundScaledX(int origX, int searchStart = 0); … … 319 312 int lowerBoundScaledY(int origY, int searchStart = 0); 320 313 int scaledY(int origY, int searchStart = 0); 321 #endif322 314 323 315 RefPtr<SharedBuffer> m_data; // The encoded data. 324 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)325 int m_maxNumPixels;326 316 Vector<int> m_scaledColumns; 327 317 Vector<int> m_scaledRows; 328 318 bool m_scaled; 329 #endif330 319 Vector<RGBA32Buffer> m_frameBufferCache; 331 320 bool m_failed; … … 346 335 bool m_sizeAvailable; 347 336 bool m_isAllDataReceived; 337 int m_maxNumPixels; 348 338 }; 349 339 -
trunk/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
r53148 r53309 249 249 if (!setSize(width, height)) 250 250 return false; 251 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)252 251 prepareScaleDataIfNecessary(); 253 #endif254 252 return true; 255 253 } … … 273 271 274 272 RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex]; 275 buffer->setRect(frameRect); 276 277 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 278 if (m_scaled) { 279 int left = upperBoundScaledX(frameRect.x()); 280 int right = lowerBoundScaledX(frameRect.right(), left); 281 int top = upperBoundScaledY(frameRect.y()); 282 int bottom = lowerBoundScaledY(frameRect.bottom(), top); 283 buffer->setScaledRect(IntRect(left, top, right - left, bottom - top)); 284 } else 285 buffer->setScaledRect(frameRect); 286 #endif 287 273 int left = upperBoundScaledX(frameRect.x()); 274 int right = lowerBoundScaledX(frameRect.right(), left); 275 int top = upperBoundScaledY(frameRect.y()); 276 int bottom = lowerBoundScaledY(frameRect.bottom(), top); 277 buffer->setRect(IntRect(left, top, right - left, bottom - top)); 278 288 279 if (frameIndex == 0) { 289 280 // This is the first frame, so we're not relying on any previous data. 290 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 291 const IntSize& bufferSize = scaledSize(); 292 #else 293 const IntSize& bufferSize = size(); 294 #endif 295 if (!buffer->setSize(bufferSize.width(), bufferSize.height())) { 281 if (!buffer->setSize(scaledSize().width(), scaledSize().height())) { 296 282 m_failed = true; 297 283 return false; … … 323 309 // We want to clear the previous frame to transparent, without 324 310 // affecting pixels in the image outside of the frame. 325 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 326 const IntRect& prevRect = prevBuffer->scaledRect(); 311 const IntRect& prevRect = prevBuffer->rect(); 327 312 const IntSize& bufferSize = scaledSize(); 328 #else329 const IntRect& prevRect = prevBuffer->rect();330 const IntSize& bufferSize = size();331 #endif332 313 if ((frameIndex == 0) 333 314 || prevRect.contains(IntRect(IntPoint(), bufferSize))) { … … 359 340 } 360 341 361 static inline void copyOnePixel(const GIFImageDecoderPrivate* reader, const unsigned char* sourceAddr, unsigned char* colorMap,362 unsigned colorMapSize, bool writeTransparentPixels, RGBA32Buffer& buffer, int x, int y, bool& sawAlpha)363 {364 const unsigned char sourceValue = *sourceAddr;365 if ((!reader->isTransparent() || (sourceValue != reader->transparentPixel())) && (sourceValue < colorMapSize)) {366 const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;367 buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);368 } else {369 sawAlpha = true;370 // We may or may not need to write transparent pixels to the buffer.371 // If we're compositing against a previous image, it's wrong, and if372 // we're writing atop a cleared, fully transparent buffer, it's373 // unnecessary; but if we're decoding an interlaced gif and374 // displaying it "Haeberli"-style, we must write these for passes375 // beyond the first, or the initial passes will "show through" the376 // later ones.377 if (writeTransparentPixels)378 buffer.setRGBA(x, y, 0, 0, 0, 0);379 }380 }381 382 342 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, 383 343 unsigned char* rowBuffer, … … 389 349 // The pixel data and coordinates supplied to us are relative to the frame's 390 350 // origin within the entire image size, i.e. 391 // (m_reader->frameXOffset(), m_reader->frameYOffset()). 392 int x = m_reader->frameXOffset(); 393 int y = m_reader->frameYOffset() + rowNumber; 394 395 // Sanity-check the arguments. 396 if ((rowBuffer == 0) || (y >= size().height())) 351 // (m_reader->frameXOffset(), m_reader->frameYOffset()). There is no 352 // guarantee that 353 // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so 354 // we must ensure we don't run off the end of either the source data or the 355 // row's X-coordinates. 356 int xBegin = upperBoundScaledX(m_reader->frameXOffset()); 357 int yBegin = upperBoundScaledY(m_reader->frameYOffset() + rowNumber); 358 int xEnd = lowerBoundScaledX(std::min(xBegin + (rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1; 359 int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1; 360 if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin)) 397 361 return true; 398 362 … … 409 373 return false; 410 374 411 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 412 int destYBegin = y; 413 int destYEnd = std::min(y + static_cast<int>(repeatCount), size().height()); 414 int destXBegin = x; 415 int destXEnd = std::min(x + (rowEnd - rowBuffer), size().width()); 416 417 if (m_scaled) { 418 destYBegin = upperBoundScaledY(destYBegin); 419 if (destYBegin < 0) 420 return true; 421 destYEnd = lowerBoundScaledY(destYEnd - 1, destYBegin + 1); 422 if (destYEnd < destYBegin) 423 return true; 424 425 destXBegin = upperBoundScaledX(destXBegin); 426 if (destXBegin < 0) 427 return true; 428 destXEnd = lowerBoundScaledX(destXEnd - 1, destXBegin + 1); 429 if (destXEnd < destXBegin) 430 return true; 431 432 ++destXEnd; 433 ++destYEnd; 434 x = destXBegin; 435 y = destYBegin; 436 } 437 #endif 438 439 // Write one row's worth of data into the frame. There is no guarantee that 440 // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so 441 // we must ensure we don't run off the end of either the source data or the 442 // row's X-coordinates. 443 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 444 if (m_scaled) { 445 for (; x < destXEnd; ++x) { 446 unsigned char* sourceAddr = rowBuffer + m_scaledColumns[x] - m_reader->frameXOffset(); 447 copyOnePixel(m_reader, sourceAddr, colorMap, colorMapSize, writeTransparentPixels, buffer, x, y, m_currentBufferSawAlpha); 448 } 449 } else 450 #endif 451 for (unsigned char* sourceAddr = rowBuffer; sourceAddr < rowEnd && x < size().width(); ++sourceAddr, ++x) 452 copyOnePixel(m_reader, sourceAddr, colorMap, colorMapSize, writeTransparentPixels, buffer, x, y, m_currentBufferSawAlpha); 453 454 // Tell the frame to copy the row data if need be. 455 if (repeatCount > 1) { 456 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 457 buffer.copyRowNTimes(destXBegin, destXEnd, destYBegin, destYEnd); 458 #else 459 buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height())); 460 #endif 461 } 375 // Write one row's worth of data into the frame. 376 for (int x = xBegin; x < xEnd; ++x) { 377 const unsigned char sourceValue = *(rowBuffer + (m_scaled ? m_scaledColumns[x] : x) - m_reader->frameXOffset()); 378 if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) { 379 const size_t colorIndex = static_cast<size_t>(sourceValue) * 3; 380 buffer.setRGBA(x, yBegin, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255); 381 } else { 382 m_currentBufferSawAlpha = true; 383 // We may or may not need to write transparent pixels to the buffer. 384 // If we're compositing against a previous image, it's wrong, and if 385 // we're writing atop a cleared, fully transparent buffer, it's 386 // unnecessary; but if we're decoding an interlaced gif and 387 // displaying it "Haeberli"-style, we must write these for passes 388 // beyond the first, or the initial passes will "show through" the 389 // later ones. 390 if (writeTransparentPixels) 391 buffer.setRGBA(x, yBegin, 0, 0, 0, 0); 392 } 393 } 394 395 // Tell the frame to copy the row data if need be. 396 if (repeatCount > 1) 397 buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd); 462 398 463 399 return true; … … 479 415 // The whole frame was non-transparent, so it's possible that the entire 480 416 // resulting buffer was non-transparent, and we can setHasAlpha(false). 481 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 482 if (buffer.scaledRect().contains(IntRect(IntPoint(), scaledSize()))) 483 #else 484 if (buffer.rect().contains(IntRect(IntPoint(), size()))) 485 #endif 417 if (buffer.rect().contains(IntRect(IntPoint(), scaledSize()))) 486 418 buffer.setHasAlpha(false); 487 419 else if (frameIndex > 0) { … … 508 440 // rect, we know the current frame has no alpha. 509 441 if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor) 510 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)511 && !prevBuffer->hasAlpha() && buffer.scaledRect().contains(prevBuffer->scaledRect()))512 #else513 442 && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect())) 514 #endif515 443 buffer.setHasAlpha(false); 516 444 } -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r53305 r53309 432 432 } 433 433 434 bool JPEGImageDecoder::setSize(unsigned width, unsigned height) 435 { 436 if (!ImageDecoder::setSize(width, height)) 437 return false; 438 prepareScaleDataIfNecessary(); 439 return true; 440 } 441 434 442 RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index) 435 443 { … … 461 469 } 462 470 463 static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth464 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)465 , bool scaled, const Vector<int>& scaledColumns466 #endif467 )468 {469 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)470 if (scaled) {471 int numColumns = scaledColumns.size();472 for (int x = 0; x < numColumns; ++x) {473 JSAMPLE* jsample = src + scaledColumns[x] * 4;474 unsigned c = jsample[0];475 unsigned m = jsample[1];476 unsigned y = jsample[2];477 unsigned k = jsample[3];478 dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);479 }480 return;481 }482 #endif483 for (JDIMENSION x = 0; x < srcWidth; ++x) {484 unsigned c = *src++;485 unsigned m = *src++;486 unsigned y = *src++;487 unsigned k = *src++;488 489 // Source is 'Inverted CMYK', output is RGB.490 // See: http://www.easyrgb.com/math.php?MATH=M12#text12491 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb492 493 // From CMYK to CMY494 // C = C * ( 1 - K ) + K495 // M = M * ( 1 - K ) + K496 // Y = Y * ( 1 - K ) + K497 498 // From Inverted CMYK to CMY is thus:499 // C = (1-iC) * (1 - (1-iK)) + (1-iK) => 1 - iC*iK500 // Same for M and Y501 502 // Convert from CMY (0..1) to RGB (0..1)503 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK504 // G = 1 - M => 1 - (1 - iM*iK) => iM*iK505 // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK506 507 dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);508 }509 }510 511 static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth512 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)513 , bool scaled, const Vector<int>& scaledColumns514 #endif515 )516 {517 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)518 if (scaled) {519 int numColumns = scaledColumns.size();520 for (int x = 0; x < numColumns; ++x) {521 JSAMPLE* jsample = src + scaledColumns[x] * 3;522 dest.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);523 }524 return;525 }526 #endif527 for (JDIMENSION x = 0; x < srcWidth; ++x) {528 unsigned r = *src++;529 unsigned g = *src++;530 unsigned b = *src++;531 dest.setRGBA(x, destY, r, g, b, 0xFF);532 }533 }534 535 471 bool JPEGImageDecoder::outputScanlines() 536 472 { … … 541 477 RGBA32Buffer& buffer = m_frameBufferCache[0]; 542 478 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 543 int bufferWidth = size().width(); 544 int bufferHeight = size().height(); 545 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 546 // Let's resize our buffer now to the correct width/height. 547 if (m_scaled) { 548 bufferWidth = m_scaledColumns.size(); 549 bufferHeight = m_scaledRows.size(); 550 } 551 #endif 552 553 if (!buffer.setSize(bufferWidth, bufferHeight)) { 479 if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { 554 480 m_failed = true; 555 481 return false; … … 573 499 return false; 574 500 575 int destY = sourceY; 576 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 577 if (m_scaled) { 578 destY = scaledY(sourceY); 579 if (destY < 0) 580 continue; 501 int destY = scaledY(sourceY); 502 if (destY < 0) 503 continue; 504 int width = m_scaled ? m_scaledColumns.size() : info->output_width; 505 for (int x = 0; x < width; ++x) { 506 JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4); 507 if (info->out_color_space == JCS_RGB) 508 buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); 509 else if (info->out_color_space == JCS_CMYK) { 510 // Source is 'Inverted CMYK', output is RGB. 511 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 512 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb 513 // From CMYK to CMY: 514 // X = X * (1 - K ) + K [for X = C, M, or Y] 515 // Thus, from Inverted CMYK to CMY is: 516 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK 517 // From CMY (0..1) to RGB (0..1): 518 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] 519 unsigned k = jsample[3]; 520 buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF); 521 } else { 522 ASSERT_NOT_REACHED(); 523 m_failed = true; 524 return false; 525 } 581 526 } 582 if (info->out_color_space == JCS_RGB)583 convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);584 else if (info->out_color_space == JCS_CMYK)585 convertCMYKToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);586 else587 return false;588 #else589 if (info->out_color_space == JCS_RGB)590 convertRGBToRGBA(buffer, destY, *samples, info->output_width);591 else if (info->out_color_space == JCS_CMYK)592 convertCMYKToRGBA(buffer, destY, *samples, info->output_width);593 else594 return false;595 #endif596 527 } 597 528 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r47381 r53309 48 48 virtual bool isSizeAvailable(); 49 49 50 virtual bool setSize(unsigned width, unsigned height); 51 50 52 virtual RGBA32Buffer* frameBufferAtIndex(size_t index); 51 53 … … 59 61 void jpegComplete(); 60 62 61 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)62 bool setSize(int width, int height)63 {64 if (!ImageDecoder::setSize(width, height))65 return false;66 prepareScaleDataIfNecessary();67 return true;68 }69 #endif70 71 63 private: 72 64 JPEGImageReader* m_reader; -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r53305 r53309 257 257 return; 258 258 } 259 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)260 259 prepareScaleDataIfNecessary(); 261 #endif262 260 } 263 261 … … 331 329 RGBA32Buffer& buffer = m_frameBufferCache[0]; 332 330 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 333 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 334 int width = m_scaled ? m_scaledColumns.size() : size().width(); 335 int height = m_scaled ? m_scaledRows.size() : size().height(); 336 #else 337 int width = size().width(); 338 int height = size().height(); 339 #endif 340 if (!buffer.setSize(width, height)) { 331 if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { 341 332 static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed(); 342 333 longjmp(reader()->pngPtr()->jmpbuf, 1); … … 397 388 398 389 // Copy the data into our buffer. 399 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 400 if (m_scaled) { 401 int destY = scaledY(rowIndex); 402 if (destY < 0) 403 return; 404 int columns = m_scaledColumns.size(); 405 bool sawAlpha = buffer.hasAlpha(); 406 for (int x = 0; x < columns; ++x) { 407 png_bytep pixel = row + m_scaledColumns[x] * colorChannels; 408 unsigned alpha = (hasAlpha ? pixel[3] : 255); 409 buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha); 410 if (!sawAlpha && alpha < 255) { 411 sawAlpha = true; 412 buffer.setHasAlpha(true); 413 } 414 } 415 return; 416 } 417 #endif 418 int width = size().width(); 390 int width = scaledSize().width(); 391 int destY = scaledY(rowIndex); 392 if (destY < 0) 393 return; 419 394 bool sawAlpha = buffer.hasAlpha(); 420 395 for (int x = 0; x < width; x++) { 421 unsigned red = *row++; 422 unsigned green = *row++; 423 unsigned blue = *row++; 424 unsigned alpha = (hasAlpha ? *row++ : 255); 425 buffer.setRGBA(x, rowIndex, red, green, blue, alpha); 396 png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels; 397 unsigned alpha = hasAlpha ? pixel[3] : 255; 398 buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha); 426 399 if (!sawAlpha && alpha < 255) { 427 400 sawAlpha = true;
Note: See TracChangeset
for help on using the changeset viewer.