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

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

Powered by Google App Engine
This is Rietveld 408576698