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->swizzle(dstRow, srcRow); |
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, fBitsPerP
ixel)); |
798 fMasks, fBitsPerPixel)); | |
799 srcRow = srcBuffer.get(); | 798 srcRow = srcBuffer.get(); |
800 for (int y = 0; y < height; y++) { | 799 for (int y = 0; y < height; y++) { |
801 // Decode the row in opaque format | 800 // Decode the row in opaque format |
802 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; | 801 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; |
803 opaqueSwizzler->next(srcRow, row); | 802 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row); |
| 803 opaqueSwizzler->swizzle(dstRow, srcRow); |
804 | 804 |
805 // Move to the next row | 805 // Move to the next row |
806 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); | 806 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); |
807 } | 807 } |
808 } | 808 } |
809 | 809 |
810 // Finished decoding the entire image | 810 // Finished decoding the entire image |
811 return kSuccess; | 811 return kSuccess; |
812 } | 812 } |
813 | 813 |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 default: | 1127 default: |
1128 SkASSERT(false); | 1128 SkASSERT(false); |
1129 return kInvalidInput; | 1129 return kInvalidInput; |
1130 } | 1130 } |
1131 | 1131 |
1132 // Get a pointer to the color table if it exists | 1132 // Get a pointer to the color table if it exists |
1133 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol
ors() : NULL; | 1133 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol
ors() : NULL; |
1134 | 1134 |
1135 // Create swizzler | 1135 // Create swizzler |
1136 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, | 1136 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, |
1137 colorPtr, dstInfo, dst, dstRowBytes, kNo_ZeroInitialized)); | 1137 colorPtr, dstInfo, kNo_ZeroInitialized)); |
1138 | 1138 |
1139 // Allocate space for a row buffer and a source for the swizzler | 1139 // Allocate space for a row buffer and a source for the swizzler |
1140 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); | 1140 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); |
1141 | 1141 |
1142 // Iterate over rows of the image | 1142 // Iterate over rows of the image |
1143 // FIXME: bool transparent = true; | 1143 // FIXME: bool transparent = true; |
1144 for (int y = 0; y < height; y++) { | 1144 for (int y = 0; y < height; y++) { |
1145 // Read a row of the input | 1145 // Read a row of the input |
1146 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { | 1146 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { |
1147 SkCodecPrintf("Warning: incomplete input stream.\n"); | 1147 SkCodecPrintf("Warning: incomplete input stream.\n"); |
1148 // Fill the destination image on failure | 1148 // Fill the destination image on failure |
1149 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) { | 1149 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) { |
1150 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde
r); | 1150 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde
r); |
1151 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height(
) - y, | 1151 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height(
) - y, |
1152 fillColorOrIndex, colorPtr); | 1152 fillColorOrIndex, colorPtr); |
1153 } | 1153 } |
1154 return kIncompleteInput; | 1154 return kIncompleteInput; |
1155 } | 1155 } |
1156 | 1156 |
1157 // Decode the row in destination format | 1157 // Decode the row in destination format |
1158 uint32_t row; | 1158 uint32_t row; |
1159 if (kTopDown_RowOrder == fRowOrder) { | 1159 if (kTopDown_RowOrder == fRowOrder) { |
1160 row = y; | 1160 row = y; |
1161 } else { | 1161 } else { |
1162 row = height - 1 - y; | 1162 row = height - 1 - y; |
1163 } | 1163 } |
1164 | 1164 |
1165 swizzler->next(srcBuffer.get(), row); | 1165 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row); |
| 1166 swizzler->swizzle(dstRow, srcBuffer.get()); |
1166 // FIXME: SkSwizzler::ResultAlpha r = | 1167 // FIXME: SkSwizzler::ResultAlpha r = |
1167 // swizzler->next(srcBuffer.get(), row); | 1168 // swizzler->swizzle(dstRow, srcBuffer.get()); |
1168 // FIXME: transparent &= SkSwizzler::IsTransparent(r); | 1169 // FIXME: transparent &= SkSwizzler::IsTransparent(r); |
1169 } | 1170 } |
1170 | 1171 |
1171 // FIXME: This code exists to match the behavior in the chromium decoder | 1172 // 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 | 1173 // 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 | 1174 // commented out because we have yet to discover a test image that provides |
1174 // an alpha mask and uses this decode mode. | 1175 // an alpha mask and uses this decode mode. |
1175 | 1176 |
1176 // Now we adjust the output image with some additional behavior that | 1177 // Now we adjust the output image with some additional behavior that |
1177 // SkSwizzler does not support. Firstly, all bmp images that contain | 1178 // SkSwizzler does not support. Firstly, all bmp images that contain |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 uint32_t alphaBit = | 1226 uint32_t alphaBit = |
1226 (srcBuffer.get()[quotient] >> shift) & 0x1; | 1227 (srcBuffer.get()[quotient] >> shift) & 0x1; |
1227 dstRow[x] &= alphaBit - 1; | 1228 dstRow[x] &= alphaBit - 1; |
1228 } | 1229 } |
1229 } | 1230 } |
1230 } | 1231 } |
1231 | 1232 |
1232 // Finished decoding the entire image | 1233 // Finished decoding the entire image |
1233 return kSuccess; | 1234 return kSuccess; |
1234 } | 1235 } |
OLD | NEW |