blob: fdb0bd642bf756cdf591ed75bb287aa002e77d05 [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -07001/*
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 */
19static bool conversion_possible(const SkImageInfo& dst,
20 const SkImageInfo& src) {
msaretteed039b2015-03-18 11:11:19 -070021 // Ensure that the profile type is unchanged
22 if (dst.profileType() != src.profileType()) {
msarett74114382015-03-16 11:55:18 -070023 return false;
24 }
msaretteed039b2015-03-18 11:11:19 -070025
msarett438b2ad2015-04-09 12:43:10 -070026 // Check for supported alpha types
27 if (src.alphaType() != dst.alphaType()) {
28 if (kOpaque_SkAlphaType == src.alphaType()) {
29 // If the source is opaque, we must decode to opaque
30 return false;
31 }
32
33 // The source is not opaque
34 switch (dst.alphaType()) {
35 case kPremul_SkAlphaType:
36 case kUnpremul_SkAlphaType:
37 // The source is not opaque, so either of these is okay
38 break;
39 default:
40 // We cannot decode a non-opaque image to opaque (or unknown)
41 return false;
42 }
43 }
44
45 // Check for supported color types
msaretteed039b2015-03-18 11:11:19 -070046 switch (dst.colorType()) {
msarett438b2ad2015-04-09 12:43:10 -070047 // Allow output to kN32 from any type of input
msaretteed039b2015-03-18 11:11:19 -070048 case kN32_SkColorType:
msarett438b2ad2015-04-09 12:43:10 -070049 return true;
50 // Allow output to kIndex_8 from compatible inputs
51 case kIndex_8_SkColorType:
52 return kIndex_8_SkColorType == src.colorType();
msaretteed039b2015-03-18 11:11:19 -070053 default:
54 return false;
msarett74114382015-03-16 11:55:18 -070055 }
msarett74114382015-03-16 11:55:18 -070056}
57
58/*
59 *
60 * Defines the version and type of the second bitmap header
61 *
62 */
63enum BitmapHeaderType {
64 kInfoV1_BitmapHeaderType,
65 kInfoV2_BitmapHeaderType,
66 kInfoV3_BitmapHeaderType,
67 kInfoV4_BitmapHeaderType,
68 kInfoV5_BitmapHeaderType,
69 kOS2V1_BitmapHeaderType,
70 kOS2VX_BitmapHeaderType,
71 kUnknown_BitmapHeaderType
72};
73
74/*
75 *
76 * Possible bitmap compression types
77 *
78 */
79enum BitmapCompressionMethod {
80 kNone_BitmapCompressionMethod = 0,
81 k8BitRLE_BitmapCompressionMethod = 1,
82 k4BitRLE_BitmapCompressionMethod = 2,
83 kBitMasks_BitmapCompressionMethod = 3,
84 kJpeg_BitmapCompressionMethod = 4,
85 kPng_BitmapCompressionMethod = 5,
86 kAlphaBitMasks_BitmapCompressionMethod = 6,
87 kCMYK_BitmapCompressionMethod = 11,
88 kCMYK8BitRLE_BitmapCompressionMethod = 12,
89 kCMYK4BitRLE_BitmapCompressionMethod = 13
90};
91
92/*
93 *
94 * Checks the start of the stream to see if the image is a bitmap
95 *
96 */
97bool SkBmpCodec::IsBmp(SkStream* stream) {
98 // TODO: Support "IC", "PT", "CI", "CP", "BA"
msarett74114382015-03-16 11:55:18 -070099 const char bmpSig[] = { 'B', 'M' };
100 char buffer[sizeof(bmpSig)];
101 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
102 !memcmp(buffer, bmpSig, sizeof(bmpSig));
103}
104
105/*
106 *
107 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -0700108 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -0700109 * Reads enough of the stream to determine the image format
110 *
111 */
112SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
msarett9bde9182015-03-25 05:27:48 -0700113 return SkBmpCodec::NewFromStream(stream, false);
114}
115
116/*
117 *
118 * Creates a bmp decoder for a bmp embedded in ico
119 * Reads enough of the stream to determine the image format
120 *
121 */
122SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
123 return SkBmpCodec::NewFromStream(stream, true);
124}
125
126/*
127 *
scroggo79e378d2015-04-01 07:39:40 -0700128 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
129 * representing success or failure. If it returned true, and codecOut was
130 * not NULL, it will be set to a new SkBmpCodec.
scroggo0a7e69c2015-04-03 07:22:22 -0700131 * Does *not* take ownership of the passed in SkStream.
msarett9bde9182015-03-25 05:27:48 -0700132 *
133 */
scroggo79e378d2015-04-01 07:39:40 -0700134bool SkBmpCodec::ReadHeader(SkStream* stream, bool isIco, SkCodec** codecOut) {
msarett74114382015-03-16 11:55:18 -0700135 // Header size constants
136 static const uint32_t kBmpHeaderBytes = 14;
137 static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
138 static const uint32_t kBmpOS2V1Bytes = 12;
139 static const uint32_t kBmpOS2V2Bytes = 64;
140 static const uint32_t kBmpInfoBaseBytes = 16;
141 static const uint32_t kBmpInfoV1Bytes = 40;
142 static const uint32_t kBmpInfoV2Bytes = 52;
143 static const uint32_t kBmpInfoV3Bytes = 56;
144 static const uint32_t kBmpInfoV4Bytes = 108;
145 static const uint32_t kBmpInfoV5Bytes = 124;
146 static const uint32_t kBmpMaskBytes = 12;
147
tomhudson7aa846c2015-03-24 13:47:41 -0700148 // The total bytes in the bmp file
msarett9bde9182015-03-25 05:27:48 -0700149 // We only need to use this value for RLE decoding, so we will only
150 // check that it is valid in the RLE case.
151 uint32_t totalBytes;
tomhudson7aa846c2015-03-24 13:47:41 -0700152 // The offset from the start of the file where the pixel data begins
msarett9bde9182015-03-25 05:27:48 -0700153 uint32_t offset;
154 // The size of the second (info) header in bytes
155 uint32_t infoBytes;
156
157 // Bmps embedded in Icos skip the first Bmp header
158 if (!isIco) {
159 // Read the first header and the size of the second header
160 SkAutoTDeleteArray<uint8_t> hBuffer(
161 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
162 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
163 kBmpHeaderBytesPlusFour) {
scroggo230d4ac2015-03-26 07:15:55 -0700164 SkCodecPrintf("Error: unable to read first bitmap header.\n");
scroggo79e378d2015-04-01 07:39:40 -0700165 return false;
msarett9bde9182015-03-25 05:27:48 -0700166 }
167
168 totalBytes = get_int(hBuffer.get(), 2);
169 offset = get_int(hBuffer.get(), 10);
170 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700171 SkCodecPrintf("Error: invalid starting location for pixel data\n");
scroggo79e378d2015-04-01 07:39:40 -0700172 return false;
msarett9bde9182015-03-25 05:27:48 -0700173 }
174
175 // The size of the second (info) header in bytes
176 // The size is the first field of the second header, so we have already
177 // read the first four infoBytes.
178 infoBytes = get_int(hBuffer.get(), 14);
179 if (infoBytes < kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700180 SkCodecPrintf("Error: invalid second header size.\n");
scroggo79e378d2015-04-01 07:39:40 -0700181 return false;
msarett9bde9182015-03-25 05:27:48 -0700182 }
183 } else {
184 // This value is only used by RLE compression. Bmp in Ico files do not
185 // use RLE. If the compression field is incorrectly signaled as RLE,
186 // we will catch this and signal an error below.
187 totalBytes = 0;
188
189 // Bmps in Ico cannot specify an offset. We will always assume that
190 // pixel data begins immediately after the color table. This value
191 // will be corrected below.
192 offset = 0;
193
194 // Read the size of the second header
195 SkAutoTDeleteArray<uint8_t> hBuffer(
196 SkNEW_ARRAY(uint8_t, 4));
197 if (stream->read(hBuffer.get(), 4) != 4) {
scroggo230d4ac2015-03-26 07:15:55 -0700198 SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
scroggo79e378d2015-04-01 07:39:40 -0700199 return false;
msarett9bde9182015-03-25 05:27:48 -0700200 }
201 infoBytes = get_int(hBuffer.get(), 0);
202 if (infoBytes < kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700203 SkCodecPrintf("Error: invalid second header size.\n");
scroggo79e378d2015-04-01 07:39:40 -0700204 return false;
msarett9bde9182015-03-25 05:27:48 -0700205 }
tomhudson7aa846c2015-03-24 13:47:41 -0700206 }
207
msarett9bde9182015-03-25 05:27:48 -0700208 // We already read the first four bytes of the info header to get the size
msarett74114382015-03-16 11:55:18 -0700209 const uint32_t infoBytesRemaining = infoBytes - 4;
msarett74114382015-03-16 11:55:18 -0700210
211 // Read the second header
212 SkAutoTDeleteArray<uint8_t> iBuffer(
213 SkNEW_ARRAY(uint8_t, infoBytesRemaining));
214 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
scroggo230d4ac2015-03-26 07:15:55 -0700215 SkCodecPrintf("Error: unable to read second bitmap header.\n");
scroggo79e378d2015-04-01 07:39:40 -0700216 return false;
msarett74114382015-03-16 11:55:18 -0700217 }
218
219 // The number of bits used per pixel in the pixel data
220 uint16_t bitsPerPixel;
221
222 // The compression method for the pixel data
223 uint32_t compression = kNone_BitmapCompressionMethod;
224
225 // Number of colors in the color table, defaults to 0 or max (see below)
226 uint32_t numColors = 0;
227
228 // Bytes per color in the color table, early versions use 3, most use 4
229 uint32_t bytesPerColor;
230
231 // The image width and height
232 int width, height;
233
234 // Determine image information depending on second header format
235 BitmapHeaderType headerType;
236 if (infoBytes >= kBmpInfoBaseBytes) {
237 // Check the version of the header
238 switch (infoBytes) {
239 case kBmpInfoV1Bytes:
240 headerType = kInfoV1_BitmapHeaderType;
241 break;
242 case kBmpInfoV2Bytes:
243 headerType = kInfoV2_BitmapHeaderType;
244 break;
245 case kBmpInfoV3Bytes:
246 headerType = kInfoV3_BitmapHeaderType;
247 break;
248 case kBmpInfoV4Bytes:
249 headerType = kInfoV4_BitmapHeaderType;
250 break;
251 case kBmpInfoV5Bytes:
252 headerType = kInfoV5_BitmapHeaderType;
253 break;
254 case 16:
255 case 20:
256 case 24:
257 case 28:
258 case 32:
259 case 36:
260 case 42:
261 case 46:
262 case 48:
263 case 60:
264 case kBmpOS2V2Bytes:
265 headerType = kOS2VX_BitmapHeaderType;
266 break;
267 default:
268 // We do not signal an error here because there is the
269 // possibility of new or undocumented bmp header types. Most
270 // of the newer versions of bmp headers are similar to and
271 // build off of the older versions, so we may still be able to
272 // decode the bmp.
scroggo230d4ac2015-03-26 07:15:55 -0700273 SkCodecPrintf("Warning: unknown bmp header format.\n");
msarett74114382015-03-16 11:55:18 -0700274 headerType = kUnknown_BitmapHeaderType;
275 break;
276 }
277 // We check the size of the header before entering the if statement.
278 // We should not reach this point unless the size is large enough for
279 // these required fields.
280 SkASSERT(infoBytesRemaining >= 12);
281 width = get_int(iBuffer.get(), 0);
282 height = get_int(iBuffer.get(), 4);
283 bitsPerPixel = get_short(iBuffer.get(), 10);
284
285 // Some versions do not have these fields, so we check before
286 // overwriting the default value.
287 if (infoBytesRemaining >= 16) {
288 compression = get_int(iBuffer.get(), 12);
289 if (infoBytesRemaining >= 32) {
290 numColors = get_int(iBuffer.get(), 28);
291 }
292 }
293
294 // All of the headers that reach this point, store color table entries
295 // using 4 bytes per pixel.
296 bytesPerColor = 4;
297 } else if (infoBytes >= kBmpOS2V1Bytes) {
298 // The OS2V1 is treated separately because it has a unique format
299 headerType = kOS2V1_BitmapHeaderType;
300 width = (int) get_short(iBuffer.get(), 0);
301 height = (int) get_short(iBuffer.get(), 2);
302 bitsPerPixel = get_short(iBuffer.get(), 6);
303 bytesPerColor = 3;
304 } else {
305 // There are no valid bmp headers
scroggo230d4ac2015-03-26 07:15:55 -0700306 SkCodecPrintf("Error: second bitmap header size is invalid.\n");
scroggo79e378d2015-04-01 07:39:40 -0700307 return false;
msarett74114382015-03-16 11:55:18 -0700308 }
309
310 // Check for valid dimensions from header
311 RowOrder rowOrder = kBottomUp_RowOrder;
312 if (height < 0) {
313 height = -height;
314 rowOrder = kTopDown_RowOrder;
315 }
msarett9bde9182015-03-25 05:27:48 -0700316 // The height field for bmp in ico is double the actual height because they
317 // contain an XOR mask followed by an AND mask
318 if (isIco) {
319 height /= 2;
320 }
msarett4b17fa32015-04-23 08:53:39 -0700321 if (width <= 0 || height <= 0) {
322 // TODO: Decide if we want to disable really large bmps as well.
323 // https://code.google.com/p/skia/issues/detail?id=3617
scroggo230d4ac2015-03-26 07:15:55 -0700324 SkCodecPrintf("Error: invalid bitmap dimensions.\n");
scroggo79e378d2015-04-01 07:39:40 -0700325 return false;
msarett74114382015-03-16 11:55:18 -0700326 }
327
328 // Create mask struct
329 SkMasks::InputMasks inputMasks;
msaretteed039b2015-03-18 11:11:19 -0700330 memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
msarett74114382015-03-16 11:55:18 -0700331
332 // Determine the input compression format and set bit masks if necessary
333 uint32_t maskBytes = 0;
334 BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat;
335 switch (compression) {
336 case kNone_BitmapCompressionMethod:
337 inputFormat = kStandard_BitmapInputFormat;
338 break;
339 case k8BitRLE_BitmapCompressionMethod:
340 if (bitsPerPixel != 8) {
scroggo230d4ac2015-03-26 07:15:55 -0700341 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
msarett74114382015-03-16 11:55:18 -0700342 bitsPerPixel = 8;
343 }
344 inputFormat = kRLE_BitmapInputFormat;
345 break;
346 case k4BitRLE_BitmapCompressionMethod:
347 if (bitsPerPixel != 4) {
scroggo230d4ac2015-03-26 07:15:55 -0700348 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
msarett74114382015-03-16 11:55:18 -0700349 bitsPerPixel = 4;
350 }
351 inputFormat = kRLE_BitmapInputFormat;
352 break;
353 case kAlphaBitMasks_BitmapCompressionMethod:
354 case kBitMasks_BitmapCompressionMethod:
355 // Load the masks
356 inputFormat = kBitMask_BitmapInputFormat;
357 switch (headerType) {
358 case kInfoV1_BitmapHeaderType: {
359 // The V1 header stores the bit masks after the header
360 SkAutoTDeleteArray<uint8_t> mBuffer(
361 SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
362 if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
363 kBmpMaskBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700364 SkCodecPrintf("Error: unable to read bit inputMasks.\n");
scroggo79e378d2015-04-01 07:39:40 -0700365 return false;
msarett74114382015-03-16 11:55:18 -0700366 }
367 maskBytes = kBmpMaskBytes;
368 inputMasks.red = get_int(mBuffer.get(), 0);
369 inputMasks.green = get_int(mBuffer.get(), 4);
370 inputMasks.blue = get_int(mBuffer.get(), 8);
371 break;
372 }
373 case kInfoV2_BitmapHeaderType:
374 case kInfoV3_BitmapHeaderType:
375 case kInfoV4_BitmapHeaderType:
376 case kInfoV5_BitmapHeaderType:
377 // Header types are matched based on size. If the header
378 // is V2+, we are guaranteed to be able to read at least
379 // this size.
380 SkASSERT(infoBytesRemaining >= 48);
381 inputMasks.red = get_int(iBuffer.get(), 36);
382 inputMasks.green = get_int(iBuffer.get(), 40);
383 inputMasks.blue = get_int(iBuffer.get(), 44);
384 break;
385 case kOS2VX_BitmapHeaderType:
386 // TODO: Decide if we intend to support this.
387 // It is unsupported in the previous version and
388 // in chromium. I have not come across a test case
389 // that uses this format.
scroggo230d4ac2015-03-26 07:15:55 -0700390 SkCodecPrintf("Error: huffman format unsupported.\n");
scroggo79e378d2015-04-01 07:39:40 -0700391 return false;
msarett74114382015-03-16 11:55:18 -0700392 default:
scroggo230d4ac2015-03-26 07:15:55 -0700393 SkCodecPrintf("Error: invalid bmp bit masks header.\n");
scroggo79e378d2015-04-01 07:39:40 -0700394 return false;
msarett74114382015-03-16 11:55:18 -0700395 }
396 break;
397 case kJpeg_BitmapCompressionMethod:
398 if (24 == bitsPerPixel) {
399 inputFormat = kRLE_BitmapInputFormat;
400 break;
401 }
402 // Fall through
403 case kPng_BitmapCompressionMethod:
404 // TODO: Decide if we intend to support this.
405 // It is unsupported in the previous version and
406 // in chromium. I think it is used mostly for printers.
scroggo230d4ac2015-03-26 07:15:55 -0700407 SkCodecPrintf("Error: compression format not supported.\n");
scroggo79e378d2015-04-01 07:39:40 -0700408 return false;
msarett74114382015-03-16 11:55:18 -0700409 case kCMYK_BitmapCompressionMethod:
410 case kCMYK8BitRLE_BitmapCompressionMethod:
411 case kCMYK4BitRLE_BitmapCompressionMethod:
412 // TODO: Same as above.
scroggo230d4ac2015-03-26 07:15:55 -0700413 SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
scroggo79e378d2015-04-01 07:39:40 -0700414 return false;
msarett74114382015-03-16 11:55:18 -0700415 default:
scroggo230d4ac2015-03-26 07:15:55 -0700416 SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
scroggo79e378d2015-04-01 07:39:40 -0700417 return false;
msarett74114382015-03-16 11:55:18 -0700418 }
419
420 // Most versions of bmps should be rendered as opaque. Either they do
421 // not have an alpha channel, or they expect the alpha channel to be
msarett9bde9182015-03-25 05:27:48 -0700422 // ignored. V3+ bmp files introduce an alpha mask and allow the creator
msarett74114382015-03-16 11:55:18 -0700423 // of the image to use the alpha channels. However, many of these images
msarett9bde9182015-03-25 05:27:48 -0700424 // leave the alpha channel blank and expect to be rendered as opaque. This
425 // is the case for almost all V3 images, so we render these as opaque. For
426 // V4+, we will use the alpha channel, and fix the image later if it turns
427 // out to be fully transparent.
428 // As an exception, V3 bmp-in-ico may use an alpha mask.
msarett74114382015-03-16 11:55:18 -0700429 SkAlphaType alphaType = kOpaque_SkAlphaType;
msarett9bde9182015-03-25 05:27:48 -0700430 if ((kInfoV3_BitmapHeaderType == headerType && isIco) ||
431 kInfoV4_BitmapHeaderType == headerType ||
msarett74114382015-03-16 11:55:18 -0700432 kInfoV5_BitmapHeaderType == headerType) {
433 // Header types are matched based on size. If the header is
msarett9bde9182015-03-25 05:27:48 -0700434 // V3+, we are guaranteed to be able to read at least this size.
msarett74114382015-03-16 11:55:18 -0700435 SkASSERT(infoBytesRemaining > 52);
436 inputMasks.alpha = get_int(iBuffer.get(), 48);
437 if (inputMasks.alpha != 0) {
438 alphaType = kUnpremul_SkAlphaType;
439 }
440 }
441 iBuffer.free();
442
msarett438b2ad2015-04-09 12:43:10 -0700443 // Additionally, 32 bit bmp-in-icos use the alpha channel.
444 // And, RLE inputs may skip pixels, leaving them as transparent. This
445 // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
446 if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat)) {
msarett9bde9182015-03-25 05:27:48 -0700447 alphaType = kUnpremul_SkAlphaType;
448 }
449
msarett438b2ad2015-04-09 12:43:10 -0700450 // Check for valid bits per pixel.
451 // At the same time, use this information to choose a suggested color type
452 // and to set default masks.
453 SkColorType colorType = kN32_SkColorType;
msarett74114382015-03-16 11:55:18 -0700454 switch (bitsPerPixel) {
455 // In addition to more standard pixel compression formats, bmp supports
456 // the use of bit masks to determine pixel components. The standard
457 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
458 // which does not map well to any Skia color formats. For this reason,
459 // we will always enable mask mode with 16 bits per pixel.
460 case 16:
461 if (kBitMask_BitmapInputFormat != inputFormat) {
462 inputMasks.red = 0x7C00;
463 inputMasks.green = 0x03E0;
464 inputMasks.blue = 0x001F;
465 inputFormat = kBitMask_BitmapInputFormat;
466 }
467 break;
msarett438b2ad2015-04-09 12:43:10 -0700468 // We want to decode to kIndex_8 for input formats that are already
469 // designed in index format.
msarett74114382015-03-16 11:55:18 -0700470 case 1:
471 case 2:
472 case 4:
473 case 8:
msarett438b2ad2015-04-09 12:43:10 -0700474 // However, we cannot in RLE format since we may need to leave some
475 // pixels as transparent. Similarly, we also cannot for ICO images
476 // since we may need to apply a transparent mask.
477 if (kRLE_BitmapInputFormat != inputFormat && !isIco) {
478 colorType = kIndex_8_SkColorType;
479 }
msarett74114382015-03-16 11:55:18 -0700480 case 24:
481 case 32:
482 break;
483 default:
scroggo230d4ac2015-03-26 07:15:55 -0700484 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
scroggo79e378d2015-04-01 07:39:40 -0700485 return false;
msarett74114382015-03-16 11:55:18 -0700486 }
487
488 // Check that input bit masks are valid and create the masks object
489 SkAutoTDelete<SkMasks>
490 masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
491 if (NULL == masks) {
scroggo230d4ac2015-03-26 07:15:55 -0700492 SkCodecPrintf("Error: invalid input masks.\n");
scroggo79e378d2015-04-01 07:39:40 -0700493 return false;
msarett74114382015-03-16 11:55:18 -0700494 }
495
msaretteed039b2015-03-18 11:11:19 -0700496 // Check for a valid number of total bytes when in RLE mode
497 if (totalBytes <= offset && kRLE_BitmapInputFormat == inputFormat) {
scroggo230d4ac2015-03-26 07:15:55 -0700498 SkCodecPrintf("Error: RLE requires valid input size.\n");
scroggo79e378d2015-04-01 07:39:40 -0700499 return false;
msarett74114382015-03-16 11:55:18 -0700500 }
msaretteed039b2015-03-18 11:11:19 -0700501 const size_t RLEBytes = totalBytes - offset;
502
503 // Calculate the number of bytes read so far
504 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
msarett9bde9182015-03-25 05:27:48 -0700505 if (!isIco && offset < bytesRead) {
scroggo230d4ac2015-03-26 07:15:55 -0700506 SkCodecPrintf("Error: pixel data offset less than header size.\n");
scroggo79e378d2015-04-01 07:39:40 -0700507 return false;
msaretteed039b2015-03-18 11:11:19 -0700508 }
msarett74114382015-03-16 11:55:18 -0700509
scroggo79e378d2015-04-01 07:39:40 -0700510 if (codecOut) {
511 // Return the codec
msarett438b2ad2015-04-09 12:43:10 -0700512 // We will use ImageInfo to store width, height, suggested color type, and
513 // suggested alpha type.
scroggo79e378d2015-04-01 07:39:40 -0700514 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
msarett438b2ad2015-04-09 12:43:10 -0700515 colorType, alphaType);
scroggo79e378d2015-04-01 07:39:40 -0700516 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
517 inputFormat, masks.detach(),
518 numColors, bytesPerColor,
519 offset - bytesRead, rowOrder,
520 RLEBytes, isIco));
521 }
522 return true;
523}
524
525/*
526 *
527 * Creates a bmp decoder
528 * Reads enough of the stream to determine the image format
529 *
530 */
531SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
scroggo0a7e69c2015-04-03 07:22:22 -0700532 SkAutoTDelete<SkStream> streamDeleter(stream);
scroggo79e378d2015-04-01 07:39:40 -0700533 SkCodec* codec = NULL;
534 if (ReadHeader(stream, isIco, &codec)) {
scroggo0a7e69c2015-04-03 07:22:22 -0700535 // codec has taken ownership of stream, so we do not need to
536 // delete it.
537 SkASSERT(codec);
538 streamDeleter.detach();
scroggo79e378d2015-04-01 07:39:40 -0700539 return codec;
540 }
541 return NULL;
msarett74114382015-03-16 11:55:18 -0700542}
543
544/*
545 *
546 * Creates an instance of the decoder
547 * Called only by NewFromStream
548 *
549 */
550SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
551 uint16_t bitsPerPixel, BitmapInputFormat inputFormat,
msaretteed039b2015-03-18 11:11:19 -0700552 SkMasks* masks, uint32_t numColors,
553 uint32_t bytesPerColor, uint32_t offset,
msarett9bde9182015-03-25 05:27:48 -0700554 RowOrder rowOrder, size_t RLEBytes, bool isIco)
msarett74114382015-03-16 11:55:18 -0700555 : INHERITED(info, stream)
556 , fBitsPerPixel(bitsPerPixel)
557 , fInputFormat(inputFormat)
558 , fMasks(masks)
msaretteed039b2015-03-18 11:11:19 -0700559 , fColorTable(NULL)
560 , fNumColors(numColors)
561 , fBytesPerColor(bytesPerColor)
562 , fOffset(offset)
msarett74114382015-03-16 11:55:18 -0700563 , fRowOrder(rowOrder)
msaretteed039b2015-03-18 11:11:19 -0700564 , fRLEBytes(RLEBytes)
msarett9bde9182015-03-25 05:27:48 -0700565 , fIsIco(isIco)
566
msarett74114382015-03-16 11:55:18 -0700567{}
568
569/*
570 *
571 * Initiates the bitmap decode
572 *
573 */
574SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
575 void* dst, size_t dstRowBytes,
msarett438b2ad2015-04-09 12:43:10 -0700576 const Options& opts,
577 SkPMColor* inputColorPtr,
578 int* inputColorCount) {
msaretteed039b2015-03-18 11:11:19 -0700579 // Check for proper input and output formats
halcanarya096d7a2015-03-27 12:16:53 -0700580 SkCodec::RewindState rewindState = this->rewindIfNeeded();
581 if (rewindState == kCouldNotRewind_RewindState) {
msarett74114382015-03-16 11:55:18 -0700582 return kCouldNotRewind;
halcanarya096d7a2015-03-27 12:16:53 -0700583 } else if (rewindState == kRewound_RewindState) {
scroggo79e378d2015-04-01 07:39:40 -0700584 if (!ReadHeader(this->stream(), fIsIco, NULL)) {
585 return kCouldNotRewind;
586 }
msarett74114382015-03-16 11:55:18 -0700587 }
msarett9bde9182015-03-25 05:27:48 -0700588 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
scroggo230d4ac2015-03-26 07:15:55 -0700589 SkCodecPrintf("Error: scaling not supported.\n");
msarett74114382015-03-16 11:55:18 -0700590 return kInvalidScale;
591 }
msarett9bde9182015-03-25 05:27:48 -0700592 if (!conversion_possible(dstInfo, this->getInfo())) {
scroggo230d4ac2015-03-26 07:15:55 -0700593 SkCodecPrintf("Error: cannot convert input type to output type.\n");
msarett74114382015-03-16 11:55:18 -0700594 return kInvalidConversion;
595 }
596
msaretteed039b2015-03-18 11:11:19 -0700597 // Create the color table if necessary and prepare the stream for decode
msarett438b2ad2015-04-09 12:43:10 -0700598 // Note that if it is non-NULL, inputColorCount will be modified
599 if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
scroggo230d4ac2015-03-26 07:15:55 -0700600 SkCodecPrintf("Error: could not create color table.\n");
msaretteed039b2015-03-18 11:11:19 -0700601 return kInvalidInput;
602 }
603
msarett438b2ad2015-04-09 12:43:10 -0700604 // Copy the color table to the client if necessary
msarett9e43cab2015-04-29 07:38:43 -0700605 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount);
msarett438b2ad2015-04-09 12:43:10 -0700606
msaretteed039b2015-03-18 11:11:19 -0700607 // Perform the decode
msarett74114382015-03-16 11:55:18 -0700608 switch (fInputFormat) {
609 case kBitMask_BitmapInputFormat:
msarett3c309db2015-04-10 14:36:48 -0700610 return decodeMask(dstInfo, dst, dstRowBytes, opts);
msarett74114382015-03-16 11:55:18 -0700611 case kRLE_BitmapInputFormat:
msarett438b2ad2015-04-09 12:43:10 -0700612 return decodeRLE(dstInfo, dst, dstRowBytes, opts);
msarett74114382015-03-16 11:55:18 -0700613 case kStandard_BitmapInputFormat:
msarett3c309db2015-04-10 14:36:48 -0700614 return decode(dstInfo, dst, dstRowBytes, opts);
msarett74114382015-03-16 11:55:18 -0700615 default:
616 SkASSERT(false);
617 return kInvalidInput;
618 }
619}
620
621/*
622 *
msaretteed039b2015-03-18 11:11:19 -0700623 * Process the color table for the bmp input
624 *
625 */
msarett438b2ad2015-04-09 12:43:10 -0700626 bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
msaretteed039b2015-03-18 11:11:19 -0700627 // Allocate memory for color table
628 uint32_t colorBytes = 0;
629 uint32_t maxColors = 0;
630 SkPMColor colorTable[256];
631 if (fBitsPerPixel <= 8) {
632 // Zero is a default for maxColors
633 // Also set fNumColors to maxColors when it is too large
634 maxColors = 1 << fBitsPerPixel;
635 if (fNumColors == 0 || fNumColors >= maxColors) {
636 fNumColors = maxColors;
637 }
638
msarett438b2ad2015-04-09 12:43:10 -0700639 // Inform the caller of the number of colors
640 if (NULL != numColors) {
msarett438b2ad2015-04-09 12:43:10 -0700641 // We set the number of colors to maxColors in order to ensure
642 // safe memory accesses. Otherwise, an invalid pixel could
643 // access memory outside of our color table array.
644 *numColors = maxColors;
645 }
646
msaretteed039b2015-03-18 11:11:19 -0700647 // Read the color table from the stream
648 colorBytes = fNumColors * fBytesPerColor;
649 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
650 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700651 SkCodecPrintf("Error: unable to read color table.\n");
msaretteed039b2015-03-18 11:11:19 -0700652 return false;
653 }
654
655 // Choose the proper packing function
656 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
657 switch (alphaType) {
658 case kOpaque_SkAlphaType:
659 case kUnpremul_SkAlphaType:
660 packARGB = &SkPackARGB32NoCheck;
661 break;
662 case kPremul_SkAlphaType:
663 packARGB = &SkPreMultiplyARGB;
664 break;
665 default:
666 // This should not be reached because conversion possible
667 // should fail if the alpha type is not one of the above
668 // values.
669 SkASSERT(false);
670 packARGB = NULL;
671 break;
672 }
673
674 // Fill in the color table
675 uint32_t i = 0;
676 for (; i < fNumColors; i++) {
677 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
678 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
679 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
msarett438b2ad2015-04-09 12:43:10 -0700680 uint8_t alpha;
681 if (kOpaque_SkAlphaType == alphaType || kRLE_BitmapInputFormat == fInputFormat) {
682 alpha = 0xFF;
683 } else {
684 alpha = (fMasks->getAlphaMask() >> 24) &
685 get_byte(cBuffer.get(), i*fBytesPerColor + 3);
686 }
msaretteed039b2015-03-18 11:11:19 -0700687 colorTable[i] = packARGB(alpha, red, green, blue);
688 }
689
690 // To avoid segmentation faults on bad pixel data, fill the end of the
691 // color table with black. This is the same the behavior as the
692 // chromium decoder.
693 for (; i < maxColors; i++) {
694 colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
695 }
msarett3c309db2015-04-10 14:36:48 -0700696
697 // Set the color table
698 fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
msaretteed039b2015-03-18 11:11:19 -0700699 }
700
msarett9bde9182015-03-25 05:27:48 -0700701 // Bmp-in-Ico files do not use an offset to indicate where the pixel data
702 // begins. Pixel data always begins immediately after the color table.
703 if (!fIsIco) {
704 // Check that we have not read past the pixel array offset
705 if(fOffset < colorBytes) {
706 // This may occur on OS 2.1 and other old versions where the color
707 // table defaults to max size, and the bmp tries to use a smaller
708 // color table. This is invalid, and our decision is to indicate
709 // an error, rather than try to guess the intended size of the
710 // color table.
scroggo230d4ac2015-03-26 07:15:55 -0700711 SkCodecPrintf("Error: pixel data offset less than color table size.\n");
msarett9bde9182015-03-25 05:27:48 -0700712 return false;
713 }
msaretteed039b2015-03-18 11:11:19 -0700714
msarett9bde9182015-03-25 05:27:48 -0700715 // After reading the color table, skip to the start of the pixel array
716 if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700717 SkCodecPrintf("Error: unable to skip to image data.\n");
msarett9bde9182015-03-25 05:27:48 -0700718 return false;
719 }
msaretteed039b2015-03-18 11:11:19 -0700720 }
721
msarett3c309db2015-04-10 14:36:48 -0700722 // Return true on success
msaretteed039b2015-03-18 11:11:19 -0700723 return true;
724}
725
726/*
727 *
msarett3c309db2015-04-10 14:36:48 -0700728 * Get the destination row to start filling from
729 * Used to fill the remainder of the image on incomplete input
730 *
731 */
732static inline void* get_dst_start_row(void* dst, size_t dstRowBytes, int32_t y,
733 SkBmpCodec::RowOrder rowOrder) {
734 return (SkBmpCodec::kTopDown_RowOrder == rowOrder) ?
735 SkTAddOffset<void*>(dst, y * dstRowBytes) : dst;
736}
737
738/*
739 *
msarett74114382015-03-16 11:55:18 -0700740 * Performs the bitmap decoding for bit masks input format
741 *
742 */
743SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo,
msarett3c309db2015-04-10 14:36:48 -0700744 void* dst, size_t dstRowBytes,
745 const Options& opts) {
msarett74114382015-03-16 11:55:18 -0700746 // Set constant values
747 const int width = dstInfo.width();
748 const int height = dstInfo.height();
749 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
750
msaretteed039b2015-03-18 11:11:19 -0700751 // Allocate a buffer large enough to hold the full image
752 SkAutoTDeleteArray<uint8_t>
753 srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes));
754 uint8_t* srcRow = srcBuffer.get();
msarett74114382015-03-16 11:55:18 -0700755
756 // Create the swizzler
msaretteed039b2015-03-18 11:11:19 -0700757 SkAutoTDelete<SkMaskSwizzler> maskSwizzler(
758 SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes,
759 fMasks, fBitsPerPixel));
msarett74114382015-03-16 11:55:18 -0700760
761 // Iterate over rows of the image
762 bool transparent = true;
763 for (int y = 0; y < height; y++) {
764 // Read a row of the input
msaretteed039b2015-03-18 11:11:19 -0700765 if (stream()->read(srcRow, rowBytes) != rowBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700766 SkCodecPrintf("Warning: incomplete input stream.\n");
msarett3c309db2015-04-10 14:36:48 -0700767 // Fill the destination image on failure
msarette16b04a2015-04-15 07:32:19 -0700768 SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ?
769 SK_ColorBLACK : SK_ColorTRANSPARENT;
770 if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) {
msarett3c309db2015-04-10 14:36:48 -0700771 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
msarette16b04a2015-04-15 07:32:19 -0700772 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, fillColor,
773 NULL);
msarett3c309db2015-04-10 14:36:48 -0700774 }
msarett74114382015-03-16 11:55:18 -0700775 return kIncompleteInput;
776 }
777
778 // Decode the row in destination format
msaretteed039b2015-03-18 11:11:19 -0700779 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
780 SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row);
msarett74114382015-03-16 11:55:18 -0700781 transparent &= SkSwizzler::IsTransparent(r);
782
783 // Move to the next row
msaretteed039b2015-03-18 11:11:19 -0700784 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
msarett74114382015-03-16 11:55:18 -0700785 }
786
787 // Some fully transparent bmp images are intended to be opaque. Here, we
788 // correct for this possibility.
msarett74114382015-03-16 11:55:18 -0700789 if (transparent) {
msaretteed039b2015-03-18 11:11:19 -0700790 const SkImageInfo& opaqueInfo =
791 dstInfo.makeAlphaType(kOpaque_SkAlphaType);
792 SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler(
793 SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, dst, dstRowBytes,
794 fMasks, fBitsPerPixel));
795 srcRow = srcBuffer.get();
msarett74114382015-03-16 11:55:18 -0700796 for (int y = 0; y < height; y++) {
msaretteed039b2015-03-18 11:11:19 -0700797 // Decode the row in opaque format
798 int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
799 opaqueSwizzler->next(srcRow, row);
800
801 // Move to the next row
802 srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
msarett74114382015-03-16 11:55:18 -0700803 }
804 }
805
806 // Finished decoding the entire image
807 return kSuccess;
808}
809
810/*
811 *
812 * Set an RLE pixel using the color table
813 *
814 */
msarett438b2ad2015-04-09 12:43:10 -0700815void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
msaretteed039b2015-03-18 11:11:19 -0700816 const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
817 uint8_t index) {
818 // Set the row
819 int height = dstInfo.height();
820 int row;
msarett74114382015-03-16 11:55:18 -0700821 if (kBottomUp_RowOrder == fRowOrder) {
msaretteed039b2015-03-18 11:11:19 -0700822 row = height - y - 1;
823 } else {
824 row = y;
msarett74114382015-03-16 11:55:18 -0700825 }
msaretteed039b2015-03-18 11:11:19 -0700826
827 // Set the pixel based on destination color type
828 switch (dstInfo.colorType()) {
829 case kN32_SkColorType: {
msarett438b2ad2015-04-09 12:43:10 -0700830 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
msaretteed039b2015-03-18 11:11:19 -0700831 row * (int) dstRowBytes);
832 dstRow[x] = fColorTable->operator[](index);
833 break;
834 }
msaretteed039b2015-03-18 11:11:19 -0700835 default:
836 // This case should not be reached. We should catch an invalid
837 // color type when we check that the conversion is possible.
838 SkASSERT(false);
839 break;
840 }
841}
842
843/*
844 *
845 * Set an RLE pixel from R, G, B values
846 *
847 */
msarett438b2ad2015-04-09 12:43:10 -0700848void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
msaretteed039b2015-03-18 11:11:19 -0700849 const SkImageInfo& dstInfo, uint32_t x,
850 uint32_t y, uint8_t red, uint8_t green,
851 uint8_t blue) {
852 // Set the row
853 int height = dstInfo.height();
854 int row;
855 if (kBottomUp_RowOrder == fRowOrder) {
856 row = height - y - 1;
857 } else {
858 row = y;
859 }
860
861 // Set the pixel based on destination color type
862 switch (dstInfo.colorType()) {
863 case kN32_SkColorType: {
msarett438b2ad2015-04-09 12:43:10 -0700864 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
msaretteed039b2015-03-18 11:11:19 -0700865 row * (int) dstRowBytes);
866 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
867 break;
868 }
msaretteed039b2015-03-18 11:11:19 -0700869 default:
870 // This case should not be reached. We should catch an invalid
871 // color type when we check that the conversion is possible.
872 SkASSERT(false);
873 break;
874 }
msarett74114382015-03-16 11:55:18 -0700875}
876
877/*
878 *
879 * Performs the bitmap decoding for RLE input format
880 * RLE decoding is performed all at once, rather than a one row at a time
881 *
882 */
883SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
msarett438b2ad2015-04-09 12:43:10 -0700884 void* dst, size_t dstRowBytes,
885 const Options& opts) {
msarett74114382015-03-16 11:55:18 -0700886 // Set RLE flags
887 static const uint8_t RLE_ESCAPE = 0;
888 static const uint8_t RLE_EOL = 0;
889 static const uint8_t RLE_EOF = 1;
890 static const uint8_t RLE_DELTA = 2;
891
892 // Set constant values
893 const int width = dstInfo.width();
894 const int height = dstInfo.height();
895
896 // Input buffer parameters
897 uint32_t currByte = 0;
msaretteed039b2015-03-18 11:11:19 -0700898 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
899 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
900 if (totalBytes < fRLEBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700901 SkCodecPrintf("Warning: incomplete RLE file.\n");
msarett74114382015-03-16 11:55:18 -0700902 } else if (totalBytes <= 0) {
scroggo230d4ac2015-03-26 07:15:55 -0700903 SkCodecPrintf("Error: could not read RLE image data.\n");
msarett74114382015-03-16 11:55:18 -0700904 return kInvalidInput;
905 }
906
907 // Destination parameters
908 int x = 0;
909 int y = 0;
msarett438b2ad2015-04-09 12:43:10 -0700910
911 // Set the background as transparent. Then, if the RLE code skips pixels,
912 // the skipped pixels will be transparent.
913 // Because of the need for transparent pixels, kN32 is the only color
914 // type that makes sense for the destination format.
915 SkASSERT(kN32_SkColorType == dstInfo.colorType());
916 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
msarett3c309db2015-04-10 14:36:48 -0700917 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL);
msarett438b2ad2015-04-09 12:43:10 -0700918 }
msarett74114382015-03-16 11:55:18 -0700919
920 while (true) {
921 // Every entry takes at least two bytes
922 if ((int) totalBytes - currByte < 2) {
scroggo230d4ac2015-03-26 07:15:55 -0700923 SkCodecPrintf("Warning: incomplete RLE input.\n");
msarett74114382015-03-16 11:55:18 -0700924 return kIncompleteInput;
925 }
926
927 // Read the next two bytes. These bytes have different meanings
928 // depending on their values. In the first interpretation, the first
929 // byte is an escape flag and the second byte indicates what special
930 // task to perform.
931 const uint8_t flag = buffer.get()[currByte++];
932 const uint8_t task = buffer.get()[currByte++];
933
934 // If we have reached a row that is beyond the image size, and the RLE
935 // code does not indicate end of file, abort and signal a warning.
936 if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
scroggo230d4ac2015-03-26 07:15:55 -0700937 SkCodecPrintf("Warning: invalid RLE input.\n");
msarett74114382015-03-16 11:55:18 -0700938 return kIncompleteInput;
939 }
940
941 // Perform decoding
942 if (RLE_ESCAPE == flag) {
943 switch (task) {
944 case RLE_EOL:
945 x = 0;
946 y++;
947 break;
948 case RLE_EOF:
949 return kSuccess;
950 case RLE_DELTA: {
951 // Two bytes are needed to specify delta
952 if ((int) totalBytes - currByte < 2) {
scroggo230d4ac2015-03-26 07:15:55 -0700953 SkCodecPrintf("Warning: incomplete RLE input\n");
msarett74114382015-03-16 11:55:18 -0700954 return kIncompleteInput;
955 }
956 // Modify x and y
957 const uint8_t dx = buffer.get()[currByte++];
958 const uint8_t dy = buffer.get()[currByte++];
959 x += dx;
960 y += dy;
961 if (x > width || y > height) {
scroggo230d4ac2015-03-26 07:15:55 -0700962 SkCodecPrintf("Warning: invalid RLE input.\n");
msarett74114382015-03-16 11:55:18 -0700963 return kIncompleteInput;
964 }
965 break;
966 }
967 default: {
968 // If task does not match any of the above signals, it
969 // indicates that we have a sequence of non-RLE pixels.
970 // Furthermore, the value of task is equal to the number
971 // of pixels to interpret.
972 uint8_t numPixels = task;
973 const size_t rowBytes = compute_row_bytes(numPixels,
974 fBitsPerPixel);
975 // Abort if setting numPixels moves us off the edge of the
976 // image. Also abort if there are not enough bytes
977 // remaining in the stream to set numPixels.
978 if (x + numPixels > width ||
979 (int) totalBytes - currByte < SkAlign2(rowBytes)) {
scroggo230d4ac2015-03-26 07:15:55 -0700980 SkCodecPrintf("Warning: invalid RLE input.\n");
msarett74114382015-03-16 11:55:18 -0700981 return kIncompleteInput;
982 }
983 // Set numPixels number of pixels
msarett74114382015-03-16 11:55:18 -0700984 while (numPixels > 0) {
985 switch(fBitsPerPixel) {
986 case 4: {
987 SkASSERT(currByte < totalBytes);
988 uint8_t val = buffer.get()[currByte++];
msarett438b2ad2015-04-09 12:43:10 -0700989 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
msaretteed039b2015-03-18 11:11:19 -0700990 y, val >> 4);
msarett74114382015-03-16 11:55:18 -0700991 numPixels--;
992 if (numPixels != 0) {
msarett438b2ad2015-04-09 12:43:10 -0700993 setRLEPixel(dst, dstRowBytes, dstInfo,
msarett74114382015-03-16 11:55:18 -0700994 x++, y, val & 0xF);
995 numPixels--;
996 }
997 break;
998 }
999 case 8:
1000 SkASSERT(currByte < totalBytes);
msarett438b2ad2015-04-09 12:43:10 -07001001 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
msaretteed039b2015-03-18 11:11:19 -07001002 y, buffer.get()[currByte++]);
msarett74114382015-03-16 11:55:18 -07001003 numPixels--;
1004 break;
1005 case 24: {
1006 SkASSERT(currByte + 2 < totalBytes);
1007 uint8_t blue = buffer.get()[currByte++];
1008 uint8_t green = buffer.get()[currByte++];
1009 uint8_t red = buffer.get()[currByte++];
msarett438b2ad2015-04-09 12:43:10 -07001010 setRLE24Pixel(dst, dstRowBytes, dstInfo,
msaretteed039b2015-03-18 11:11:19 -07001011 x++, y, red, green, blue);
msarett74114382015-03-16 11:55:18 -07001012 numPixels--;
1013 }
1014 default:
1015 SkASSERT(false);
1016 return kInvalidInput;
1017 }
1018 }
1019 // Skip a byte if necessary to maintain alignment
1020 if (!SkIsAlign2(rowBytes)) {
1021 currByte++;
1022 }
1023 break;
1024 }
1025 }
1026 } else {
1027 // If the first byte read is not a flag, it indicates the number of
1028 // pixels to set in RLE mode.
1029 const uint8_t numPixels = flag;
1030 const int endX = SkTMin<int>(x + numPixels, width);
1031
1032 if (24 == fBitsPerPixel) {
1033 // In RLE24, the second byte read is part of the pixel color.
1034 // There are two more required bytes to finish encoding the
1035 // color.
1036 if ((int) totalBytes - currByte < 2) {
scroggo230d4ac2015-03-26 07:15:55 -07001037 SkCodecPrintf("Warning: incomplete RLE input\n");
msarett74114382015-03-16 11:55:18 -07001038 return kIncompleteInput;
1039 }
1040
1041 // Fill the pixels up to endX with the specified color
1042 uint8_t blue = task;
1043 uint8_t green = buffer.get()[currByte++];
1044 uint8_t red = buffer.get()[currByte++];
msarett74114382015-03-16 11:55:18 -07001045 while (x < endX) {
msarett438b2ad2015-04-09 12:43:10 -07001046 setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
msaretteed039b2015-03-18 11:11:19 -07001047 green, blue);
msarett74114382015-03-16 11:55:18 -07001048 }
1049 } else {
1050 // In RLE8 or RLE4, the second byte read gives the index in the
1051 // color table to look up the pixel color.
1052 // RLE8 has one color index that gets repeated
1053 // RLE4 has two color indexes in the upper and lower 4 bits of
1054 // the bytes, which are alternated
1055 uint8_t indices[2] = { task, task };
1056 if (4 == fBitsPerPixel) {
1057 indices[0] >>= 4;
1058 indices[1] &= 0xf;
1059 }
1060
1061 // Set the indicated number of pixels
1062 for (int which = 0; x < endX; x++) {
msarett438b2ad2015-04-09 12:43:10 -07001063 setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
msarett74114382015-03-16 11:55:18 -07001064 indices[which]);
1065 which = !which;
1066 }
1067 }
1068 }
1069 }
1070}
1071
1072/*
1073 *
1074 * Performs the bitmap decoding for standard input format
1075 *
1076 */
1077SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
msarett3c309db2015-04-10 14:36:48 -07001078 void* dst, size_t dstRowBytes,
1079 const Options& opts) {
msarett74114382015-03-16 11:55:18 -07001080 // Set constant values
1081 const int width = dstInfo.width();
1082 const int height = dstInfo.height();
1083 const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
msarett74114382015-03-16 11:55:18 -07001084
msarette16b04a2015-04-15 07:32:19 -07001085 // Get swizzler configuration and choose the fill value for failures. We will use
1086 // zero as the default palette index, black for opaque images, and transparent for
1087 // non-opaque images.
msarett74114382015-03-16 11:55:18 -07001088 SkSwizzler::SrcConfig config;
msarette16b04a2015-04-15 07:32:19 -07001089 uint32_t fillColorOrIndex;
1090 bool zeroFill = true;
msarett74114382015-03-16 11:55:18 -07001091 switch (fBitsPerPixel) {
1092 case 1:
1093 config = SkSwizzler::kIndex1;
msarette16b04a2015-04-15 07:32:19 -07001094 fillColorOrIndex = 0;
msarett74114382015-03-16 11:55:18 -07001095 break;
1096 case 2:
1097 config = SkSwizzler::kIndex2;
msarette16b04a2015-04-15 07:32:19 -07001098 fillColorOrIndex = 0;
msarett74114382015-03-16 11:55:18 -07001099 break;
1100 case 4:
1101 config = SkSwizzler::kIndex4;
msarette16b04a2015-04-15 07:32:19 -07001102 fillColorOrIndex = 0;
msarett74114382015-03-16 11:55:18 -07001103 break;
1104 case 8:
1105 config = SkSwizzler::kIndex;
msarette16b04a2015-04-15 07:32:19 -07001106 fillColorOrIndex = 0;
msarett74114382015-03-16 11:55:18 -07001107 break;
1108 case 24:
1109 config = SkSwizzler::kBGR;
msarette16b04a2015-04-15 07:32:19 -07001110 fillColorOrIndex = SK_ColorBLACK;
1111 zeroFill = false;
msarett74114382015-03-16 11:55:18 -07001112 break;
1113 case 32:
msaretteed039b2015-03-18 11:11:19 -07001114 if (kOpaque_SkAlphaType == dstInfo.alphaType()) {
msarett74114382015-03-16 11:55:18 -07001115 config = SkSwizzler::kBGRX;
msarette16b04a2015-04-15 07:32:19 -07001116 fillColorOrIndex = SK_ColorBLACK;
1117 zeroFill = false;
msarett74114382015-03-16 11:55:18 -07001118 } else {
1119 config = SkSwizzler::kBGRA;
msarette16b04a2015-04-15 07:32:19 -07001120 fillColorOrIndex = SK_ColorTRANSPARENT;
msarett74114382015-03-16 11:55:18 -07001121 }
1122 break;
1123 default:
1124 SkASSERT(false);
1125 return kInvalidInput;
1126 }
1127
msarett3c309db2015-04-10 14:36:48 -07001128 // Get a pointer to the color table if it exists
1129 const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readColors() : NULL;
1130
msarett74114382015-03-16 11:55:18 -07001131 // Create swizzler
msaretteed039b2015-03-18 11:11:19 -07001132 SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config,
msarett3c309db2015-04-10 14:36:48 -07001133 colorPtr, dstInfo, dst, dstRowBytes,
msaretteed039b2015-03-18 11:11:19 -07001134 SkImageGenerator::kNo_ZeroInitialized));
msarett74114382015-03-16 11:55:18 -07001135
1136 // Allocate space for a row buffer and a source for the swizzler
1137 SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
1138
1139 // Iterate over rows of the image
1140 // FIXME: bool transparent = true;
1141 for (int y = 0; y < height; y++) {
1142 // Read a row of the input
1143 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
scroggo230d4ac2015-03-26 07:15:55 -07001144 SkCodecPrintf("Warning: incomplete input stream.\n");
msarett3c309db2015-04-10 14:36:48 -07001145 // Fill the destination image on failure
msarette16b04a2015-04-15 07:32:19 -07001146 if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) {
msarett3c309db2015-04-10 14:36:48 -07001147 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
msarette16b04a2015-04-15 07:32:19 -07001148 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y,
1149 fillColorOrIndex, colorPtr);
msarett3c309db2015-04-10 14:36:48 -07001150 }
msarett74114382015-03-16 11:55:18 -07001151 return kIncompleteInput;
1152 }
1153
1154 // Decode the row in destination format
1155 uint32_t row;
1156 if (kTopDown_RowOrder == fRowOrder) {
1157 row = y;
1158 } else {
1159 row = height - 1 - y;
1160 }
1161
1162 swizzler->next(srcBuffer.get(), row);
1163 // FIXME: SkSwizzler::ResultAlpha r =
1164 // swizzler->next(srcBuffer.get(), row);
1165 // FIXME: transparent &= SkSwizzler::IsTransparent(r);
1166 }
1167
1168 // FIXME: This code exists to match the behavior in the chromium decoder
1169 // and to follow the bmp specification as it relates to alpha masks. It is
1170 // commented out because we have yet to discover a test image that provides
1171 // an alpha mask and uses this decode mode.
1172
1173 // Now we adjust the output image with some additional behavior that
1174 // SkSwizzler does not support. Firstly, all bmp images that contain
1175 // alpha are masked by the alpha mask. Secondly, many fully transparent
msarett438b2ad2015-04-09 12:43:10 -07001176 // bmp images are intended to be opaque. Here, we make those corrections
1177 // in the kN32 case.
msarett74114382015-03-16 11:55:18 -07001178 /*
1179 SkPMColor* dstRow = (SkPMColor*) dst;
1180 if (SkSwizzler::kBGRA == config) {
1181 for (int y = 0; y < height; y++) {
1182 for (int x = 0; x < width; x++) {
1183 if (transparent) {
1184 dstRow[x] |= 0xFF000000;
1185 } else {
1186 dstRow[x] &= alphaMask;
1187 }
1188 dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
1189 }
1190 }
1191 }
1192 */
1193
msarett9bde9182015-03-25 05:27:48 -07001194 // Finally, apply the AND mask for bmp-in-ico images
1195 if (fIsIco) {
1196 // The AND mask is always 1 bit per pixel
1197 const size_t rowBytes = SkAlign4(compute_row_bytes(width, 1));
1198
1199 SkPMColor* dstPtr = (SkPMColor*) dst;
1200 for (int y = 0; y < height; y++) {
1201 // The srcBuffer will at least be large enough
1202 if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
scroggo230d4ac2015-03-26 07:15:55 -07001203 SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n");
msarett9bde9182015-03-25 05:27:48 -07001204 return kIncompleteInput;
1205 }
1206
1207 int row;
1208 if (kBottomUp_RowOrder == fRowOrder) {
1209 row = height - y - 1;
1210 } else {
1211 row = y;
1212 }
1213
1214 SkPMColor* dstRow =
1215 SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);
1216
1217 for (int x = 0; x < width; x++) {
1218 int quotient;
1219 int modulus;
1220 SkTDivMod(x, 8, &quotient, &modulus);
1221 uint32_t shift = 7 - modulus;
1222 uint32_t alphaBit =
1223 (srcBuffer.get()[quotient] >> shift) & 0x1;
1224 dstRow[x] &= alphaBit - 1;
1225 }
1226 }
1227 }
1228
msarett74114382015-03-16 11:55:18 -07001229 // Finished decoding the entire image
1230 return kSuccess;
1231}