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