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

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

Issue 1258863008: Split SkBmpCodec into three separate classes (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 4 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 | « src/codec/SkBmpCodec.h ('k') | src/codec/SkBmpMaskCodec.h » ('j') | no next file with comments »
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 "SkBmpCodec.h" 8 #include "SkBmpCodec.h"
9 #include "SkBmpMaskCodec.h"
10 #include "SkBmpRLECodec.h"
11 #include "SkBmpStandardCodec.h"
9 #include "SkCodecPriv.h" 12 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 13 #include "SkColorPriv.h"
11 #include "SkStream.h" 14 #include "SkStream.h"
12 15
13 /* 16 /*
14 * 17 * Defines the version and type of the second bitmap header
15 * Checks if the conversion between the input image and the requested output
16 * image has been implemented
17 *
18 */ 18 */
19 static bool conversion_possible(const SkImageInfo& dst, 19 enum BmpHeaderType {
20 const SkImageInfo& src) { 20 kInfoV1_BmpHeaderType,
21 // Ensure that the profile type is unchanged 21 kInfoV2_BmpHeaderType,
22 if (dst.profileType() != src.profileType()) { 22 kInfoV3_BmpHeaderType,
23 return false; 23 kInfoV4_BmpHeaderType,
24 } 24 kInfoV5_BmpHeaderType,
25 25 kOS2V1_BmpHeaderType,
26 // Check for supported alpha types 26 kOS2VX_BmpHeaderType,
27 if (src.alphaType() != dst.alphaType()) { 27 kUnknown_BmpHeaderType
28 if (kOpaque_SkAlphaType == src.alphaType()) {
29 // If the source is opaque, we must decode to opaque
30 return false;
31 }
32
33 // The source is not opaque
34 switch (dst.alphaType()) {
35 case kPremul_SkAlphaType:
36 case kUnpremul_SkAlphaType:
37 // The source is not opaque, so either of these is okay
38 break;
39 default:
40 // We cannot decode a non-opaque image to opaque (or unknown)
41 return false;
42 }
43 }
44
45 // Check for supported color types
46 switch (dst.colorType()) {
47 // Allow output to kN32 from any type of input
48 case kN32_SkColorType:
49 return true;
50 // Allow output to kIndex_8 from compatible inputs
51 case kIndex_8_SkColorType:
52 return kIndex_8_SkColorType == src.colorType();
53 default:
54 return false;
55 }
56 }
57
58 /*
59 *
60 * Defines the version and type of the second bitmap header
61 *
62 */
63 enum BitmapHeaderType {
64 kInfoV1_BitmapHeaderType,
65 kInfoV2_BitmapHeaderType,
66 kInfoV3_BitmapHeaderType,
67 kInfoV4_BitmapHeaderType,
68 kInfoV5_BitmapHeaderType,
69 kOS2V1_BitmapHeaderType,
70 kOS2VX_BitmapHeaderType,
71 kUnknown_BitmapHeaderType
72 }; 28 };
73 29
74 /* 30 /*
75 *
76 * Possible bitmap compression types 31 * Possible bitmap compression types
77 *
78 */ 32 */
79 enum BitmapCompressionMethod { 33 enum BmpCompressionMethod {
80 kNone_BitmapCompressionMethod = 0, 34 kNone_BmpCompressionMethod = 0,
81 k8BitRLE_BitmapCompressionMethod = 1, 35 k8BitRLE_BmpCompressionMethod = 1,
82 k4BitRLE_BitmapCompressionMethod = 2, 36 k4BitRLE_BmpCompressionMethod = 2,
83 kBitMasks_BitmapCompressionMethod = 3, 37 kBitMasks_BmpCompressionMethod = 3,
84 kJpeg_BitmapCompressionMethod = 4, 38 kJpeg_BmpCompressionMethod = 4,
85 kPng_BitmapCompressionMethod = 5, 39 kPng_BmpCompressionMethod = 5,
86 kAlphaBitMasks_BitmapCompressionMethod = 6, 40 kAlphaBitMasks_BmpCompressionMethod = 6,
87 kCMYK_BitmapCompressionMethod = 11, 41 kCMYK_BmpCompressionMethod = 11,
88 kCMYK8BitRLE_BitmapCompressionMethod = 12, 42 kCMYK8BitRLE_BmpCompressionMethod = 12,
89 kCMYK4BitRLE_BitmapCompressionMethod = 13 43 kCMYK4BitRLE_BmpCompressionMethod = 13
90 }; 44 };
91 45
92 /* 46 /*
93 * 47 * Used to define the input format of the bmp
48 */
49 enum BmpInputFormat {
50 kStandard_BmpInputFormat,
51 kRLE_BmpInputFormat,
52 kBitMask_BmpInputFormat,
53 kUnknown_BmpInputFormat
54 };
55
56 /*
94 * Checks the start of the stream to see if the image is a bitmap 57 * Checks the start of the stream to see if the image is a bitmap
95 *
96 */ 58 */
97 bool SkBmpCodec::IsBmp(SkStream* stream) { 59 bool SkBmpCodec::IsBmp(SkStream* stream) {
98 // TODO: Support "IC", "PT", "CI", "CP", "BA" 60 // TODO: Support "IC", "PT", "CI", "CP", "BA"
99 const char bmpSig[] = { 'B', 'M' }; 61 const char bmpSig[] = { 'B', 'M' };
100 char buffer[sizeof(bmpSig)]; 62 char buffer[sizeof(bmpSig)];
101 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) && 63 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
102 !memcmp(buffer, bmpSig, sizeof(bmpSig)); 64 !memcmp(buffer, bmpSig, sizeof(bmpSig));
103 } 65 }
104 66
105 /* 67 /*
106 *
107 * Assumes IsBmp was called and returned true 68 * Assumes IsBmp was called and returned true
108 * Creates a bmp decoder 69 * Creates a bmp decoder
109 * Reads enough of the stream to determine the image format 70 * Reads enough of the stream to determine the image format
110 *
111 */ 71 */
112 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) { 72 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
113 return SkBmpCodec::NewFromStream(stream, false); 73 return SkBmpCodec::NewFromStream(stream, false);
114 } 74 }
115 75
116 /* 76 /*
117 *
118 * Creates a bmp decoder for a bmp embedded in ico 77 * Creates a bmp decoder for a bmp embedded in ico
119 * Reads enough of the stream to determine the image format 78 * Reads enough of the stream to determine the image format
120 *
121 */ 79 */
122 SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) { 80 SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
123 return SkBmpCodec::NewFromStream(stream, true); 81 return SkBmpCodec::NewFromStream(stream, true);
124 } 82 }
125 83
126 /* 84 /*
127 *
128 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool 85 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
129 * representing success or failure. If it returned true, and codecOut was 86 * representing success or failure. If it returned true, and codecOut was
130 * not NULL, it will be set to a new SkBmpCodec. 87 * not NULL, it will be set to a new SkBmpCodec.
131 * Does *not* take ownership of the passed in SkStream. 88 * Does *not* take ownership of the passed in SkStream.
132 *
133 */ 89 */
134 bool SkBmpCodec::ReadHeader(SkStream* stream, bool isIco, SkCodec** codecOut) { 90 bool SkBmpCodec::ReadHeader(SkStream* stream, bool inIco, SkCodec** codecOut) {
135 // Header size constants 91 // Header size constants
136 static const uint32_t kBmpHeaderBytes = 14; 92 static const uint32_t kBmpHeaderBytes = 14;
137 static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4; 93 static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
138 static const uint32_t kBmpOS2V1Bytes = 12; 94 static const uint32_t kBmpOS2V1Bytes = 12;
139 static const uint32_t kBmpOS2V2Bytes = 64; 95 static const uint32_t kBmpOS2V2Bytes = 64;
140 static const uint32_t kBmpInfoBaseBytes = 16; 96 static const uint32_t kBmpInfoBaseBytes = 16;
141 static const uint32_t kBmpInfoV1Bytes = 40; 97 static const uint32_t kBmpInfoV1Bytes = 40;
142 static const uint32_t kBmpInfoV2Bytes = 52; 98 static const uint32_t kBmpInfoV2Bytes = 52;
143 static const uint32_t kBmpInfoV3Bytes = 56; 99 static const uint32_t kBmpInfoV3Bytes = 56;
144 static const uint32_t kBmpInfoV4Bytes = 108; 100 static const uint32_t kBmpInfoV4Bytes = 108;
145 static const uint32_t kBmpInfoV5Bytes = 124; 101 static const uint32_t kBmpInfoV5Bytes = 124;
146 static const uint32_t kBmpMaskBytes = 12; 102 static const uint32_t kBmpMaskBytes = 12;
147 103
148 // The total bytes in the bmp file 104 // The total bytes in the bmp file
149 // We only need to use this value for RLE decoding, so we will only 105 // We only need to use this value for RLE decoding, so we will only
150 // check that it is valid in the RLE case. 106 // check that it is valid in the RLE case.
151 uint32_t totalBytes; 107 uint32_t totalBytes;
152 // The offset from the start of the file where the pixel data begins 108 // The offset from the start of the file where the pixel data begins
153 uint32_t offset; 109 uint32_t offset;
154 // The size of the second (info) header in bytes 110 // The size of the second (info) header in bytes
155 uint32_t infoBytes; 111 uint32_t infoBytes;
156 112
157 // Bmps embedded in Icos skip the first Bmp header 113 // Bmps embedded in Icos skip the first Bmp header
158 if (!isIco) { 114 if (!inIco) {
159 // Read the first header and the size of the second header 115 // Read the first header and the size of the second header
160 SkAutoTDeleteArray<uint8_t> hBuffer( 116 SkAutoTDeleteArray<uint8_t> hBuffer(
161 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour)); 117 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
162 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) != 118 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
163 kBmpHeaderBytesPlusFour) { 119 kBmpHeaderBytesPlusFour) {
164 SkCodecPrintf("Error: unable to read first bitmap header.\n"); 120 SkCodecPrintf("Error: unable to read first bitmap header.\n");
165 return false; 121 return false;
166 } 122 }
167 123
168 totalBytes = get_int(hBuffer.get(), 2); 124 totalBytes = get_int(hBuffer.get(), 2);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 SkNEW_ARRAY(uint8_t, infoBytesRemaining)); 169 SkNEW_ARRAY(uint8_t, infoBytesRemaining));
214 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) { 170 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
215 SkCodecPrintf("Error: unable to read second bitmap header.\n"); 171 SkCodecPrintf("Error: unable to read second bitmap header.\n");
216 return false; 172 return false;
217 } 173 }
218 174
219 // The number of bits used per pixel in the pixel data 175 // The number of bits used per pixel in the pixel data
220 uint16_t bitsPerPixel; 176 uint16_t bitsPerPixel;
221 177
222 // The compression method for the pixel data 178 // The compression method for the pixel data
223 uint32_t compression = kNone_BitmapCompressionMethod; 179 uint32_t compression = kNone_BmpCompressionMethod;
224 180
225 // Number of colors in the color table, defaults to 0 or max (see below) 181 // Number of colors in the color table, defaults to 0 or max (see below)
226 uint32_t numColors = 0; 182 uint32_t numColors = 0;
227 183
228 // Bytes per color in the color table, early versions use 3, most use 4 184 // Bytes per color in the color table, early versions use 3, most use 4
229 uint32_t bytesPerColor; 185 uint32_t bytesPerColor;
230 186
231 // The image width and height 187 // The image width and height
232 int width, height; 188 int width, height;
233 189
234 // Determine image information depending on second header format 190 // Determine image information depending on second header format
235 BitmapHeaderType headerType; 191 BmpHeaderType headerType;
236 if (infoBytes >= kBmpInfoBaseBytes) { 192 if (infoBytes >= kBmpInfoBaseBytes) {
237 // Check the version of the header 193 // Check the version of the header
238 switch (infoBytes) { 194 switch (infoBytes) {
239 case kBmpInfoV1Bytes: 195 case kBmpInfoV1Bytes:
240 headerType = kInfoV1_BitmapHeaderType; 196 headerType = kInfoV1_BmpHeaderType;
241 break; 197 break;
242 case kBmpInfoV2Bytes: 198 case kBmpInfoV2Bytes:
243 headerType = kInfoV2_BitmapHeaderType; 199 headerType = kInfoV2_BmpHeaderType;
244 break; 200 break;
245 case kBmpInfoV3Bytes: 201 case kBmpInfoV3Bytes:
246 headerType = kInfoV3_BitmapHeaderType; 202 headerType = kInfoV3_BmpHeaderType;
247 break; 203 break;
248 case kBmpInfoV4Bytes: 204 case kBmpInfoV4Bytes:
249 headerType = kInfoV4_BitmapHeaderType; 205 headerType = kInfoV4_BmpHeaderType;
250 break; 206 break;
251 case kBmpInfoV5Bytes: 207 case kBmpInfoV5Bytes:
252 headerType = kInfoV5_BitmapHeaderType; 208 headerType = kInfoV5_BmpHeaderType;
253 break; 209 break;
254 case 16: 210 case 16:
255 case 20: 211 case 20:
256 case 24: 212 case 24:
257 case 28: 213 case 28:
258 case 32: 214 case 32:
259 case 36: 215 case 36:
260 case 42: 216 case 42:
261 case 46: 217 case 46:
262 case 48: 218 case 48:
263 case 60: 219 case 60:
264 case kBmpOS2V2Bytes: 220 case kBmpOS2V2Bytes:
265 headerType = kOS2VX_BitmapHeaderType; 221 headerType = kOS2VX_BmpHeaderType;
266 break; 222 break;
267 default: 223 default:
268 // We do not signal an error here because there is the 224 // We do not signal an error here because there is the
269 // possibility of new or undocumented bmp header types. Most 225 // possibility of new or undocumented bmp header types. Most
270 // of the newer versions of bmp headers are similar to and 226 // of the newer versions of bmp headers are similar to and
271 // build off of the older versions, so we may still be able to 227 // build off of the older versions, so we may still be able to
272 // decode the bmp. 228 // decode the bmp.
273 SkCodecPrintf("Warning: unknown bmp header format.\n"); 229 SkCodecPrintf("Warning: unknown bmp header format.\n");
274 headerType = kUnknown_BitmapHeaderType; 230 headerType = kUnknown_BmpHeaderType;
275 break; 231 break;
276 } 232 }
277 // We check the size of the header before entering the if statement. 233 // We check the size of the header before entering the if statement.
278 // We should not reach this point unless the size is large enough for 234 // We should not reach this point unless the size is large enough for
279 // these required fields. 235 // these required fields.
280 SkASSERT(infoBytesRemaining >= 12); 236 SkASSERT(infoBytesRemaining >= 12);
281 width = get_int(iBuffer.get(), 0); 237 width = get_int(iBuffer.get(), 0);
282 height = get_int(iBuffer.get(), 4); 238 height = get_int(iBuffer.get(), 4);
283 bitsPerPixel = get_short(iBuffer.get(), 10); 239 bitsPerPixel = get_short(iBuffer.get(), 10);
284 240
285 // Some versions do not have these fields, so we check before 241 // Some versions do not have these fields, so we check before
286 // overwriting the default value. 242 // overwriting the default value.
287 if (infoBytesRemaining >= 16) { 243 if (infoBytesRemaining >= 16) {
288 compression = get_int(iBuffer.get(), 12); 244 compression = get_int(iBuffer.get(), 12);
289 if (infoBytesRemaining >= 32) { 245 if (infoBytesRemaining >= 32) {
290 numColors = get_int(iBuffer.get(), 28); 246 numColors = get_int(iBuffer.get(), 28);
291 } 247 }
292 } 248 }
293 249
294 // All of the headers that reach this point, store color table entries 250 // All of the headers that reach this point, store color table entries
295 // using 4 bytes per pixel. 251 // using 4 bytes per pixel.
296 bytesPerColor = 4; 252 bytesPerColor = 4;
297 } else if (infoBytes >= kBmpOS2V1Bytes) { 253 } else if (infoBytes >= kBmpOS2V1Bytes) {
298 // The OS2V1 is treated separately because it has a unique format 254 // The OS2V1 is treated separately because it has a unique format
299 headerType = kOS2V1_BitmapHeaderType; 255 headerType = kOS2V1_BmpHeaderType;
300 width = (int) get_short(iBuffer.get(), 0); 256 width = (int) get_short(iBuffer.get(), 0);
301 height = (int) get_short(iBuffer.get(), 2); 257 height = (int) get_short(iBuffer.get(), 2);
302 bitsPerPixel = get_short(iBuffer.get(), 6); 258 bitsPerPixel = get_short(iBuffer.get(), 6);
303 bytesPerColor = 3; 259 bytesPerColor = 3;
304 } else { 260 } else {
305 // There are no valid bmp headers 261 // There are no valid bmp headers
306 SkCodecPrintf("Error: second bitmap header size is invalid.\n"); 262 SkCodecPrintf("Error: second bitmap header size is invalid.\n");
307 return false; 263 return false;
308 } 264 }
309 265
310 // Check for valid dimensions from header 266 // Check for valid dimensions from header
311 RowOrder rowOrder = kBottomUp_RowOrder; 267 RowOrder rowOrder = kBottomUp_RowOrder;
312 if (height < 0) { 268 if (height < 0) {
313 height = -height; 269 height = -height;
314 rowOrder = kTopDown_RowOrder; 270 rowOrder = kTopDown_RowOrder;
315 } 271 }
316 // The height field for bmp in ico is double the actual height because they 272 // The height field for bmp in ico is double the actual height because they
317 // contain an XOR mask followed by an AND mask 273 // contain an XOR mask followed by an AND mask
318 if (isIco) { 274 if (inIco) {
319 height /= 2; 275 height /= 2;
320 } 276 }
321 if (width <= 0 || height <= 0) { 277 if (width <= 0 || height <= 0) {
322 // TODO: Decide if we want to disable really large bmps as well. 278 // TODO: Decide if we want to disable really large bmps as well.
323 // https://code.google.com/p/skia/issues/detail?id=3617 279 // https://code.google.com/p/skia/issues/detail?id=3617
324 SkCodecPrintf("Error: invalid bitmap dimensions.\n"); 280 SkCodecPrintf("Error: invalid bitmap dimensions.\n");
325 return false; 281 return false;
326 } 282 }
327 283
328 // Create mask struct 284 // Create mask struct
329 SkMasks::InputMasks inputMasks; 285 SkMasks::InputMasks inputMasks;
330 memset(&inputMasks, 0, sizeof(SkMasks::InputMasks)); 286 memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
331 287
332 // Determine the input compression format and set bit masks if necessary 288 // Determine the input compression format and set bit masks if necessary
333 uint32_t maskBytes = 0; 289 uint32_t maskBytes = 0;
334 BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat; 290 BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
335 switch (compression) { 291 switch (compression) {
336 case kNone_BitmapCompressionMethod: 292 case kNone_BmpCompressionMethod:
337 inputFormat = kStandard_BitmapInputFormat; 293 inputFormat = kStandard_BmpInputFormat;
338 break; 294 break;
339 case k8BitRLE_BitmapCompressionMethod: 295 case k8BitRLE_BmpCompressionMethod:
340 if (bitsPerPixel != 8) { 296 if (bitsPerPixel != 8) {
341 SkCodecPrintf("Warning: correcting invalid bitmap format.\n"); 297 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
342 bitsPerPixel = 8; 298 bitsPerPixel = 8;
343 } 299 }
344 inputFormat = kRLE_BitmapInputFormat; 300 inputFormat = kRLE_BmpInputFormat;
345 break; 301 break;
346 case k4BitRLE_BitmapCompressionMethod: 302 case k4BitRLE_BmpCompressionMethod:
347 if (bitsPerPixel != 4) { 303 if (bitsPerPixel != 4) {
348 SkCodecPrintf("Warning: correcting invalid bitmap format.\n"); 304 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
349 bitsPerPixel = 4; 305 bitsPerPixel = 4;
350 } 306 }
351 inputFormat = kRLE_BitmapInputFormat; 307 inputFormat = kRLE_BmpInputFormat;
352 break; 308 break;
353 case kAlphaBitMasks_BitmapCompressionMethod: 309 case kAlphaBitMasks_BmpCompressionMethod:
354 case kBitMasks_BitmapCompressionMethod: 310 case kBitMasks_BmpCompressionMethod:
355 // Load the masks 311 // Load the masks
356 inputFormat = kBitMask_BitmapInputFormat; 312 inputFormat = kBitMask_BmpInputFormat;
357 switch (headerType) { 313 switch (headerType) {
358 case kInfoV1_BitmapHeaderType: { 314 case kInfoV1_BmpHeaderType: {
359 // The V1 header stores the bit masks after the header 315 // The V1 header stores the bit masks after the header
360 SkAutoTDeleteArray<uint8_t> mBuffer( 316 SkAutoTDeleteArray<uint8_t> mBuffer(
361 SkNEW_ARRAY(uint8_t, kBmpMaskBytes)); 317 SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
362 if (stream->read(mBuffer.get(), kBmpMaskBytes) != 318 if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
363 kBmpMaskBytes) { 319 kBmpMaskBytes) {
364 SkCodecPrintf("Error: unable to read bit inputMasks.\n") ; 320 SkCodecPrintf("Error: unable to read bit inputMasks.\n") ;
365 return false; 321 return false;
366 } 322 }
367 maskBytes = kBmpMaskBytes; 323 maskBytes = kBmpMaskBytes;
368 inputMasks.red = get_int(mBuffer.get(), 0); 324 inputMasks.red = get_int(mBuffer.get(), 0);
369 inputMasks.green = get_int(mBuffer.get(), 4); 325 inputMasks.green = get_int(mBuffer.get(), 4);
370 inputMasks.blue = get_int(mBuffer.get(), 8); 326 inputMasks.blue = get_int(mBuffer.get(), 8);
371 break; 327 break;
372 } 328 }
373 case kInfoV2_BitmapHeaderType: 329 case kInfoV2_BmpHeaderType:
374 case kInfoV3_BitmapHeaderType: 330 case kInfoV3_BmpHeaderType:
375 case kInfoV4_BitmapHeaderType: 331 case kInfoV4_BmpHeaderType:
376 case kInfoV5_BitmapHeaderType: 332 case kInfoV5_BmpHeaderType:
377 // Header types are matched based on size. If the header 333 // Header types are matched based on size. If the header
378 // is V2+, we are guaranteed to be able to read at least 334 // is V2+, we are guaranteed to be able to read at least
379 // this size. 335 // this size.
380 SkASSERT(infoBytesRemaining >= 48); 336 SkASSERT(infoBytesRemaining >= 48);
381 inputMasks.red = get_int(iBuffer.get(), 36); 337 inputMasks.red = get_int(iBuffer.get(), 36);
382 inputMasks.green = get_int(iBuffer.get(), 40); 338 inputMasks.green = get_int(iBuffer.get(), 40);
383 inputMasks.blue = get_int(iBuffer.get(), 44); 339 inputMasks.blue = get_int(iBuffer.get(), 44);
384 break; 340 break;
385 case kOS2VX_BitmapHeaderType: 341 case kOS2VX_BmpHeaderType:
386 // TODO: Decide if we intend to support this. 342 // TODO: Decide if we intend to support this.
387 // It is unsupported in the previous version and 343 // It is unsupported in the previous version and
388 // in chromium. I have not come across a test case 344 // in chromium. I have not come across a test case
389 // that uses this format. 345 // that uses this format.
390 SkCodecPrintf("Error: huffman format unsupported.\n"); 346 SkCodecPrintf("Error: huffman format unsupported.\n");
391 return false; 347 return false;
392 default: 348 default:
393 SkCodecPrintf("Error: invalid bmp bit masks header.\n"); 349 SkCodecPrintf("Error: invalid bmp bit masks header.\n");
394 return false; 350 return false;
395 } 351 }
396 break; 352 break;
397 case kJpeg_BitmapCompressionMethod: 353 case kJpeg_BmpCompressionMethod:
398 if (24 == bitsPerPixel) { 354 if (24 == bitsPerPixel) {
399 inputFormat = kRLE_BitmapInputFormat; 355 inputFormat = kRLE_BmpInputFormat;
400 break; 356 break;
401 } 357 }
402 // Fall through 358 // Fall through
403 case kPng_BitmapCompressionMethod: 359 case kPng_BmpCompressionMethod:
404 // TODO: Decide if we intend to support this. 360 // TODO: Decide if we intend to support this.
405 // It is unsupported in the previous version and 361 // It is unsupported in the previous version and
406 // in chromium. I think it is used mostly for printers. 362 // in chromium. I think it is used mostly for printers.
407 SkCodecPrintf("Error: compression format not supported.\n"); 363 SkCodecPrintf("Error: compression format not supported.\n");
408 return false; 364 return false;
409 case kCMYK_BitmapCompressionMethod: 365 case kCMYK_BmpCompressionMethod:
410 case kCMYK8BitRLE_BitmapCompressionMethod: 366 case kCMYK8BitRLE_BmpCompressionMethod:
411 case kCMYK4BitRLE_BitmapCompressionMethod: 367 case kCMYK4BitRLE_BmpCompressionMethod:
412 // TODO: Same as above. 368 // TODO: Same as above.
413 SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n"); 369 SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
414 return false; 370 return false;
415 default: 371 default:
416 SkCodecPrintf("Error: invalid format for bitmap decoding.\n"); 372 SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
417 return false; 373 return false;
418 } 374 }
419 375
420 // Most versions of bmps should be rendered as opaque. Either they do 376 // Most versions of bmps should be rendered as opaque. Either they do
421 // not have an alpha channel, or they expect the alpha channel to be 377 // not have an alpha channel, or they expect the alpha channel to be
422 // ignored. V3+ bmp files introduce an alpha mask and allow the creator 378 // ignored. V3+ bmp files introduce an alpha mask and allow the creator
423 // of the image to use the alpha channels. However, many of these images 379 // of the image to use the alpha channels. However, many of these images
424 // leave the alpha channel blank and expect to be rendered as opaque. This 380 // leave the alpha channel blank and expect to be rendered as opaque. This
425 // is the case for almost all V3 images, so we render these as opaque. For 381 // is the case for almost all V3 images, so we render these as opaque. For
426 // V4+, we will use the alpha channel, and fix the image later if it turns 382 // V4+, we will use the alpha channel, and fix the image later if it turns
427 // out to be fully transparent. 383 // out to be fully transparent.
428 // As an exception, V3 bmp-in-ico may use an alpha mask. 384 // As an exception, V3 bmp-in-ico may use an alpha mask.
429 SkAlphaType alphaType = kOpaque_SkAlphaType; 385 SkAlphaType alphaType = kOpaque_SkAlphaType;
430 if ((kInfoV3_BitmapHeaderType == headerType && isIco) || 386 if ((kInfoV3_BmpHeaderType == headerType && inIco) ||
431 kInfoV4_BitmapHeaderType == headerType || 387 kInfoV4_BmpHeaderType == headerType ||
432 kInfoV5_BitmapHeaderType == headerType) { 388 kInfoV5_BmpHeaderType == headerType) {
433 // Header types are matched based on size. If the header is 389 // Header types are matched based on size. If the header is
434 // V3+, we are guaranteed to be able to read at least this size. 390 // V3+, we are guaranteed to be able to read at least this size.
435 SkASSERT(infoBytesRemaining > 52); 391 SkASSERT(infoBytesRemaining > 52);
436 inputMasks.alpha = get_int(iBuffer.get(), 48); 392 inputMasks.alpha = get_int(iBuffer.get(), 48);
437 if (inputMasks.alpha != 0) { 393 if (inputMasks.alpha != 0) {
438 alphaType = kUnpremul_SkAlphaType; 394 alphaType = kUnpremul_SkAlphaType;
439 } 395 }
440 } 396 }
441 iBuffer.free(); 397 iBuffer.free();
442 398
443 // Additionally, 32 bit bmp-in-icos use the alpha channel. 399 // Additionally, 32 bit bmp-in-icos use the alpha channel.
444 // And, RLE inputs may skip pixels, leaving them as transparent. This 400 // And, RLE inputs may skip pixels, leaving them as transparent. This
445 // is uncommon, but we cannot be certain that an RLE bmp will be opaque. 401 // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
446 if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat) ) { 402 if ((inIco && 32 == bitsPerPixel) || (kRLE_BmpInputFormat == inputFormat)) {
447 alphaType = kUnpremul_SkAlphaType; 403 alphaType = kUnpremul_SkAlphaType;
448 } 404 }
449 405
450 // Check for valid bits per pixel. 406 // Check for valid bits per pixel.
451 // At the same time, use this information to choose a suggested color type 407 // At the same time, use this information to choose a suggested color type
452 // and to set default masks. 408 // and to set default masks.
453 SkColorType colorType = kN32_SkColorType; 409 SkColorType colorType = kN32_SkColorType;
454 switch (bitsPerPixel) { 410 switch (bitsPerPixel) {
455 // In addition to more standard pixel compression formats, bmp supports 411 // In addition to more standard pixel compression formats, bmp supports
456 // the use of bit masks to determine pixel components. The standard 412 // the use of bit masks to determine pixel components. The standard
457 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB), 413 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
458 // which does not map well to any Skia color formats. For this reason, 414 // which does not map well to any Skia color formats. For this reason,
459 // we will always enable mask mode with 16 bits per pixel. 415 // we will always enable mask mode with 16 bits per pixel.
460 case 16: 416 case 16:
461 if (kBitMask_BitmapInputFormat != inputFormat) { 417 if (kBitMask_BmpInputFormat != inputFormat) {
462 inputMasks.red = 0x7C00; 418 inputMasks.red = 0x7C00;
463 inputMasks.green = 0x03E0; 419 inputMasks.green = 0x03E0;
464 inputMasks.blue = 0x001F; 420 inputMasks.blue = 0x001F;
465 inputFormat = kBitMask_BitmapInputFormat; 421 inputFormat = kBitMask_BmpInputFormat;
466 } 422 }
467 break; 423 break;
468 // We want to decode to kIndex_8 for input formats that are already 424 // We want to decode to kIndex_8 for input formats that are already
469 // designed in index format. 425 // designed in index format.
470 case 1: 426 case 1:
471 case 2: 427 case 2:
472 case 4: 428 case 4:
473 case 8: 429 case 8:
474 // However, we cannot in RLE format since we may need to leave some 430 // However, we cannot in RLE format since we may need to leave some
475 // pixels as transparent. Similarly, we also cannot for ICO images 431 // pixels as transparent. Similarly, we also cannot for ICO images
476 // since we may need to apply a transparent mask. 432 // since we may need to apply a transparent mask.
477 if (kRLE_BitmapInputFormat != inputFormat && !isIco) { 433 if (kRLE_BmpInputFormat != inputFormat && !inIco) {
478 colorType = kIndex_8_SkColorType; 434 colorType = kIndex_8_SkColorType;
479 } 435 }
480 case 24: 436 case 24:
481 case 32: 437 case 32:
482 break; 438 break;
483 default: 439 default:
484 SkCodecPrintf("Error: invalid input value for bits per pixel.\n"); 440 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
485 return false; 441 return false;
486 } 442 }
487 443
488 // Check that input bit masks are valid and create the masks object 444 // Check that input bit masks are valid and create the masks object
489 SkAutoTDelete<SkMasks> 445 SkAutoTDelete<SkMasks>
490 masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel)); 446 masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
491 if (NULL == masks) { 447 if (NULL == masks) {
492 SkCodecPrintf("Error: invalid input masks.\n"); 448 SkCodecPrintf("Error: invalid input masks.\n");
493 return false; 449 return false;
494 } 450 }
495 451
496 // Check for a valid number of total bytes when in RLE mode 452 // Check for a valid number of total bytes when in RLE mode
497 if (totalBytes <= offset && kRLE_BitmapInputFormat == inputFormat) { 453 if (totalBytes <= offset && kRLE_BmpInputFormat == inputFormat) {
498 SkCodecPrintf("Error: RLE requires valid input size.\n"); 454 SkCodecPrintf("Error: RLE requires valid input size.\n");
499 return false; 455 return false;
500 } 456 }
501 const size_t RLEBytes = totalBytes - offset; 457 const size_t RLEBytes = totalBytes - offset;
502 458
503 // Calculate the number of bytes read so far 459 // Calculate the number of bytes read so far
504 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes; 460 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
505 if (!isIco && offset < bytesRead) { 461 if (!inIco && offset < bytesRead) {
506 SkCodecPrintf("Error: pixel data offset less than header size.\n"); 462 SkCodecPrintf("Error: pixel data offset less than header size.\n");
507 return false; 463 return false;
508 } 464 }
509 465
510 if (codecOut) { 466 if (codecOut) {
511 // Return the codec 467 // Set the image info
512 // We will use ImageInfo to store width, height, suggested color type, a nd
513 // suggested alpha type.
514 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, 468 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
515 colorType, alphaType); 469 colorType, alphaType);
516 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel, 470
517 inputFormat, masks.detach(), 471 // Return the codec
518 numColors, bytesPerColor, 472 switch (inputFormat) {
519 offset - bytesRead, rowOrder, 473 case kStandard_BmpInputFormat:
520 RLEBytes, isIco)); 474 *codecOut = SkNEW_ARGS(SkBmpStandardCodec, (imageInfo, stream,
475 bitsPerPixel, numColors, bytesPerColor,
476 offset - bytesRead, rowOrder, inIco));
477 return true;
478 case kBitMask_BmpInputFormat:
479 // Bmp-in-Ico must be standard mode
480 if (inIco) {
481 return false;
482 }
483 // Skip to the start of the pixel array.
484 // We can do this here because there is no color table to read
485 // in bit mask mode.
486 if (stream->skip(offset - bytesRead) != offset - bytesRead) {
487 SkCodecPrintf("Error: unable to skip to image data.\n");
488 return false;
489 }
490
491 *codecOut = SkNEW_ARGS(SkBmpMaskCodec, (imageInfo, stream,
492 bitsPerPixel, masks.detach(), rowOrder));
493 return true;
494 case kRLE_BmpInputFormat:
495 // Bmp-in-Ico must be standard mode
496 if (inIco) {
497 return false;
498 }
499 *codecOut = SkNEW_ARGS(SkBmpRLECodec, (
500 imageInfo, stream, bitsPerPixel, numColors,
501 bytesPerColor, offset - bytesRead, rowOrder, RLEBytes));
502 return true;
503 default:
504 SkASSERT(false);
505 return false;
506 }
521 } 507 }
508
522 return true; 509 return true;
523 } 510 }
524 511
525 /* 512 /*
526 *
527 * Creates a bmp decoder 513 * Creates a bmp decoder
528 * Reads enough of the stream to determine the image format 514 * Reads enough of the stream to determine the image format
529 *
530 */ 515 */
531 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) { 516 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool inIco) {
532 SkAutoTDelete<SkStream> streamDeleter(stream); 517 SkAutoTDelete<SkStream> streamDeleter(stream);
533 SkCodec* codec = NULL; 518 SkCodec* codec = NULL;
534 if (ReadHeader(stream, isIco, &codec)) { 519 if (ReadHeader(stream, inIco, &codec)) {
535 // codec has taken ownership of stream, so we do not need to 520 // codec has taken ownership of stream, so we do not need to
536 // delete it. 521 // delete it.
537 SkASSERT(codec); 522 SkASSERT(codec);
538 streamDeleter.detach(); 523 streamDeleter.detach();
539 return codec; 524 return codec;
540 } 525 }
541 return NULL; 526 return NULL;
542 } 527 }
543 528
544 /*
545 *
546 * Creates an instance of the decoder
547 * Called only by NewFromStream
548 *
549 */
550 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream, 529 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
551 uint16_t bitsPerPixel, BitmapInputFormat inputFormat, 530 uint16_t bitsPerPixel, RowOrder rowOrder)
552 SkMasks* masks, uint32_t numColors,
553 uint32_t bytesPerColor, uint32_t offset,
554 RowOrder rowOrder, size_t RLEBytes, bool isIco)
555 : INHERITED(info, stream) 531 : INHERITED(info, stream)
556 , fBitsPerPixel(bitsPerPixel) 532 , fBitsPerPixel(bitsPerPixel)
557 , fInputFormat(inputFormat)
558 , fMasks(masks)
559 , fColorTable(NULL)
560 , fNumColors(numColors)
561 , fBytesPerColor(bytesPerColor)
562 , fOffset(offset)
563 , fRowOrder(rowOrder) 533 , fRowOrder(rowOrder)
564 , fRLEBytes(RLEBytes)
565 , fIsIco(isIco)
566
567 {} 534 {}
568 535
569 /* 536 /*
570 * 537 * Rewinds the image stream if necessary
571 * Initiates the bitmap decode
572 *
573 */ 538 */
574 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, 539 bool SkBmpCodec::handleRewind(bool inIco) {
575 void* dst, size_t dstRowBytes,
576 const Options& opts,
577 SkPMColor* inputColorPtr,
578 int* inputColorCount) {
579 // Check for proper input and output formats
580 SkCodec::RewindState rewindState = this->rewindIfNeeded(); 540 SkCodec::RewindState rewindState = this->rewindIfNeeded();
581 if (rewindState == kCouldNotRewind_RewindState) { 541 if (rewindState == kCouldNotRewind_RewindState) {
582 return kCouldNotRewind; 542 return false;
583 } else if (rewindState == kRewound_RewindState) { 543 } else if (rewindState == kRewound_RewindState) {
584 if (!ReadHeader(this->stream(), fIsIco, NULL)) { 544 if (!SkBmpCodec::ReadHeader(this->stream(), inIco, NULL)) {
585 return kCouldNotRewind;
586 }
587 }
588 if (opts.fSubset) {
589 // Subsets are not supported.
590 return kUnimplemented;
591 }
592 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
593 SkCodecPrintf("Error: scaling not supported.\n");
594 return kInvalidScale;
595 }
596 if (!conversion_possible(dstInfo, this->getInfo())) {
597 SkCodecPrintf("Error: cannot convert input type to output type.\n");
598 return kInvalidConversion;
599 }
600
601 // Create the color table if necessary and prepare the stream for decode
602 // Note that if it is non-NULL, inputColorCount will be modified
603 if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
604 SkCodecPrintf("Error: could not create color table.\n");
605 return kInvalidInput;
606 }
607
608 // Copy the color table to the client if necessary
609 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount);
610
611 // Perform the decode
612 switch (fInputFormat) {
613 case kBitMask_BitmapInputFormat:
614 return decodeMask(dstInfo, dst, dstRowBytes, opts);
615 case kRLE_BitmapInputFormat:
616 return decodeRLE(dstInfo, dst, dstRowBytes, opts);
617 case kStandard_BitmapInputFormat:
618 return decode(dstInfo, dst, dstRowBytes, opts);
619 default:
620 SkASSERT(false);
621 return kInvalidInput;
622 }
623 }
624
625 /*
626 *
627 * Process the color table for the bmp input
628 *
629 */
630 bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
631 // Allocate memory for color table
632 uint32_t colorBytes = 0;
633 uint32_t maxColors = 0;
634 SkPMColor colorTable[256];
635 if (fBitsPerPixel <= 8) {
636 // Zero is a default for maxColors
637 // Also set fNumColors to maxColors when it is too large
638 maxColors = 1 << fBitsPerPixel;
639 if (fNumColors == 0 || fNumColors >= maxColors) {
640 fNumColors = maxColors;
641 }
642
643 // Inform the caller of the number of colors
644 if (NULL != numColors) {
645 // We set the number of colors to maxColors in order to ensure
646 // safe memory accesses. Otherwise, an invalid pixel could
647 // access memory outside of our color table array.
648 *numColors = maxColors;
649 }
650
651 // Read the color table from the stream
652 colorBytes = fNumColors * fBytesPerColor;
653 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
654 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
655 SkCodecPrintf("Error: unable to read color table.\n");
656 return false;
657 }
658
659 // Choose the proper packing function
660 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
661 switch (alphaType) {
662 case kOpaque_SkAlphaType:
663 case kUnpremul_SkAlphaType:
664 packARGB = &SkPackARGB32NoCheck;
665 break;
666 case kPremul_SkAlphaType:
667 packARGB = &SkPreMultiplyARGB;
668 break;
669 default:
670 // This should not be reached because conversion possible
671 // should fail if the alpha type is not one of the above
672 // values.
673 SkASSERT(false);
674 packARGB = NULL;
675 break;
676 }
677
678 // Fill in the color table
679 uint32_t i = 0;
680 for (; i < fNumColors; i++) {
681 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
682 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
683 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
684 uint8_t alpha;
685 if (kOpaque_SkAlphaType == alphaType || kRLE_BitmapInputFormat == fI nputFormat) {
686 alpha = 0xFF;
687 } else {
688 alpha = (fMasks->getAlphaMask() >> 24) &
689 get_byte(cBuffer.get(), i*fBytesPerColor + 3);
690 }
691 colorTable[i] = packARGB(alpha, red, green, blue);
692 }
693
694 // To avoid segmentation faults on bad pixel data, fill the end of the
695 // color table with black. This is the same the behavior as the
696 // chromium decoder.
697 for (; i < maxColors; i++) {
698 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
699 }
700
701 // Set the color table
702 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
703 }
704
705 // Bmp-in-Ico files do not use an offset to indicate where the pixel data
706 // begins. Pixel data always begins immediately after the color table.
707 if (!fIsIco) {
708 // Check that we have not read past the pixel array offset
709 if(fOffset < colorBytes) {
710 // This may occur on OS 2.1 and other old versions where the color
711 // table defaults to max size, and the bmp tries to use a smaller
712 // color table. This is invalid, and our decision is to indicate
713 // an error, rather than try to guess the intended size of the
714 // color table.
715 SkCodecPrintf("Error: pixel data offset less than color table size.\ n");
716 return false;
717 }
718
719 // After reading the color table, skip to the start of the pixel array
720 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
721 SkCodecPrintf("Error: unable to skip to image data.\n");
722 return false; 545 return false;
723 } 546 }
724 } 547 }
725
726 // Return true on success
727 return true; 548 return true;
728 } 549 }
729 550
730 /* 551 /*
731 *
732 * Get the destination row to start filling from 552 * Get the destination row to start filling from
733 * Used to fill the remainder of the image on incomplete input 553 * Used to fill the remainder of the image on incomplete input for bmps
734 * 554 * This is tricky since bmps may be kTopDown or kBottomUp. For kTopDown,
555 * we start filling from where we left off, but for kBottomUp we start
556 * filling at the top of the image.
735 */ 557 */
736 static inline void* get_dst_start_row(void* dst, size_t dstRowBytes, int32_t y, 558 void* SkBmpCodec::getDstStartRow(void* dst, size_t dstRowBytes, int32_t y) const {
737 SkBmpCodec::RowOrder rowOrder) { 559 return (kTopDown_RowOrder == fRowOrder) ? SkTAddOffset<void*>(dst, y * dstRo wBytes) : dst;
738 return (SkBmpCodec::kTopDown_RowOrder == rowOrder) ?
739 SkTAddOffset<void*>(dst, y * dstRowBytes) : dst;
740 } 560 }
741 561
742 /* 562 /*
743 * 563 * Compute the number of colors in the color table
744 * Performs the bitmap decoding for bit masks input format
745 *
746 */ 564 */
747 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, 565 uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) {
748 void* dst, size_t dstRowBytes, 566 // Zero is a default for maxColors
749 const Options& opts) { 567 // Also set fNumColors to maxColors when it is too large
750 // Set constant values 568 uint32_t maxColors = 1 << fBitsPerPixel;
751 const int width = dstInfo.width(); 569 if (numColors == 0 || numColors >= maxColors) {
752 const int height = dstInfo.height(); 570 return maxColors;
753 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
754
755 // Allocate a buffer large enough to hold the full image
756 SkAutoTDeleteArray<uint8_t>
757 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes));
758 uint8_t* srcRow = srcBuffer.get();
759
760 // Create the swizzler
761 SkAutoTDelete<SkMaskSwizzler> maskSwizzler(
762 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, fMasks, fBitsPerPixel));
763
764 // Iterate over rows of the image
765 bool transparent = true;
766 for (int y = 0; y < height; y++) {
767 // Read a row of the input
768 if (stream()->read(srcRow, rowBytes) != rowBytes) {
769 SkCodecPrintf("Warning: incomplete input stream.\n");
770 // Fill the destination image on failure
771 SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ?
772 SK_ColorBLACK : SK_ColorTRANSPARENT;
773 if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) {
774 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r);
775 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y, fillColor,
776 NULL);
777 }
778 return kIncompleteInput;
779 }
780
781 // Decode the row in destination format
782 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
783 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row);
784 SkSwizzler::ResultAlpha r = maskSwizzler->swizzle(dstRow, srcRow);
785 transparent &= SkSwizzler::IsTransparent(r);
786
787 // Move to the next row
788 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
789 } 571 }
790 572 return numColors;
791 // Some fully transparent bmp images are intended to be opaque. Here, we
792 // correct for this possibility.
793 if (transparent) {
794 const SkImageInfo& opaqueInfo =
795 dstInfo.makeAlphaType(kOpaque_SkAlphaType);
796 SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler(
797 SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, fMasks, fBitsPerP ixel));
798 srcRow = srcBuffer.get();
799 for (int y = 0; y < height; y++) {
800 // Decode the row in opaque format
801 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
802 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row);
803 opaqueSwizzler->swizzle(dstRow, srcRow);
804
805 // Move to the next row
806 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
807 }
808 }
809
810 // Finished decoding the entire image
811 return kSuccess;
812 } 573 }
813
814 /*
815 *
816 * Set an RLE pixel using the color table
817 *
818 */
819 void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
820 const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
821 uint8_t index) {
822 // Set the row
823 int height = dstInfo.height();
824 int row;
825 if (kBottomUp_RowOrder == fRowOrder) {
826 row = height - y - 1;
827 } else {
828 row = y;
829 }
830
831 // Set the pixel based on destination color type
832 switch (dstInfo.colorType()) {
833 case kN32_SkColorType: {
834 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
835 row * (int) dstRowBytes);
836 dstRow[x] = fColorTable->operator[](index);
837 break;
838 }
839 default:
840 // This case should not be reached. We should catch an invalid
841 // color type when we check that the conversion is possible.
842 SkASSERT(false);
843 break;
844 }
845 }
846
847 /*
848 *
849 * Set an RLE pixel from R, G, B values
850 *
851 */
852 void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
853 const SkImageInfo& dstInfo, uint32_t x,
854 uint32_t y, uint8_t red, uint8_t green,
855 uint8_t blue) {
856 // Set the row
857 int height = dstInfo.height();
858 int row;
859 if (kBottomUp_RowOrder == fRowOrder) {
860 row = height - y - 1;
861 } else {
862 row = y;
863 }
864
865 // Set the pixel based on destination color type
866 switch (dstInfo.colorType()) {
867 case kN32_SkColorType: {
868 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
869 row * (int) dstRowBytes);
870 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
871 break;
872 }
873 default:
874 // This case should not be reached. We should catch an invalid
875 // color type when we check that the conversion is possible.
876 SkASSERT(false);
877 break;
878 }
879 }
880
881 /*
882 *
883 * Performs the bitmap decoding for RLE input format
884 * RLE decoding is performed all at once, rather than a one row at a time
885 *
886 */
887 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
888 void* dst, size_t dstRowBytes,
889 const Options& opts) {
890 // Set RLE flags
891 static const uint8_t RLE_ESCAPE = 0;
892 static const uint8_t RLE_EOL = 0;
893 static const uint8_t RLE_EOF = 1;
894 static const uint8_t RLE_DELTA = 2;
895
896 // Set constant values
897 const int width = dstInfo.width();
898 const int height = dstInfo.height();
899
900 // Input buffer parameters
901 uint32_t currByte = 0;
902 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
903 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
904 if (totalBytes < fRLEBytes) {
905 SkCodecPrintf("Warning: incomplete RLE file.\n");
906 } else if (totalBytes <= 0) {
907 SkCodecPrintf("Error: could not read RLE image data.\n");
908 return kInvalidInput;
909 }
910
911 // Destination parameters
912 int x = 0;
913 int y = 0;
914
915 // Set the background as transparent. Then, if the RLE code skips pixels,
916 // the skipped pixels will be transparent.
917 // Because of the need for transparent pixels, kN32 is the only color
918 // type that makes sense for the destination format.
919 SkASSERT(kN32_SkColorType == dstInfo.colorType());
920 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
921 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL);
922 }
923
924 while (true) {
925 // Every entry takes at least two bytes
926 if ((int) totalBytes - currByte < 2) {
927 SkCodecPrintf("Warning: incomplete RLE input.\n");
928 return kIncompleteInput;
929 }
930
931 // Read the next two bytes. These bytes have different meanings
932 // depending on their values. In the first interpretation, the first
933 // byte is an escape flag and the second byte indicates what special
934 // task to perform.
935 const uint8_t flag = buffer.get()[currByte++];
936 const uint8_t task = buffer.get()[currByte++];
937
938 // If we have reached a row that is beyond the image size, and the RLE
939 // code does not indicate end of file, abort and signal a warning.
940 if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
941 SkCodecPrintf("Warning: invalid RLE input.\n");
942 return kIncompleteInput;
943 }
944
945 // Perform decoding
946 if (RLE_ESCAPE == flag) {
947 switch (task) {
948 case RLE_EOL:
949 x = 0;
950 y++;
951 break;
952 case RLE_EOF:
953 return kSuccess;
954 case RLE_DELTA: {
955 // Two bytes are needed to specify delta
956 if ((int) totalBytes - currByte < 2) {
957 SkCodecPrintf("Warning: incomplete RLE input\n");
958 return kIncompleteInput;
959 }
960 // Modify x and y
961 const uint8_t dx = buffer.get()[currByte++];
962 const uint8_t dy = buffer.get()[currByte++];
963 x += dx;
964 y += dy;
965 if (x > width || y > height) {
966 SkCodecPrintf("Warning: invalid RLE input.\n");
967 return kIncompleteInput;
968 }
969 break;
970 }
971 default: {
972 // If task does not match any of the above signals, it
973 // indicates that we have a sequence of non-RLE pixels.
974 // Furthermore, the value of task is equal to the number
975 // of pixels to interpret.
976 uint8_t numPixels = task;
977 const size_t rowBytes = compute_row_bytes(numPixels,
978 fBitsPerPixel);
979 // Abort if setting numPixels moves us off the edge of the
980 // image. Also abort if there are not enough bytes
981 // remaining in the stream to set numPixels.
982 if (x + numPixels > width ||
983 (int) totalBytes - currByte < SkAlign2(rowBytes)) {
984 SkCodecPrintf("Warning: invalid RLE input.\n");
985 return kIncompleteInput;
986 }
987 // Set numPixels number of pixels
988 while (numPixels > 0) {
989 switch(fBitsPerPixel) {
990 case 4: {
991 SkASSERT(currByte < totalBytes);
992 uint8_t val = buffer.get()[currByte++];
993 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
994 y, val >> 4);
995 numPixels--;
996 if (numPixels != 0) {
997 setRLEPixel(dst, dstRowBytes, dstInfo,
998 x++, y, val & 0xF);
999 numPixels--;
1000 }
1001 break;
1002 }
1003 case 8:
1004 SkASSERT(currByte < totalBytes);
1005 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
1006 y, buffer.get()[currByte++]);
1007 numPixels--;
1008 break;
1009 case 24: {
1010 SkASSERT(currByte + 2 < totalBytes);
1011 uint8_t blue = buffer.get()[currByte++];
1012 uint8_t green = buffer.get()[currByte++];
1013 uint8_t red = buffer.get()[currByte++];
1014 setRLE24Pixel(dst, dstRowBytes, dstInfo,
1015 x++, y, red, green, blue);
1016 numPixels--;
1017 }
1018 default:
1019 SkASSERT(false);
1020 return kInvalidInput;
1021 }
1022 }
1023 // Skip a byte if necessary to maintain alignment
1024 if (!SkIsAlign2(rowBytes)) {
1025 currByte++;
1026 }
1027 break;
1028 }
1029 }
1030 } else {
1031 // If the first byte read is not a flag, it indicates the number of
1032 // pixels to set in RLE mode.
1033 const uint8_t numPixels = flag;
1034 const int endX = SkTMin<int>(x + numPixels, width);
1035
1036 if (24 == fBitsPerPixel) {
1037 // In RLE24, the second byte read is part of the pixel color.
1038 // There are two more required bytes to finish encoding the
1039 // color.
1040 if ((int) totalBytes - currByte < 2) {
1041 SkCodecPrintf("Warning: incomplete RLE input\n");
1042 return kIncompleteInput;
1043 }
1044
1045 // Fill the pixels up to endX with the specified color
1046 uint8_t blue = task;
1047 uint8_t green = buffer.get()[currByte++];
1048 uint8_t red = buffer.get()[currByte++];
1049 while (x < endX) {
1050 setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
1051 green, blue);
1052 }
1053 } else {
1054 // In RLE8 or RLE4, the second byte read gives the index in the
1055 // color table to look up the pixel color.
1056 // RLE8 has one color index that gets repeated
1057 // RLE4 has two color indexes in the upper and lower 4 bits of
1058 // the bytes, which are alternated
1059 uint8_t indices[2] = { task, task };
1060 if (4 == fBitsPerPixel) {
1061 indices[0] >>= 4;
1062 indices[1] &= 0xf;
1063 }
1064
1065 // Set the indicated number of pixels
1066 for (int which = 0; x < endX; x++) {
1067 setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
1068 indices[which]);
1069 which = !which;
1070 }
1071 }
1072 }
1073 }
1074 }
1075
1076 /*
1077 *
1078 * Performs the bitmap decoding for standard input format
1079 *
1080 */
1081 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
1082 void* dst, size_t dstRowBytes,
1083 const Options& opts) {
1084 // Set constant values
1085 const int width = dstInfo.width();
1086 const int height = dstInfo.height();
1087 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
1088
1089 // Get swizzler configuration and choose the fill value for failures. We wi ll use
1090 // zero as the default palette index, black for opaque images, and transpare nt for
1091 // non-opaque images.
1092 SkSwizzler::SrcConfig config;
1093 uint32_t fillColorOrIndex;
1094 bool zeroFill = true;
1095 switch (fBitsPerPixel) {
1096 case 1:
1097 config = SkSwizzler::kIndex1;
1098 fillColorOrIndex = 0;
1099 break;
1100 case 2:
1101 config = SkSwizzler::kIndex2;
1102 fillColorOrIndex = 0;
1103 break;
1104 case 4:
1105 config = SkSwizzler::kIndex4;
1106 fillColorOrIndex = 0;
1107 break;
1108 case 8:
1109 config = SkSwizzler::kIndex;
1110 fillColorOrIndex = 0;
1111 break;
1112 case 24:
1113 config = SkSwizzler::kBGR;
1114 fillColorOrIndex = SK_ColorBLACK;
1115 zeroFill = false;
1116 break;
1117 case 32:
1118 if (kOpaque_SkAlphaType == dstInfo.alphaType()) {
1119 config = SkSwizzler::kBGRX;
1120 fillColorOrIndex = SK_ColorBLACK;
1121 zeroFill = false;
1122 } else {
1123 config = SkSwizzler::kBGRA;
1124 fillColorOrIndex = SK_ColorTRANSPARENT;
1125 }
1126 break;
1127 default:
1128 SkASSERT(false);
1129 return kInvalidInput;
1130 }
1131
1132 // Get a pointer to the color table if it exists
1133 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readCol ors() : NULL;
1134
1135 // Create swizzler
1136 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config,
1137 colorPtr, dstInfo, kNo_ZeroInitialized));
1138
1139 // Allocate space for a row buffer and a source for the swizzler
1140 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
1141
1142 // Iterate over rows of the image
1143 // FIXME: bool transparent = true;
1144 for (int y = 0; y < height; y++) {
1145 // Read a row of the input
1146 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1147 SkCodecPrintf("Warning: incomplete input stream.\n");
1148 // Fill the destination image on failure
1149 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) {
1150 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrde r);
1151 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height( ) - y,
1152 fillColorOrIndex, colorPtr);
1153 }
1154 return kIncompleteInput;
1155 }
1156
1157 // Decode the row in destination format
1158 uint32_t row;
1159 if (kTopDown_RowOrder == fRowOrder) {
1160 row = y;
1161 } else {
1162 row = height - 1 - y;
1163 }
1164
1165 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * row);
1166 swizzler->swizzle(dstRow, srcBuffer.get());
1167 // FIXME: SkSwizzler::ResultAlpha r =
1168 // swizzler->swizzle(dstRow, srcBuffer.get());
1169 // FIXME: transparent &= SkSwizzler::IsTransparent(r);
1170 }
1171
1172 // FIXME: This code exists to match the behavior in the chromium decoder
1173 // and to follow the bmp specification as it relates to alpha masks. It is
1174 // commented out because we have yet to discover a test image that provides
1175 // an alpha mask and uses this decode mode.
1176
1177 // Now we adjust the output image with some additional behavior that
1178 // SkSwizzler does not support. Firstly, all bmp images that contain
1179 // alpha are masked by the alpha mask. Secondly, many fully transparent
1180 // bmp images are intended to be opaque. Here, we make those corrections
1181 // in the kN32 case.
1182 /*
1183 SkPMColor* dstRow = (SkPMColor*) dst;
1184 if (SkSwizzler::kBGRA == config) {
1185 for (int y = 0; y < height; y++) {
1186 for (int x = 0; x < width; x++) {
1187 if (transparent) {
1188 dstRow[x] |= 0xFF000000;
1189 } else {
1190 dstRow[x] &= alphaMask;
1191 }
1192 dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
1193 }
1194 }
1195 }
1196 */
1197
1198 // Finally, apply the AND mask for bmp-in-ico images
1199 if (fIsIco) {
1200 // The AND mask is always 1 bit per pixel
1201 const size_t rowBytes = SkAlign4(compute_row_bytes(width, 1));
1202
1203 SkPMColor* dstPtr = (SkPMColor*) dst;
1204 for (int y = 0; y < height; y++) {
1205 // The srcBuffer will at least be large enough
1206 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1207 SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n");
1208 return kIncompleteInput;
1209 }
1210
1211 int row;
1212 if (kBottomUp_RowOrder == fRowOrder) {
1213 row = height - y - 1;
1214 } else {
1215 row = y;
1216 }
1217
1218 SkPMColor* dstRow =
1219 SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);
1220
1221 for (int x = 0; x < width; x++) {
1222 int quotient;
1223 int modulus;
1224 SkTDivMod(x, 8, &quotient, &modulus);
1225 uint32_t shift = 7 - modulus;
1226 uint32_t alphaBit =
1227 (srcBuffer.get()[quotient] >> shift) & 0x1;
1228 dstRow[x] &= alphaBit - 1;
1229 }
1230 }
1231 }
1232
1233 // Finished decoding the entire image
1234 return kSuccess;
1235 }
OLDNEW
« no previous file with comments | « src/codec/SkBmpCodec.h ('k') | src/codec/SkBmpMaskCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698