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 |