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

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

Issue 1076923002: SkJpegCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@gif-real
Patch Set: JpegAutoClean is easier to use, Scaling is tested 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
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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 kCMYK4BitRLE_BitmapCompressionMethod = 13 90 kCMYK4BitRLE_BitmapCompressionMethod = 13
91 }; 91 };
92 92
93 /* 93 /*
94 * 94 *
95 * Checks the start of the stream to see if the image is a bitmap 95 * Checks the start of the stream to see if the image is a bitmap
96 * 96 *
97 */ 97 */
98 bool SkBmpCodec::IsBmp(SkStream* stream) { 98 bool SkBmpCodec::IsBmp(SkStream* stream) {
99 // TODO: Support "IC", "PT", "CI", "CP", "BA" 99 // TODO: Support "IC", "PT", "CI", "CP", "BA"
100 // TODO: ICO files may contain a BMP and need to use this decoder
101 const char bmpSig[] = { 'B', 'M' }; 100 const char bmpSig[] = { 'B', 'M' };
102 char buffer[sizeof(bmpSig)]; 101 char buffer[sizeof(bmpSig)];
103 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) && 102 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
104 !memcmp(buffer, bmpSig, sizeof(bmpSig)); 103 !memcmp(buffer, bmpSig, sizeof(bmpSig));
105 } 104 }
106 105
107 /* 106 /*
108 * 107 *
109 * Assumes IsBmp was called and returned true 108 * Assumes IsBmp was called and returned true
110 * Creates a bmp decoder 109 * Creates a bmp decoder
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 if (kIndex_8_SkColorType == dstInfo.colorType()) { 606 if (kIndex_8_SkColorType == dstInfo.colorType()) {
608 SkASSERT(NULL != inputColorPtr); 607 SkASSERT(NULL != inputColorPtr);
609 SkASSERT(NULL != inputColorCount); 608 SkASSERT(NULL != inputColorCount);
610 SkASSERT(NULL != fColorTable.get()); 609 SkASSERT(NULL != fColorTable.get());
611 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount); 610 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount);
612 } 611 }
613 612
614 // Perform the decode 613 // Perform the decode
615 switch (fInputFormat) { 614 switch (fInputFormat) {
616 case kBitMask_BitmapInputFormat: 615 case kBitMask_BitmapInputFormat:
617 return decodeMask(dstInfo, dst, dstRowBytes, opts); 616 return decodeMask(dstInfo, dst, dstRowBytes, opts);
scroggo 2015/04/14 13:10:32 nit: Rebasing between uploads can make it harder t
msarett 2015/04/14 19:30:36 Sorry about that. Good to know.
618 case kRLE_BitmapInputFormat: 617 case kRLE_BitmapInputFormat:
619 return decodeRLE(dstInfo, dst, dstRowBytes, opts); 618 return decodeRLE(dstInfo, dst, dstRowBytes, opts);
620 case kStandard_BitmapInputFormat: 619 case kStandard_BitmapInputFormat:
621 return decode(dstInfo, dst, dstRowBytes, opts); 620 return decode(dstInfo, dst, dstRowBytes, opts);
622 default: 621 default:
623 SkASSERT(false); 622 SkASSERT(false);
624 return kInvalidInput; 623 return kInvalidInput;
625 } 624 }
626 } 625 }
627 626
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes, 765 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes,
767 fMasks, fBitsPerPixel)); 766 fMasks, fBitsPerPixel));
768 767
769 // Iterate over rows of the image 768 // Iterate over rows of the image
770 bool transparent = true; 769 bool transparent = true;
771 for (int y = 0; y < height; y++) { 770 for (int y = 0; y < height; y++) {
772 // Read a row of the input 771 // Read a row of the input
773 if (stream()->read(srcRow, rowBytes) != rowBytes) { 772 if (stream()->read(srcRow, rowBytes) != rowBytes) {
774 SkCodecPrintf("Warning: incomplete input stream.\n"); 773 SkCodecPrintf("Warning: incomplete input stream.\n");
775 // Fill the destination image on failure 774 // Fill the destination image on failure
776 // By using zero as the fill value, we will fill with transparent 775 SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ?
777 // pixels for non-opaque images and white for opaque images. 776 SK_ColorBLACK : SK_ColorTRANSPARENT;
778 // These are arbitrary choices but allow for consistent behavior.
779 if (kNo_ZeroInitialized == opts.fZeroInitialized) { 777 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
780 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); 778 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r);
781 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, 0, NULL); 779 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, fillColor,
780 NULL);
782 } 781 }
783 return kIncompleteInput; 782 return kIncompleteInput;
784 } 783 }
785 784
786 // Decode the row in destination format 785 // Decode the row in destination format
787 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y; 786 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
788 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row); 787 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row);
789 transparent &= SkSwizzler::IsTransparent(r); 788 transparent &= SkSwizzler::IsTransparent(r);
790 789
791 // Move to the next row 790 // Move to the next row
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 * 1082 *
1084 */ 1083 */
1085 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, 1084 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
1086 void* dst, size_t dstRowBytes, 1085 void* dst, size_t dstRowBytes,
1087 const Options& opts) { 1086 const Options& opts) {
1088 // Set constant values 1087 // Set constant values
1089 const int width = dstInfo.width(); 1088 const int width = dstInfo.width();
1090 const int height = dstInfo.height(); 1089 const int height = dstInfo.height();
1091 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel)); 1090 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
1092 1091
1093 // Get swizzler configuration 1092 // Get swizzler configuration and choose the fill value for failures. We wi ll use
1093 // zero as the default palette index, black for opaque images, and transpare nt for
1094 // non-opaque images.
1094 SkSwizzler::SrcConfig config; 1095 SkSwizzler::SrcConfig config;
1096 uint32_t fillColorOrIndex;
1095 switch (fBitsPerPixel) { 1097 switch (fBitsPerPixel) {
1096 case 1: 1098 case 1:
1097 config = SkSwizzler::kIndex1; 1099 config = SkSwizzler::kIndex1;
1100 fillColorOrIndex = 0;
1098 break; 1101 break;
1099 case 2: 1102 case 2:
1100 config = SkSwizzler::kIndex2; 1103 config = SkSwizzler::kIndex2;
1104 fillColorOrIndex = 0;
1101 break; 1105 break;
1102 case 4: 1106 case 4:
1103 config = SkSwizzler::kIndex4; 1107 config = SkSwizzler::kIndex4;
1108 fillColorOrIndex = 0;
1104 break; 1109 break;
1105 case 8: 1110 case 8:
1106 config = SkSwizzler::kIndex; 1111 config = SkSwizzler::kIndex;
1112 fillColorOrIndex = 0;
1107 break; 1113 break;
1108 case 24: 1114 case 24:
1109 config = SkSwizzler::kBGR; 1115 config = SkSwizzler::kBGR;
1116 fillColorOrIndex = SK_ColorBLACK;
1110 break; 1117 break;
1111 case 32: 1118 case 32:
1112 if (kOpaque_SkAlphaType == dstInfo.alphaType()) { 1119 if (kOpaque_SkAlphaType == dstInfo.alphaType()) {
1113 config = SkSwizzler::kBGRX; 1120 config = SkSwizzler::kBGRX;
1121 fillColorOrIndex = SK_ColorBLACK;
1114 } else { 1122 } else {
1115 config = SkSwizzler::kBGRA; 1123 config = SkSwizzler::kBGRA;
1124 fillColorOrIndex = SK_ColorTRANSPARENT;
1116 } 1125 }
1117 break; 1126 break;
1118 default: 1127 default:
1119 SkASSERT(false); 1128 SkASSERT(false);
1120 return kInvalidInput; 1129 return kInvalidInput;
1121 } 1130 }
1122 1131
1123 // Get a pointer to the color table if it exists 1132 // Get a pointer to the color table if it exists
1124 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL; 1133 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL;
1125 1134
1126 // Create swizzler 1135 // Create swizzler
1127 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, 1136 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config,
1128 colorPtr, dstInfo, dst, dstRowBytes, 1137 colorPtr, dstInfo, dst, dstRowBytes,
1129 SkImageGenerator::kNo_ZeroInitialized)); 1138 SkImageGenerator::kNo_ZeroInitialized));
1130 1139
1131 // 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
1132 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes)); 1141 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
1133 1142
1134 // Iterate over rows of the image 1143 // Iterate over rows of the image
1135 // FIXME: bool transparent = true; 1144 // FIXME: bool transparent = true;
1136 for (int y = 0; y < height; y++) { 1145 for (int y = 0; y < height; y++) {
1137 // Read a row of the input 1146 // Read a row of the input
1138 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { 1147 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1139 SkCodecPrintf("Warning: incomplete input stream.\n"); 1148 SkCodecPrintf("Warning: incomplete input stream.\n");
1140 // Fill the destination image on failure 1149 // Fill the destination image on failure
1141 // By using zero as the fill value, we will fill with the first
1142 // color in the color table for palette images, transparent
1143 // pixels for non-opaque images, and white for opaque images.
1144 // These are arbitrary choices but allow for consistent behavior.
1145 if (kNo_ZeroInitialized == opts.fZeroInitialized) { 1150 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
scroggo 2015/04/14 13:10:32 Since fillColorOrIndex may not be 0, being zero in
msarett 2015/04/14 19:30:36 Yes you are right!
1146 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r); 1151 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r);
1147 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, 0, 1152 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y,
1148 colorPtr); 1153 fillColorOrIndex, colorPtr);
1149 } 1154 }
1150 return kIncompleteInput; 1155 return kIncompleteInput;
1151 } 1156 }
1152 1157
1153 // Decode the row in destination format 1158 // Decode the row in destination format
1154 uint32_t row; 1159 uint32_t row;
1155 if (kTopDown_RowOrder == fRowOrder) { 1160 if (kTopDown_RowOrder == fRowOrder) {
1156 row = y; 1161 row = y;
1157 } else { 1162 } else {
1158 row = height - 1 - y; 1163 row = height - 1 - y;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 uint32_t alphaBit = 1226 uint32_t alphaBit =
1222 (srcBuffer.get()[quotient] >> shift) & 0x1; 1227 (srcBuffer.get()[quotient] >> shift) & 0x1;
1223 dstRow[x] &= alphaBit - 1; 1228 dstRow[x] &= alphaBit - 1;
1224 } 1229 }
1225 } 1230 }
1226 } 1231 }
1227 1232
1228 // Finished decoding the entire image 1233 // Finished decoding the entire image
1229 return kSuccess; 1234 return kSuccess;
1230 } 1235 }
OLDNEW
« no previous file with comments | « src/codec/SkCodec.cpp ('k') | src/codec/SkJpegAutoClean.h » ('j') | src/codec/SkJpegAutoClean.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698