Changeset 47371 in webkit
- Timestamp:
- Aug 17, 2009 11:37:21 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r47370 r47371 1 2009-08-17 Yong Li <yong.li@torchmobile.com> 2 3 Reviewed by Adam Treat. 4 5 Allow image decoders to down-sample the image directly 6 to scaled output buffer. This can be enabled/disabled by 7 macro ENABLE(IMAGE_DECODER_DOWN_SAMPLING). 8 Only JPEG and PNG decoders are modified to support it now. 9 https://bugs.webkit.org/show_bug.cgi?id=28308 10 11 * platform/graphics/ImageSource.cpp: 12 (WebCore::ImageSource::setData): 13 * platform/image-decoders/ImageDecoder.cpp: Added. 14 * platform/image-decoders/ImageDecoder.h: 15 (WebCore::ImageDecoder::ImageDecoder): 16 (WebCore::ImageDecoder::setMaxNumPixels): 17 * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: 18 (WebCore::convertCMYKToRGBA): 19 (WebCore::convertRGBToRGBA): 20 (WebCore::JPEGImageDecoder::outputScanlines): 21 * platform/image-decoders/jpeg/JPEGImageDecoder.h: 22 (WebCore::JPEGImageDecoder::setSize): 23 * platform/image-decoders/png/PNGImageDecoder.cpp: 24 (WebCore::PNGImageDecoder::headerAvailable): 25 (WebCore::PNGImageDecoder::rowAvailable): 26 1 27 2009-08-17 Simon Fraser <simon.fraser@apple.com> 2 28 -
trunk/WebCore/platform/graphics/ImageSource.cpp
r47081 r47371 3 3 * Copyright (C) 2007 Alp Toker <alp.toker@collabora.co.uk> 4 4 * Copyright (C) 2008, Google Inc. All rights reserved. 5 * Copyright (C) 2007-2009 Torch Mobile, Inc 5 6 * 6 7 * Redistribution and use in source and binary forms, with or without … … 34 35 #include "JPEGImageDecoder.h" 35 36 #include "PNGImageDecoder.h" 37 #include "SharedBuffer.h" 36 38 #include "XBMImageDecoder.h" 37 #include "SharedBuffer.h" 39 40 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 41 #ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS 42 #define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024) 43 #endif 44 #endif 38 45 39 46 namespace WebCore { … … 119 126 // If insufficient bytes are available to determine the image type, no decoder plugin will be 120 127 // made. 121 if (!m_decoder) 128 if (!m_decoder) { 122 129 m_decoder = createDecoder(data->buffer()); 130 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 131 if (m_decoder) 132 m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS); 133 #endif 134 } 123 135 124 136 if (m_decoder) -
trunk/WebCore/platform/image-decoders/ImageDecoder.h
r47144 r47371 1 1 /* 2 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2008-2009 Torch Mobile, Inc. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 183 184 class ImageDecoder { 184 185 public: 186 // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to write directly to 187 // scaled output buffers by down sampling. Call setMaxNumPixels() to specify the 188 // biggest size that decoded images can have. Image decoders will deflate those 189 // images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet) 185 190 ImageDecoder() 186 191 : m_failed(false) 187 192 , m_sizeAvailable(false) 193 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 194 , m_maxNumPixels(-1) 195 , m_scaled(false) 196 #endif 188 197 { 189 198 } … … 267 276 virtual void clearFrameBufferCache(size_t clearBeforeFrame) { } 268 277 278 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 279 void setMaxNumPixels(int m) { m_maxNumPixels = m; } 280 #endif 281 269 282 protected: 283 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 284 void prepareScaleDataIfNecessary(); 285 int upperBoundScaledX(int origX, int searchStart = 0); 286 int lowerBoundScaledX(int origX, int searchStart = 0); 287 int scaledY(int origY, int searchStart = 0); 288 #endif 289 270 290 RefPtr<SharedBuffer> m_data; // The encoded data. 291 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 292 int m_maxNumPixels; 293 Vector<int> m_scaledColumns; 294 Vector<int> m_scaledRows; 295 bool m_scaled; 296 #endif 271 297 Vector<RGBA32Buffer> m_frameBufferCache; 272 298 bool m_failed; -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
r46931 r47371 462 462 } 463 463 464 static void convertCMYKToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info) 465 { 466 ASSERT(info->out_color_space == JCS_CMYK); 467 468 for (unsigned x = 0; x < info->output_width; ++x) { 464 static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, int srcWidth 465 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 466 , bool scaled, const Vector<int>& scaledColumns 467 #endif 468 ) 469 { 470 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 471 if (scaled) { 472 int numColumns = scaledColumns.size(); 473 for (int x = 0; x < numColumns; ++x) { 474 JSAMPLE* jsample = src + scaledColumns[x] * 3; 475 unsigned c = jsample[0]; 476 unsigned m = jsample[1]; 477 unsigned y = jsample[2]; 478 unsigned k = jsample[3]; 479 dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF); 480 } 481 return; 482 } 483 #endif 484 for (unsigned x = 0; x < srcWidth; ++x) { 469 485 unsigned c = *src++; 470 486 unsigned m = *src++; … … 490 506 // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK 491 507 492 // read_scanlines has increased the scanline counter, so we 493 // actually mean the previous one. 494 dest.setRGBA(x, info->output_scanline - 1, c * k / 255, m * k / 255, y * k / 255, 0xFF); 495 } 496 } 497 498 static void convertRGBToRGBA(RGBA32Buffer& dest, JSAMPROW src, jpeg_decompress_struct* info) 499 { 500 ASSERT(info->out_color_space == JCS_RGB); 501 502 for (unsigned x = 0; x < info->output_width; ++x) { 508 dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF); 509 } 510 } 511 512 static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, int srcWidth 513 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 514 , bool scaled, const Vector<int>& scaledColumns 515 #endif 516 ) 517 { 518 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 519 if (scaled) { 520 int numColumns = scaledColumns.size(); 521 for (int x = 0; x < numColumns; ++x) { 522 JSAMPLE* jsample = src + scaledColumns[x] * 3; 523 dest.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF); 524 } 525 return; 526 } 527 #endif 528 for (unsigned x = 0; x < srcWidth; ++x) { 503 529 unsigned r = *src++; 504 530 unsigned g = *src++; 505 531 unsigned b = *src++; 506 // read_scanlines has increased the scanline counter, so we 507 // actually mean the previous one. 508 dest.setRGBA(x, info->output_scanline - 1, r, g, b, 0xFF); 532 dest.setRGBA(x, destY, r, g, b, 0xFF); 509 533 } 510 534 } … … 518 542 RGBA32Buffer& buffer = m_frameBufferCache[0]; 519 543 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 520 if (!buffer.setSize(size().width(), size().height())) { 544 int bufferWidth = size().width(); 545 int bufferHeight = size().height(); 546 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 547 // Let's resize our buffer now to the correct width/height. 548 if (m_scaled) { 549 bufferWidth = m_scaledColumns.size(); 550 bufferHeight = m_scaledRows.size(); 551 } 552 #endif 553 554 if (!buffer.setSize(bufferWidth, bufferHeight)) { 521 555 m_failed = true; 522 556 return false; … … 533 567 534 568 while (info->output_scanline < info->output_height) { 569 // jpeg_read_scanlines will increase the scanline counter, so we 570 // save the scanline before calling it. 571 int sourceY = info->output_scanline; 535 572 /* Request one scanline. Returns 0 or 1 scanlines. */ 536 573 if (jpeg_read_scanlines(info, samples, 1) != 1) 537 574 return false; 538 575 576 int destY = sourceY; 577 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 578 if (m_scaled) { 579 destY = scaledY(sourceY); 580 if (destY < 0) 581 continue; 582 } 539 583 if (info->out_color_space == JCS_RGB) 540 convertRGBToRGBA(buffer, *samples, info);584 convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns); 541 585 else if (info->out_color_space == JCS_CMYK) 542 convertCMYKToRGBA(buffer, *samples, info);586 convertCMYKToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns); 543 587 else 544 588 return false; 589 #else 590 if (info->out_color_space == JCS_RGB) 591 convertRGBToRGBA(buffer, destY, *samples, info->output_width); 592 else if (info->out_color_space == JCS_CMYK) 593 convertCMYKToRGBA(buffer, destY, *samples, info->output_width); 594 else 595 return false; 596 #endif 545 597 } 546 598 -
trunk/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
r44825 r47371 1 1 /* 2 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2008-2009 Torch Mobile, Inc. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 58 59 void jpegComplete(); 59 60 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 #endif 70 60 71 private: 61 72 JPEGImageReader* m_reader; -
trunk/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
r44825 r47371 1 1 /* 2 2 * Copyright (C) 2006 Apple Computer, Inc. 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. 3 4 * 4 5 * Portions are Copyright (C) 2001 mozilla.org … … 243 244 return; 244 245 } 246 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 247 prepareScaleDataIfNecessary(); 248 #endif 245 249 } 246 250 … … 314 318 RGBA32Buffer& buffer = m_frameBufferCache[0]; 315 319 if (buffer.status() == RGBA32Buffer::FrameEmpty) { 316 if (!buffer.setSize(size().width(), size().height())) { 320 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 321 int width = m_scaled ? m_scaledColumns.size() : size().width(); 322 int height = m_scaled ? m_scaledRows.size() : size().height(); 323 #else 324 int width = size().width(); 325 int height = size().height(); 326 #endif 327 if (!buffer.setSize(width, height)) { 317 328 static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed(); 318 329 longjmp(reader()->pngPtr()->jmpbuf, 1); … … 359 370 * old row and the new row. 360 371 */ 361 372 362 373 png_structp png = reader()->pngPtr(); 363 374 bool hasAlpha = reader()->hasAlpha(); … … 373 384 374 385 // Copy the data into our buffer. 386 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) 387 if (m_scaled) { 388 int destY = scaledY(rowIndex); 389 if (destY < 0) 390 return; 391 int columns = m_scaledColumns.size(); 392 bool sawAlpha = buffer.hasAlpha(); 393 for (int x = 0; x < columns; ++x) { 394 png_bytep pixel = row + m_scaledColumns[x] * 4; 395 unsigned alpha = pixel[3]; 396 buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha); 397 if (!sawAlpha && alpha < 255) { 398 sawAlpha = true; 399 buffer.setHasAlpha(true); 400 } 401 } 402 return; 403 } 404 #endif 375 405 int width = size().width(); 376 bool sawAlpha = false;406 bool sawAlpha = buffer.hasAlpha(); 377 407 for (int x = 0; x < width; x++) { 378 408 unsigned red = *row++; … … 386 416 } 387 417 } 418 #endif 388 419 } 389 420
Note: See TracChangeset
for help on using the changeset viewer.