OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCodec_libbmp.h" | 8 #include "SkCodec_libbmp.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
752 const int height = dstInfo.height(); | 752 const int height = dstInfo.height(); |
753 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); | 753 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); |
754 | 754 |
755 // Allocate a buffer large enough to hold the full image | 755 // Allocate a buffer large enough to hold the full image |
756 SkAutoTDeleteArray<uint8_t> | 756 SkAutoTDeleteArray<uint8_t> |
757 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes)); | 757 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes)); |
758 uint8_t* srcRow = srcBuffer.get(); | 758 uint8_t* srcRow = srcBuffer.get(); |
759 | 759 |
760 // Create the swizzler | 760 // Create the swizzler |
761 SkAutoTDelete<SkMaskSwizzler> maskSwizzler( | 761 SkAutoTDelete<SkMaskSwizzler> maskSwizzler( |
762 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes, | 762 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, fMasks, fBitsPerPixel)); |
763 fMasks, fBitsPerPixel)); | |
764 | 763 |
765 // Iterate over rows of the image | 764 // Iterate over rows of the image |
766 bool transparent = true; | 765 bool transparent = true; |
767 for (int y = 0; y < height; y++) { | 766 for (int y = 0; y < height; y++) { |
768 // Read a row of the input | 767 // Read a row of the input |
769 if (stream()->read(srcRow, rowBytes) != rowBytes) { | 768 if (stream()->read(srcRow, rowBytes) != rowBytes) { |
770 SkCodecPrintf("Warning: incomplete input stream.\n"); | 769 SkCodecPrintf("Warning: incomplete input stream.\n"); |
771 // Fill the destination image on failure | 770 // Fill the destination image on failure |
772 SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ? | 771 SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ? |
773 SK_ColorBLACK : SK_ColorTRANSPARENT; | 772 SK_ColorBLACK : SK_ColorTRANSPARENT; |
774 if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) { | 773 if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) { |
775 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); | 774 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); |
776 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, fillColor, | 775 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, fillColor, |
777 NULL); | 776 NULL); |
778 } | 777 } |
779 return kIncompleteInput; | 778 return kIncompleteInput; |
780 } | 779 } |
781 | 780 |
782 // Decode the row in destination format | 781 // Decode the row in destination format |
783 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; | 782 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; |
784 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row); | 783 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row); |
784 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, dstRow); | |
785 transparent &= SkSwizzler::IsTransparent(r); | 785 transparent &= SkSwizzler::IsTransparent(r); |
786 | 786 |
787 // Move to the next row | 787 // Move to the next row |
788 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); | 788 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); |
789 } | 789 } |
790 | 790 |
791 // Some fully transparent bmp images are intended to be opaque. Here, we | 791 // Some fully transparent bmp images are intended to be opaque. Here, we |
792 // correct for this possibility. | 792 // correct for this possibility. |
793 if (transparent) { | 793 if (transparent) { |
794 const SkImageInfo& opaqueInfo = | 794 const SkImageInfo& opaqueInfo = |
795 dstInfo.makeAlphaType(kOpaque_SkAlphaType); | 795 dstInfo.makeAlphaType(kOpaque_SkAlphaType); |
796 SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler( | 796 SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler( |
797 SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, dst, dstRowBytes, | 797 SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, fMasks, |
798 fMasks, fBitsPerPixel)); | 798 fBitsPerPixel)); |
scroggo
2015/07/27 20:42:06
nit: Can this fit on the previous line now?
msarett
2015/07/27 21:11:33
Yes!
| |
799 srcRow = srcBuffer.get(); | 799 srcRow = srcBuffer.get(); |
800 for (int y = 0; y < height; y++) { | 800 for (int y = 0; y < height; y++) { |
801 // Decode the row in opaque format | 801 // Decode the row in opaque format |
802 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; | 802 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; |
803 opaqueSwizzler->next(srcRow, row); | 803 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row); |
804 opaqueSwizzler->next(srcRow, dstRow); | |
804 | 805 |
805 // Move to the next row | 806 // Move to the next row |
806 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); | 807 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); |
807 } | 808 } |
808 } | 809 } |
809 | 810 |
810 // Finished decoding the entire image | 811 // Finished decoding the entire image |
811 return kSuccess; | 812 return kSuccess; |
812 } | 813 } |
813 | 814 |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 default: | 1128 default: |
1128 SkASSERT(false); | 1129 SkASSERT(false); |
1129 return kInvalidInput; | 1130 return kInvalidInput; |
1130 } | 1131 } |
1131 | 1132 |
1132 // Get a pointer to the color table if it exists | 1133 // Get a pointer to the color table if it exists |
1133 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL; | 1134 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL; |
1134 | 1135 |
1135 // Create swizzler | 1136 // Create swizzler |
1136 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, | 1137 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, |
1137 colorPtr, dstInfo, dst, dstRowBytes, kNo_ZeroInitialized)); | 1138 colorPtr, dstInfo, kNo_ZeroInitialized)); |
1138 | 1139 |
1139 // Allocate space for a row buffer and a source for the swizzler | 1140 // Allocate space for a row buffer and a source for the swizzler |
1140 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); | 1141 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); |
1141 | 1142 |
1142 // Iterate over rows of the image | 1143 // Iterate over rows of the image |
1143 // FIXME: bool transparent = true; | 1144 // FIXME: bool transparent = true; |
1144 for (int y = 0; y < height; y++) { | 1145 for (int y = 0; y < height; y++) { |
1145 // Read a row of the input | 1146 // Read a row of the input |
1146 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { | 1147 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { |
1147 SkCodecPrintf("Warning: incomplete input stream.\n"); | 1148 SkCodecPrintf("Warning: incomplete input stream.\n"); |
1148 // Fill the destination image on failure | 1149 // Fill the destination image on failure |
1149 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) { | 1150 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) { |
1150 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); | 1151 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); |
1151 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, | 1152 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, |
1152 fillColorOrIndex, colorPtr); | 1153 fillColorOrIndex, colorPtr); |
1153 } | 1154 } |
1154 return kIncompleteInput; | 1155 return kIncompleteInput; |
1155 } | 1156 } |
1156 | 1157 |
1157 // Decode the row in destination format | 1158 // Decode the row in destination format |
1158 uint32_t row; | 1159 uint32_t row; |
1159 if (kTopDown_RowOrder == fRowOrder) { | 1160 if (kTopDown_RowOrder == fRowOrder) { |
1160 row = y; | 1161 row = y; |
1161 } else { | 1162 } else { |
1162 row = height - 1 - y; | 1163 row = height - 1 - y; |
1163 } | 1164 } |
1164 | 1165 |
1165 swizzler->next(srcBuffer.get(), row); | 1166 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row); |
1167 swizzler->next(srcBuffer.get(), dstRow); | |
1166 // FIXME: SkSwizzler::ResultAlpha r = | 1168 // FIXME: SkSwizzler::ResultAlpha r = |
1167 // swizzler->next(srcBuffer.get(), row); | 1169 // swizzler->next(srcBuffer.get(), row); |
1168 // FIXME: transparent &= SkSwizzler::IsTransparent(r); | 1170 // FIXME: transparent &= SkSwizzler::IsTransparent(r); |
1169 } | 1171 } |
1170 | 1172 |
1171 // FIXME: This code exists to match the behavior in the chromium decoder | 1173 // FIXME: This code exists to match the behavior in the chromium decoder |
1172 // and to follow the bmp specification as it relates to alpha masks. It is | 1174 // and to follow the bmp specification as it relates to alpha masks. It is |
1173 // commented out because we have yet to discover a test image that provides | 1175 // commented out because we have yet to discover a test image that provides |
1174 // an alpha mask and uses this decode mode. | 1176 // an alpha mask and uses this decode mode. |
1175 | 1177 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1225 uint32_t alphaBit = | 1227 uint32_t alphaBit = |
1226 (srcBuffer.get()[quotient] >> shift) & 0x1; | 1228 (srcBuffer.get()[quotient] >> shift) & 0x1; |
1227 dstRow[x] &= alphaBit - 1; | 1229 dstRow[x] &= alphaBit - 1; |
1228 } | 1230 } |
1229 } | 1231 } |
1230 } | 1232 } |
1231 | 1233 |
1232 // Finished decoding the entire image | 1234 // Finished decoding the entire image |
1233 return kSuccess; | 1235 return kSuccess; |
1234 } | 1236 } |
OLD | NEW |