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

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

Powered by Google App Engine
This is Rietveld 408576698