| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 2001-6 mozilla.org | 4 * Portions are Copyright (C) 2001-6 mozilla.org |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Stuart Parmenter <stuart@mozilla.com> | 7 * Stuart Parmenter <stuart@mozilla.com> |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
| 11 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
| 12 * version 2.1 of the License, or (at your option) any later version. | 12 * version 2.1 of the License, or (at your option) any later version. |
| 13 * | 13 * |
| 14 * This library is distributed in the hope that it will be useful, | 14 * This library is distributed in the hope that it will be useful, |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 * Lesser General Public License for more details. | 17 * Lesser General Public License for more details. |
| 18 * | 18 * |
| 19 * You should have received a copy of the GNU Lesser General Public | 19 * You should have received a copy of the GNU Lesser General Public |
| 20 * License along with this library; if not, write to the Free Software | 20 * License along with this library; if not, write to the Free Software |
| 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A | 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 * | 22 * |
| 23 * Alternatively, the contents of this file may be used under the terms | 23 * Alternatively, the contents of this file may be used under the terms |
| 24 * of either the Mozilla Public License Version 1.1, found at | 24 * of either the Mozilla Public License Version 1.1, found at |
| 25 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public | 25 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public |
| 26 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html | 26 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html |
| 27 * (the "GPL"), in which case the provisions of the MPL or the GPL are | 27 * (the "GPL"), in which case the provisions of the MPL or the GPL are |
| 28 * applicable instead of those above. If you wish to allow use of your | 28 * applicable instead of those above. If you wish to allow use of your |
| 29 * version of this file only under the terms of one of those two | 29 * version of this file only under the terms of one of those two |
| 30 * licenses (the MPL or the GPL) and not to allow others to use your | 30 * licenses (the MPL or the GPL) and not to allow others to use your |
| 31 * version of this file under the LGPL, indicate your decision by | 31 * version of this file under the LGPL, indicate your decision by |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 if (m_needsRestart) { | 350 if (m_needsRestart) { |
| 351 m_needsRestart = false; | 351 m_needsRestart = false; |
| 352 m_nextReadPosition = m_restartPosition; | 352 m_nextReadPosition = m_restartPosition; |
| 353 } else { | 353 } else { |
| 354 updateRestartPosition(); | 354 updateRestartPosition(); |
| 355 } | 355 } |
| 356 | 356 |
| 357 const char* segment; | 357 const char* segment; |
| 358 const size_t bytes = m_data->getSomeData(segment, m_nextReadPosition); | 358 const size_t bytes = m_data->getSomeData(segment, m_nextReadPosition); |
| 359 if (bytes == 0) { | 359 if (bytes == 0) { |
| 360 // We had to suspend. When we resume, we will need to start from the resta
rt position. | 360 // We had to suspend. When we resume, we will need to start from the |
| 361 // restart position. |
| 361 m_needsRestart = true; | 362 m_needsRestart = true; |
| 362 clearBuffer(); | 363 clearBuffer(); |
| 363 return false; | 364 return false; |
| 364 } | 365 } |
| 365 | 366 |
| 366 m_nextReadPosition += bytes; | 367 m_nextReadPosition += bytes; |
| 367 m_info.src->bytes_in_buffer = bytes; | 368 m_info.src->bytes_in_buffer = bytes; |
| 368 const JOCTET* nextByte = reinterpret_cast_ptr<const JOCTET*>(segment); | 369 const JOCTET* nextByte = reinterpret_cast_ptr<const JOCTET*>(segment); |
| 369 m_info.src->next_input_byte = nextByte; | 370 m_info.src->next_input_byte = nextByte; |
| 370 m_lastSetByte = nextByte; | 371 m_lastSetByte = nextByte; |
| 371 return true; | 372 return true; |
| 372 } | 373 } |
| 373 | 374 |
| 374 void setData(SegmentReader* data) { | 375 void setData(SegmentReader* data) { |
| 375 if (m_data.get() == data) | 376 if (m_data.get() == data) |
| 376 return; | 377 return; |
| 377 | 378 |
| 378 m_data = data; | 379 m_data = data; |
| 379 | 380 |
| 380 // If a restart is needed, the next call to fillBuffer will read from the ne
w SegmentReader. | 381 // If a restart is needed, the next call to fillBuffer will read from the |
| 382 // new SegmentReader. |
| 381 if (m_needsRestart) | 383 if (m_needsRestart) |
| 382 return; | 384 return; |
| 383 | 385 |
| 384 // Otherwise, empty the buffer, and leave the position the same, so fillBuff
er continues | 386 // Otherwise, empty the buffer, and leave the position the same, so |
| 385 // reading from the same position in the new SegmentReader. | 387 // fillBuffer continues reading from the same position in the new |
| 388 // SegmentReader. |
| 386 m_nextReadPosition -= m_info.src->bytes_in_buffer; | 389 m_nextReadPosition -= m_info.src->bytes_in_buffer; |
| 387 clearBuffer(); | 390 clearBuffer(); |
| 388 } | 391 } |
| 389 | 392 |
| 390 bool decode(bool onlySize) { | 393 bool decode(bool onlySize) { |
| 391 // We need to do the setjmp here. Otherwise bad things will happen | 394 // We need to do the setjmp here. Otherwise bad things will happen |
| 392 if (setjmp(m_err.setjmp_buffer)) | 395 if (setjmp(m_err.setjmp_buffer)) |
| 393 return m_decoder->setFailed(); | 396 return m_decoder->setFailed(); |
| 394 | 397 |
| 395 J_COLOR_SPACE overrideColorSpace = JCS_UNKNOWN; | 398 J_COLOR_SPACE overrideColorSpace = JCS_UNKNOWN; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 dimensionsLocationHistogram.count(m_nextReadPosition - | 444 dimensionsLocationHistogram.count(m_nextReadPosition - |
| 442 m_info.src->bytes_in_buffer - 1); | 445 m_info.src->bytes_in_buffer - 1); |
| 443 } | 446 } |
| 444 // We can fill in the size now that the header is available. | 447 // We can fill in the size now that the header is available. |
| 445 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) | 448 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) |
| 446 return false; | 449 return false; |
| 447 | 450 |
| 448 // Calculate and set decoded size. | 451 // Calculate and set decoded size. |
| 449 m_info.scale_num = m_decoder->desiredScaleNumerator(); | 452 m_info.scale_num = m_decoder->desiredScaleNumerator(); |
| 450 m_info.scale_denom = scaleDenominator; | 453 m_info.scale_denom = scaleDenominator; |
| 451 // Scaling caused by running low on memory isn't supported by YUV decodi
ng since | 454 // Scaling caused by running low on memory isn't supported by YUV |
| 452 // YUV decoding is performed on full sized images. At this point, buffer
s and various | 455 // decoding since YUV decoding is performed on full sized images. At |
| 453 // image info structs have already been setup to the scaled size after r
eading the | 456 // this point, buffers and various image info structs have already been |
| 454 // image header using this decoder, so using the full size is no longer
possible. | 457 // set up for the scaled size after reading the image header using this |
| 458 // decoder, so using the full size is no longer possible. |
| 455 if (m_info.scale_num != m_info.scale_denom) | 459 if (m_info.scale_num != m_info.scale_denom) |
| 456 overrideColorSpace = JCS_UNKNOWN; | 460 overrideColorSpace = JCS_UNKNOWN; |
| 457 jpeg_calc_output_dimensions(&m_info); | 461 jpeg_calc_output_dimensions(&m_info); |
| 458 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height); | 462 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height); |
| 459 | 463 |
| 460 m_decoder->setOrientation(readImageOrientation(info())); | 464 m_decoder->setOrientation(readImageOrientation(info())); |
| 461 | 465 |
| 462 // Allow color management of the decoded RGBA pixels if possible. | 466 // Allow color management of the decoded RGBA pixels if possible. |
| 463 if (!m_decoder->ignoresGammaAndColorProfile()) { | 467 if (!m_decoder->ignoresGammaAndColorProfile()) { |
| 464 #if USE(ICCJPEG) | 468 #if USE(ICCJPEG) |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 return true; | 624 return true; |
| 621 } | 625 } |
| 622 | 626 |
| 623 jpeg_decompress_struct* info() { return &m_info; } | 627 jpeg_decompress_struct* info() { return &m_info; } |
| 624 JSAMPARRAY samples() const { return m_samples; } | 628 JSAMPARRAY samples() const { return m_samples; } |
| 625 JPEGImageDecoder* decoder() { return m_decoder; } | 629 JPEGImageDecoder* decoder() { return m_decoder; } |
| 626 IntSize uvSize() const { return m_uvSize; } | 630 IntSize uvSize() const { return m_uvSize; } |
| 627 | 631 |
| 628 private: | 632 private: |
| 629 JSAMPARRAY allocateSampleArray() { | 633 JSAMPARRAY allocateSampleArray() { |
| 630 // Some output color spaces don't need the sample array: don't allocate in that
case. | 634 // Some output color spaces don't need the sample array: don't allocate in that |
| 635 // case. |
| 631 #if defined(TURBO_JPEG_RGB_SWIZZLE) | 636 #if defined(TURBO_JPEG_RGB_SWIZZLE) |
| 632 if (turboSwizzled(m_info.out_color_space)) | 637 if (turboSwizzled(m_info.out_color_space)) |
| 633 return nullptr; | 638 return nullptr; |
| 634 #endif | 639 #endif |
| 635 | 640 |
| 636 if (m_info.out_color_space != JCS_YCbCr) | 641 if (m_info.out_color_space != JCS_YCbCr) |
| 637 return (*m_info.mem->alloc_sarray)( | 642 return (*m_info.mem->alloc_sarray)( |
| 638 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, | 643 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, |
| 639 4 * m_info.output_width, 1); | 644 4 * m_info.output_width, 1); |
| 640 | 645 |
| 641 // Compute the width of the Y plane in bytes. This may be larger than the o
utput | 646 // Compute the width of the Y plane in bytes. This may be larger than the |
| 642 // width, since the jpeg library requires that the allocated width be a mult
iple of | 647 // output width, since the jpeg library requires that the allocated width be |
| 643 // DCTSIZE. Note that this buffer will be used as garbage memory for rows t
hat | 648 // a multiple of DCTSIZE. Note that this buffer will be used as garbage |
| 644 // extend below the actual height of the image. We can reuse the same memor
y for | 649 // memory for rows that extend below the actual height of the image. We can |
| 645 // the U and V planes, since we are guaranteed that the Y plane width is at
least | 650 // reuse the same memory for the U and V planes, since we are guaranteed |
| 646 // as large as the U and V plane widths. | 651 // that the Y plane width is at least as large as the U and V plane widths. |
| 647 int widthBytes = computeYUVWidthBytes(&m_info, 0); | 652 int widthBytes = computeYUVWidthBytes(&m_info, 0); |
| 648 return (*m_info.mem->alloc_sarray)( | 653 return (*m_info.mem->alloc_sarray)( |
| 649 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, widthBytes, | 654 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, widthBytes, |
| 650 1); | 655 1); |
| 651 } | 656 } |
| 652 | 657 |
| 653 void updateRestartPosition() { | 658 void updateRestartPosition() { |
| 654 if (m_lastSetByte != m_info.src->next_input_byte) { | 659 if (m_lastSetByte != m_info.src->next_input_byte) { |
| 655 // next_input_byte was updated by jpeg, meaning that it found a restart po
sition. | 660 // next_input_byte was updated by jpeg, meaning that it found a restart |
| 661 // position. |
| 656 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer; | 662 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer; |
| 657 } | 663 } |
| 658 } | 664 } |
| 659 | 665 |
| 660 void clearBuffer() { | 666 void clearBuffer() { |
| 661 // Let libjpeg know that the buffer needs to be refilled. | 667 // Let libjpeg know that the buffer needs to be refilled. |
| 662 m_info.src->bytes_in_buffer = 0; | 668 m_info.src->bytes_in_buffer = 0; |
| 663 m_info.src->next_input_byte = nullptr; | 669 m_info.src->next_input_byte = nullptr; |
| 664 m_lastSetByte = nullptr; | 670 m_lastSetByte = nullptr; |
| 665 } | 671 } |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 // has failed. | 1026 // has failed. |
| 1021 if (!m_reader->decode(onlySize) && isAllDataReceived()) | 1027 if (!m_reader->decode(onlySize) && isAllDataReceived()) |
| 1022 setFailed(); | 1028 setFailed(); |
| 1023 | 1029 |
| 1024 // If decoding is done or failed, we don't need the JPEGImageReader anymore. | 1030 // If decoding is done or failed, we don't need the JPEGImageReader anymore. |
| 1025 if (isComplete(this, onlySize) || failed()) | 1031 if (isComplete(this, onlySize) || failed()) |
| 1026 m_reader.reset(); | 1032 m_reader.reset(); |
| 1027 } | 1033 } |
| 1028 | 1034 |
| 1029 } // namespace blink | 1035 } // namespace blink |
| OLD | NEW |