blob: d97dff09719af50022f7c94f87410ed57ddcf03c [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
msarettb46e5e22015-07-30 11:36:40 -07008#include "SkBmpCodec.h"
msarett4ab9d5f2015-08-06 15:34:42 -07009#include "SkBmpMaskCodec.h"
10#include "SkBmpRLECodec.h"
11#include "SkBmpStandardCodec.h"
msarett74114382015-03-16 11:55:18 -070012#include "SkCodecPriv.h"
Cary Clarka4083c92017-09-15 11:59:23 -040013#include "SkColorData.h"
msarett74114382015-03-16 11:55:18 -070014#include "SkStream.h"
15
16/*
msarett74114382015-03-16 11:55:18 -070017 * Defines the version and type of the second bitmap header
msarett74114382015-03-16 11:55:18 -070018 */
msarett4ab9d5f2015-08-06 15:34:42 -070019enum BmpHeaderType {
20 kInfoV1_BmpHeaderType,
21 kInfoV2_BmpHeaderType,
22 kInfoV3_BmpHeaderType,
23 kInfoV4_BmpHeaderType,
24 kInfoV5_BmpHeaderType,
25 kOS2V1_BmpHeaderType,
26 kOS2VX_BmpHeaderType,
27 kUnknown_BmpHeaderType
msarett74114382015-03-16 11:55:18 -070028};
29
30/*
msarett74114382015-03-16 11:55:18 -070031 * Possible bitmap compression types
msarett74114382015-03-16 11:55:18 -070032 */
msarett4ab9d5f2015-08-06 15:34:42 -070033enum BmpCompressionMethod {
34 kNone_BmpCompressionMethod = 0,
35 k8BitRLE_BmpCompressionMethod = 1,
36 k4BitRLE_BmpCompressionMethod = 2,
37 kBitMasks_BmpCompressionMethod = 3,
38 kJpeg_BmpCompressionMethod = 4,
39 kPng_BmpCompressionMethod = 5,
40 kAlphaBitMasks_BmpCompressionMethod = 6,
41 kCMYK_BmpCompressionMethod = 11,
42 kCMYK8BitRLE_BmpCompressionMethod = 12,
43 kCMYK4BitRLE_BmpCompressionMethod = 13
msarett74114382015-03-16 11:55:18 -070044};
45
46/*
msarett4ab9d5f2015-08-06 15:34:42 -070047 * Used to define the input format of the bmp
48 */
49enum BmpInputFormat {
50 kStandard_BmpInputFormat,
51 kRLE_BmpInputFormat,
52 kBitMask_BmpInputFormat,
53 kUnknown_BmpInputFormat
54};
55
56/*
msarett74114382015-03-16 11:55:18 -070057 * Checks the start of the stream to see if the image is a bitmap
msarett74114382015-03-16 11:55:18 -070058 */
scroggodb30be22015-12-08 18:54:13 -080059bool SkBmpCodec::IsBmp(const void* buffer, size_t bytesRead) {
msarett74114382015-03-16 11:55:18 -070060 // TODO: Support "IC", "PT", "CI", "CP", "BA"
msarett74114382015-03-16 11:55:18 -070061 const char bmpSig[] = { 'B', 'M' };
scroggodb30be22015-12-08 18:54:13 -080062 return bytesRead >= sizeof(bmpSig) && !memcmp(buffer, bmpSig, sizeof(bmpSig));
msarett74114382015-03-16 11:55:18 -070063}
64
65/*
msarett74114382015-03-16 11:55:18 -070066 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -070067 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -070068 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -070069 */
Mike Reedede7bac2017-07-23 15:30:02 -040070std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
71 Result* result) {
72 return SkBmpCodec::MakeFromStream(std::move(stream), result, false);
msarett9bde9182015-03-25 05:27:48 -070073}
74
75/*
msarett9bde9182015-03-25 05:27:48 -070076 * Creates a bmp decoder for a bmp embedded in ico
77 * Reads enough of the stream to determine the image format
msarett9bde9182015-03-25 05:27:48 -070078 */
Mike Reedede7bac2017-07-23 15:30:02 -040079std::unique_ptr<SkCodec> SkBmpCodec::MakeFromIco(std::unique_ptr<SkStream> stream, Result* result) {
80 return SkBmpCodec::MakeFromStream(std::move(stream), result, true);
msarett9bde9182015-03-25 05:27:48 -070081}
82
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -050083// Header size constants
Leon Scroggins III862c1962017-10-02 16:28:49 -040084static constexpr uint32_t kBmpHeaderBytes = 14;
85static constexpr uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
86static constexpr uint32_t kBmpOS2V1Bytes = 12;
87static constexpr uint32_t kBmpOS2V2Bytes = 64;
88static constexpr uint32_t kBmpInfoBaseBytes = 16;
89static constexpr uint32_t kBmpInfoV1Bytes = 40;
90static constexpr uint32_t kBmpInfoV2Bytes = 52;
91static constexpr uint32_t kBmpInfoV3Bytes = 56;
92static constexpr uint32_t kBmpInfoV4Bytes = 108;
93static constexpr uint32_t kBmpInfoV5Bytes = 124;
94static constexpr uint32_t kBmpMaskBytes = 12;
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -050095
96static BmpHeaderType get_header_type(size_t infoBytes) {
97 if (infoBytes >= kBmpInfoBaseBytes) {
98 // Check the version of the header
99 switch (infoBytes) {
100 case kBmpInfoV1Bytes:
101 return kInfoV1_BmpHeaderType;
102 case kBmpInfoV2Bytes:
103 return kInfoV2_BmpHeaderType;
104 case kBmpInfoV3Bytes:
105 return kInfoV3_BmpHeaderType;
106 case kBmpInfoV4Bytes:
107 return kInfoV4_BmpHeaderType;
108 case kBmpInfoV5Bytes:
109 return kInfoV5_BmpHeaderType;
110 case 16:
111 case 20:
112 case 24:
113 case 28:
114 case 32:
115 case 36:
116 case 42:
117 case 46:
118 case 48:
119 case 60:
120 case kBmpOS2V2Bytes:
121 return kOS2VX_BmpHeaderType;
122 default:
123 SkCodecPrintf("Error: unknown bmp header format.\n");
124 return kUnknown_BmpHeaderType;
125 }
126 } if (infoBytes >= kBmpOS2V1Bytes) {
127 // The OS2V1 is treated separately because it has a unique format
128 return kOS2V1_BmpHeaderType;
129 } else {
130 // There are no valid bmp headers
131 SkCodecPrintf("Error: second bitmap header size is invalid.\n");
132 return kUnknown_BmpHeaderType;
133 }
134}
135
Leon Scroggins III588fb042017-07-14 16:32:31 -0400136SkCodec::Result SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
Leon Scroggins IIIfc4ee222017-07-14 11:48:52 -0400137 std::unique_ptr<SkCodec>* codecOut) {
tomhudson7aa846c2015-03-24 13:47:41 -0700138 // The total bytes in the bmp file
msarett9bde9182015-03-25 05:27:48 -0700139 // We only need to use this value for RLE decoding, so we will only
140 // check that it is valid in the RLE case.
141 uint32_t totalBytes;
tomhudson7aa846c2015-03-24 13:47:41 -0700142 // The offset from the start of the file where the pixel data begins
msarett9bde9182015-03-25 05:27:48 -0700143 uint32_t offset;
144 // The size of the second (info) header in bytes
145 uint32_t infoBytes;
146
147 // Bmps embedded in Icos skip the first Bmp header
msarett4ab9d5f2015-08-06 15:34:42 -0700148 if (!inIco) {
msarett9bde9182015-03-25 05:27:48 -0700149 // Read the first header and the size of the second header
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400150 uint8_t hBuffer[kBmpHeaderBytesPlusFour];
151 if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
msarett9bde9182015-03-25 05:27:48 -0700152 kBmpHeaderBytesPlusFour) {
scroggo230d4ac2015-03-26 07:15:55 -0700153 SkCodecPrintf("Error: unable to read first bitmap header.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400154 return kIncompleteInput;
msarett9bde9182015-03-25 05:27:48 -0700155 }
156
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400157 totalBytes = get_int(hBuffer, 2);
158 offset = get_int(hBuffer, 10);
msarett9bde9182015-03-25 05:27:48 -0700159 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700160 SkCodecPrintf("Error: invalid starting location for pixel data\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400161 return kInvalidInput;
msarett9bde9182015-03-25 05:27:48 -0700162 }
163
164 // The size of the second (info) header in bytes
165 // The size is the first field of the second header, so we have already
166 // read the first four infoBytes.
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400167 infoBytes = get_int(hBuffer, 14);
msarett9bde9182015-03-25 05:27:48 -0700168 if (infoBytes < kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700169 SkCodecPrintf("Error: invalid second header size.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400170 return kInvalidInput;
msarett9bde9182015-03-25 05:27:48 -0700171 }
172 } else {
173 // This value is only used by RLE compression. Bmp in Ico files do not
174 // use RLE. If the compression field is incorrectly signaled as RLE,
175 // we will catch this and signal an error below.
176 totalBytes = 0;
177
178 // Bmps in Ico cannot specify an offset. We will always assume that
179 // pixel data begins immediately after the color table. This value
180 // will be corrected below.
181 offset = 0;
182
183 // Read the size of the second header
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400184 uint8_t hBuffer[4];
185 if (stream->read(hBuffer, 4) != 4) {
scroggo230d4ac2015-03-26 07:15:55 -0700186 SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400187 return kIncompleteInput;
msarett9bde9182015-03-25 05:27:48 -0700188 }
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400189 infoBytes = get_int(hBuffer, 0);
msarett9bde9182015-03-25 05:27:48 -0700190 if (infoBytes < kBmpOS2V1Bytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700191 SkCodecPrintf("Error: invalid second header size.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400192 return kInvalidInput;
msarett9bde9182015-03-25 05:27:48 -0700193 }
tomhudson7aa846c2015-03-24 13:47:41 -0700194 }
195
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -0500196 // Determine image information depending on second header format
197 const BmpHeaderType headerType = get_header_type(infoBytes);
198 if (kUnknown_BmpHeaderType == headerType) {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400199 return kInvalidInput;
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -0500200 }
201
msarett9bde9182015-03-25 05:27:48 -0700202 // We already read the first four bytes of the info header to get the size
msarett74114382015-03-16 11:55:18 -0700203 const uint32_t infoBytesRemaining = infoBytes - 4;
msarett74114382015-03-16 11:55:18 -0700204
205 // Read the second header
Ben Wagner7ecc5962016-11-02 17:07:33 -0400206 std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
msarett74114382015-03-16 11:55:18 -0700207 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
scroggo230d4ac2015-03-26 07:15:55 -0700208 SkCodecPrintf("Error: unable to read second bitmap header.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400209 return kIncompleteInput;
msarett74114382015-03-16 11:55:18 -0700210 }
211
212 // The number of bits used per pixel in the pixel data
213 uint16_t bitsPerPixel;
214
215 // The compression method for the pixel data
msarett4ab9d5f2015-08-06 15:34:42 -0700216 uint32_t compression = kNone_BmpCompressionMethod;
msarett74114382015-03-16 11:55:18 -0700217
218 // Number of colors in the color table, defaults to 0 or max (see below)
219 uint32_t numColors = 0;
220
221 // Bytes per color in the color table, early versions use 3, most use 4
222 uint32_t bytesPerColor;
223
224 // The image width and height
225 int width, height;
226
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -0500227 switch (headerType) {
228 case kInfoV1_BmpHeaderType:
229 case kInfoV2_BmpHeaderType:
230 case kInfoV3_BmpHeaderType:
231 case kInfoV4_BmpHeaderType:
232 case kInfoV5_BmpHeaderType:
233 case kOS2VX_BmpHeaderType:
234 // We check the size of the header before entering the if statement.
235 // We should not reach this point unless the size is large enough for
236 // these required fields.
237 SkASSERT(infoBytesRemaining >= 12);
238 width = get_int(iBuffer.get(), 0);
239 height = get_int(iBuffer.get(), 4);
240 bitsPerPixel = get_short(iBuffer.get(), 10);
msarett74114382015-03-16 11:55:18 -0700241
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -0500242 // Some versions do not have these fields, so we check before
243 // overwriting the default value.
244 if (infoBytesRemaining >= 16) {
245 compression = get_int(iBuffer.get(), 12);
246 if (infoBytesRemaining >= 32) {
247 numColors = get_int(iBuffer.get(), 28);
248 }
msarett74114382015-03-16 11:55:18 -0700249 }
msarett74114382015-03-16 11:55:18 -0700250
Leon Scroggins III0b24cbd2016-12-15 15:58:22 -0500251 // All of the headers that reach this point, store color table entries
252 // using 4 bytes per pixel.
253 bytesPerColor = 4;
254 break;
255 case kOS2V1_BmpHeaderType:
256 // The OS2V1 is treated separately because it has a unique format
257 width = (int) get_short(iBuffer.get(), 0);
258 height = (int) get_short(iBuffer.get(), 2);
259 bitsPerPixel = get_short(iBuffer.get(), 6);
260 bytesPerColor = 3;
261 break;
262 case kUnknown_BmpHeaderType:
263 // We'll exit above in this case.
264 SkASSERT(false);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400265 return kInvalidInput;
msarett74114382015-03-16 11:55:18 -0700266 }
267
268 // Check for valid dimensions from header
scroggo46c57472015-09-30 08:57:13 -0700269 SkCodec::SkScanlineOrder rowOrder = SkCodec::kBottomUp_SkScanlineOrder;
msarett74114382015-03-16 11:55:18 -0700270 if (height < 0) {
271 height = -height;
scroggo46c57472015-09-30 08:57:13 -0700272 rowOrder = SkCodec::kTopDown_SkScanlineOrder;
msarett74114382015-03-16 11:55:18 -0700273 }
msarett9bde9182015-03-25 05:27:48 -0700274 // The height field for bmp in ico is double the actual height because they
275 // contain an XOR mask followed by an AND mask
msarett4ab9d5f2015-08-06 15:34:42 -0700276 if (inIco) {
msarett9bde9182015-03-25 05:27:48 -0700277 height /= 2;
278 }
Leon Scroggins III0354c622017-02-24 15:33:24 -0500279
280 // Arbitrary maximum. Matches Chromium.
281 constexpr int kMaxDim = 1 << 16;
282 if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
scroggo230d4ac2015-03-26 07:15:55 -0700283 SkCodecPrintf("Error: invalid bitmap dimensions.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400284 return kInvalidInput;
msarett74114382015-03-16 11:55:18 -0700285 }
286
287 // Create mask struct
288 SkMasks::InputMasks inputMasks;
msaretteed039b2015-03-18 11:11:19 -0700289 memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
msarett74114382015-03-16 11:55:18 -0700290
291 // Determine the input compression format and set bit masks if necessary
292 uint32_t maskBytes = 0;
msarett4ab9d5f2015-08-06 15:34:42 -0700293 BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
msarett74114382015-03-16 11:55:18 -0700294 switch (compression) {
msarett4ab9d5f2015-08-06 15:34:42 -0700295 case kNone_BmpCompressionMethod:
296 inputFormat = kStandard_BmpInputFormat;
msarett1088db92016-03-22 08:58:35 -0700297
298 // In addition to more standard pixel compression formats, bmp supports
299 // the use of bit masks to determine pixel components. The standard
300 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
301 // which does not map well to any Skia color formats. For this reason,
302 // we will always enable mask mode with 16 bits per pixel.
303 if (16 == bitsPerPixel) {
304 inputMasks.red = 0x7C00;
305 inputMasks.green = 0x03E0;
306 inputMasks.blue = 0x001F;
307 inputFormat = kBitMask_BmpInputFormat;
308 }
msarett74114382015-03-16 11:55:18 -0700309 break;
msarett4ab9d5f2015-08-06 15:34:42 -0700310 case k8BitRLE_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700311 if (bitsPerPixel != 8) {
scroggo230d4ac2015-03-26 07:15:55 -0700312 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
msarett74114382015-03-16 11:55:18 -0700313 bitsPerPixel = 8;
314 }
msarett4ab9d5f2015-08-06 15:34:42 -0700315 inputFormat = kRLE_BmpInputFormat;
msarett74114382015-03-16 11:55:18 -0700316 break;
msarett4ab9d5f2015-08-06 15:34:42 -0700317 case k4BitRLE_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700318 if (bitsPerPixel != 4) {
scroggo230d4ac2015-03-26 07:15:55 -0700319 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
msarett74114382015-03-16 11:55:18 -0700320 bitsPerPixel = 4;
321 }
msarett4ab9d5f2015-08-06 15:34:42 -0700322 inputFormat = kRLE_BmpInputFormat;
msarett74114382015-03-16 11:55:18 -0700323 break;
msarett4ab9d5f2015-08-06 15:34:42 -0700324 case kAlphaBitMasks_BmpCompressionMethod:
325 case kBitMasks_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700326 // Load the masks
msarett4ab9d5f2015-08-06 15:34:42 -0700327 inputFormat = kBitMask_BmpInputFormat;
msarett74114382015-03-16 11:55:18 -0700328 switch (headerType) {
msarett4ab9d5f2015-08-06 15:34:42 -0700329 case kInfoV1_BmpHeaderType: {
msarett74114382015-03-16 11:55:18 -0700330 // The V1 header stores the bit masks after the header
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400331 uint8_t buffer[kBmpMaskBytes];
332 if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
scroggo230d4ac2015-03-26 07:15:55 -0700333 SkCodecPrintf("Error: unable to read bit inputMasks.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400334 return kIncompleteInput;
msarett74114382015-03-16 11:55:18 -0700335 }
336 maskBytes = kBmpMaskBytes;
Leon Scroggins IIIec4400b2017-06-01 14:06:35 -0400337 inputMasks.red = get_int(buffer, 0);
338 inputMasks.green = get_int(buffer, 4);
339 inputMasks.blue = get_int(buffer, 8);
msarett74114382015-03-16 11:55:18 -0700340 break;
341 }
msarett4ab9d5f2015-08-06 15:34:42 -0700342 case kInfoV2_BmpHeaderType:
343 case kInfoV3_BmpHeaderType:
344 case kInfoV4_BmpHeaderType:
345 case kInfoV5_BmpHeaderType:
msarett74114382015-03-16 11:55:18 -0700346 // Header types are matched based on size. If the header
347 // is V2+, we are guaranteed to be able to read at least
348 // this size.
349 SkASSERT(infoBytesRemaining >= 48);
350 inputMasks.red = get_int(iBuffer.get(), 36);
351 inputMasks.green = get_int(iBuffer.get(), 40);
352 inputMasks.blue = get_int(iBuffer.get(), 44);
msarett1088db92016-03-22 08:58:35 -0700353
354 if (kInfoV2_BmpHeaderType == headerType ||
355 (kInfoV3_BmpHeaderType == headerType && !inIco)) {
356 break;
357 }
358
359 // V3+ bmp files introduce an alpha mask and allow the creator of the image
360 // to use the alpha channels. However, many of these images leave the
361 // alpha channel blank and expect to be rendered as opaque. This is the
362 // case for almost all V3 images, so we ignore the alpha mask. For V4+
363 // images in kMask mode, we will use the alpha mask. Additionally, V3
364 // bmp-in-ico expect us to use the alpha mask.
365 //
366 // skbug.com/4116: We should perhaps also apply the alpha mask in kStandard
367 // mode. We just haven't seen any images that expect this
368 // behavior.
369 //
370 // Header types are matched based on size. If the header is
371 // V3+, we are guaranteed to be able to read at least this size.
372 SkASSERT(infoBytesRemaining > 52);
373 inputMasks.alpha = get_int(iBuffer.get(), 48);
msarett74114382015-03-16 11:55:18 -0700374 break;
msarett4ab9d5f2015-08-06 15:34:42 -0700375 case kOS2VX_BmpHeaderType:
msarett74114382015-03-16 11:55:18 -0700376 // TODO: Decide if we intend to support this.
377 // It is unsupported in the previous version and
378 // in chromium. I have not come across a test case
379 // that uses this format.
scroggo230d4ac2015-03-26 07:15:55 -0700380 SkCodecPrintf("Error: huffman format unsupported.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400381 return kUnimplemented;
msarett74114382015-03-16 11:55:18 -0700382 default:
scroggo230d4ac2015-03-26 07:15:55 -0700383 SkCodecPrintf("Error: invalid bmp bit masks header.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400384 return kInvalidInput;
msarett74114382015-03-16 11:55:18 -0700385 }
386 break;
msarett4ab9d5f2015-08-06 15:34:42 -0700387 case kJpeg_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700388 if (24 == bitsPerPixel) {
msarett4ab9d5f2015-08-06 15:34:42 -0700389 inputFormat = kRLE_BmpInputFormat;
msarett74114382015-03-16 11:55:18 -0700390 break;
391 }
392 // Fall through
msarett4ab9d5f2015-08-06 15:34:42 -0700393 case kPng_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700394 // TODO: Decide if we intend to support this.
395 // It is unsupported in the previous version and
396 // in chromium. I think it is used mostly for printers.
scroggo230d4ac2015-03-26 07:15:55 -0700397 SkCodecPrintf("Error: compression format not supported.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400398 return kUnimplemented;
msarett4ab9d5f2015-08-06 15:34:42 -0700399 case kCMYK_BmpCompressionMethod:
400 case kCMYK8BitRLE_BmpCompressionMethod:
401 case kCMYK4BitRLE_BmpCompressionMethod:
msarett74114382015-03-16 11:55:18 -0700402 // TODO: Same as above.
scroggo230d4ac2015-03-26 07:15:55 -0700403 SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400404 return kUnimplemented;
msarett74114382015-03-16 11:55:18 -0700405 default:
scroggo230d4ac2015-03-26 07:15:55 -0700406 SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400407 return kInvalidInput;
msarett74114382015-03-16 11:55:18 -0700408 }
mtklein852f15d2016-03-17 10:51:27 -0700409 iBuffer.reset();
msarett74114382015-03-16 11:55:18 -0700410
msaretteed039b2015-03-18 11:11:19 -0700411 // Calculate the number of bytes read so far
412 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
msarett4ab9d5f2015-08-06 15:34:42 -0700413 if (!inIco && offset < bytesRead) {
msarett9aa32d12015-09-01 14:40:46 -0700414 // TODO (msarett): Do we really want to fail if the offset in the header is invalid?
415 // Seems like we can just assume that the offset is zero and try to decode?
416 // Maybe we don't want to try to decode corrupt images?
scroggo230d4ac2015-03-26 07:15:55 -0700417 SkCodecPrintf("Error: pixel data offset less than header size.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400418 return kInvalidInput;
msaretteed039b2015-03-18 11:11:19 -0700419 }
msarett74114382015-03-16 11:55:18 -0700420
msarett9aa32d12015-09-01 14:40:46 -0700421
msarettf4004f92016-02-11 10:49:31 -0800422
msarett1088db92016-03-22 08:58:35 -0700423 switch (inputFormat) {
424 case kStandard_BmpInputFormat: {
msarettc30c4182016-04-20 11:53:35 -0700425 // BMPs are generally opaque, however BMPs-in-ICOs may contain
426 // a transparency mask after the image. Therefore, we mark the
427 // alpha as kBinary if the BMP is contained in an ICO.
428 // We use |isOpaque| to indicate if the BMP itself is opaque.
429 SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
430 SkEncodedInfo::kOpaque_Alpha;
msarett1088db92016-03-22 08:58:35 -0700431 bool isOpaque = true;
msarettc30c4182016-04-20 11:53:35 -0700432
433 SkEncodedInfo::Color color;
434 uint8_t bitsPerComponent;
msarett1088db92016-03-22 08:58:35 -0700435 switch (bitsPerPixel) {
436 // Palette formats
437 case 1:
438 case 2:
439 case 4:
440 case 8:
msarettc30c4182016-04-20 11:53:35 -0700441 // In the case of ICO, kBGRA is actually the closest match,
442 // since we will need to apply a transparency mask.
443 if (inIco) {
444 color = SkEncodedInfo::kBGRA_Color;
445 bitsPerComponent = 8;
446 } else {
447 color = SkEncodedInfo::kPalette_Color;
448 bitsPerComponent = (uint8_t) bitsPerPixel;
msarett1088db92016-03-22 08:58:35 -0700449 }
450 break;
451 case 24:
msarett3e375b02016-05-04 13:03:48 -0700452 // In the case of ICO, kBGRA is actually the closest match,
453 // since we will need to apply a transparency mask.
454 color = inIco ? SkEncodedInfo::kBGRA_Color : SkEncodedInfo::kBGR_Color;
msarettc30c4182016-04-20 11:53:35 -0700455 bitsPerComponent = 8;
456 break;
msarett1088db92016-03-22 08:58:35 -0700457 case 32:
458 // 32-bit BMP-in-ICOs actually use the alpha channel in place of a
459 // transparency mask.
460 if (inIco) {
461 isOpaque = false;
msarettc30c4182016-04-20 11:53:35 -0700462 alpha = SkEncodedInfo::kUnpremul_Alpha;
463 color = SkEncodedInfo::kBGRA_Color;
464 } else {
465 color = SkEncodedInfo::kBGRX_Color;
msarett1088db92016-03-22 08:58:35 -0700466 }
msarettc30c4182016-04-20 11:53:35 -0700467 bitsPerComponent = 8;
msarett1088db92016-03-22 08:58:35 -0700468 break;
469 default:
470 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400471 return kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700472 }
msarett4ab9d5f2015-08-06 15:34:42 -0700473
msarett1088db92016-03-22 08:58:35 -0700474 if (codecOut) {
msarettbe8216a2015-12-04 08:00:50 -0800475 // We require streams to have a memory base for Bmp-in-Ico decodes.
476 SkASSERT(!inIco || nullptr != stream->getMemoryBase());
msarett1088db92016-03-22 08:58:35 -0700477
478 // Set the image info and create a codec.
msarettc30c4182016-04-20 11:53:35 -0700479 const SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, bitsPerComponent);
Mike Reedede7bac2017-07-23 15:30:02 -0400480 codecOut->reset(new SkBmpStandardCodec(width, height, info,
481 std::unique_ptr<SkStream>(stream),
482 bitsPerPixel, numColors, bytesPerColor,
483 offset - bytesRead, rowOrder, isOpaque,
484 inIco));
Leon Scroggins III588fb042017-07-14 16:32:31 -0400485 return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
486 ? kSuccess : kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700487 }
Leon Scroggins III588fb042017-07-14 16:32:31 -0400488 return kSuccess;
msarett1088db92016-03-22 08:58:35 -0700489 }
490
491 case kBitMask_BmpInputFormat: {
492 // Bmp-in-Ico must be standard mode
493 if (inIco) {
494 SkCodecPrintf("Error: Icos may not use bit mask format.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400495 return kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700496 }
497
498 switch (bitsPerPixel) {
499 case 16:
500 case 24:
501 case 32:
502 break;
503 default:
504 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400505 return kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700506 }
507
508 // Skip to the start of the pixel array.
509 // We can do this here because there is no color table to read
510 // in bit mask mode.
511 if (stream->skip(offset - bytesRead) != offset - bytesRead) {
512 SkCodecPrintf("Error: unable to skip to image data.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400513 return kIncompleteInput;
msarett1088db92016-03-22 08:58:35 -0700514 }
515
516 if (codecOut) {
517 // Check that input bit masks are valid and create the masks object
Ben Wagner145dbcd2016-11-03 14:40:50 -0400518 std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
msarett1088db92016-03-22 08:58:35 -0700519 if (nullptr == masks) {
520 SkCodecPrintf("Error: invalid input masks.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400521 return kInvalidInput;
msarett4ab9d5f2015-08-06 15:34:42 -0700522 }
msarett4ab9d5f2015-08-06 15:34:42 -0700523
msarettc30c4182016-04-20 11:53:35 -0700524 // Masked bmps are not a great fit for SkEncodedInfo, since they have
525 // arbitrary component orderings and bits per component. Here we choose
526 // somewhat reasonable values - it's ok that we don't match exactly
527 // because SkBmpMaskCodec has its own mask swizzler anyway.
528 SkEncodedInfo::Color color;
529 SkEncodedInfo::Alpha alpha;
530 if (masks->getAlphaMask()) {
531 color = SkEncodedInfo::kBGRA_Color;
532 alpha = SkEncodedInfo::kUnpremul_Alpha;
533 } else {
534 color = SkEncodedInfo::kBGR_Color;
535 alpha = SkEncodedInfo::kOpaque_Alpha;
536 }
537 const SkEncodedInfo info = SkEncodedInfo::Make(color, alpha, 8);
Mike Reedede7bac2017-07-23 15:30:02 -0400538 codecOut->reset(new SkBmpMaskCodec(width, height, info,
539 std::unique_ptr<SkStream>(stream), bitsPerPixel,
Leon Scroggins IIIfc4ee222017-07-14 11:48:52 -0400540 masks.release(), rowOrder));
Leon Scroggins III588fb042017-07-14 16:32:31 -0400541 return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
542 ? kSuccess : kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700543 }
Leon Scroggins III588fb042017-07-14 16:32:31 -0400544 return kSuccess;
msarett1088db92016-03-22 08:58:35 -0700545 }
546
547 case kRLE_BmpInputFormat: {
548 // We should not reach this point without a valid value of bitsPerPixel.
549 SkASSERT(4 == bitsPerPixel || 8 == bitsPerPixel || 24 == bitsPerPixel);
550
551 // Check for a valid number of total bytes when in RLE mode
552 if (totalBytes <= offset) {
553 SkCodecPrintf("Error: RLE requires valid input size.\n");
Leon Scroggins III588fb042017-07-14 16:32:31 -0400554 return kInvalidInput;
msarett1088db92016-03-22 08:58:35 -0700555 }
msarett1088db92016-03-22 08:58:35 -0700556
557 // Bmp-in-Ico must be standard mode
558 // When inIco is true, this line cannot be reached, since we
559 // require that RLE Bmps have a valid number of totalBytes, and
560 // Icos skip the header that contains totalBytes.
561 SkASSERT(!inIco);
562
563 if (codecOut) {
564 // RLE inputs may skip pixels, leaving them as transparent. This
565 // is uncommon, but we cannot be certain that an RLE bmp will be
msarettc30c4182016-04-20 11:53:35 -0700566 // opaque or that we will be able to represent it with a palette.
567 // For that reason, we always indicate that we are kBGRA.
568 const SkEncodedInfo info = SkEncodedInfo::Make(SkEncodedInfo::kBGRA_Color,
569 SkEncodedInfo::kBinary_Alpha, 8);
Mike Reedede7bac2017-07-23 15:30:02 -0400570 codecOut->reset(new SkBmpRLECodec(width, height, info,
571 std::unique_ptr<SkStream>(stream), bitsPerPixel,
Leon Scroggins IIIfc4ee222017-07-14 11:48:52 -0400572 numColors, bytesPerColor, offset - bytesRead,
573 rowOrder));
msarett1088db92016-03-22 08:58:35 -0700574 }
Leon Scroggins III588fb042017-07-14 16:32:31 -0400575 return kSuccess;
msarett4ab9d5f2015-08-06 15:34:42 -0700576 }
msarett1088db92016-03-22 08:58:35 -0700577 default:
578 SkASSERT(false);
Leon Scroggins III588fb042017-07-14 16:32:31 -0400579 return kInvalidInput;
scroggo79e378d2015-04-01 07:39:40 -0700580 }
scroggo79e378d2015-04-01 07:39:40 -0700581}
582
583/*
scroggo79e378d2015-04-01 07:39:40 -0700584 * Creates a bmp decoder
585 * Reads enough of the stream to determine the image format
scroggo79e378d2015-04-01 07:39:40 -0700586 */
Mike Reedede7bac2017-07-23 15:30:02 -0400587std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
588 Result* result, bool inIco) {
Leon Scroggins IIIfc4ee222017-07-14 11:48:52 -0400589 std::unique_ptr<SkCodec> codec;
Mike Reedede7bac2017-07-23 15:30:02 -0400590 *result = ReadHeader(stream.get(), inIco, &codec);
Leon Scroggins IIIfc4ee222017-07-14 11:48:52 -0400591 if (codec) {
Mike Reedede7bac2017-07-23 15:30:02 -0400592 // codec has taken ownership of stream, so we do not need to delete it.
593 stream.release();
scroggo79e378d2015-04-01 07:39:40 -0700594 }
Mike Reedede7bac2017-07-23 15:30:02 -0400595 return kSuccess == *result ? std::move(codec) : nullptr;
msarett74114382015-03-16 11:55:18 -0700596}
597
Mike Reedede7bac2017-07-23 15:30:02 -0400598SkBmpCodec::SkBmpCodec(int width, int height, const SkEncodedInfo& info,
599 std::unique_ptr<SkStream> stream,
scroggo46c57472015-09-30 08:57:13 -0700600 uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder)
Mike Reedede7bac2017-07-23 15:30:02 -0400601 : INHERITED(width, height, info, kXformSrcColorFormat, std::move(stream),
602 SkColorSpace::MakeSRGB())
msarett74114382015-03-16 11:55:18 -0700603 , fBitsPerPixel(bitsPerPixel)
msarett74114382015-03-16 11:55:18 -0700604 , fRowOrder(rowOrder)
msarettc30c4182016-04-20 11:53:35 -0700605 , fSrcRowBytes(SkAlign4(compute_row_bytes(width, fBitsPerPixel)))
Matt Sarett1b96c6f2016-11-03 16:15:20 -0400606 , fXformBuffer(nullptr)
msarett74114382015-03-16 11:55:18 -0700607{}
608
scroggob427db12015-08-12 07:24:13 -0700609bool SkBmpCodec::onRewind() {
Leon Scroggins III588fb042017-07-14 16:32:31 -0400610 return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr) == kSuccess;
msaretteed039b2015-03-18 11:11:19 -0700611}
612
scroggo46c57472015-09-30 08:57:13 -0700613int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
614 if (SkCodec::kTopDown_SkScanlineOrder == fRowOrder) {
msarett5406d6f2015-08-31 06:55:13 -0700615 return y;
616 }
scroggo46c57472015-09-30 08:57:13 -0700617 SkASSERT(SkCodec::kBottomUp_SkScanlineOrder == fRowOrder);
msarett5406d6f2015-08-31 06:55:13 -0700618 return height - y - 1;
619}
620
Matt Sarett1b96c6f2016-11-03 16:15:20 -0400621SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +0000622 const SkCodec::Options& options) {
Leon Scroggins571b30f2017-07-11 17:35:31 +0000623 return this->onPrepareToDecode(dstInfo, options);
Matt Sarett1b96c6f2016-11-03 16:15:20 -0400624}
625
626SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +0000627 const SkCodec::Options& options) {
628 return prepareToDecode(dstInfo, options);
scroggo46c57472015-09-30 08:57:13 -0700629}
msarett5406d6f2015-08-31 06:55:13 -0700630
msarette6dd0042015-10-09 11:07:34 -0700631int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
scroggo46c57472015-09-30 08:57:13 -0700632 // Create a new image info representing the portion of the image to decode
633 SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
msarett5406d6f2015-08-31 06:55:13 -0700634
scroggo46c57472015-09-30 08:57:13 -0700635 // Decode the requested rows
636 return this->decodeRows(rowInfo, dst, rowBytes, this->options());
637}
msarett9b9497e2016-02-11 13:29:36 -0800638
639bool SkBmpCodec::skipRows(int count) {
640 const size_t bytesToSkip = count * fSrcRowBytes;
641 return this->stream()->skip(bytesToSkip) == bytesToSkip;
642}
643
644bool SkBmpCodec::onSkipScanlines(int count) {
645 return this->skipRows(count);
646}