| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
| 3 * Copyright (C) 2007-2009 Torch Mobile, Inc. | |
| 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
| 5 * | 4 * |
| 6 * Portions are Copyright (C) 2001 mozilla.org | 5 * Portions are Copyright (C) 2001 mozilla.org |
| 7 * | 6 * |
| 8 * Other contributors: | 7 * Other contributors: |
| 9 * Stuart Parmenter <stuart@mozilla.com> | 8 * Stuart Parmenter <stuart@mozilla.com> |
| 10 * | 9 * |
| 11 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| 12 * modify it under the terms of the GNU Lesser General Public | 11 * modify it under the terms of the GNU Lesser General Public |
| 13 * License as published by the Free Software Foundation; either | 12 * License as published by the Free Software Foundation; either |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 227 } |
| 229 | 228 |
| 230 bool PNGImageDecoder::isSizeAvailable() | 229 bool PNGImageDecoder::isSizeAvailable() |
| 231 { | 230 { |
| 232 if (!ImageDecoder::isSizeAvailable()) | 231 if (!ImageDecoder::isSizeAvailable()) |
| 233 decode(true); | 232 decode(true); |
| 234 | 233 |
| 235 return ImageDecoder::isSizeAvailable(); | 234 return ImageDecoder::isSizeAvailable(); |
| 236 } | 235 } |
| 237 | 236 |
| 238 bool PNGImageDecoder::setSize(unsigned width, unsigned height) | |
| 239 { | |
| 240 if (!ImageDecoder::setSize(width, height)) | |
| 241 return false; | |
| 242 | |
| 243 prepareScaleDataIfNecessary(); | |
| 244 return true; | |
| 245 } | |
| 246 | |
| 247 ImageFrame* PNGImageDecoder::frameBufferAtIndex(size_t index) | 237 ImageFrame* PNGImageDecoder::frameBufferAtIndex(size_t index) |
| 248 { | 238 { |
| 249 if (index) | 239 if (index) |
| 250 return 0; | 240 return 0; |
| 251 | 241 |
| 252 if (m_frameBufferCache.isEmpty()) { | 242 if (m_frameBufferCache.isEmpty()) { |
| 253 m_frameBufferCache.resize(1); | 243 m_frameBufferCache.resize(1); |
| 254 m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); | 244 m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); |
| 255 } | 245 } |
| 256 | 246 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 394 |
| 405 void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
int) | 395 void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
int) |
| 406 { | 396 { |
| 407 if (m_frameBufferCache.isEmpty()) | 397 if (m_frameBufferCache.isEmpty()) |
| 408 return; | 398 return; |
| 409 | 399 |
| 410 // Initialize the framebuffer if needed. | 400 // Initialize the framebuffer if needed. |
| 411 ImageFrame& buffer = m_frameBufferCache[0]; | 401 ImageFrame& buffer = m_frameBufferCache[0]; |
| 412 if (buffer.status() == ImageFrame::FrameEmpty) { | 402 if (buffer.status() == ImageFrame::FrameEmpty) { |
| 413 png_structp png = m_reader->pngPtr(); | 403 png_structp png = m_reader->pngPtr(); |
| 414 if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { | 404 if (!buffer.setSize(size().width(), size().height())) { |
| 415 longjmp(JMPBUF(png), 1); | 405 longjmp(JMPBUF(png), 1); |
| 416 return; | 406 return; |
| 417 } | 407 } |
| 418 | 408 |
| 419 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; | 409 unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3; |
| 420 if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr
())) { | 410 if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr
())) { |
| 421 m_reader->createInterlaceBuffer(colorChannels * size().width() * siz
e().height()); | 411 m_reader->createInterlaceBuffer(colorChannels * size().width() * siz
e().height()); |
| 422 if (!m_reader->interlaceBuffer()) { | 412 if (!m_reader->interlaceBuffer()) { |
| 423 longjmp(JMPBUF(png), 1); | 413 longjmp(JMPBUF(png), 1); |
| 424 return; | 414 return; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 451 * The rows and passes are called in order, so you don't really | 441 * The rows and passes are called in order, so you don't really |
| 452 * need the row_num and pass, but I'm supplying them because it | 442 * need the row_num and pass, but I'm supplying them because it |
| 453 * may make your life easier. | 443 * may make your life easier. |
| 454 */ | 444 */ |
| 455 | 445 |
| 456 // Nothing to do if the row is unchanged, or the row is outside | 446 // Nothing to do if the row is unchanged, or the row is outside |
| 457 // the image bounds: libpng may send extra rows, ignore them to | 447 // the image bounds: libpng may send extra rows, ignore them to |
| 458 // make our lives easier. | 448 // make our lives easier. |
| 459 if (!rowBuffer) | 449 if (!rowBuffer) |
| 460 return; | 450 return; |
| 461 int y = !m_scaled ? rowIndex : scaledY(rowIndex); | 451 int y = rowIndex; |
| 462 if (y < 0 || y >= scaledSize().height()) | 452 if (y < 0 || y >= size().height()) |
| 463 return; | 453 return; |
| 464 | 454 |
| 465 /* libpng comments (continued). | 455 /* libpng comments (continued). |
| 466 * | 456 * |
| 467 * For the non-NULL rows of interlaced images, you must call | 457 * For the non-NULL rows of interlaced images, you must call |
| 468 * png_progressive_combine_row() passing in the row and the | 458 * png_progressive_combine_row() passing in the row and the |
| 469 * old row. You can call this function for NULL rows (it will | 459 * old row. You can call this function for NULL rows (it will |
| 470 * just return) and for non-interlaced images (it just does the | 460 * just return) and for non-interlaced images (it just does the |
| 471 * memcpy for you) if it will make the code easier. Thus, you | 461 * memcpy for you) if it will make the code easier. Thus, you |
| 472 * can just do this for all cases: | 462 * can just do this for all cases: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 492 | 482 |
| 493 #if USE(QCMSLIB) | 483 #if USE(QCMSLIB) |
| 494 if (qcms_transform* transform = m_reader->colorTransform()) { | 484 if (qcms_transform* transform = m_reader->colorTransform()) { |
| 495 qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width(
)); | 485 qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width(
)); |
| 496 row = m_reader->rowBuffer(); | 486 row = m_reader->rowBuffer(); |
| 497 } | 487 } |
| 498 #endif | 488 #endif |
| 499 | 489 |
| 500 // Write the decoded row pixels to the frame buffer. | 490 // Write the decoded row pixels to the frame buffer. |
| 501 ImageFrame::PixelData* address = buffer.getAddr(0, y); | 491 ImageFrame::PixelData* address = buffer.getAddr(0, y); |
| 502 int width = scaledSize().width(); | |
| 503 bool nonTrivialAlpha = false; | 492 bool nonTrivialAlpha = false; |
| 493 int width = size().width(); |
| 504 | 494 |
| 505 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) | |
| 506 for (int x = 0; x < width; ++x) { | |
| 507 png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChann
els; | |
| 508 unsigned alpha = hasAlpha ? pixel[3] : 255; | |
| 509 buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); | |
| 510 nonTrivialAlpha |= alpha < 255; | |
| 511 } | |
| 512 #else | |
| 513 ASSERT(!m_scaled); | |
| 514 png_bytep pixel = row; | 495 png_bytep pixel = row; |
| 515 for (int x = 0; x < width; ++x, pixel += colorChannels) { | 496 for (int x = 0; x < width; ++x, pixel += colorChannels) { |
| 516 unsigned alpha = hasAlpha ? pixel[3] : 255; | 497 unsigned alpha = hasAlpha ? pixel[3] : 255; |
| 517 buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); | 498 buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); |
| 518 nonTrivialAlpha |= alpha < 255; | 499 nonTrivialAlpha |= alpha < 255; |
| 519 } | 500 } |
| 520 #endif | |
| 521 | 501 |
| 522 if (nonTrivialAlpha && !buffer.hasAlpha()) | 502 if (nonTrivialAlpha && !buffer.hasAlpha()) |
| 523 buffer.setHasAlpha(nonTrivialAlpha); | 503 buffer.setHasAlpha(nonTrivialAlpha); |
| 524 } | 504 } |
| 525 | 505 |
| 526 void PNGImageDecoder::pngComplete() | 506 void PNGImageDecoder::pngComplete() |
| 527 { | 507 { |
| 528 if (!m_frameBufferCache.isEmpty()) | 508 if (!m_frameBufferCache.isEmpty()) |
| 529 m_frameBufferCache.first().setStatus(ImageFrame::FrameComplete); | 509 m_frameBufferCache.first().setStatus(ImageFrame::FrameComplete); |
| 530 } | 510 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 541 // has failed. | 521 // has failed. |
| 542 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) | 522 if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) |
| 543 setFailed(); | 523 setFailed(); |
| 544 // If we're done decoding the image, we don't need the PNGImageReader | 524 // If we're done decoding the image, we don't need the PNGImageReader |
| 545 // anymore. (If we failed, |m_reader| has already been cleared.) | 525 // anymore. (If we failed, |m_reader| has already been cleared.) |
| 546 else if (isComplete()) | 526 else if (isComplete()) |
| 547 m_reader.clear(); | 527 m_reader.clear(); |
| 548 } | 528 } |
| 549 | 529 |
| 550 } // namespace WebCore | 530 } // namespace WebCore |
| OLD | NEW |