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

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: Creation of SkMasks 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 "SkColorPriv.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 static bool premul_and_unpremul(SkAlphaType dst, SkAlphaType src) {
53 return kPremul_SkAlphaType == dst && kUnpremul_SkAlphaType == src;
54 }
55
56 /*
57 *
58 * Checks if the conversion between the input image and the requested output
59 * image has been implemented
60 *
61 */
62 static bool conversion_possible(const SkImageInfo& dst,
63 const SkImageInfo& src) {
64 // TODO: Support more conversions
65 if (kN32_SkColorType != dst.colorType()) {
66 return false;
67 }
68 if (dst.alphaType() == src.alphaType()) {
69 return true;
70 }
71 return premul_and_unpremul(dst.alphaType(), src.alphaType())
72 || premul_and_unpremul(dst.alphaType(), src.alphaType());
73 }
74
75 /*
76 *
77 * Compute row bytes for an image
78 *
79 */
80 size_t compute_row_bytes(int width, uint32_t bitsPerPixel) {
81 if (bitsPerPixel < 16) {
82 SkASSERT(0 == 8 % bitsPerPixel);
83 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
84 return (width + pixelsPerByte - 1) / pixelsPerByte;
85 } else {
86 SkASSERT(0 == bitsPerPixel % 8);
87 const uint32_t bytesPerPixel = bitsPerPixel / 8;
88 return width * bytesPerPixel;
89 }
90 }
91
92 /*
93 *
94 * Defines the version and type of the second bitmap header
95 *
96 */
97 enum BitmapHeaderType {
98 kInfoV1_BitmapHeaderType,
99 kInfoV2_BitmapHeaderType,
100 kInfoV3_BitmapHeaderType,
101 kInfoV4_BitmapHeaderType,
102 kInfoV5_BitmapHeaderType,
103 kOS2V1_BitmapHeaderType,
104 kOS2VX_BitmapHeaderType,
105 kUnknown_BitmapHeaderType
106 };
107
108 /*
109 *
110 * Possible bitmap compression types
111 *
112 */
113 enum BitmapCompressionMethod {
114 kNone_BitmapCompressionMethod = 0,
115 k8BitRLE_BitmapCompressionMethod = 1,
116 k4BitRLE_BitmapCompressionMethod = 2,
117 kBitMasks_BitmapCompressionMethod = 3,
118 kJpeg_BitmapCompressionMethod = 4,
119 kPng_BitmapCompressionMethod = 5,
120 kAlphaBitMasks_BitmapCompressionMethod = 6,
121 kCMYK_BitmapCompressionMethod = 11,
122 kCMYK8BitRLE_BitmapCompressionMethod = 12,
123 kCMYK4BitRLE_BitmapCompressionMethod = 13
124 };
125
126 /*
127 *
128 * Checks the start of the stream to see if the image is a bitmap
129 *
130 */
131 bool SkBmpCodec::IsBmp(SkStream* stream) {
132 // TODO: Support "IC", "PT", "CI", "CP", "BA"
133 // TODO: ICO files may contain a BMP and need to use this decoder
134 const char bmpSig[] = { 'B', 'M' };
135 char buffer[sizeof(bmpSig)];
136 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
137 !memcmp(buffer, bmpSig, sizeof(bmpSig));
138 }
139
140 /*
141 *
142 * Assumes IsBmp was called and returned true
143 * Creates a bitmap decoder
144 * Reads enough of the stream to determine the image format
145 *
146 */
147 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
148 // Header size constants
149 static const uint32_t kBmpHeaderBytes = 14;
150 static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
151 static const uint32_t kBmpOS2V1Bytes = 12;
152 static const uint32_t kBmpOS2V2Bytes = 64;
153 static const uint32_t kBmpInfoBaseBytes = 16;
154 static const uint32_t kBmpInfoV1Bytes = 40;
155 static const uint32_t kBmpInfoV2Bytes = 52;
156 static const uint32_t kBmpInfoV3Bytes = 56;
157 static const uint32_t kBmpInfoV4Bytes = 108;
158 static const uint32_t kBmpInfoV5Bytes = 124;
159 static const uint32_t kBmpMaskBytes = 12;
160
161 // Read the first header and the size of the second header
162 SkAutoTDeleteArray<uint8_t> hBuffer(
163 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
164 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
165 kBmpHeaderBytesPlusFour) {
166 SkDebugf("Error: unable to read first bitmap header.\n");
167 return NULL;
168 }
169
170 // The total bytes in the bmp file
171 // We only need to use this value for RLE decoding, so we will only check
172 // that it is valid in the RLE case.
173 const uint32_t totalBytes = get_int(hBuffer.get(), 2);
174
175 // The offset from the start of the file where the pixel data begins
176 const uint32_t offset = get_int(hBuffer.get(), 10);
177 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
178 SkDebugf("Error: invalid starting location for pixel data\n");
179 return NULL;
180 }
181
182 // The size of the second (info) header in bytes
183 // The size is the first field of the second header, so we have already
184 // read the first four infoBytes.
185 const uint32_t infoBytes = get_int(hBuffer.get(), 14);
186 if (infoBytes < kBmpOS2V1Bytes) {
187 SkDebugf("Error: invalid second header size.\n");
188 return NULL;
189 }
190 const uint32_t infoBytesRemaining = infoBytes - 4;
191 hBuffer.free();
192
193 // Read the second header
194 SkAutoTDeleteArray<uint8_t> iBuffer(
195 SkNEW_ARRAY(uint8_t, infoBytesRemaining));
196 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
197 SkDebugf("Error: unable to read second bitmap header.\n");
198 return NULL;
199 }
200
201 // The number of bits used per pixel in the pixel data
202 uint16_t bitsPerPixel;
203
204 // The compression method for the pixel data
205 uint32_t compression = kNone_BitmapCompressionMethod;
206
207 // Number of colors in the color table, defaults to 0 or max (see below)
208 uint32_t numColors = 0;
209
210 // Bytes per color in the color table, early versions use 3, most use 4
211 uint32_t bytesPerColor;
212
213 // The image width and height
214 int width, height;
215
216 // Determine image information depending on second header format
217 BitmapHeaderType headerType;
218 if (infoBytes >= kBmpInfoBaseBytes) {
219 // Check the version of the header
220 switch (infoBytes) {
221 case kBmpInfoV1Bytes:
222 headerType = kInfoV1_BitmapHeaderType;
223 break;
224 case kBmpInfoV2Bytes:
225 headerType = kInfoV2_BitmapHeaderType;
226 break;
227 case kBmpInfoV3Bytes:
228 headerType = kInfoV3_BitmapHeaderType;
229 break;
230 case kBmpInfoV4Bytes:
231 headerType = kInfoV4_BitmapHeaderType;
232 break;
233 case kBmpInfoV5Bytes:
234 headerType = kInfoV5_BitmapHeaderType;
235 break;
236 case 16:
237 case 20:
238 case 24:
239 case 28:
240 case 32:
241 case 36:
242 case 42:
243 case 46:
244 case 48:
245 case 60:
246 case kBmpOS2V2Bytes:
247 headerType = kOS2VX_BitmapHeaderType;
248 break;
249 default:
250 // We do not signal an error here because there is the
251 // possibility of new or undocumented bmp header types. Most
252 // of the newer versions of bmp headers are similar to and
253 // build off of the older versions, so we may still be able to
254 // decode the bmp.
255 SkDebugf("Warning: unknown bmp header format.\n");
256 headerType = kUnknown_BitmapHeaderType;
257 break;
258 }
259 // We check the size of the header before entering the if statement.
260 // We should not reach this point unless the size is large enough for
261 // these required fields.
262 SkASSERT(infoBytesRemaining >= 12);
263 width = get_int(iBuffer.get(), 0);
264 height = get_int(iBuffer.get(), 4);
265 //uint16_t planes = get_short(iBuffer, 8);
266 bitsPerPixel = get_short(iBuffer.get(), 10);
267
268 // Some versions do not have this field, so we check before
269 // overwriting the default value.
270 if (infoBytesRemaining >= 16) {
271 compression = get_int(iBuffer.get(), 12);
272 }
273
274 // Some versions do not have this field, so we check before
275 // overwriting the default value.
276 if (infoBytesRemaining >= 32) {
277 numColors = get_int(iBuffer.get(), 28);
278 }
279
280 bytesPerColor = 4;
281 } else if (infoBytes >= kBmpOS2V1Bytes) {
282 // The OS2V1 is treated separately because it has a unique format
283 headerType = kOS2V1_BitmapHeaderType;
284 width = (int) get_short(iBuffer.get(), 0);
285 height = (int) get_short(iBuffer.get(), 2);
286 bitsPerPixel = get_short(iBuffer.get(), 6);
287 bytesPerColor = 3;
288 } else {
289 // There are no valid bmp headers
290 SkDebugf("Error: second bitmap header size is invalid.\n");
291 return NULL;
292 }
293
294 // Check for valid dimensions from header
295 RowOrder rowOrder = kBottomUp_RowOrder;
296 if (height < 0) {
297 height = -height;
298 rowOrder = kTopDown_RowOrder;
299 }
300 static const int kBmpMaxDim = 1 << 16;
301 if (width < 0 || width >= kBmpMaxDim || height >= kBmpMaxDim) {
302 // TODO: Decide if we want to support really large bmps.
303 SkDebugf("Error: invalid bitmap dimensions.\n");
304 return NULL;
305 }
306
307 // Create mask struct
308 SkMasks::InputMasks inputMasks;
309 memset(&inputMasks, 0, 4*sizeof(uint32_t));
310
311 // Determine the input compression format and set bit masks if necessary
312 uint32_t maskBytes = 0;
313 BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat;
314 switch (compression) {
315 case kNone_BitmapCompressionMethod:
316 inputFormat = kStandard_BitmapInputFormat;
317 break;
318 case k8BitRLE_BitmapCompressionMethod:
319 if (bitsPerPixel != 8) {
320 SkDebugf("Warning: correcting invalid bitmap format.\n");
321 bitsPerPixel = 8;
322 }
323 inputFormat = kRLE_BitmapInputFormat;
324 break;
325 case k4BitRLE_BitmapCompressionMethod:
326 if (bitsPerPixel != 4) {
327 SkDebugf("Warning: correcting invalid bitmap format.\n");
328 bitsPerPixel = 4;
329 }
330 inputFormat = kRLE_BitmapInputFormat;
331 break;
332 case kAlphaBitMasks_BitmapCompressionMethod:
333 case kBitMasks_BitmapCompressionMethod:
334 // Load the masks
335 inputFormat = kBitMask_BitmapInputFormat;
336 switch (headerType) {
337 case kInfoV1_BitmapHeaderType: {
338 // The V1 header stores the bit masks after the header
339 SkAutoTDeleteArray<uint8_t> mBuffer(
340 SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
341 if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
342 kBmpMaskBytes) {
343 SkDebugf("Error: unable to read bit inputMasks.\n");
344 return NULL;
345 }
346 maskBytes = kBmpMaskBytes;
347 inputMasks.red = get_int(mBuffer.get(), 0);
348 inputMasks.green = get_int(mBuffer.get(), 4);
349 inputMasks.blue = get_int(mBuffer.get(), 8);
350 break;
351 }
352 case kInfoV2_BitmapHeaderType:
353 case kInfoV3_BitmapHeaderType:
354 case kInfoV4_BitmapHeaderType:
355 case kInfoV5_BitmapHeaderType:
356 // Header types are matched based on size. If the header
357 // is V2+, we are guaranteed to be able at least this size.
358 SkASSERT(infoBytesRemaining >= 48);
359 inputMasks.red = get_int(iBuffer.get(), 36);
360 inputMasks.green = get_int(iBuffer.get(), 40);
361 inputMasks.blue = get_int(iBuffer.get(), 44);
362 break;
363 case kOS2VX_BitmapHeaderType:
364 // TODO: Decide if we intend to support this.
365 // It is unsupported in the previous version and
366 // in chromium. I have not come across a test case
367 // that uses this format.
368 SkDebugf("Error: huffman format unsupported.\n");
369 return NULL;
370 default:
371 SkDebugf("Error: invalid bmp bit masks header.\n");
372 return NULL;
373 }
374 break;
375 case kJpeg_BitmapCompressionMethod:
376 if (24 == bitsPerPixel) {
377 inputFormat = kRLE_BitmapInputFormat;
378 break;
379 }
380 // Fall through
381 case kPng_BitmapCompressionMethod:
382 // TODO: Decide if we intend to support this.
383 // It is unsupported in the previous version and
384 // in chromium. I think it is used mostly for printers.
385 SkDebugf("Error: compression format not supported.\n");
386 return NULL;
387 case kCMYK_BitmapCompressionMethod:
388 case kCMYK8BitRLE_BitmapCompressionMethod:
389 case kCMYK4BitRLE_BitmapCompressionMethod:
390 // TODO: Same as above.
391 SkDebugf("Error: CMYK not supported for bitmap decoding.\n");
392 return NULL;
393 default:
394 SkDebugf("Error: invalid format for bitmap decoding.\n");
395 return NULL;
396 }
397
398 // Most versions of bmps should be rendered as opaque. Either they do
399 // not have an alpha channel, or they expect the alpha channel to be
400 // ignored. V4+ bmp files introduce an alpha mask and allow the creator
401 // of the image to use the alpha channels. However, many of these images
402 // leave the alpha channel blank and expect to be rendered as opaque. For
403 // this reason, we set the alpha type to kUnknown for V4+ bmps and figure
404 // out the alpha type during the decode.
405 SkAlphaType alphaType = kOpaque_SkAlphaType;
406 if (kInfoV4_BitmapHeaderType == headerType ||
407 kInfoV5_BitmapHeaderType == headerType) {
408 // Header types are matched based on size. If the header is
409 // V4+, we are guaranteed to be able to read at least this size.
410 SkASSERT(infoBytesRemaining > 52);
411 inputMasks.alpha = get_int(iBuffer.get(), 48);
412 if (inputMasks.alpha != 0) {
413 alphaType = kUnpremul_SkAlphaType;
414 }
415 }
416 iBuffer.free();
417
418 // Check for valid bits per pixel input
419 switch (bitsPerPixel) {
420 // In addition to more standard pixel compression formats, bmp supports
421 // the use of bit masks to determine pixel components. The standard
422 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
423 // which does not map well to any Skia color formats. For this reason,
424 // we will always enable mask mode with 16 bits per pixel.
425 case 16:
426 if (kBitMask_BitmapInputFormat != inputFormat) {
427 inputMasks.red = 0x7C00;
428 inputMasks.green = 0x03E0;
429 inputMasks.blue = 0x001F;
430 inputFormat = kBitMask_BitmapInputFormat;
431 }
432 break;
433 case 1:
434 case 2:
435 case 4:
436 case 8:
437 case 24:
438 case 32:
439 break;
440 default:
441 SkDebugf("Error: invalid input value for bits per pixel.\n");
442 return NULL;
443 }
444
445 // Check that input bit masks are valid and create the masks object
446 SkMasks* masks = SkMasks::CreateMasks(inputMasks, bitsPerPixel);
scroggo 2015/03/11 19:22:45 This can be leaked from one of our debug statement
msarett 2015/03/11 20:03:11 Got it. I will try to fix this.
447 if (NULL == masks) {
448 SkDebugf("Error: invalid input masks.\n");
449 return NULL;
450 }
451
452 // Process the color table
453 uint32_t colorBytes = 0;
454 SkPMColor* colorTable = NULL;
455 if (bitsPerPixel < 16) {
456 // Verify the number of colors for the color table
457 const uint32_t maxColors = 1 << bitsPerPixel;
458 // Zero is a default for maxColors
459 // Also set numColors to maxColors when input is too large
460 if (numColors <= 0 || numColors > maxColors) {
461 numColors = maxColors;
462 }
463 colorTable = SkNEW_ARRAY(SkPMColor, maxColors);
464
465 // Construct the color table
466 colorBytes = numColors * bytesPerColor;
467 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
468 if (stream->read(cBuffer.get(), colorBytes) != colorBytes) {
469 SkDebugf("Error: unable to read color table.\n");
470 return NULL;
471 }
472
473 // Fill in the color table
474 uint32_t i = 0;
475 for (; i < numColors; i++) {
476 uint8_t blue = get_byte(cBuffer.get(), i*bytesPerColor);
477 uint8_t green = get_byte(cBuffer.get(), i*bytesPerColor + 1);
478 uint8_t red = get_byte(cBuffer.get(), i*bytesPerColor + 2);
479 uint8_t alpha = 0xFF;
480 if (kOpaque_SkAlphaType != alphaType) {
481 alpha = (inputMasks.alpha >> 24) &
482 get_byte(cBuffer.get(), i*bytesPerColor + 3);
483 }
484 colorTable[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
485 }
486
487 // To avoid segmentation faults on bad pixel data, fill the end of the
488 // color table with black. This is the same the behavior as the
489 // chromium decoder.
490 for (; i < maxColors; i++) {
491 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
492 }
493 } else {
494 // We will not use the color table if bitsPerPixel >= 16, but if there
495 // is a color table, we may need to skip the color table bytes.
496 // We will assume that the maximum color table size is the same as when
497 // there are 8 bits per pixel (the largest color table actually used).
498 // Color tables for greater than 8 bits per pixel are somewhat
499 // undocumented. It is indicated that they may exist to store a list
500 // of colors for optimization on devices with limited color display
501 // capacity. While we do not know for sure, we will guess that any
502 // value of numColors greater than this maximum is invalid.
503 if (numColors <= (1 << 8)) {
504 colorBytes = numColors * bytesPerColor;
505 if (stream->skip(colorBytes) != colorBytes) {
506 SkDebugf("Error: Could not skip color table bytes.\n");
507 return NULL;
508 }
509 }
510 }
511
512 // Ensure that the stream now points to the start of the pixel array
513 uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes + colorBytes;
514
515 // Check that we have not read past the pixel array offset
516 if(bytesRead > offset) {
517 // This may occur on OS 2.1 and other old versions where the color
518 // table defaults to max size, and the bmp tries to use a smaller color
519 // table. This is invalid, and our decision is to indicate an error,
520 // rather than try to guess the intended size of the color table and
521 // rewind the stream to display the image.
522 SkDebugf("Error: pixel data offset less than header size.\n");
523 return NULL;
524 }
525
526 // Skip to the start of the pixel array
527 if (stream->skip(offset - bytesRead) != offset - bytesRead) {
528 SkDebugf("Error: unable to skip to image data.\n");
529 return NULL;
530 }
531
532 // Remaining bytes is only used for RLE
533 const int remainingBytes = totalBytes - offset;
534 if (remainingBytes <= 0 && kRLE_BitmapInputFormat == inputFormat) {
535 SkDebugf("Error: RLE requires valid input size.\n");
536 return NULL;
537 }
538
539 // Return the codec
540 // We will use ImageInfo to store width, height, and alpha type. The Skia
541 // color types do not match with the many possible bmp input color types,
542 // so we will ignore this field and depend on other parameters for input
543 // information.
544 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
545 kUnknown_SkColorType, alphaType);
546 return SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
547 inputFormat, masks, colorTable, rowOrder,
548 remainingBytes));
549 }
550
551 /*
552 *
553 * Creates an instance of the decoder
554 * Called only by NewFromStream
555 *
556 */
557 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
558 uint16_t bitsPerPixel, BitmapInputFormat inputFormat,
559 SkMasks* masks, SkPMColor* colorTable,
560 RowOrder rowOrder,
561 const uint32_t remainingBytes)
562 : INHERITED(info, stream)
563 , fBitsPerPixel(bitsPerPixel)
564 , fInputFormat(inputFormat)
565 , fMasks(masks)
566 , fColorTable(colorTable)
567 , fRowOrder(rowOrder)
568 , fRemainingBytes(remainingBytes)
569 {}
570
571 /*
572 *
573 * Initiates the bitmap decode
574 *
575 */
576 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
577 void* dst, size_t dstRowBytes,
578 SkPMColor*, int*) {
579 if (!this->rewindIfNeeded()) {
580 return kCouldNotRewind;
581 }
582 if (dstInfo.dimensions() != this->getOriginalInfo().dimensions()) {
583 SkDebugf("Error: scaling not supported.\n");
584 return kInvalidScale;
585 }
586 if (!conversion_possible(dstInfo, this->getOriginalInfo())) {
587 SkDebugf("Error: cannot convert input type to output type.\n");
588 return kInvalidConversion;
589 }
590
591 switch (fInputFormat) {
592 case kBitMask_BitmapInputFormat:
593 return decodeMask(dstInfo, dst, dstRowBytes);
594 case kRLE_BitmapInputFormat:
595 return decodeRLE(dstInfo, dst, dstRowBytes);
596 case kStandard_BitmapInputFormat:
597 return decode(dstInfo, dst, dstRowBytes);
598 default:
599 SkASSERT(false);
600 return kInvalidInput;
601 }
602 }
603
604 /*
605 *
606 * Performs the bitmap decoding for bit masks input format
607 *
608 */
609 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo,
610 void* dst, uint32_t dstRowBytes) {
611 // Set constant values
612 const int width = dstInfo.width();
613 const int height = dstInfo.height();
614 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
615
616 // Allocate space for a row buffer and a source for the swizzler
617 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
618
619 // Get the destination start row and delta
620 SkPMColor* dstRow;
621 int32_t delta;
622 if (kTopDown_RowOrder == fRowOrder) {
623 dstRow = (SkPMColor*) dst;
624 delta = dstRowBytes;
625 } else {
626 dstRow = (SkPMColor*) SkTAddOffset<void>(dst, (height-1) * dstRowBytes);
627 delta = -dstRowBytes;
628 }
629
630 // Create the swizzler
631 SkMaskSwizzler* swizzler = SkMaskSwizzler::CreateMaskSwizzler(
632 dstInfo, fMasks, fBitsPerPixel);
633
634 // Iterate over rows of the image
635 bool transparent = true;
636 for (int y = 0; y < height; y++) {
637 // Read a row of the input
638 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
639 SkDebugf("Warning: incomplete input stream.\n");
640 return kIncompleteInput;
641 }
642
643 // Decode the row in destination format
644 SkSwizzler::ResultAlpha r = swizzler->next(dstRow, srcBuffer.get());
645 transparent &= (SkSwizzler::kTransparent_ResultAlpha == r);
646
647 // Move to the next row
648 dstRow = SkTAddOffset<SkPMColor>(dstRow, delta);
649 }
650
651 // Many fully transparent bmp images are intended to be opaque. Here, we
652 // correct for this possibility.
653 dstRow = (SkPMColor*) dst;
654 if (transparent) {
655 for (int y = 0; y < height; y++) {
656 for (int x = 0; x < width; x++) {
657 dstRow[x] |= 0xFF000000;
658 }
659 dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
660 }
661 }
662
663 // Finished decoding the entire image
664 return kSuccess;
665 }
666
667 /*
668 *
669 * Set an RLE pixel using the color table
670 *
671 */
672 void SkBmpCodec::setRLEPixel(SkPMColor* dst, uint32_t dstRowBytes, int height,
673 uint32_t x, uint32_t y, uint8_t index) {
674 if (kBottomUp_RowOrder == fRowOrder) {
675 y = height - y - 1;
676 }
677 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, y * dstRowBytes);
678 dstRow[x] = fColorTable.get()[index];
679 }
680
681 /*
682 *
683 * Performs the bitmap decoding for RLE input format
684 * RLE decoding is performed all at once, rather than a one row at a time
685 *
686 */
687 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
688 void* dst, uint32_t dstRowBytes) {
689 // Set RLE flags
690 static const uint8_t RLE_ESCAPE = 0;
691 static const uint8_t RLE_EOL = 0;
692 static const uint8_t RLE_EOF = 1;
693 static const uint8_t RLE_DELTA = 2;
694
695 // Set constant values
696 const int width = dstInfo.width();
697 const int height = dstInfo.height();
698
699 // Input buffer parameters
700 uint32_t currByte = 0;
701 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRemainingBytes));
702 uint32_t totalBytes = stream()->read(buffer.get(), fRemainingBytes);
703 if (totalBytes < fRemainingBytes) {
704 SkDebugf("Warning: incomplete RLE file.\n");
705 } else if (totalBytes <= 0) {
706 SkDebugf("Error: could not read RLE image data.\n");
707 return kInvalidInput;
708 }
709
710 // Destination parameters
711 int x = 0;
712 int y = 0;
713 // If the code skips pixels, remaining pixels are transparent or black
714 // TODO: Skip this if memory was already zeroed.
715 memset(dst, 0, dstRowBytes * height);
716 SkPMColor* dstPtr = (SkPMColor*) dst;
717
718 while (true) {
719 // Every entry takes at least two bytes
720 if (totalBytes - currByte < 2) {
721 SkDebugf("Warning: incomplete RLE input.\n");
722 return kIncompleteInput;
723 }
724
725 // Read the next two bytes. These bytes have different meanings
726 // depending on their values. In the first interpretation, the first
727 // byte is an escape flag and the second byte indicates what special
728 // task to perform.
729 const uint8_t flag = buffer.get()[currByte++];
730 const uint8_t task = buffer.get()[currByte++];
731
732 // If we have reached a row that is beyond the image size, and the RLE
733 // code does not indicate end of file, abort and signal a warning.
734 if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
735 SkDebugf("Warning: invalid RLE input.\n");
736 return kIncompleteInput;
737 }
738
739 // Perform decoding
740 if (RLE_ESCAPE == flag) {
741 switch (task) {
742 case RLE_EOL:
743 x = 0;
744 y++;
745 break;
746 case RLE_EOF:
747 return kSuccess;
748 case RLE_DELTA: {
749 // Two bytes are needed to specify delta
750 if (totalBytes - currByte < 2) {
751 SkDebugf("Warning: incomplete RLE input\n");
752 return kIncompleteInput;
753 }
754 // Modify x and y
755 const uint8_t dx = buffer.get()[currByte++];
756 const uint8_t dy = buffer.get()[currByte++];
757 x += dx;
758 y += dy;
759 if (x > width || y > height) {
760 SkDebugf("Warning: invalid RLE input.\n");
761 return kIncompleteInput;
762 }
763 break;
764 }
765 default: {
766 // If task does not match any of the above signals, it
767 // indicates that we have a sequence of non-RLE pixels.
768 // Furthermore, the value of task is equal to the number
769 // of pixels to interpret.
770 uint8_t numPixels = task;
771 const size_t rowBytes = compute_row_bytes(numPixels,
772 fBitsPerPixel);
773 // Abort if setting numPixels moves us off the edge of the
774 // image. Also abort if there are not enough bytes
775 // remaining in the stream to set numPixels.
776 if (x + numPixels > width ||
777 totalBytes - currByte < SkAlign2(rowBytes)) {
778 SkDebugf("Warning: invalid RLE input.\n");
779 return kIncompleteInput;
780 }
781 // Set count number of pixels
782 while (numPixels > 0) {
783 switch(fBitsPerPixel) {
784 case 4: {
785 uint8_t val = buffer.get()[currByte++];
786 setRLEPixel(dstPtr, dstRowBytes, height, x++, y,
787 val >> 4);
788 numPixels--;
789 if (numPixels != 0) {
790 setRLEPixel(dstPtr, dstRowBytes, height,
791 x++, y, val & 0xF);
792 numPixels--;
793 }
794 break;
795 }
796 case 8:
797 setRLEPixel(dstPtr, dstRowBytes, height, x++, y,
798 buffer.get()[currByte++]);
799 numPixels--;
800 break;
801 case 24: {
802 uint8_t blue = buffer.get()[currByte++];
803 uint8_t green = buffer.get()[currByte++];
804 uint8_t red = buffer.get()[currByte++];
805 SkPMColor color = SkPackARGB32NoCheck(
806 0xFF, red, green, blue);
807 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(
808 dstPtr, y * dstRowBytes);
809 dstRow[x++] = color;
810 numPixels--;
811 }
812 default:
813 SkASSERT(false);
814 return kInvalidInput;
815 }
816 }
817 // Skip a byte if necessary to maintain alignment
818 if (rowBytes & 1) {
scroggo 2015/03/11 19:22:45 SkIsAlign2?
msarett 2015/03/11 20:03:11 Yes that would be the better choice!
819 currByte++;
820 }
821 break;
822 }
823 }
824 } else {
825 // If the first byte read is not a flag, it indicates the number of
826 // pixels to set in RLE mode.
827 const uint8_t numPixels = flag;
828 const int endX = SkTMin<int>(x + numPixels, width);
829
830 if (24 == fBitsPerPixel) {
831 // In RLE24, the second byte read is part of the pixel color.
832 // There are two more required bytes to finish encoding the
833 // color.
834 if (totalBytes - currByte < 2) {
835 SkDebugf("Warning: incomplete RLE input\n");
836 return kIncompleteInput;
837 }
838
839 // Fill the pixels up to endX with the specified color
840 uint8_t blue = task;
841 uint8_t green = buffer.get()[currByte++];
842 uint8_t red = buffer.get()[currByte++];
843 SkPMColor color = SkPackARGB32NoCheck(0xFF, red, green, blue);
844 SkPMColor* dstRow =
845 SkTAddOffset<SkPMColor>(dstPtr, y * dstRowBytes);
846 while (x < endX) {
847 dstRow[x++] = color;
848 }
849 } else {
850 // In RLE8 or RLE4, the second byte read gives the index in the
851 // color table to look up the pixel color.
852 // RLE8 has one color index that gets repeated
853 // RLE4 has two color indexes in the upper and lower 4 bits of
854 // the bytes, which are alternated
855 uint8_t indices[2] = { task, task };
856 if (4 == fBitsPerPixel) {
857 indices[0] >>= 4;
858 indices[1] &= 0xf;
859 }
860
861 // Set the indicated number of pixels
862 for (int which = 0; x < endX; x++) {
863 setRLEPixel(dstPtr, dstRowBytes, height, x, y,
864 indices[which]);
865 which = !which;
866 }
867 }
868 }
869 }
870 }
871
872 /*
873 *
874 * Performs the bitmap decoding for standard input format
875 *
876 */
877 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
878 void* dst, uint32_t dstRowBytes) {
879 // Set constant values
880 const int width = dstInfo.width();
881 const int height = dstInfo.height();
882 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
883 const uint32_t alphaMask = fMasks->getAlphaMask();
884
885 // Get swizzler configuration
886 SkSwizzler::SrcConfig config;
887 switch (fBitsPerPixel) {
888 case 1:
889 config = SkSwizzler::kIndex1;
890 break;
891 case 2:
892 config = SkSwizzler::kIndex2;
893 break;
894 case 4:
895 config = SkSwizzler::kIndex4;
896 break;
897 case 8:
898 config = SkSwizzler::kIndex;
899 break;
900 case 24:
901 config = SkSwizzler::kBGR;
902 break;
903 case 32:
904 if (alphaMask == 0) {
905 config = SkSwizzler::kBGRX;
906 } else {
907 config = SkSwizzler::kBGRA;
908 }
909 break;
910 default:
911 SkASSERT(false);
912 return kInvalidInput;
913 }
914
915 // Create swizzler
916 SkSwizzler* swizzler = SkSwizzler::CreateSwizzler(config, fColorTable.get(),
917 dstInfo, dst, dstRowBytes, false);
918
919 // Allocate space for a row buffer and a source for the swizzler
920 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
921
922 // Iterate over rows of the image
923 bool transparent = true;
924 for (int y = 0; y < height; y++) {
925 // Read a row of the input
926 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
927 SkDebugf("Warning: incomplete input stream.\n");
928 return kIncompleteInput;
929 }
930
931 // Decode the row in destination format
932 uint32_t row;
933 if (kTopDown_RowOrder == fRowOrder) {
934 row = y;
935 } else {
936 row = height - 1 - y;
937 }
938 SkSwizzler::ResultAlpha r = swizzler->next(srcBuffer.get(), row);
939 transparent &= (SkSwizzler::kTransparent_ResultAlpha == r);
940 }
941
942 // Now we adjust the output image with some additional behavior that
943 // SkSwizzler does not support. Firstly, all bmp images that contain
944 // alpha are masked by the alpha mask. Secondly, many fully transparent
945 // bmp images are intended to be opaque. Here, we make those corrections.
946 SkPMColor* dstRow = (SkPMColor*) dst;
947 if (alphaMask != 0) {
948 for (int y = 0; y < height; y++) {
949 for (int x = 0; x < width; x++) {
950 if (transparent) {
951 dstRow[x] |= 0xFF000000;
952 } else {
953 dstRow[x] &= alphaMask;
954 }
955 dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
956 }
957 }
958 }
959
960 // Finished decoding the entire image
961 return kSuccess;
962 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698