Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: src/codec/SkCodec_libbmp.cpp

Issue 1075243003: Implementing filling for SkBmpCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/codec/SkSwizzler.h » ('j') | src/codec/SkSwizzler.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 } 694 }
695 colorTable[i] = packARGB(alpha, red, green, blue); 695 colorTable[i] = packARGB(alpha, red, green, blue);
696 } 696 }
697 697
698 // To avoid segmentation faults on bad pixel data, fill the end of the 698 // To avoid segmentation faults on bad pixel data, fill the end of the
699 // color table with black. This is the same the behavior as the 699 // color table with black. This is the same the behavior as the
700 // chromium decoder. 700 // chromium decoder.
701 for (; i < maxColors; i++) { 701 for (; i < maxColors; i++) {
702 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); 702 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
703 } 703 }
704
705 // Set the color table
706 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
704 } 707 }
705 708
706 // Bmp-in-Ico files do not use an offset to indicate where the pixel data 709 // Bmp-in-Ico files do not use an offset to indicate where the pixel data
707 // begins. Pixel data always begins immediately after the color table. 710 // begins. Pixel data always begins immediately after the color table.
708 if (!fIsIco) { 711 if (!fIsIco) {
709 // Check that we have not read past the pixel array offset 712 // Check that we have not read past the pixel array offset
710 if(fOffset < colorBytes) { 713 if(fOffset < colorBytes) {
711 // This may occur on OS 2.1 and other old versions where the color 714 // This may occur on OS 2.1 and other old versions where the color
712 // table defaults to max size, and the bmp tries to use a smaller 715 // table defaults to max size, and the bmp tries to use a smaller
713 // color table. This is invalid, and our decision is to indicate 716 // color table. This is invalid, and our decision is to indicate
714 // an error, rather than try to guess the intended size of the 717 // an error, rather than try to guess the intended size of the
715 // color table. 718 // color table.
716 SkCodecPrintf("Error: pixel data offset less than color table size.\ n"); 719 SkCodecPrintf("Error: pixel data offset less than color table size.\ n");
717 return false; 720 return false;
718 } 721 }
719 722
720 // After reading the color table, skip to the start of the pixel array 723 // After reading the color table, skip to the start of the pixel array
721 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) { 724 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
722 SkCodecPrintf("Error: unable to skip to image data.\n"); 725 SkCodecPrintf("Error: unable to skip to image data.\n");
723 return false; 726 return false;
724 } 727 }
725 } 728 }
726 729
727 // Set the color table and return true on success 730 // Return true on success
728 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
729 return true; 731 return true;
730 } 732 }
731 733
732 /* 734 /*
733 * 735 *
734 * Performs the bitmap decoding for bit masks input format 736 * Performs the bitmap decoding for bit masks input format
735 * 737 *
736 */ 738 */
737 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, 739 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo,
738 void* dst, size_t dstRowBytes) { 740 void* dst, size_t dstRowBytes) {
(...skipping 11 matching lines...) Expand all
750 SkAutoTDelete<SkMaskSwizzler> maskSwizzler( 752 SkAutoTDelete<SkMaskSwizzler> maskSwizzler(
751 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes, 753 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes,
752 fMasks, fBitsPerPixel)); 754 fMasks, fBitsPerPixel));
753 755
754 // Iterate over rows of the image 756 // Iterate over rows of the image
755 bool transparent = true; 757 bool transparent = true;
756 for (int y = 0; y < height; y++) { 758 for (int y = 0; y < height; y++) {
757 // Read a row of the input 759 // Read a row of the input
758 if (stream()->read(srcRow, rowBytes) != rowBytes) { 760 if (stream()->read(srcRow, rowBytes) != rowBytes) {
759 SkCodecPrintf("Warning: incomplete input stream.\n"); 761 SkCodecPrintf("Warning: incomplete input stream.\n");
762 // Fill the destination image on failure
763 // By using zero as the fill value, we will fill with transparent
764 // pixels for non-opaque images and white for opaque images.
765 // These are arbitrary choices but allow for consistent behavior.
766 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, y, 0, NULL,
767 fRowOrder == kBottomUp_RowOrder);
760 return kIncompleteInput; 768 return kIncompleteInput;
761 } 769 }
762 770
763 // Decode the row in destination format 771 // Decode the row in destination format
764 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; 772 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
765 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row); 773 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row);
766 transparent &= SkSwizzler::IsTransparent(r); 774 transparent &= SkSwizzler::IsTransparent(r);
767 775
768 // Move to the next row 776 // Move to the next row
769 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes); 777 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 config = SkSwizzler::kBGRX; 1097 config = SkSwizzler::kBGRX;
1090 } else { 1098 } else {
1091 config = SkSwizzler::kBGRA; 1099 config = SkSwizzler::kBGRA;
1092 } 1100 }
1093 break; 1101 break;
1094 default: 1102 default:
1095 SkASSERT(false); 1103 SkASSERT(false);
1096 return kInvalidInput; 1104 return kInvalidInput;
1097 } 1105 }
1098 1106
1107 // Get a pointer to the color table if it exists
1108 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL;
1109
1099 // Create swizzler 1110 // Create swizzler
1100 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, 1111 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config,
1101 fColorTable->readColors(), dstInfo, dst, dstRowBytes, 1112 colorPtr, dstInfo, dst, dstRowBytes,
1102 SkImageGenerator::kNo_ZeroInitialized)); 1113 SkImageGenerator::kNo_ZeroInitialized));
1103 1114
1104 // Allocate space for a row buffer and a source for the swizzler 1115 // Allocate space for a row buffer and a source for the swizzler
1105 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); 1116 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
1106 1117
1107 // Iterate over rows of the image 1118 // Iterate over rows of the image
1108 // FIXME: bool transparent = true; 1119 // FIXME: bool transparent = true;
1109 for (int y = 0; y < height; y++) { 1120 for (int y = 0; y < height; y++) {
1110 // Read a row of the input 1121 // Read a row of the input
1111 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { 1122 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1112 SkCodecPrintf("Warning: incomplete input stream.\n"); 1123 SkCodecPrintf("Warning: incomplete input stream.\n");
1124 // Fill the destination image on failure
1125 // By using zero as the fill value, we will fill with the first
1126 // color in the color table for palette images, transparent
1127 // pixels for non-opaque images, and white for opaque images.
1128 // These are arbitrary choices but allow for consistent behavior.
1129 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, y, 0, colorPtr,
1130 fRowOrder == kBottomUp_RowOrder);
1113 return kIncompleteInput; 1131 return kIncompleteInput;
1114 } 1132 }
1115 1133
1116 // Decode the row in destination format 1134 // Decode the row in destination format
1117 uint32_t row; 1135 uint32_t row;
1118 if (kTopDown_RowOrder == fRowOrder) { 1136 if (kTopDown_RowOrder == fRowOrder) {
1119 row = y; 1137 row = y;
1120 } else { 1138 } else {
1121 row = height - 1 - y; 1139 row = height - 1 - y;
1122 } 1140 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 uint32_t alphaBit = 1202 uint32_t alphaBit =
1185 (srcBuffer.get()[quotient] >> shift) & 0x1; 1203 (srcBuffer.get()[quotient] >> shift) & 0x1;
1186 dstRow[x] &= alphaBit - 1; 1204 dstRow[x] &= alphaBit - 1;
1187 } 1205 }
1188 } 1206 }
1189 } 1207 }
1190 1208
1191 // Finished decoding the entire image 1209 // Finished decoding the entire image
1192 return kSuccess; 1210 return kSuccess;
1193 } 1211 }
OLDNEW
« no previous file with comments | « no previous file | src/codec/SkSwizzler.h » ('j') | src/codec/SkSwizzler.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698