OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 26 matching lines...) Expand all Loading... |
37 : m_parent(parent) | 37 : m_parent(parent) |
38 , m_buffer(0) | 38 , m_buffer(0) |
39 , m_decodedOffset(decodedAndHeaderOffset) | 39 , m_decodedOffset(decodedAndHeaderOffset) |
40 , m_headerOffset(decodedAndHeaderOffset) | 40 , m_headerOffset(decodedAndHeaderOffset) |
41 , m_imgDataOffset(imgDataOffset) | 41 , m_imgDataOffset(imgDataOffset) |
42 , m_isOS21x(false) | 42 , m_isOS21x(false) |
43 , m_isOS22x(false) | 43 , m_isOS22x(false) |
44 , m_isTopDown(false) | 44 , m_isTopDown(false) |
45 , m_needToProcessBitmasks(false) | 45 , m_needToProcessBitmasks(false) |
46 , m_needToProcessColorTable(false) | 46 , m_needToProcessColorTable(false) |
47 , m_tableSizeInBytes(0) | |
48 , m_seenNonZeroAlphaPixel(false) | 47 , m_seenNonZeroAlphaPixel(false) |
49 , m_seenZeroAlphaPixel(false) | 48 , m_seenZeroAlphaPixel(false) |
50 , m_andMaskState(usesAndMask ? NotYetDecoded : None) | 49 , m_andMaskState(usesAndMask ? NotYetDecoded : None) |
51 { | 50 { |
52 // Clue-in decodeBMP() that we need to detect the correct info header size. | 51 // Clue-in decodeBMP() that we need to detect the correct info header size. |
53 memset(&m_infoHeader, 0, sizeof(m_infoHeader)); | 52 memset(&m_infoHeader, 0, sizeof(m_infoHeader)); |
54 } | 53 } |
55 | 54 |
56 bool BMPImageReader::decodeBMP(bool onlySize) | 55 bool BMPImageReader::decodeBMP(bool onlySize) |
57 { | 56 { |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 m_bitShiftsRight[i] -= m_bitShiftsLeft[i]; | 459 m_bitShiftsRight[i] -= m_bitShiftsLeft[i]; |
461 m_bitShiftsLeft[i] = 0; | 460 m_bitShiftsLeft[i] = 0; |
462 } | 461 } |
463 } | 462 } |
464 | 463 |
465 return true; | 464 return true; |
466 } | 465 } |
467 | 466 |
468 bool BMPImageReader::processColorTable() | 467 bool BMPImageReader::processColorTable() |
469 { | 468 { |
470 m_tableSizeInBytes = m_infoHeader.biClrUsed * (m_isOS21x ? 3 : 4); | 469 size_t tableSizeInBytes = m_infoHeader.biClrUsed * (m_isOS21x ? 3 : 4); |
471 | 470 |
472 // Fail if we don't have enough file space for the color table. | 471 // Fail if we don't have enough file space for the color table. |
473 if (((m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes) < (m_header
Offset + m_infoHeader.biSize)) || (m_imgDataOffset && (m_imgDataOffset < (m_head
erOffset + m_infoHeader.biSize + m_tableSizeInBytes)))) | 472 if (((m_headerOffset + m_infoHeader.biSize + tableSizeInBytes) < (m_headerOf
fset + m_infoHeader.biSize)) || (m_imgDataOffset && (m_imgDataOffset < (m_header
Offset + m_infoHeader.biSize + tableSizeInBytes)))) |
474 return m_parent->setFailed(); | 473 return m_parent->setFailed(); |
475 | 474 |
476 // Read color table. | 475 // Read color table. |
477 if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset
) < m_tableSizeInBytes)) | 476 if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset
) < tableSizeInBytes)) |
478 return false; | 477 return false; |
479 m_colorTable.resize(m_infoHeader.biClrUsed); | 478 m_colorTable.resize(m_infoHeader.biClrUsed); |
480 for (size_t i = 0; i < m_infoHeader.biClrUsed; ++i) { | 479 for (size_t i = 0; i < m_infoHeader.biClrUsed; ++i) { |
481 m_colorTable[i].rgbBlue = m_data->data()[m_decodedOffset++]; | 480 m_colorTable[i].rgbBlue = m_data->data()[m_decodedOffset++]; |
482 m_colorTable[i].rgbGreen = m_data->data()[m_decodedOffset++]; | 481 m_colorTable[i].rgbGreen = m_data->data()[m_decodedOffset++]; |
483 m_colorTable[i].rgbRed = m_data->data()[m_decodedOffset++]; | 482 m_colorTable[i].rgbRed = m_data->data()[m_decodedOffset++]; |
484 // Skip padding byte (not present on OS/2 1.x). | 483 // Skip padding byte (not present on OS/2 1.x). |
485 if (!m_isOS21x) | 484 if (!m_isOS21x) |
486 ++m_decodedOffset; | 485 ++m_decodedOffset; |
487 } | 486 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 m_decodedOffset += 4; | 607 m_decodedOffset += 4; |
609 } else { | 608 } else { |
610 // RLE8 has one color index that gets repeated; RLE4 has two | 609 // RLE8 has one color index that gets repeated; RLE4 has two |
611 // color indexes in the upper and lower 4 bits of the byte, | 610 // color indexes in the upper and lower 4 bits of the byte, |
612 // which are alternated. | 611 // which are alternated. |
613 size_t colorIndexes[2] = {code, code}; | 612 size_t colorIndexes[2] = {code, code}; |
614 if (m_infoHeader.biCompression == RLE4) { | 613 if (m_infoHeader.biCompression == RLE4) { |
615 colorIndexes[0] = (colorIndexes[0] >> 4) & 0xf; | 614 colorIndexes[0] = (colorIndexes[0] >> 4) & 0xf; |
616 colorIndexes[1] &= 0xf; | 615 colorIndexes[1] &= 0xf; |
617 } | 616 } |
618 if ((colorIndexes[0] >= m_infoHeader.biClrUsed) || (colorIndexes
[1] >= m_infoHeader.biClrUsed)) | |
619 return m_parent->setFailed(); | |
620 for (int which = 0; m_coord.x() < endX; ) { | 617 for (int which = 0; m_coord.x() < endX; ) { |
621 setI(colorIndexes[which]); | 618 // Some images specify color values past the end of the |
| 619 // color table; set these pixels to black. |
| 620 if (colorIndexes[which] < m_infoHeader.biClrUsed) |
| 621 setI(colorIndexes[which]); |
| 622 else |
| 623 setRGBA(0, 0, 0, 255); |
622 which = !which; | 624 which = !which; |
623 } | 625 } |
624 | 626 |
625 m_decodedOffset += 2; | 627 m_decodedOffset += 2; |
626 } | 628 } |
627 } | 629 } |
628 } | 630 } |
629 } | 631 } |
630 | 632 |
631 BMPImageReader::ProcessingResult BMPImageReader::processNonRLEData(bool inRLE, i
nt numPixels) | 633 BMPImageReader::ProcessingResult BMPImageReader::processNonRLEData(bool inRLE, i
nt numPixels) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 // operation as an RGBA image, so where the AND values | 674 // operation as an RGBA image, so where the AND values |
673 // are 1, we simply set the framebuffer pixels to fully | 675 // are 1, we simply set the framebuffer pixels to fully |
674 // transparent, on the assumption that most ICOs on the | 676 // transparent, on the assumption that most ICOs on the |
675 // web will not be doing a lot of inverting. | 677 // web will not be doing a lot of inverting. |
676 if (colorIndex) { | 678 if (colorIndex) { |
677 setRGBA(0, 0, 0, 0); | 679 setRGBA(0, 0, 0, 0); |
678 m_buffer->setHasAlpha(true); | 680 m_buffer->setHasAlpha(true); |
679 } else | 681 } else |
680 m_coord.move(1, 0); | 682 m_coord.move(1, 0); |
681 } else { | 683 } else { |
682 if (colorIndex >= m_infoHeader.biClrUsed) | 684 // See comments near the end of processRLEData(). |
683 return Failure; | 685 if (colorIndex < m_infoHeader.biClrUsed) |
684 setI(colorIndex); | 686 setI(colorIndex); |
| 687 else |
| 688 setRGBA(0, 0, 0, 255); |
685 } | 689 } |
686 pixelData <<= m_infoHeader.biBitCount; | 690 pixelData <<= m_infoHeader.biBitCount; |
687 } | 691 } |
688 } | 692 } |
689 } else { | 693 } else { |
690 // RGB data. Decode pixels one at a time, left to right. | 694 // RGB data. Decode pixels one at a time, left to right. |
691 while (m_coord.x() < endX) { | 695 while (m_coord.x() < endX) { |
692 const uint32_t pixel = readCurrentPixel(bytesPerPixel); | 696 const uint32_t pixel = readCurrentPixel(bytesPerPixel); |
693 | 697 |
694 // Some BMPs specify an alpha channel but don't actually use it | 698 // Some BMPs specify an alpha channel but don't actually use it |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 // Finished decoding whole image. | 732 // Finished decoding whole image. |
729 return Success; | 733 return Success; |
730 } | 734 } |
731 | 735 |
732 void BMPImageReader::moveBufferToNextRow() | 736 void BMPImageReader::moveBufferToNextRow() |
733 { | 737 { |
734 m_coord.move(-m_coord.x(), m_isTopDown ? 1 : -1); | 738 m_coord.move(-m_coord.x(), m_isTopDown ? 1 : -1); |
735 } | 739 } |
736 | 740 |
737 } // namespace WebCore | 741 } // namespace WebCore |
OLD | NEW |