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

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

Issue 947283002: Bmp Image Decoding (Closed) Base URL: https://skia.googlesource.com/skia.git@decode-leon-3
Patch Set: Moved bmp specific code out of the swizzler Created 5 years, 9 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
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkCodec_libbmp.h"
9 #include "SkColor.h"
10 #include "SkEndian.h"
11 #include "SkStream.h"
12
13 /*
14 *
15 * Get a byte from the buffer
16 *
17 */
18 uint8_t get_byte(uint8_t* buffer, uint32_t i) {
19 return buffer[i];
20 }
21
22 /*
23 *
24 * Get a short from the buffer
25 *
26 */
27 uint16_t get_short(uint8_t* buffer, uint32_t i) {
28 uint16_t result;
29 memcpy(&result, &(buffer[i]), 2);
30 #ifdef SK_CPU_BENDIAN
31 return SkEndianSwap16(result);
32 #else
33 return result;
34 #endif
35 }
36
37 /*
38 *
39 * Get an int from the buffer
40 *
41 */
42 uint32_t get_int(uint8_t* buffer, uint32_t i) {
43 uint32_t result;
44 memcpy(&result, &(buffer[i]), 4);
45 #ifdef SK_CPU_BENDIAN
46 return SkEndianSwap32(result);
47 #else
48 return result;
49 #endif
50 }
51
52 /*
53 *
54 * Used to convert 1-7 bit color components into 8-bit color components
55 *
56 */
57 const static uint8_t n_bit_to_8_bit_lookup_table[] = {
58 // 1 bit
59 0, 255,
60 // 2 bits
61 0, 85, 170, 255,
62 // 3 bits
63 0, 36, 73, 109, 146, 182, 219, 255,
64 // 4 bits
65 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
66 // 5 bits
67 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
68 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
69 // 6 bits
70 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
71 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
72 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
73 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
74 // 7 bits
75 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
76 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
77 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
78 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
79 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
80 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
81 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
82 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
83 };
84
85 /*
86 *
87 * Convert an n bit component to an 8-bit component
88 *
89 */
90 static uint8_t convert_n_to_8(uint32_t component, uint32_t n) {
91 if (0 == n) {
92 return 0;
93 } else if (8 > n) {
94 return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
95 } else if (8 == n) {
scroggo 2015/03/06 18:56:13 I would change this to: } else { SkASSERT(8 ==
96 return component;
97 } else {
98 SkASSERT(false);
99 return 0;
100 }
101 }
102
103 /*
104 *
105 * Row procedure for masked color components with 16 bits per pixel
106 *
107 */
108 static SkSwizzler::ResultAlpha swizzle_mask16_to_n32(
109 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
110 const SkBmpCodec::BitMasks masks,
111 const SkBmpCodec::BitMaskShifts shifts,
112 const SkBmpCodec::BitMaskSizes sizes) {
113
114 // Use the masks to decode to the destination
115 uint16_t* srcPtr = (uint16_t*) src;
116 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
117 for (uint32_t i = 0; i < width; i++) {
118 uint16_t p = srcPtr[i];
119 uint8_t red = convert_n_to_8(
120 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
scroggo 2015/03/06 18:56:13 It looks like this same code is repeated a few tim
121 uint8_t green = convert_n_to_8(
122 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
123 uint8_t blue = convert_n_to_8(
124 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
125 dstPtr[i] = SkColorSetARGBInline(0xFF, red, green, blue);
scroggo 2015/03/06 18:56:12 This doesn't do what we want. We want either premu
126 }
127 return SkSwizzler::kOpaque_ResultAlpha;
128 }
129
130 /*
131 *
132 * Row procedure for masked color components with 16 bits per pixel with alpha
133 *
134 */
135 static SkSwizzler::ResultAlpha swizzle_mask16_alpha_to_n32(
136 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
137 const SkBmpCodec::BitMasks masks,
138 const SkBmpCodec::BitMaskShifts shifts,
139 const SkBmpCodec::BitMaskSizes sizes) {
140
141 // Use the masks to decode to the destination
142 uint16_t* srcPtr = (uint16_t*) src;
143 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
144 uint8_t zAlpha = 0;
scroggo 2015/03/06 18:56:13 What does zAlpha mean? zeroAlpha?
145 uint8_t mAlpha = 0xFF;
scroggo 2015/03/06 18:56:13 I think this is max alpha? Refrain from using mVar
146 for (uint32_t i = 0; i < width; i++) {
147 uint16_t p = srcPtr[i];
148 uint8_t red = convert_n_to_8(
149 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
150 uint8_t green = convert_n_to_8(
151 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
152 uint8_t blue = convert_n_to_8(
153 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
154 uint8_t alpha = convert_n_to_8((
155 p & masks.alphaMask) >> shifts.alphaShift, sizes.alphaSize);
156 zAlpha |= alpha;
157 mAlpha &= alpha;
158 dstPtr[i] = SkColorSetARGBInline(alpha, red, green, blue);
159 }
160 return (mAlpha == 0xFF) ? SkSwizzler::kOpaque_ResultAlpha :
scroggo 2015/03/06 18:56:13 Can you make a helper function for this? Something
161 ((zAlpha == 0) ? SkSwizzler::kTransparent_ResultAlpha :
162 SkSwizzler::kNeither_ResultAlpha);
163 }
164
165 /*
166 *
167 * Row procedure for masked color components with 24 bits per pixel
168 *
169 */
170 static SkSwizzler::ResultAlpha swizzle_mask24_to_n32(
171 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
172 const SkBmpCodec::BitMasks masks,
173 const SkBmpCodec::BitMaskShifts shifts,
174 const SkBmpCodec::BitMaskSizes sizes) {
175
176 // Use the masks to decode to the destination
177 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
178 for (uint32_t i = 0; i < 3*width; i += 3) {
179 uint32_t p = src[i] | (src[i + 1] << 8) | src[i + 2] << 16;
180 uint8_t red = convert_n_to_8(
181 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
182 uint8_t green = convert_n_to_8(
183 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
184 uint8_t blue = convert_n_to_8(
185 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
186 dstPtr[i/3] = SkColorSetARGBInline(0xFF, red, green, blue);
187 }
188 return SkSwizzler::kOpaque_ResultAlpha;
189 }
190
191 /*
192 *
193 * Row procedure for masked color components with 24 bits per pixel with alpha
194 *
195 */
196 static SkSwizzler::ResultAlpha swizzle_mask24_alpha_to_n32(
197 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
198 const SkBmpCodec::BitMasks masks,
199 const SkBmpCodec::BitMaskShifts shifts,
200 const SkBmpCodec::BitMaskSizes sizes) {
201
202 // Use the masks to decode to the destination
203 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
204 uint8_t zAlpha = 0;
205 uint8_t mAlpha = 0xFF;
206 for (uint32_t i = 0; i < 3*width; i += 3) {
207 uint32_t p = src[i] | (src[i + 1] << 8) | src[i + 2] << 16;
208 uint8_t red = convert_n_to_8(
209 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
210 uint8_t green = convert_n_to_8(
211 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
212 uint8_t blue = convert_n_to_8(
213 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
214 uint8_t alpha = convert_n_to_8((
215 p & masks.alphaMask) >> shifts.alphaShift, sizes.alphaSize);
216 zAlpha |= alpha;
217 mAlpha &= alpha;
218 dstPtr[i/3] = SkColorSetARGBInline(alpha, red, green, blue);
219 }
220 return (mAlpha == 0xFF) ? SkSwizzler::kOpaque_ResultAlpha :
221 ((zAlpha == 0) ? SkSwizzler::kTransparent_ResultAlpha :
222 SkSwizzler::kNeither_ResultAlpha);
223 }
224
225 /*
226 *
227 * Row procedure for masked color components with 32 bits per pixel
228 *
229 */
230 static SkSwizzler::ResultAlpha swizzle_mask32_to_n32(
231 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
232 const SkBmpCodec::BitMasks masks,
233 const SkBmpCodec::BitMaskShifts shifts,
234 const SkBmpCodec::BitMaskSizes sizes) {
235
236 // Use the masks to decode to the destination
237 uint32_t* srcPtr = (uint32_t*) src;
238 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
239 for (uint32_t i = 0; i < width; i++) {
240 uint32_t p = srcPtr[i];
241 uint8_t red = convert_n_to_8(
242 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
243 uint8_t green = convert_n_to_8(
244 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
245 uint8_t blue = convert_n_to_8(
246 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
247 dstPtr[i] = SkColorSetARGBInline(0xFF, red, green, blue);
248 }
249 return SkSwizzler::kOpaque_ResultAlpha;
250 }
251
252 /*
253 *
254 * Row procedure for masked color components with 32 bits per pixel
255 *
256 */
257 static SkSwizzler::ResultAlpha swizzle_mask32_alpha_to_n32(
258 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
259 const SkBmpCodec::BitMasks masks,
260 const SkBmpCodec::BitMaskShifts shifts,
261 const SkBmpCodec::BitMaskSizes sizes) {
262
263 // Use the masks to decode to the destination
264 uint32_t* srcPtr = (uint32_t*) src;
265 SkColor* SK_RESTRICT dstPtr = (SkColor*) dstRow;
266 uint8_t zAlpha = 0;
267 uint8_t mAlpha = 0xFF;
268 for (uint32_t i = 0; i < width; i++) {
269 uint32_t p = srcPtr[i];
270 uint8_t red = convert_n_to_8(
271 (p & masks.redMask) >> shifts.redShift, sizes.redSize);
272 uint8_t green = convert_n_to_8(
273 (p & masks.greenMask) >> shifts.greenShift, sizes.greenSize);
274 uint8_t blue = convert_n_to_8(
275 (p & masks.blueMask) >> shifts.blueShift, sizes.blueSize);
276 uint8_t alpha = convert_n_to_8((
277 p & masks.alphaMask) >> shifts.alphaShift, sizes.alphaSize);
278 zAlpha |= alpha;
279 mAlpha &= alpha;
280 dstPtr[i] = SkColorSetARGBInline(alpha, red, green, blue);
281 }
282 return (mAlpha == 0xFF) ? SkSwizzler::kOpaque_ResultAlpha :
283 ((zAlpha == 0) ? SkSwizzler::kTransparent_ResultAlpha :
284 SkSwizzler::kNeither_ResultAlpha);
285 }
286
287 /*
288 *
289 * Checks if the conversion between the input image and the requested output
290 * image has been implemented
291 *
292 */
293 static bool conversion_possible(const SkImageInfo& dst,
294 const SkImageInfo& src) {
295 // TODO: Support all conversions
scroggo 2015/03/06 18:56:13 nit: we won't support *all* conversions, but perha
296 if (kN32_SkColorType != dst.colorType()) {
297 return false;
298 }
299 if (kIgnore_SkAlphaType == dst.alphaType()) {
scroggo 2015/03/06 18:56:13 Can we also check for opaque vs non-opaque? For P
300 SkDebugf("Error: invalid dst alpha type.");
301 return false;
302 }
303 return true;
304 }
305
306 /*
307 *
308 * Defines the version and type of the second bitmap header
309 *
310 */
311 enum BitmapHeaderType {
312 kInfoV1_BitmapHeaderType,
313 kInfoV2_BitmapHeaderType,
314 kInfoV3_BitmapHeaderType,
315 kInfoV4_BitmapHeaderType,
316 kInfoV5_BitmapHeaderType,
317 kOS2V1_BitmapHeaderType,
318 kOS2VX_BitmapHeaderType,
319 kUnknown_BitmapHeaderType
320 };
321
322 /*
323 *
324 * Possible bitmap compression types
325 *
326 */
327 enum BitmapCompressionMethod {
328 kNone_BitmapCompressionMethod = 0,
329 k8BitRLE_BitmapCompressionMethod = 1,
330 k4BitRLE_BitmapCompressionMethod = 2,
331 kBitMasks_BitmapCompressionMethod = 3,
332 kJpeg_BitmapCompressionMethod = 4,
333 kPng_BitmapCompressionMethod = 5,
334 kAlphaBitMasks_BitmapCompressionMethod = 6,
335 kCMYK_BitmapCompressionMethod = 11,
336 kCMYK8BitRLE_BitmapCompressionMethod = 12,
337 kCMYK4BitRLE_BitmapCompressionMethod = 13
338 };
339
340 /*
341 *
342 * Checks the start of the stream to see if the image is a bitmap
343 *
344 */
345 bool SkBmpCodec::IsBmp(SkStream* stream) {
346 // TODO: Support "IC", "PT", "CI", "CP", "BA"
347 // TODO: ICO files may contain a BMP and need to use this decoder
348 const char bmpSig[] = { 'B', 'M' };
349 char buffer[sizeof(bmpSig)];
350 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
351 !memcmp(buffer, bmpSig, sizeof(bmpSig));
352 }
353
354 /*
355 *
356 * Assumes IsBmp was called and returned true
357 * Creates a bitmap decoder
358 * Reads enough of the stream to determine the image format
359 *
360 */
361 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
msarett 2015/03/05 23:13:17 This function is very long. There is not really r
scroggo 2015/03/05 23:32:35 I'm going to look at the whole of the code more in
362 // Header size constants
363 static const uint32_t kBmpHeaderBytes = 14;
364 static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
365 static const uint32_t kBmpOS2V1Bytes = 12;
366 static const uint32_t kBmpOS2V2Bytes = 64;
367 static const uint32_t kBmpInfoBaseBytes = 16;
368 static const uint32_t kBmpInfoV1Bytes = 40;
369 static const uint32_t kBmpInfoV2Bytes = 52;
370 static const uint32_t kBmpInfoV3Bytes = 56;
371 static const uint32_t kBmpInfoV4Bytes = 108;
372 static const uint32_t kBmpInfoV5Bytes = 124;
373 static const uint32_t kBmpMaskBytes = 12;
374
375 // Read the first header and the size of the second header
376 SkAutoTDeleteArray<uint8_t> hBuffer(
377 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
378 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
379 kBmpHeaderBytesPlusFour) {
380 SkDebugf("Error: unable to read first bitmap header.\n");
381 return NULL;
382 }
383
384 // The total bytes in the bmp file
385 // We only need to use this value for RLE decoding, so we will only check
386 // that it is valid in the RLE case.
387 const uint32_t totalBytes = get_int(hBuffer.get(), 2);
388
389 // The offset from the start of the file where the pixel data begins
390 const uint32_t offset = get_int(hBuffer.get(), 10);
391 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
392 SkDebugf("Error: invalid starting location for pixel data\n");
393 return NULL;
394 }
395
396 // The size of the second (info) header in bytes
397 // The size is the first field of the second header, so we have already
398 // read the first four infoBytes.
399 const uint32_t infoBytes = get_int(hBuffer.get(), 14);
400 if (infoBytes < kBmpOS2V1Bytes) {
401 SkDebugf("Error: invalid second header size.\n");
402 return NULL;
403 }
404 const uint32_t infoBytesRemaining = infoBytes - 4;
405 hBuffer.free();
406
407 // Read the second header
408 SkAutoTDeleteArray<uint8_t> iBuffer(
409 SkNEW_ARRAY(uint8_t, infoBytesRemaining));
410 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
411 SkDebugf("Error: unable to read second bitmap header.\n");
412 return NULL;
413 }
414
415 // The number of bits used per pixel in the pixel data
416 uint16_t bitsPerPixel;
417
418 // The compression method for the pixel data
419 uint32_t compression = kNone_BitmapCompressionMethod;
420
421 // Number of colors in the color table, defaults to 0 or max (see below)
422 uint32_t numColors = 0;
423
424 // Bytes per color in the color table, early versions use 3, most use 4
425 uint32_t bytesPerColor;
426
427 // The image width and height
428 int width, height;
429
430 // Determine image information depending on second header format
431 BitmapHeaderType headerType;
432 if (infoBytes >= kBmpInfoBaseBytes) {
433 // Check the version of the header
434 switch (infoBytes) {
435 case kBmpInfoV1Bytes:
436 headerType = kInfoV1_BitmapHeaderType;
437 break;
438 case kBmpInfoV2Bytes:
439 headerType = kInfoV2_BitmapHeaderType;
440 break;
441 case kBmpInfoV3Bytes:
442 headerType = kInfoV3_BitmapHeaderType;
443 break;
444 case kBmpInfoV4Bytes:
445 headerType = kInfoV4_BitmapHeaderType;
446 break;
447 case kBmpInfoV5Bytes:
448 headerType = kInfoV5_BitmapHeaderType;
449 break;
450 case 16:
451 case 20:
452 case 24:
453 case 28:
454 case 32:
455 case 36:
456 case 42:
457 case 46:
458 case 48:
459 case 60:
460 case kBmpOS2V2Bytes:
461 headerType = kOS2VX_BitmapHeaderType;
462 break;
463 default:
464 // We do not signal an error here because there is the
465 // possibility of new or undocumented bmp header types. Most
466 // of the newer versions of bmp headers are similar to and
467 // build off of the older versions, so we may still be able to
468 // decode the bmp.
469 SkDebugf("Warning: unknown bmp header format.\n");
470 headerType = kUnknown_BitmapHeaderType;
471 break;
472 }
473 // We check the size of the header before entering the if statement.
474 // We should not reach this point unless the size is large enough for
475 // these required fields.
476 SkASSERT(infoBytesRemaining >= 12);
477 width = get_int(iBuffer.get(), 0);
478 height = get_int(iBuffer.get(), 4);
479 //uint16_t planes = get_short(iBuffer, 8);
480 bitsPerPixel = get_short(iBuffer.get(), 10);
481
482 // Some versions do not have this field, so we check before
483 // overwriting the default value.
484 if (infoBytesRemaining >= 16) {
485 compression = get_int(iBuffer.get(), 12);
486 }
487
488 // Some versions do not have this field, so we check before
489 // overwriting the default value.
490 if (infoBytesRemaining >= 32) {
491 numColors = get_int(iBuffer.get(), 28);
492 }
493
494 bytesPerColor = 4;
495 } else if (infoBytes >= kBmpOS2V1Bytes) {
496 // The OS2V1 is treated separately because it has a unique format
497 headerType = kOS2V1_BitmapHeaderType;
498 width = (int) get_short(iBuffer.get(), 0);
499 height = (int) get_short(iBuffer.get(), 2);
500 bitsPerPixel = get_short(iBuffer.get(), 6);
501 bytesPerColor = 3;
502 } else {
503 // There are no valid bmp headers
504 SkDebugf("Error: second bitmap header size is invalid.\n");
505 return NULL;
506 }
507
508 // Check for valid dimensions from header
509 RowOrder rowOrder = kBottomUp_RowOrder;
510 if (height < 0) {
511 height = -height;
512 rowOrder = kTopDown_RowOrder;
513 }
514 static const uint32_t kBmpMaxDim = 1 << 16;
515 if (width < 0 || width >= kBmpMaxDim || height >= kBmpMaxDim) {
516 // TODO: Decide if we want to support really large bmps.
517 SkDebugf("Error: invalid bitmap dimensions.\n");
518 return NULL;
519 }
520
521 // Create mask struct
522 BitMasks masks;
523 memset(&masks, 0, 4*sizeof(uint32_t));
524
525 // Determine the input compression format and set bit masks if necessary
526 uint32_t maskBytes = 0;
527 BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat;
528 switch (compression) {
529 case kNone_BitmapCompressionMethod:
530 inputFormat = kStandard_BitmapInputFormat;
531 break;
532 case k8BitRLE_BitmapCompressionMethod:
533 if (bitsPerPixel != 8) {
534 SkDebugf("Warning: correcting invalid bitmap format.\n");
535 bitsPerPixel = 8;
536 }
537 inputFormat = kRLE_BitmapInputFormat;
538 break;
539 case k4BitRLE_BitmapCompressionMethod:
540 if (bitsPerPixel != 4) {
541 SkDebugf("Warning: correcting invalid bitmap format.\n");
542 bitsPerPixel = 4;
543 }
544 inputFormat = kRLE_BitmapInputFormat;
545 break;
546 case kAlphaBitMasks_BitmapCompressionMethod:
547 case kBitMasks_BitmapCompressionMethod:
548 // Load the masks
549 inputFormat = kBitMask_BitmapInputFormat;
550 switch (headerType) {
551 case kInfoV1_BitmapHeaderType: {
552 // The V1 header stores the bit masks after the header
553 SkAutoTDeleteArray<uint8_t> mBuffer(
554 SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
555 if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
556 kBmpMaskBytes) {
557 SkDebugf("Error: unable to read bit masks.\n");
558 return NULL;
559 }
560 maskBytes = kBmpMaskBytes;
561 masks.redMask = get_int(mBuffer.get(), 0);
562 masks.greenMask = get_int(mBuffer.get(), 4);
563 masks.blueMask = get_int(mBuffer.get(), 8);
564 break;
565 }
566 case kInfoV2_BitmapHeaderType:
567 case kInfoV3_BitmapHeaderType:
568 case kInfoV4_BitmapHeaderType:
569 case kInfoV5_BitmapHeaderType:
570 // Header types are matched based on size. If the header
571 // is V2+, we are guaranteed to be able at least this size.
572 SkASSERT(infoBytesRemaining >= 48);
573 masks.redMask = get_int(iBuffer.get(), 36);
574 masks.greenMask = get_int(iBuffer.get(), 40);
575 masks.blueMask = get_int(iBuffer.get(), 44);
576 break;
577 case kOS2VX_BitmapHeaderType:
578 // TODO: Decide if we intend to support this.
579 // It is unsupported in the previous version and
580 // in chromium. I have not come across a test case
581 // that uses this format.
582 SkDebugf("Error: huffman format unsupported.\n");
583 return NULL;
584 default:
585 SkDebugf("Error: invalid bmp bit masks header.\n");
586 return NULL;
587 }
588 break;
589 case kJpeg_BitmapCompressionMethod:
590 if (24 == bitsPerPixel) {
591 inputFormat = kRLE_BitmapInputFormat;
592 break;
593 }
594 // Fall through
595 case kPng_BitmapCompressionMethod:
596 // TODO: Decide if we intend to support this.
597 // It is unsupported in the previous version and
598 // in chromium. I think it is used mostly for printers.
599 SkDebugf("Error: compression format not supported.\n");
600 return NULL;
601 case kCMYK_BitmapCompressionMethod:
602 case kCMYK8BitRLE_BitmapCompressionMethod:
603 case kCMYK4BitRLE_BitmapCompressionMethod:
604 // TODO: Same as above.
605 SkDebugf("Error: CMYK not supported for bitmap decoding.\n");
606 return NULL;
607 default:
608 SkDebugf("Error: invalid format for bitmap decoding.\n");
609 return NULL;
610 }
611
612 // Most versions of bmps should to be rendered as opaque. Either they do
scroggo 2015/03/06 18:56:13 should be*
613 // not have an alpha channel, or they expect the alpha channel to be
614 // ignored. V4+ bmp files introduce an alpha mask and allow the creator
615 // of the image to use the alpha channels. However, many of these images
616 // leave the alpha channel blank and expect to be rendered as opaque. For
617 // this reason, we set the alpha type to kUnknown for V4+ bmps and figure
618 // out the alpha type during the decode.
619 SkAlphaType alphaType = kOpaque_SkAlphaType;
620 if (kInfoV4_BitmapHeaderType == headerType ||
621 kInfoV5_BitmapHeaderType == headerType) {
622 // Header types are matched based on size. If the header is
623 // V4+, we are guaranteed to be able at least this size.
scroggo 2015/03/06 18:56:13 able... to read?
624 SkASSERT(infoBytesRemaining > 52);
625 masks.alphaMask = get_int(iBuffer.get(), 48);
626 if (masks.alphaMask != 0) {
627 alphaType = kUnpremul_SkAlphaType;
628 }
629 }
630 iBuffer.free();
631
632 // Check for valid bits per pixel input
633 switch (bitsPerPixel) {
634 // In addition to more standard pixel compression formats, bmp supports
635 // the use of bit masks to determine pixel components. The standard
636 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
637 // which does not map well to any Skia color formats. For this reason,
638 // we will always enable mask mode with 16 bits per pixel.
639 case 16:
640 if (kBitMask_BitmapInputFormat != inputFormat) {
641 masks.redMask = 0x7C00;
642 masks.greenMask = 0x03E0;
643 masks.blueMask = 0x001F;
644 inputFormat = kBitMask_BitmapInputFormat;
645 }
646 break;
647 case 1:
648 case 2:
649 case 4:
650 case 8:
651 case 24:
652 case 32:
653 break;
654 default:
655 SkDebugf("Error: invalid input value for bits per pixel.\n");
656 return NULL;
657 }
658
659 // Process the color table
660 uint32_t colorBytes = 0;
661 SkColor* colorTable = NULL;
scroggo 2015/03/06 18:56:13 SkPMColor. Same down below.
662 if (bitsPerPixel < 16) {
663 // Verify the number of colors for the color table
664 const int maxColors = 1 << bitsPerPixel;
665 // Zero is a default for maxColors
666 // Also set numColors to maxColors when input is too large
667 if (numColors <= 0 || numColors > maxColors) {
668 numColors = maxColors;
669 }
670 colorTable = SkNEW_ARRAY(SkColor, maxColors);
671
672 // Construct the color table
673 colorBytes = numColors * bytesPerColor;
674 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
675 if (stream->read(cBuffer.get(), colorBytes) != colorBytes) {
676 SkDebugf("Error: unable to read color table.\n");
677 return NULL;
678 }
679
680 // Fill in the color table
681 uint32_t i = 0;
682 for (; i < numColors; i++) {
683 uint8_t blue = get_byte(cBuffer.get(), i*bytesPerColor);
684 uint8_t green = get_byte(cBuffer.get(), i*bytesPerColor + 1);
685 uint8_t red = get_byte(cBuffer.get(), i*bytesPerColor + 2);
686 uint8_t alpha = 0xFF;
687 if (kOpaque_SkAlphaType != alphaType) {
688 alpha = (masks.alphaMask >> 24) &
689 get_byte(cBuffer.get(), i*bytesPerColor + 3);
690 }
691 colorTable[i] = SkColorSetARGBInline(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] = SkColorSetARGBInline(0xFF, 0, 0, 0);
699 }
700 } else {
701 // We will not use the color table if bitsPerPixel >= 16, but if there
702 // is a color table, we may need to skip the color table bytes.
703 // We will assume that the maximum color table size is the same as when
704 // there are 8 bits per pixel (the largest color table actually used).
705 // Color tables for greater than 8 bits per pixel are somewhat
706 // undocumented. It is indicated that they may exist to store a list
707 // of colors for optimization on devices with limited color display
708 // capacity. While we do not know for sure, we will guess that any
709 // value of numColors greater than this maximum is invalid.
710 if (numColors <= (1 << 8)) {
711 colorBytes = numColors * bytesPerColor;
712 if (stream->skip(colorBytes) != colorBytes) {
713 SkDebugf("Error: Could not skip color table bytes.\n");
714 return NULL;
715 }
716 }
717 }
718
719 // Ensure that the stream now points to the start of the pixel array
720 uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes + colorBytes;
721
722 // Check that we have not read past the pixel array offset
723 if(bytesRead > offset) {
724 // This may occur on OS 2.1 and other old versions where the color
725 // table defaults to max size, and the bmp tries to use a smaller color
726 // table. This is invalid, and our decision is to indicate an error,
727 // rather than try to guess the intended size of the color table and
728 // rewind the stream to display the image.
729 SkDebugf("Error: pixel data offset less than header size.\n");
730 return NULL;
731 }
732
733 // Skip to the start of the pixel array
734 if (stream->skip(offset - bytesRead) != offset - bytesRead) {
735 SkDebugf("Error: unable to skip to image data.\n");
736 return NULL;
737 }
738
739 // Remaining bytes is only used for RLE
740 const int remainingBytes = totalBytes - offset;
741 if (remainingBytes <= 0 && kRLE_BitmapInputFormat == inputFormat) {
742 SkDebugf("Error: RLE requires valid input size.\n");
743 return NULL;
744 }
745
746 // Return the codec
747 // We will use ImageInfo to store width, height, and alpha type. The Skia
748 // color types do not match with the many possible bmp input color types,
749 // so we will ignore this field and depend on other parameters for input
750 // information.
751 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
752 kUnknown_SkColorType, alphaType);
753 return SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
754 inputFormat, masks, colorTable, rowOrder,
755 remainingBytes));
756 }
757
758 /*
759 *
760 * Creates an instance of the decoder
761 * Called only by NewFromStream
762 *
763 */
764 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
765 uint16_t bitsPerPixel, BitmapInputFormat inputFormat,
766 BitMasks masks, SkColor* colorTable,
767 RowOrder rowOrder,
768 const uint32_t remainingBytes)
769 : INHERITED(info, stream)
770 , fBitsPerPixel(bitsPerPixel)
771 , fInputFormat(inputFormat)
772 , fBitMasks(masks)
773 , fMaskShifts( { 0, 0, 0, 0 } )
774 , fMaskSizes( { 0, 0, 0, 0 } )
775 , fColorTable(colorTable)
776 , fRowOrder(rowOrder)
777 , fRemainingBytes(remainingBytes)
778 {}
779
780 /*
781 *
782 * Initiates the bitmap decode
783 *
784 */
785 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
786 void* dst, size_t dstRowBytes,
787 SkColor*, int*) {
788 if (!this->couldRewindIfNeeded()) {
789 SkDebugf("Error: rewind should not be necessary.\n");
scroggo 2015/03/06 18:56:13 This comment isn't necessary. couldRewindIfNeeded
790 return kCouldNotRewind;
791 }
792 if (dstInfo.dimensions() != this->getOriginalInfo().dimensions()) {
793 SkDebugf("Error: scaling not supported.\n");
794 return kInvalidScale;
795 }
796 if (!conversion_possible(dstInfo, this->getOriginalInfo())) {
797 SkDebugf("Error: cannot convert input type to output type.\n");
798 return kInvalidConversion;
799 }
800
801 switch (fInputFormat) {
802 case kBitMask_BitmapInputFormat:
803 return decodeMask(dstInfo, dst, dstRowBytes);
804 case kRLE_BitmapInputFormat:
805 return decodeRLE(dstInfo, dst, dstRowBytes);
806 case kStandard_BitmapInputFormat:
807 return decode(dstInfo, dst, dstRowBytes);
808 default:
809 SkASSERT(false);
810 return kInvalidInput;
811 }
812 }
813
814 /*
815 *
816 * For a continuous bit mask (ex: 0011100), retrieves the size of the mask and
817 * the number of bits to shift the mask
818 *
819 */
820 void SkBmpCodec::processMasks() {
msarett 2015/03/05 23:13:17 I can make this function less repetitive (but hard
scroggo 2015/03/06 18:56:13 Hard to say... My initial thought was to let timin
821 // Trim the masks to the allowed number of bits
822 if (fBitsPerPixel < 32) {
scroggo 2015/03/06 18:56:13 If you merged all the masks together, as suggested
823 fBitMasks.redMask &= (1 << fBitsPerPixel) - 1;
824 fBitMasks.greenMask &= (1 << fBitsPerPixel) - 1;
825 fBitMasks.blueMask &= (1 << fBitsPerPixel) - 1;
826 fBitMasks.alphaMask &= (1 << fBitsPerPixel) - 1;
827 }
828
829 // Get temporary versions of the inputs masks
830 uint32_t redMask = fBitMasks.redMask;
831 uint32_t greenMask = fBitMasks.greenMask;
832 uint32_t blueMask = fBitMasks.blueMask;
833 uint32_t alphaMask = fBitMasks.alphaMask;
834
835 // Count trailing zeros on masks and the size of masks
836 if (redMask != 0) {
837 for (; (redMask & 1) == 0; redMask >>= 1) {
838 fMaskShifts.redShift++;
839 }
840 for (; redMask & 1; redMask >>= 1) {
841 fMaskSizes.redSize++;
842 }
843 // Truncate masks greater than 8 bits
844 if (fMaskSizes.redSize > 8) {
845 fMaskShifts.redShift += fMaskSizes.redSize - 8;
846 fMaskSizes.redSize = 8;
847 }
848 }
849 if (greenMask != 0) {
850 for (; (greenMask & 1) == 0; greenMask >>= 1) {
851 fMaskShifts.greenShift++;
852 }
853 for (; greenMask & 1; greenMask >>= 1) {
854 fMaskSizes.greenSize++;
855 }
856 // Truncate masks greater than 8 bits
857 if (fMaskSizes.greenSize > 8) {
858 fMaskShifts.greenShift += fMaskSizes.greenSize - 8;
859 fMaskSizes.greenSize = 8;
860 }
861 }
862 if (blueMask != 0) {
863 for (; (blueMask & 1) == 0; blueMask >>= 1) {
864 fMaskShifts.blueShift++;
865 }
866 for (; blueMask & 1; blueMask >>= 1) {
867 fMaskSizes.blueSize++;
868 }
869 // Truncate masks greater than 8 bits
870 if (fMaskSizes.blueSize > 8) {
871 fMaskShifts.blueShift += fMaskSizes.blueSize - 8;
872 fMaskSizes.blueSize = 8;
873 }
874 }
875 if (alphaMask != 0) {
876 for (; (alphaMask & 1) == 0; alphaMask >>= 1) {
877 fMaskShifts.alphaShift++;
878 }
879 for (; alphaMask & 1; alphaMask >>= 1) {
880 fMaskSizes.alphaSize++;
881 }
882 // Truncate masks greater than 8 bits
883 if (fMaskSizes.alphaSize > 8) {
884 fMaskShifts.alphaShift += fMaskSizes.alphaSize - 8;
885 fMaskSizes.alphaSize = 8;
886 }
887 }
888 return;
scroggo 2015/03/06 18:56:13 not needed.
889 }
890
891 /*
892 *
893 * Performs the bitmap decoding for bit masks input format
894 *
895 */
896 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo,
897 void* dst, uint32_t dstRowBytes) {
898 // Set constant values
899 const int width = dstInfo.width();
900 const int height = dstInfo.height();
901 const uint32_t pixelsPerByte = 8 / fBitsPerPixel;
902 const uint32_t bytesPerPixel = fBitsPerPixel / 8;
scroggo 2015/03/06 18:56:13 what happens if fBitsPerPixel is not an even multi
msarett 2015/03/07 00:19:50 It would an error if it happened. We should proba
903 const uint32_t unpaddedRowBytes = fBitsPerPixel < 16 ?
scroggo 2015/03/06 18:56:13 I think all you want here is the paddedRowBytes? A
904 (width + pixelsPerByte - 1) / pixelsPerByte : width * bytesPerPixel;
905 const uint32_t paddedRowBytes = SkAlign4(unpaddedRowBytes);
906 const uint32_t alphaMask = fBitMasks.alphaMask;
907
908 // Allocate space for a row buffer and a source for the swizzler
909 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, paddedRowBytes));
910
911 // Define the type of mask row procedures
912 typedef SkSwizzler::ResultAlpha (*RowProc)(void* SK_RESTRICT dstRow,
913 const uint8_t* SK_RESTRICT src, int width,
914 BitMasks masks, BitMaskShifts shifts,
915 BitMaskSizes sizes);
916
917 // Choose the appropriate row procedure
918 RowProc proc = NULL;
919 switch (fBitsPerPixel) {
920 case 16:
921 if (alphaMask == 0) {
922 proc = &swizzle_mask16_to_n32;
923 } else {
924 proc = &swizzle_mask16_alpha_to_n32;
925 }
926 break;
927 case 24:
928 if (alphaMask == 0) {
929 proc = &swizzle_mask24_to_n32;
930 } else {
931 proc = &swizzle_mask24_alpha_to_n32;
932 }
933 break;
934 case 32:
935 if (alphaMask == 0) {
936 proc = &swizzle_mask32_to_n32;
937 } else {
938 proc = &swizzle_mask32_alpha_to_n32;
939 }
940 break;
941 default:
942 SkASSERT(false);
943 return kInvalidInput;
944 }
945
946 // Obtain the size and location of the input bit masks
947 processMasks();
948
949 // Get the destination start row and delta
950 SkColor* dstRow;
951 int32_t delta;
952 if (kTopDown_RowOrder == fRowOrder) {
953 dstRow = (SkColor*) dst;
954 delta = dstRowBytes;
955 } else {
956 dstRow = (SkColor*) SkTAddOffset<void>(dst, (height - 1) * dstRowBytes);
957 delta = -dstRowBytes;
958 }
959
960 // Iterate over rows of the image
961 bool transparent = true;
962 for (uint32_t y = 0; y < height; y++) {
963 // Read a row of the input
964 if (stream()->read(srcBuffer.get(), paddedRowBytes) != paddedRowBytes) {
965 SkDebugf("Warning: incomplete input stream.\n");
966 return kIncompleteInput;
967 }
968
969 // Decode the row in destination format
970 SkSwizzler::ResultAlpha r = proc(dstRow, srcBuffer.get(), width,
971 fBitMasks, fMaskShifts, fMaskSizes);
972 transparent &= SkSwizzler::kTransparent_ResultAlpha == r;
scroggo 2015/03/06 18:56:13 nit: parens around the == check
973
974 // Move to the next row
975 dstRow = SkTAddOffset<SkColor>(dstRow, delta);
976 }
977
978 // Many fully transparent bmp images are intended to be opaque. Here, we
979 // correct for this possibility.
980 SkColor* dstPtr = (SkColor*) dst;
981 if (transparent) {
982 for (uint32_t y = 0; y < height; y++) {
983 for (uint32_t x = 0; x < width; x++) {
984 dstPtr[y * dstRowBytes + x] |= 0xFF000000;
985 }
986 }
987 }
988
989 // Finished decoding the entire image
990 return kSuccess;
991 }
992
993 /*
994 *
995 * Set an RLE pixel using the color table
996 *
997 */
998 void SkBmpCodec::setRLEPixel(SkColor* dst, uint32_t dstRowBytes, int height,
999 uint32_t x, uint32_t y, uint8_t index) {
1000 if (kBottomUp_RowOrder == fRowOrder) {
1001 y = height - y - 1;
1002 }
1003 SkColor* dstRow = SkTAddOffset<SkColor>(dst, y * dstRowBytes);
1004 dstRow[x] = fColorTable.get()[index];
1005 }
1006
1007 /*
1008 *
1009 * Performs the bitmap decoding for RLE input format
1010 * RLE decoding is performed all at once, rather than a one row at a time
1011 *
1012 */
1013 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
1014 void* dst, uint32_t dstRowBytes) {
1015 // Set RLE flags
1016 static const uint8_t RLE_ESCAPE = 0;
1017 static const uint8_t RLE_EOL = 0;
1018 static const uint8_t RLE_EOF = 1;
1019 static const uint8_t RLE_DELTA = 2;
1020
1021 // Set constant values
1022 const int width = dstInfo.width();
1023 const int height = dstInfo.height();
1024 const uint32_t pixelsPerByte = 8 / fBitsPerPixel;
1025 const uint32_t bytesPerPixel = fBitsPerPixel / 8;
1026
1027 // Input buffer parameters
1028 uint32_t currByte = 0;
1029 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRemainingBytes));
1030 uint32_t totalBytes = stream()->read(buffer.get(), fRemainingBytes);
1031 if (totalBytes < fRemainingBytes) {
1032 SkDebugf("Warning: incomplete RLE file.\n");
1033 } else if (totalBytes <= 0) {
1034 SkDebugf("Error: could not read RLE image data.\n");
1035 return kInvalidInput;
1036 }
1037
1038 // Destination parameters
1039 uint32_t x = 0;
1040 uint32_t y = 0;
1041 // If the code skips pixels, remaining pixels are transparent or black
1042 // TODO: Skip this if memory was already zeroed.
1043 memset(dst, 0, dstRowBytes * height);
1044 SkColor* dstPtr = (SkColor*) dst;
1045
1046 while (true) {
1047 // Every entry takes at least two bytes
1048 if (totalBytes - currByte < 2) {
1049 SkDebugf("Warning: incomplete RLE input.\n");
1050 return kIncompleteInput;
1051 }
1052
1053 // Read the next two bytes. These bytes have different meanings
scroggo 2015/03/06 18:56:13 Thanks for the comments! It makes this code a lot
1054 // depending on their values. In the first interpretation, the first
1055 // byte is an escape flag and the second byte indicates what special
1056 // task to perform.
1057 const uint8_t flag = buffer.get()[currByte++];
1058 const uint8_t task = buffer.get()[currByte++];
1059
1060 // If we have reached a row that is beyond the image size, and the RLE
1061 // code does not indicate end of file, abort and signal a warning.
1062 if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
1063 SkDebugf("Warning: invalid RLE input.\n");
1064 return kIncompleteInput;
1065 }
1066
1067 // Perform decoding
1068 if (RLE_ESCAPE == flag) {
1069 switch (task) {
1070 case RLE_EOL:
1071 x = 0;
1072 y++;
1073 break;
1074 case RLE_EOF:
1075 return kSuccess;
1076 case RLE_DELTA: {
1077 // Two bytes are needed to specify delta
1078 if (totalBytes - currByte < 2) {
1079 SkDebugf("Warning: incomplete RLE input\n");
1080 return kIncompleteInput;
1081 }
1082 // Modify x and y
1083 const uint8_t dx = buffer.get()[currByte++];
1084 const uint8_t dy = buffer.get()[currByte++];
1085 x += dx;
1086 y += dy;
1087 if (x > width || y > height) {
1088 SkDebugf("Warning: invalid RLE input.\n");
1089 return kIncompleteInput;
1090 }
1091 break;
1092 }
1093 default: {
1094 // If task does not match any of the above signals, it
1095 // indicates that we have a sequence of non-RLE pixels.
1096 // Furthermore, the value of task is equal to the number
1097 // of pixels to interpret.
1098 uint8_t numPixels = task;
1099 const uint32_t unpaddedBytes = fBitsPerPixel < 16 ?
1100 (numPixels + pixelsPerByte - 1) / pixelsPerByte :
1101 numPixels * bytesPerPixel;
1102 const uint32_t paddedBytes = SkAlign2(unpaddedBytes);
1103 if (x + numPixels > width ||
1104 totalBytes - currByte < paddedBytes) {
1105 SkDebugf("Warning: invalid RLE input.\n");
1106 return kIncompleteInput;
1107 }
1108 // Set count number of pixels
1109 while (numPixels > 0) {
1110 switch(fBitsPerPixel) {
1111 case 4: {
1112 uint8_t val = buffer.get()[currByte++];
1113 setRLEPixel(dstPtr, dstRowBytes, height, x++, y,
1114 val >> 4);
1115 numPixels--;
1116 if (numPixels != 0) {
1117 setRLEPixel(dstPtr, dstRowBytes, height,
1118 x++, y, val & 0xF);
1119 numPixels--;
1120 }
1121 break;
1122 }
1123 case 8:
1124 setRLEPixel(dstPtr, dstRowBytes, height, x++, y,
1125 buffer.get()[currByte++]);
1126 numPixels--;
1127 break;
1128 case 24: {
1129 uint8_t blue = buffer.get()[currByte++];
1130 uint8_t green = buffer.get()[currByte++];
1131 uint8_t red = buffer.get()[currByte++];
1132 SkColor color = SkColorSetARGBInline(
1133 0xFF, red, green, blue);
1134 SkColor* dstRow = SkTAddOffset<SkColor>(
1135 dstPtr, y * dstRowBytes);
1136 dstRow[x++] = color;
1137 numPixels--;
1138 }
1139 default:
1140 SkASSERT(false);
1141 return kInvalidInput;
1142 }
1143 }
1144 // Skip a byte if necessary to maintain alignment
1145 if (unpaddedBytes & 1) {
1146 currByte++;
1147 }
1148 break;
1149 }
1150 }
1151 } else {
1152 // If the first byte read is not a flag, it indicates the number of
1153 // pixels to set in RLE mode.
1154 const uint8_t numPixels = flag;
1155 const uint32_t endX = SkTMin<uint32_t>(x + numPixels,
1156 (uint32_t) width);
1157
1158 if (24 == fBitsPerPixel) {
1159 // In RLE24, the second byte read is part of the pixel color.
1160 // There are two more required bytes to finish encoding the
1161 // color.
1162 if (totalBytes - currByte < 2) {
1163 SkDebugf("Warning: incomplete RLE input\n");
1164 return kIncompleteInput;
1165 }
1166
1167 // Fill the pixels up to endX with the specified color
1168 uint8_t blue = task;
1169 uint8_t green = buffer.get()[currByte++];
1170 uint8_t red = buffer.get()[currByte++];
1171 SkColor color = SkColorSetARGBInline(0xFF, red, green, blue);
1172 SkColor* dstRow =
1173 SkTAddOffset<SkColor>(dstPtr, y * dstRowBytes);
1174 while (x < endX) {
1175 dstRow[x++] = color;
1176 }
1177 } else {
1178 // In RLE8 or RLE4, the second byte read gives the index in the
1179 // color table to look up the pixel color.
1180 // RLE8 has one color index that gets repeated
1181 // RLE4 has two color indexes in the upper and lower 4 bits of
1182 // the bytes, which are alternated
1183 uint8_t indices[2] = { task, task };
1184 if (4 == fBitsPerPixel) {
1185 indices[0] >>= 4;
1186 indices[1] &= 0xf;
1187 }
1188
1189 // Set the indicated number of pixels
1190 for (int which = 0; x < endX; x++) {
1191 setRLEPixel(dstPtr, dstRowBytes, height, x, y,
1192 indices[which]);
1193 which = !which;
1194 }
1195 }
1196 }
1197 }
1198 }
1199
1200 /*
1201 *
1202 * Performs the bitmap decoding for standard input format
1203 *
1204 */
1205 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
1206 void* dst, uint32_t dstRowBytes) {
1207 // Set constant values
1208 const int width = dstInfo.width();
1209 const int height = dstInfo.height();
1210 const uint32_t pixelsPerByte = 8 / fBitsPerPixel;
1211 const uint32_t bytesPerPixel = fBitsPerPixel / 8;
1212 const uint32_t unpaddedRowBytes = fBitsPerPixel < 16 ?
1213 (width + pixelsPerByte - 1) / pixelsPerByte : width * bytesPerPixel;
1214 const uint32_t paddedRowBytes = SkAlign4(unpaddedRowBytes);
1215 const uint32_t alphaMask = fBitMasks.alphaMask;
1216
1217 // Get the destination start row and delta
1218 SkColor* dstRow;
1219 int32_t delta;
1220 if (kTopDown_RowOrder == fRowOrder) {
1221 dstRow = (SkColor*) dst;
1222 delta = dstRowBytes;
1223 } else {
1224 dstRow = (SkColor*) SkTAddOffset<void>(dst, (height - 1) * dstRowBytes);
1225 delta = -dstRowBytes;
1226 }
1227
1228 // Get swizzler configuration
1229 SkSwizzler::SrcConfig config;
1230 switch (fBitsPerPixel) {
1231 case 1:
1232 config = SkSwizzler::kIndex1;
1233 break;
1234 case 2:
1235 config = SkSwizzler::kIndex2;
1236 break;
1237 case 4:
1238 config = SkSwizzler::kIndex4;
1239 break;
1240 case 8:
1241 config = SkSwizzler::kIndex;
1242 break;
1243 case 24:
1244 config = SkSwizzler::kBGR;
1245 break;
1246 case 32:
1247 if (alphaMask == 0) {
1248 config = SkSwizzler::kBGRX;
1249 } else {
1250 config = SkSwizzler::kBGRA;
1251 }
1252 break;
1253 default:
1254 SkASSERT(false);
1255 return kInvalidInput;
1256 }
1257
1258 // Create swizzler
1259 SkSwizzler* swizzler = SkSwizzler::CreateSwizzler(config, fColorTable.get(),
1260 dstInfo, dstRow, dstRowBytes, false);
1261
1262 // Allocate space for a row buffer and a source for the swizzler
1263 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, paddedRowBytes));
1264
1265 // Iterate over rows of the image
1266 bool transparent = true;
1267 for (uint32_t y = 0; y < height; y++) {
1268 // Read a row of the input
1269 if (stream()->read(srcBuffer.get(), paddedRowBytes) != paddedRowBytes) {
1270 SkDebugf("Warning: incomplete input stream.\n");
1271 return kIncompleteInput;
1272 }
1273
1274 // Decode the row in destination format
1275 SkSwizzler::ResultAlpha r = swizzler->next(srcBuffer.get(), delta);
1276 transparent &= SkSwizzler::kTransparent_ResultAlpha == r;
1277 }
1278
1279 // Now we adjust the output image with some additional behavior that
1280 // SkSwizzler does not support. Firstly, all bmp images that contain
1281 // alpha are masked by the alpha mask. Secondly, many fully transparent
1282 // bmp images are intended to be opaque. Here, we make those corrections.
1283 SkColor* dstPtr = (SkColor*) dst;
1284 if (alphaMask != 0) {
1285 for (uint32_t y = 0; y < height; y++) {
1286 for (uint32_t x = 0; x < width; x++) {
1287 if (transparent) {
1288 dstPtr[y * dstRowBytes + x] |= 0xFF000000;
1289 } else {
1290 dstPtr[y * dstRowBytes + x] &= alphaMask;
1291 }
1292 }
1293 }
1294 }
1295
1296 // Finished decoding the entire image
1297 return kSuccess;
1298 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698