Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/codec/SkBmpCodec.cpp
Line
Count
Source (jump to first uncovered line)
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 "src/codec/SkBmpCodec.h"
9
10
#include "include/codec/SkBmpDecoder.h"
11
#include "include/core/SkData.h"
12
#include "include/core/SkImageInfo.h"
13
#include "include/core/SkRefCnt.h"
14
#include "include/core/SkSize.h"
15
#include "include/core/SkStream.h"
16
#include "include/private/SkEncodedInfo.h"
17
#include "include/private/base/SkAlign.h"
18
#include "src/codec/SkBmpMaskCodec.h"
19
#include "src/codec/SkBmpRLECodec.h"
20
#include "src/codec/SkBmpStandardCodec.h"
21
#include "src/codec/SkCodecPriv.h"
22
#include "src/core/SkMasks.h"
23
24
#include <cstring>
25
#include <memory>
26
#include <utility>
27
28
/*
29
 * Defines the version and type of the second bitmap header
30
 */
31
enum BmpHeaderType {
32
    kInfoV1_BmpHeaderType,
33
    kInfoV2_BmpHeaderType,
34
    kInfoV3_BmpHeaderType,
35
    kInfoV4_BmpHeaderType,
36
    kInfoV5_BmpHeaderType,
37
    kOS2V1_BmpHeaderType,
38
    kOS2VX_BmpHeaderType,
39
    kUnknown_BmpHeaderType
40
};
41
42
/*
43
 * Possible bitmap compression types
44
 */
45
enum BmpCompressionMethod {
46
    kNone_BmpCompressionMethod =          0,
47
    k8BitRLE_BmpCompressionMethod =       1,
48
    k4BitRLE_BmpCompressionMethod =       2,
49
    kBitMasks_BmpCompressionMethod =      3,
50
    kJpeg_BmpCompressionMethod =          4,
51
    kPng_BmpCompressionMethod =           5,
52
    kAlphaBitMasks_BmpCompressionMethod = 6,
53
    kCMYK_BmpCompressionMethod =          11,
54
    kCMYK8BitRLE_BmpCompressionMethod =   12,
55
    kCMYK4BitRLE_BmpCompressionMethod =   13
56
};
57
58
/*
59
 * Used to define the input format of the bmp
60
 */
61
enum BmpInputFormat {
62
    kStandard_BmpInputFormat,
63
    kRLE_BmpInputFormat,
64
    kBitMask_BmpInputFormat,
65
    kUnknown_BmpInputFormat
66
};
67
68
/*
69
 * Checks the start of the stream to see if the image is a bitmap
70
 */
71
40.2k
bool SkBmpCodec::IsBmp(const void* buffer, size_t bytesRead) {
72
    // TODO: Support "IC", "PT", "CI", "CP", "BA"
73
40.2k
    const char bmpSig[] = { 'B', 'M' };
74
40.2k
    return bytesRead >= sizeof(bmpSig) && !memcmp(buffer, bmpSig, sizeof(bmpSig));
75
40.2k
}
76
77
/*
78
 * Assumes IsBmp was called and returned true
79
 * Creates a bmp decoder
80
 * Reads enough of the stream to determine the image format
81
 */
82
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
83
4.58k
                                                    Result* result) {
84
4.58k
    return SkBmpCodec::MakeFromStream(std::move(stream), result, false);
85
4.58k
}
86
87
/*
88
 * Creates a bmp decoder for a bmp embedded in ico
89
 * Reads enough of the stream to determine the image format
90
 */
91
12.9k
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromIco(std::unique_ptr<SkStream> stream, Result* result) {
92
12.9k
    return SkBmpCodec::MakeFromStream(std::move(stream), result, true);
93
12.9k
}
94
95
// Header size constants
96
static constexpr uint32_t kBmpHeaderBytes = 14;
97
static constexpr uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
98
static constexpr uint32_t kBmpOS2V1Bytes = 12;
99
static constexpr uint32_t kBmpOS2V2Bytes = 64;
100
static constexpr uint32_t kBmpInfoBaseBytes = 16;
101
static constexpr uint32_t kBmpInfoV1Bytes = 40;
102
static constexpr uint32_t kBmpInfoV2Bytes = 52;
103
static constexpr uint32_t kBmpInfoV3Bytes = 56;
104
static constexpr uint32_t kBmpInfoV4Bytes = 108;
105
static constexpr uint32_t kBmpInfoV5Bytes = 124;
106
static constexpr uint32_t kBmpMaskBytes = 12;
107
108
15.8k
static BmpHeaderType get_header_type(size_t infoBytes) {
109
15.8k
    if (infoBytes >= kBmpInfoBaseBytes) {
110
        // Check the version of the header
111
14.4k
        switch (infoBytes) {
112
2.22k
            case kBmpInfoV1Bytes:
113
2.22k
                return kInfoV1_BmpHeaderType;
114
647
            case kBmpInfoV2Bytes:
115
647
                return kInfoV2_BmpHeaderType;
116
754
            case kBmpInfoV3Bytes:
117
754
                return kInfoV3_BmpHeaderType;
118
1.09k
            case kBmpInfoV4Bytes:
119
1.09k
                return kInfoV4_BmpHeaderType;
120
423
            case kBmpInfoV5Bytes:
121
423
                return kInfoV5_BmpHeaderType;
122
468
            case 16:
123
1.62k
            case 20:
124
2.03k
            case 24:
125
2.55k
            case 28:
126
2.90k
            case 32:
127
4.13k
            case 36:
128
4.55k
            case 42:
129
4.74k
            case 46:
130
5.20k
            case 48:
131
5.80k
            case 60:
132
6.03k
            case kBmpOS2V2Bytes:
133
6.03k
                return kOS2VX_BmpHeaderType;
134
3.24k
            default:
135
3.24k
                SkCodecPrintf("Error: unknown bmp header format.\n");
136
3.24k
                return kUnknown_BmpHeaderType;
137
14.4k
        }
138
14.4k
    } if (infoBytes >= kBmpOS2V1Bytes) {
139
        // The OS2V1 is treated separately because it has a unique format
140
1.45k
        return kOS2V1_BmpHeaderType;
141
1.45k
    } else {
142
        // There are no valid bmp headers
143
0
        SkCodecPrintf("Error: second bitmap header size is invalid.\n");
144
0
        return kUnknown_BmpHeaderType;
145
0
    }
146
1.45k
}
147
148
SkCodec::Result SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
149
17.5k
        std::unique_ptr<SkCodec>* codecOut) {
150
    // The total bytes in the bmp file
151
    // We only need to use this value for RLE decoding, so we will only
152
    // check that it is valid in the RLE case.
153
17.5k
    uint32_t totalBytes;
154
    // The offset from the start of the file where the pixel data begins
155
17.5k
    uint32_t offset;
156
    // The size of the second (info) header in bytes
157
17.5k
    uint32_t infoBytes;
158
159
    // Bmps embedded in Icos skip the first Bmp header
160
17.5k
    if (!inIco) {
161
        // Read the first header and the size of the second header
162
4.59k
        uint8_t hBuffer[kBmpHeaderBytesPlusFour];
163
4.59k
        if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
164
4.59k
                kBmpHeaderBytesPlusFour) {
165
144
            SkCodecPrintf("Error: unable to read first bitmap header.\n");
166
144
            return kIncompleteInput;
167
144
        }
168
169
4.44k
        totalBytes = get_int(hBuffer, 2);
170
4.44k
        offset = get_int(hBuffer, 10);
171
4.44k
        if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
172
56
            SkCodecPrintf("Error: invalid starting location for pixel data\n");
173
56
            return kInvalidInput;
174
56
        }
175
176
        // The size of the second (info) header in bytes
177
        // The size is the first field of the second header, so we have already
178
        // read the first four infoBytes.
179
4.39k
        infoBytes = get_int(hBuffer, 14);
180
4.39k
        if (infoBytes < kBmpOS2V1Bytes) {
181
35
            SkCodecPrintf("Error: invalid second header size.\n");
182
35
            return kInvalidInput;
183
35
        }
184
13.0k
    } else {
185
        // This value is only used by RLE compression.  Bmp in Ico files do not
186
        // use RLE.  If the compression field is incorrectly signaled as RLE,
187
        // we will catch this and signal an error below.
188
13.0k
        totalBytes = 0;
189
190
        // Bmps in Ico cannot specify an offset.  We will always assume that
191
        // pixel data begins immediately after the color table.  This value
192
        // will be corrected below.
193
13.0k
        offset = 0;
194
195
        // Read the size of the second header
196
13.0k
        uint8_t hBuffer[4];
197
13.0k
        if (stream->read(hBuffer, 4) != 4) {
198
1.00k
            SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
199
1.00k
            return kIncompleteInput;
200
1.00k
        }
201
11.9k
        infoBytes = get_int(hBuffer, 0);
202
11.9k
        if (infoBytes < kBmpOS2V1Bytes) {
203
476
            SkCodecPrintf("Error: invalid second header size.\n");
204
476
            return kInvalidInput;
205
476
        }
206
11.9k
    }
207
208
    // Determine image information depending on second header format
209
15.8k
    const BmpHeaderType headerType = get_header_type(infoBytes);
210
15.8k
    if (kUnknown_BmpHeaderType == headerType) {
211
3.24k
        return kInvalidInput;
212
3.24k
    }
213
214
    // We already read the first four bytes of the info header to get the size
215
12.6k
    const uint32_t infoBytesRemaining = infoBytes - 4;
216
217
    // Read the second header
218
12.6k
    std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
219
12.6k
    if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
220
1.42k
        SkCodecPrintf("Error: unable to read second bitmap header.\n");
221
1.42k
        return kIncompleteInput;
222
1.42k
    }
223
224
    // The number of bits used per pixel in the pixel data
225
11.2k
    uint16_t bitsPerPixel;
226
227
    // The compression method for the pixel data
228
11.2k
    uint32_t compression = kNone_BmpCompressionMethod;
229
230
    // Number of colors in the color table, defaults to 0 or max (see below)
231
11.2k
    uint32_t numColors = 0;
232
233
    // Bytes per color in the color table, early versions use 3, most use 4
234
11.2k
    uint32_t bytesPerColor;
235
236
    // The image width and height
237
11.2k
    int width, height;
238
239
11.2k
    switch (headerType) {
240
2.15k
        case kInfoV1_BmpHeaderType:
241
2.67k
        case kInfoV2_BmpHeaderType:
242
3.28k
        case kInfoV3_BmpHeaderType:
243
4.30k
        case kInfoV4_BmpHeaderType:
244
4.62k
        case kInfoV5_BmpHeaderType:
245
9.79k
        case kOS2VX_BmpHeaderType:
246
            // We check the size of the header before entering the if statement.
247
            // We should not reach this point unless the size is large enough for
248
            // these required fields.
249
9.79k
            SkASSERT(infoBytesRemaining >= 12);
250
9.79k
            width = get_int(iBuffer.get(), 0);
251
9.79k
            height = get_int(iBuffer.get(), 4);
252
9.79k
            bitsPerPixel = get_short(iBuffer.get(), 10);
253
254
            // Some versions do not have these fields, so we check before
255
            // overwriting the default value.
256
9.79k
            if (infoBytesRemaining >= 16) {
257
9.33k
                compression = get_int(iBuffer.get(), 12);
258
9.33k
                if (infoBytesRemaining >= 32) {
259
7.17k
                    numColors = get_int(iBuffer.get(), 28);
260
7.17k
                }
261
9.33k
            }
262
263
            // All of the headers that reach this point, store color table entries
264
            // using 4 bytes per pixel.
265
9.79k
            bytesPerColor = 4;
266
9.79k
            break;
267
1.40k
        case kOS2V1_BmpHeaderType:
268
            // The OS2V1 is treated separately because it has a unique format
269
1.40k
            width = (int) get_short(iBuffer.get(), 0);
270
1.40k
            height = (int) get_short(iBuffer.get(), 2);
271
1.40k
            bitsPerPixel = get_short(iBuffer.get(), 6);
272
1.40k
            bytesPerColor = 3;
273
1.40k
            break;
274
0
        case kUnknown_BmpHeaderType:
275
            // We'll exit above in this case.
276
0
            SkASSERT(false);
277
0
            return kInvalidInput;
278
11.2k
    }
279
280
    // Check for valid dimensions from header
281
11.2k
    SkCodec::SkScanlineOrder rowOrder = SkCodec::kBottomUp_SkScanlineOrder;
282
11.2k
    if (height < 0) {
283
        // We can't negate INT32_MIN.
284
3.19k
        if (height == INT32_MIN) {
285
147
            return kInvalidInput;
286
147
        }
287
288
3.04k
        height = -height;
289
3.04k
        rowOrder = SkCodec::kTopDown_SkScanlineOrder;
290
3.04k
    }
291
    // The height field for bmp in ico is double the actual height because they
292
    // contain an XOR mask followed by an AND mask
293
11.0k
    if (inIco) {
294
7.08k
        height /= 2;
295
7.08k
    }
296
297
    // Arbitrary maximum. Matches Chromium.
298
11.0k
    constexpr int kMaxDim = 1 << 16;
299
11.0k
    if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
300
2.56k
        SkCodecPrintf("Error: invalid bitmap dimensions.\n");
301
2.56k
        return kInvalidInput;
302
2.56k
    }
303
304
    // Create mask struct
305
8.49k
    SkMasks::InputMasks inputMasks;
306
8.49k
    memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
307
308
    // Determine the input compression format and set bit masks if necessary
309
8.49k
    uint32_t maskBytes = 0;
310
8.49k
    BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
311
8.49k
    switch (compression) {
312
2.77k
        case kNone_BmpCompressionMethod:
313
2.77k
            inputFormat = kStandard_BmpInputFormat;
314
315
            // In addition to more standard pixel compression formats, bmp supports
316
            // the use of bit masks to determine pixel components.  The standard
317
            // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
318
            // which does not map well to any Skia color formats.  For this reason,
319
            // we will always enable mask mode with 16 bits per pixel.
320
2.77k
            if (16 == bitsPerPixel) {
321
257
                inputMasks.red = 0x7C00;
322
257
                inputMasks.green = 0x03E0;
323
257
                inputMasks.blue = 0x001F;
324
257
                inputFormat = kBitMask_BmpInputFormat;
325
257
            }
326
2.77k
            break;
327
674
        case k8BitRLE_BmpCompressionMethod:
328
674
            if (bitsPerPixel != 8) {
329
551
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
330
551
                bitsPerPixel = 8;
331
551
            }
332
674
            inputFormat = kRLE_BmpInputFormat;
333
674
            break;
334
588
        case k4BitRLE_BmpCompressionMethod:
335
588
            if (bitsPerPixel != 4) {
336
500
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
337
500
                bitsPerPixel = 4;
338
500
            }
339
588
            inputFormat = kRLE_BmpInputFormat;
340
588
            break;
341
719
        case kAlphaBitMasks_BmpCompressionMethod:
342
2.89k
        case kBitMasks_BmpCompressionMethod:
343
            // Load the masks
344
2.89k
            inputFormat = kBitMask_BmpInputFormat;
345
2.89k
            switch (headerType) {
346
1.23k
                case kInfoV1_BmpHeaderType: {
347
                    // The V1 header stores the bit masks after the header
348
1.23k
                    uint8_t buffer[kBmpMaskBytes];
349
1.23k
                    if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
350
95
                        SkCodecPrintf("Error: unable to read bit inputMasks.\n");
351
95
                        return kIncompleteInput;
352
95
                    }
353
1.13k
                    maskBytes = kBmpMaskBytes;
354
1.13k
                    inputMasks.red = get_int(buffer, 0);
355
1.13k
                    inputMasks.green = get_int(buffer, 4);
356
1.13k
                    inputMasks.blue = get_int(buffer, 8);
357
1.13k
                    break;
358
1.23k
                }
359
344
                case kInfoV2_BmpHeaderType:
360
587
                case kInfoV3_BmpHeaderType:
361
1.26k
                case kInfoV4_BmpHeaderType:
362
1.46k
                case kInfoV5_BmpHeaderType:
363
                    // Header types are matched based on size.  If the header
364
                    // is V2+, we are guaranteed to be able to read at least
365
                    // this size.
366
1.46k
                    SkASSERT(infoBytesRemaining >= 48);
367
1.46k
                    inputMasks.red = get_int(iBuffer.get(), 36);
368
1.46k
                    inputMasks.green = get_int(iBuffer.get(), 40);
369
1.46k
                    inputMasks.blue = get_int(iBuffer.get(), 44);
370
371
1.46k
                    if (kInfoV2_BmpHeaderType == headerType ||
372
1.46k
                            (kInfoV3_BmpHeaderType == headerType && !inIco)) {
373
399
                        break;
374
399
                    }
375
376
                    // V3+ bmp files introduce an alpha mask and allow the creator of the image
377
                    // to use the alpha channels.  However, many of these images leave the
378
                    // alpha channel blank and expect to be rendered as opaque.  This is the
379
                    // case for almost all V3 images, so we ignore the alpha mask.  For V4+
380
                    // images in kMask mode, we will use the alpha mask.  Additionally, V3
381
                    // bmp-in-ico expect us to use the alpha mask.
382
                    //
383
                    // skbug.com/4116: We should perhaps also apply the alpha mask in kStandard
384
                    //                 mode.  We just haven't seen any images that expect this
385
                    //                 behavior.
386
                    //
387
                    // Header types are matched based on size.  If the header is
388
                    // V3+, we are guaranteed to be able to read at least this size.
389
1.06k
                    SkASSERT(infoBytesRemaining >= 52);
390
1.06k
                    inputMasks.alpha = get_int(iBuffer.get(), 48);
391
1.06k
                    break;
392
194
                case kOS2VX_BmpHeaderType:
393
                    // TODO: Decide if we intend to support this.
394
                    //       It is unsupported in the previous version and
395
                    //       in chromium.  I have not come across a test case
396
                    //       that uses this format.
397
194
                    SkCodecPrintf("Error: huffman format unsupported.\n");
398
194
                    return kUnimplemented;
399
0
                default:
400
0
                   SkCodecPrintf("Error: invalid bmp bit masks header.\n");
401
0
                   return kInvalidInput;
402
2.89k
            }
403
2.60k
            break;
404
2.60k
        case kJpeg_BmpCompressionMethod:
405
583
            if (24 == bitsPerPixel) {
406
464
                inputFormat = kRLE_BmpInputFormat;
407
464
                break;
408
464
            }
409
583
            [[fallthrough]];
410
317
        case kPng_BmpCompressionMethod:
411
            // TODO: Decide if we intend to support this.
412
            //       It is unsupported in the previous version and
413
            //       in chromium.  I think it is used mostly for printers.
414
317
            SkCodecPrintf("Error: compression format not supported.\n");
415
317
            return kUnimplemented;
416
60
        case kCMYK_BmpCompressionMethod:
417
237
        case kCMYK8BitRLE_BmpCompressionMethod:
418
407
        case kCMYK4BitRLE_BmpCompressionMethod:
419
            // TODO: Same as above.
420
407
            SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
421
407
            return kUnimplemented;
422
376
        default:
423
376
            SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
424
376
            return kInvalidInput;
425
8.49k
    }
426
7.10k
    iBuffer.reset();
427
428
    // Calculate the number of bytes read so far
429
7.10k
    const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
430
7.10k
    if (!inIco && offset < bytesRead) {
431
        // TODO (msarett): Do we really want to fail if the offset in the header is invalid?
432
        //                 Seems like we can just assume that the offset is zero and try to decode?
433
        //                 Maybe we don't want to try to decode corrupt images?
434
36
        SkCodecPrintf("Error: pixel data offset less than header size.\n");
435
36
        return kInvalidInput;
436
36
    }
437
438
439
440
7.06k
    switch (inputFormat) {
441
2.51k
        case kStandard_BmpInputFormat: {
442
            // BMPs are generally opaque, however BMPs-in-ICOs may contain
443
            // a transparency mask after the image.  Therefore, we mark the
444
            // alpha as kBinary if the BMP is contained in an ICO.
445
            // We use |isOpaque| to indicate if the BMP itself is opaque.
446
2.51k
            SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
447
2.51k
                    SkEncodedInfo::kOpaque_Alpha;
448
2.51k
            bool isOpaque = true;
449
450
2.51k
            SkEncodedInfo::Color color;
451
2.51k
            uint8_t bitsPerComponent;
452
2.51k
            switch (bitsPerPixel) {
453
                // Palette formats
454
557
                case 1:
455
862
                case 2:
456
1.18k
                case 4:
457
1.55k
                case 8:
458
                    // In the case of ICO, kBGRA is actually the closest match,
459
                    // since we will need to apply a transparency mask.
460
1.55k
                    if (inIco) {
461
1.29k
                        color = SkEncodedInfo::kBGRA_Color;
462
1.29k
                        bitsPerComponent = 8;
463
1.29k
                    } else {
464
260
                        color = SkEncodedInfo::kPalette_Color;
465
260
                        bitsPerComponent = (uint8_t) bitsPerPixel;
466
260
                    }
467
1.55k
                    break;
468
200
                case 24:
469
                    // In the case of ICO, kBGRA is actually the closest match,
470
                    // since we will need to apply a transparency mask.
471
200
                    color = inIco ? SkEncodedInfo::kBGRA_Color : SkEncodedInfo::kBGR_Color;
472
200
                    bitsPerComponent = 8;
473
200
                    break;
474
408
                case 32:
475
                    // 32-bit BMP-in-ICOs actually use the alpha channel in place of a
476
                    // transparency mask.
477
408
                    if (inIco) {
478
314
                        isOpaque = false;
479
314
                        alpha = SkEncodedInfo::kUnpremul_Alpha;
480
314
                        color = SkEncodedInfo::kBGRA_Color;
481
314
                    } else {
482
94
                        color = SkEncodedInfo::kBGRX_Color;
483
94
                    }
484
408
                    bitsPerComponent = 8;
485
408
                    break;
486
350
                default:
487
350
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
488
350
                    return kInvalidInput;
489
2.51k
            }
490
491
2.16k
            if (codecOut) {
492
                // We require streams to have a memory base for Bmp-in-Ico decodes.
493
2.08k
                SkASSERT(!inIco || nullptr != stream->getMemoryBase());
494
495
                // Set the image info and create a codec.
496
2.08k
                auto info = SkEncodedInfo::Make(width, height, color, alpha, bitsPerComponent);
497
2.08k
                *codecOut = std::make_unique<SkBmpStandardCodec>(std::move(info),
498
2.08k
                                                       std::unique_ptr<SkStream>(stream),
499
2.08k
                                                       bitsPerPixel, numColors, bytesPerColor,
500
2.08k
                                                       offset - bytesRead, rowOrder, isOpaque,
501
2.08k
                                                       inIco);
502
2.08k
                return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
503
2.08k
                        ? kSuccess : kInvalidInput;
504
2.08k
            }
505
81
            return kSuccess;
506
2.16k
        }
507
508
2.82k
        case kBitMask_BmpInputFormat: {
509
            // Bmp-in-Ico must be standard mode
510
2.82k
            if (inIco) {
511
1.04k
                SkCodecPrintf("Error: Icos may not use bit mask format.\n");
512
1.04k
                return kInvalidInput;
513
1.04k
            }
514
515
1.78k
            switch (bitsPerPixel) {
516
259
                case 16:
517
553
                case 24:
518
1.75k
                case 32:
519
1.75k
                    break;
520
25
                default:
521
25
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
522
25
                    return kInvalidInput;
523
1.78k
            }
524
525
            // Skip to the start of the pixel array.
526
            // We can do this here because there is no color table to read
527
            // in bit mask mode.
528
1.75k
            if (stream->skip(offset - bytesRead) != offset - bytesRead) {
529
97
                SkCodecPrintf("Error: unable to skip to image data.\n");
530
97
                return kIncompleteInput;
531
97
            }
532
533
1.66k
            if (codecOut) {
534
                // Check that input bit masks are valid and create the masks object
535
1.66k
                SkASSERT(bitsPerPixel % 8 == 0);
536
1.66k
                std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel/8));
537
1.66k
                if (nullptr == masks) {
538
122
                    SkCodecPrintf("Error: invalid input masks.\n");
539
122
                    return kInvalidInput;
540
122
                }
541
542
                // Masked bmps are not a great fit for SkEncodedInfo, since they have
543
                // arbitrary component orderings and bits per component.  Here we choose
544
                // somewhat reasonable values - it's ok that we don't match exactly
545
                // because SkBmpMaskCodec has its own mask swizzler anyway.
546
1.54k
                SkEncodedInfo::Color color;
547
1.54k
                SkEncodedInfo::Alpha alpha;
548
1.54k
                if (masks->getAlphaMask()) {
549
441
                    color = SkEncodedInfo::kBGRA_Color;
550
441
                    alpha = SkEncodedInfo::kUnpremul_Alpha;
551
1.09k
                } else {
552
1.09k
                    color = SkEncodedInfo::kBGR_Color;
553
1.09k
                    alpha = SkEncodedInfo::kOpaque_Alpha;
554
1.09k
                }
555
1.54k
                auto info = SkEncodedInfo::Make(width, height, color, alpha, 8);
556
1.54k
                *codecOut = std::make_unique<SkBmpMaskCodec>(std::move(info),
557
1.54k
                                                   std::unique_ptr<SkStream>(stream), bitsPerPixel,
558
1.54k
                                                   masks.release(), rowOrder);
559
1.54k
                return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
560
1.54k
                        ? kSuccess : kInvalidInput;
561
1.66k
            }
562
0
            return kSuccess;
563
1.66k
        }
564
565
1.72k
        case kRLE_BmpInputFormat: {
566
            // We should not reach this point without a valid value of bitsPerPixel.
567
1.72k
            SkASSERT(4 == bitsPerPixel || 8 == bitsPerPixel || 24 == bitsPerPixel);
568
569
            // Check for a valid number of total bytes when in RLE mode
570
1.72k
            if (totalBytes <= offset) {
571
618
                SkCodecPrintf("Error: RLE requires valid input size.\n");
572
618
                return kInvalidInput;
573
618
            }
574
575
            // Bmp-in-Ico must be standard mode
576
            // When inIco is true, this line cannot be reached, since we
577
            // require that RLE Bmps have a valid number of totalBytes, and
578
            // Icos skip the header that contains totalBytes.
579
1.10k
            SkASSERT(!inIco);
580
581
1.10k
            if (codecOut) {
582
                // RLE inputs may skip pixels, leaving them as transparent.  This
583
                // is uncommon, but we cannot be certain that an RLE bmp will be
584
                // opaque or that we will be able to represent it with a palette.
585
                // For that reason, we always indicate that we are kBGRA.
586
1.10k
                auto info = SkEncodedInfo::Make(width, height, SkEncodedInfo::kBGRA_Color,
587
1.10k
                                                SkEncodedInfo::kBinary_Alpha, 8);
588
1.10k
                *codecOut = std::make_unique<SkBmpRLECodec>(std::move(info),
589
1.10k
                                                  std::unique_ptr<SkStream>(stream), bitsPerPixel,
590
1.10k
                                                  numColors, bytesPerColor, offset - bytesRead,
591
1.10k
                                                  rowOrder);
592
1.10k
            }
593
1.10k
            return kSuccess;
594
1.72k
        }
595
0
        default:
596
0
            SkASSERT(false);
597
0
            return kInvalidInput;
598
7.06k
    }
599
7.06k
}
SkBmpCodec::ReadHeader(SkStream*, bool, std::__1::unique_ptr<SkCodec, std::__1::default_delete<SkCodec> >*)
Line
Count
Source
149
17.5k
        std::unique_ptr<SkCodec>* codecOut) {
150
    // The total bytes in the bmp file
151
    // We only need to use this value for RLE decoding, so we will only
152
    // check that it is valid in the RLE case.
153
17.5k
    uint32_t totalBytes;
154
    // The offset from the start of the file where the pixel data begins
155
17.5k
    uint32_t offset;
156
    // The size of the second (info) header in bytes
157
17.5k
    uint32_t infoBytes;
158
159
    // Bmps embedded in Icos skip the first Bmp header
160
17.5k
    if (!inIco) {
161
        // Read the first header and the size of the second header
162
4.59k
        uint8_t hBuffer[kBmpHeaderBytesPlusFour];
163
4.59k
        if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
164
4.59k
                kBmpHeaderBytesPlusFour) {
165
144
            SkCodecPrintf("Error: unable to read first bitmap header.\n");
166
144
            return kIncompleteInput;
167
144
        }
168
169
4.44k
        totalBytes = get_int(hBuffer, 2);
170
4.44k
        offset = get_int(hBuffer, 10);
171
4.44k
        if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
172
56
            SkCodecPrintf("Error: invalid starting location for pixel data\n");
173
56
            return kInvalidInput;
174
56
        }
175
176
        // The size of the second (info) header in bytes
177
        // The size is the first field of the second header, so we have already
178
        // read the first four infoBytes.
179
4.39k
        infoBytes = get_int(hBuffer, 14);
180
4.39k
        if (infoBytes < kBmpOS2V1Bytes) {
181
35
            SkCodecPrintf("Error: invalid second header size.\n");
182
35
            return kInvalidInput;
183
35
        }
184
13.0k
    } else {
185
        // This value is only used by RLE compression.  Bmp in Ico files do not
186
        // use RLE.  If the compression field is incorrectly signaled as RLE,
187
        // we will catch this and signal an error below.
188
13.0k
        totalBytes = 0;
189
190
        // Bmps in Ico cannot specify an offset.  We will always assume that
191
        // pixel data begins immediately after the color table.  This value
192
        // will be corrected below.
193
13.0k
        offset = 0;
194
195
        // Read the size of the second header
196
13.0k
        uint8_t hBuffer[4];
197
13.0k
        if (stream->read(hBuffer, 4) != 4) {
198
1.00k
            SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
199
1.00k
            return kIncompleteInput;
200
1.00k
        }
201
11.9k
        infoBytes = get_int(hBuffer, 0);
202
11.9k
        if (infoBytes < kBmpOS2V1Bytes) {
203
476
            SkCodecPrintf("Error: invalid second header size.\n");
204
476
            return kInvalidInput;
205
476
        }
206
11.9k
    }
207
208
    // Determine image information depending on second header format
209
15.8k
    const BmpHeaderType headerType = get_header_type(infoBytes);
210
15.8k
    if (kUnknown_BmpHeaderType == headerType) {
211
3.24k
        return kInvalidInput;
212
3.24k
    }
213
214
    // We already read the first four bytes of the info header to get the size
215
12.6k
    const uint32_t infoBytesRemaining = infoBytes - 4;
216
217
    // Read the second header
218
12.6k
    std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
219
12.6k
    if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
220
1.42k
        SkCodecPrintf("Error: unable to read second bitmap header.\n");
221
1.42k
        return kIncompleteInput;
222
1.42k
    }
223
224
    // The number of bits used per pixel in the pixel data
225
11.2k
    uint16_t bitsPerPixel;
226
227
    // The compression method for the pixel data
228
11.2k
    uint32_t compression = kNone_BmpCompressionMethod;
229
230
    // Number of colors in the color table, defaults to 0 or max (see below)
231
11.2k
    uint32_t numColors = 0;
232
233
    // Bytes per color in the color table, early versions use 3, most use 4
234
11.2k
    uint32_t bytesPerColor;
235
236
    // The image width and height
237
11.2k
    int width, height;
238
239
11.2k
    switch (headerType) {
240
2.15k
        case kInfoV1_BmpHeaderType:
241
2.67k
        case kInfoV2_BmpHeaderType:
242
3.28k
        case kInfoV3_BmpHeaderType:
243
4.30k
        case kInfoV4_BmpHeaderType:
244
4.62k
        case kInfoV5_BmpHeaderType:
245
9.79k
        case kOS2VX_BmpHeaderType:
246
            // We check the size of the header before entering the if statement.
247
            // We should not reach this point unless the size is large enough for
248
            // these required fields.
249
9.79k
            SkASSERT(infoBytesRemaining >= 12);
250
9.79k
            width = get_int(iBuffer.get(), 0);
251
9.79k
            height = get_int(iBuffer.get(), 4);
252
9.79k
            bitsPerPixel = get_short(iBuffer.get(), 10);
253
254
            // Some versions do not have these fields, so we check before
255
            // overwriting the default value.
256
9.79k
            if (infoBytesRemaining >= 16) {
257
9.33k
                compression = get_int(iBuffer.get(), 12);
258
9.33k
                if (infoBytesRemaining >= 32) {
259
7.17k
                    numColors = get_int(iBuffer.get(), 28);
260
7.17k
                }
261
9.33k
            }
262
263
            // All of the headers that reach this point, store color table entries
264
            // using 4 bytes per pixel.
265
9.79k
            bytesPerColor = 4;
266
9.79k
            break;
267
1.40k
        case kOS2V1_BmpHeaderType:
268
            // The OS2V1 is treated separately because it has a unique format
269
1.40k
            width = (int) get_short(iBuffer.get(), 0);
270
1.40k
            height = (int) get_short(iBuffer.get(), 2);
271
1.40k
            bitsPerPixel = get_short(iBuffer.get(), 6);
272
1.40k
            bytesPerColor = 3;
273
1.40k
            break;
274
0
        case kUnknown_BmpHeaderType:
275
            // We'll exit above in this case.
276
0
            SkASSERT(false);
277
0
            return kInvalidInput;
278
11.2k
    }
279
280
    // Check for valid dimensions from header
281
11.2k
    SkCodec::SkScanlineOrder rowOrder = SkCodec::kBottomUp_SkScanlineOrder;
282
11.2k
    if (height < 0) {
283
        // We can't negate INT32_MIN.
284
3.19k
        if (height == INT32_MIN) {
285
147
            return kInvalidInput;
286
147
        }
287
288
3.04k
        height = -height;
289
3.04k
        rowOrder = SkCodec::kTopDown_SkScanlineOrder;
290
3.04k
    }
291
    // The height field for bmp in ico is double the actual height because they
292
    // contain an XOR mask followed by an AND mask
293
11.0k
    if (inIco) {
294
7.08k
        height /= 2;
295
7.08k
    }
296
297
    // Arbitrary maximum. Matches Chromium.
298
11.0k
    constexpr int kMaxDim = 1 << 16;
299
11.0k
    if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
300
2.56k
        SkCodecPrintf("Error: invalid bitmap dimensions.\n");
301
2.56k
        return kInvalidInput;
302
2.56k
    }
303
304
    // Create mask struct
305
8.49k
    SkMasks::InputMasks inputMasks;
306
8.49k
    memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
307
308
    // Determine the input compression format and set bit masks if necessary
309
8.49k
    uint32_t maskBytes = 0;
310
8.49k
    BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
311
8.49k
    switch (compression) {
312
2.77k
        case kNone_BmpCompressionMethod:
313
2.77k
            inputFormat = kStandard_BmpInputFormat;
314
315
            // In addition to more standard pixel compression formats, bmp supports
316
            // the use of bit masks to determine pixel components.  The standard
317
            // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
318
            // which does not map well to any Skia color formats.  For this reason,
319
            // we will always enable mask mode with 16 bits per pixel.
320
2.77k
            if (16 == bitsPerPixel) {
321
257
                inputMasks.red = 0x7C00;
322
257
                inputMasks.green = 0x03E0;
323
257
                inputMasks.blue = 0x001F;
324
257
                inputFormat = kBitMask_BmpInputFormat;
325
257
            }
326
2.77k
            break;
327
674
        case k8BitRLE_BmpCompressionMethod:
328
674
            if (bitsPerPixel != 8) {
329
551
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
330
551
                bitsPerPixel = 8;
331
551
            }
332
674
            inputFormat = kRLE_BmpInputFormat;
333
674
            break;
334
588
        case k4BitRLE_BmpCompressionMethod:
335
588
            if (bitsPerPixel != 4) {
336
500
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
337
500
                bitsPerPixel = 4;
338
500
            }
339
588
            inputFormat = kRLE_BmpInputFormat;
340
588
            break;
341
719
        case kAlphaBitMasks_BmpCompressionMethod:
342
2.89k
        case kBitMasks_BmpCompressionMethod:
343
            // Load the masks
344
2.89k
            inputFormat = kBitMask_BmpInputFormat;
345
2.89k
            switch (headerType) {
346
1.23k
                case kInfoV1_BmpHeaderType: {
347
                    // The V1 header stores the bit masks after the header
348
1.23k
                    uint8_t buffer[kBmpMaskBytes];
349
1.23k
                    if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
350
95
                        SkCodecPrintf("Error: unable to read bit inputMasks.\n");
351
95
                        return kIncompleteInput;
352
95
                    }
353
1.13k
                    maskBytes = kBmpMaskBytes;
354
1.13k
                    inputMasks.red = get_int(buffer, 0);
355
1.13k
                    inputMasks.green = get_int(buffer, 4);
356
1.13k
                    inputMasks.blue = get_int(buffer, 8);
357
1.13k
                    break;
358
1.23k
                }
359
344
                case kInfoV2_BmpHeaderType:
360
587
                case kInfoV3_BmpHeaderType:
361
1.26k
                case kInfoV4_BmpHeaderType:
362
1.46k
                case kInfoV5_BmpHeaderType:
363
                    // Header types are matched based on size.  If the header
364
                    // is V2+, we are guaranteed to be able to read at least
365
                    // this size.
366
1.46k
                    SkASSERT(infoBytesRemaining >= 48);
367
1.46k
                    inputMasks.red = get_int(iBuffer.get(), 36);
368
1.46k
                    inputMasks.green = get_int(iBuffer.get(), 40);
369
1.46k
                    inputMasks.blue = get_int(iBuffer.get(), 44);
370
371
1.46k
                    if (kInfoV2_BmpHeaderType == headerType ||
372
1.46k
                            (kInfoV3_BmpHeaderType == headerType && !inIco)) {
373
399
                        break;
374
399
                    }
375
376
                    // V3+ bmp files introduce an alpha mask and allow the creator of the image
377
                    // to use the alpha channels.  However, many of these images leave the
378
                    // alpha channel blank and expect to be rendered as opaque.  This is the
379
                    // case for almost all V3 images, so we ignore the alpha mask.  For V4+
380
                    // images in kMask mode, we will use the alpha mask.  Additionally, V3
381
                    // bmp-in-ico expect us to use the alpha mask.
382
                    //
383
                    // skbug.com/4116: We should perhaps also apply the alpha mask in kStandard
384
                    //                 mode.  We just haven't seen any images that expect this
385
                    //                 behavior.
386
                    //
387
                    // Header types are matched based on size.  If the header is
388
                    // V3+, we are guaranteed to be able to read at least this size.
389
1.06k
                    SkASSERT(infoBytesRemaining >= 52);
390
1.06k
                    inputMasks.alpha = get_int(iBuffer.get(), 48);
391
1.06k
                    break;
392
194
                case kOS2VX_BmpHeaderType:
393
                    // TODO: Decide if we intend to support this.
394
                    //       It is unsupported in the previous version and
395
                    //       in chromium.  I have not come across a test case
396
                    //       that uses this format.
397
194
                    SkCodecPrintf("Error: huffman format unsupported.\n");
398
194
                    return kUnimplemented;
399
0
                default:
400
0
                   SkCodecPrintf("Error: invalid bmp bit masks header.\n");
401
0
                   return kInvalidInput;
402
2.89k
            }
403
2.60k
            break;
404
2.60k
        case kJpeg_BmpCompressionMethod:
405
583
            if (24 == bitsPerPixel) {
406
464
                inputFormat = kRLE_BmpInputFormat;
407
464
                break;
408
464
            }
409
583
            [[fallthrough]];
410
317
        case kPng_BmpCompressionMethod:
411
            // TODO: Decide if we intend to support this.
412
            //       It is unsupported in the previous version and
413
            //       in chromium.  I think it is used mostly for printers.
414
317
            SkCodecPrintf("Error: compression format not supported.\n");
415
317
            return kUnimplemented;
416
60
        case kCMYK_BmpCompressionMethod:
417
237
        case kCMYK8BitRLE_BmpCompressionMethod:
418
407
        case kCMYK4BitRLE_BmpCompressionMethod:
419
            // TODO: Same as above.
420
407
            SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
421
407
            return kUnimplemented;
422
376
        default:
423
376
            SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
424
376
            return kInvalidInput;
425
8.49k
    }
426
7.10k
    iBuffer.reset();
427
428
    // Calculate the number of bytes read so far
429
7.10k
    const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
430
7.10k
    if (!inIco && offset < bytesRead) {
431
        // TODO (msarett): Do we really want to fail if the offset in the header is invalid?
432
        //                 Seems like we can just assume that the offset is zero and try to decode?
433
        //                 Maybe we don't want to try to decode corrupt images?
434
36
        SkCodecPrintf("Error: pixel data offset less than header size.\n");
435
36
        return kInvalidInput;
436
36
    }
437
438
439
440
7.06k
    switch (inputFormat) {
441
2.51k
        case kStandard_BmpInputFormat: {
442
            // BMPs are generally opaque, however BMPs-in-ICOs may contain
443
            // a transparency mask after the image.  Therefore, we mark the
444
            // alpha as kBinary if the BMP is contained in an ICO.
445
            // We use |isOpaque| to indicate if the BMP itself is opaque.
446
2.51k
            SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
447
2.51k
                    SkEncodedInfo::kOpaque_Alpha;
448
2.51k
            bool isOpaque = true;
449
450
2.51k
            SkEncodedInfo::Color color;
451
2.51k
            uint8_t bitsPerComponent;
452
2.51k
            switch (bitsPerPixel) {
453
                // Palette formats
454
557
                case 1:
455
862
                case 2:
456
1.18k
                case 4:
457
1.55k
                case 8:
458
                    // In the case of ICO, kBGRA is actually the closest match,
459
                    // since we will need to apply a transparency mask.
460
1.55k
                    if (inIco) {
461
1.29k
                        color = SkEncodedInfo::kBGRA_Color;
462
1.29k
                        bitsPerComponent = 8;
463
1.29k
                    } else {
464
260
                        color = SkEncodedInfo::kPalette_Color;
465
260
                        bitsPerComponent = (uint8_t) bitsPerPixel;
466
260
                    }
467
1.55k
                    break;
468
200
                case 24:
469
                    // In the case of ICO, kBGRA is actually the closest match,
470
                    // since we will need to apply a transparency mask.
471
200
                    color = inIco ? SkEncodedInfo::kBGRA_Color : SkEncodedInfo::kBGR_Color;
472
200
                    bitsPerComponent = 8;
473
200
                    break;
474
408
                case 32:
475
                    // 32-bit BMP-in-ICOs actually use the alpha channel in place of a
476
                    // transparency mask.
477
408
                    if (inIco) {
478
314
                        isOpaque = false;
479
314
                        alpha = SkEncodedInfo::kUnpremul_Alpha;
480
314
                        color = SkEncodedInfo::kBGRA_Color;
481
314
                    } else {
482
94
                        color = SkEncodedInfo::kBGRX_Color;
483
94
                    }
484
408
                    bitsPerComponent = 8;
485
408
                    break;
486
350
                default:
487
350
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
488
350
                    return kInvalidInput;
489
2.51k
            }
490
491
2.16k
            if (codecOut) {
492
                // We require streams to have a memory base for Bmp-in-Ico decodes.
493
2.08k
                SkASSERT(!inIco || nullptr != stream->getMemoryBase());
494
495
                // Set the image info and create a codec.
496
2.08k
                auto info = SkEncodedInfo::Make(width, height, color, alpha, bitsPerComponent);
497
2.08k
                *codecOut = std::make_unique<SkBmpStandardCodec>(std::move(info),
498
2.08k
                                                       std::unique_ptr<SkStream>(stream),
499
2.08k
                                                       bitsPerPixel, numColors, bytesPerColor,
500
2.08k
                                                       offset - bytesRead, rowOrder, isOpaque,
501
2.08k
                                                       inIco);
502
2.08k
                return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
503
2.08k
                        ? kSuccess : kInvalidInput;
504
2.08k
            }
505
81
            return kSuccess;
506
2.16k
        }
507
508
2.82k
        case kBitMask_BmpInputFormat: {
509
            // Bmp-in-Ico must be standard mode
510
2.82k
            if (inIco) {
511
1.04k
                SkCodecPrintf("Error: Icos may not use bit mask format.\n");
512
1.04k
                return kInvalidInput;
513
1.04k
            }
514
515
1.78k
            switch (bitsPerPixel) {
516
259
                case 16:
517
553
                case 24:
518
1.75k
                case 32:
519
1.75k
                    break;
520
25
                default:
521
25
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
522
25
                    return kInvalidInput;
523
1.78k
            }
524
525
            // Skip to the start of the pixel array.
526
            // We can do this here because there is no color table to read
527
            // in bit mask mode.
528
1.75k
            if (stream->skip(offset - bytesRead) != offset - bytesRead) {
529
97
                SkCodecPrintf("Error: unable to skip to image data.\n");
530
97
                return kIncompleteInput;
531
97
            }
532
533
1.66k
            if (codecOut) {
534
                // Check that input bit masks are valid and create the masks object
535
1.66k
                SkASSERT(bitsPerPixel % 8 == 0);
536
1.66k
                std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel/8));
537
1.66k
                if (nullptr == masks) {
538
122
                    SkCodecPrintf("Error: invalid input masks.\n");
539
122
                    return kInvalidInput;
540
122
                }
541
542
                // Masked bmps are not a great fit for SkEncodedInfo, since they have
543
                // arbitrary component orderings and bits per component.  Here we choose
544
                // somewhat reasonable values - it's ok that we don't match exactly
545
                // because SkBmpMaskCodec has its own mask swizzler anyway.
546
1.54k
                SkEncodedInfo::Color color;
547
1.54k
                SkEncodedInfo::Alpha alpha;
548
1.54k
                if (masks->getAlphaMask()) {
549
441
                    color = SkEncodedInfo::kBGRA_Color;
550
441
                    alpha = SkEncodedInfo::kUnpremul_Alpha;
551
1.09k
                } else {
552
1.09k
                    color = SkEncodedInfo::kBGR_Color;
553
1.09k
                    alpha = SkEncodedInfo::kOpaque_Alpha;
554
1.09k
                }
555
1.54k
                auto info = SkEncodedInfo::Make(width, height, color, alpha, 8);
556
1.54k
                *codecOut = std::make_unique<SkBmpMaskCodec>(std::move(info),
557
1.54k
                                                   std::unique_ptr<SkStream>(stream), bitsPerPixel,
558
1.54k
                                                   masks.release(), rowOrder);
559
1.54k
                return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
560
1.54k
                        ? kSuccess : kInvalidInput;
561
1.66k
            }
562
0
            return kSuccess;
563
1.66k
        }
564
565
1.72k
        case kRLE_BmpInputFormat: {
566
            // We should not reach this point without a valid value of bitsPerPixel.
567
1.72k
            SkASSERT(4 == bitsPerPixel || 8 == bitsPerPixel || 24 == bitsPerPixel);
568
569
            // Check for a valid number of total bytes when in RLE mode
570
1.72k
            if (totalBytes <= offset) {
571
618
                SkCodecPrintf("Error: RLE requires valid input size.\n");
572
618
                return kInvalidInput;
573
618
            }
574
575
            // Bmp-in-Ico must be standard mode
576
            // When inIco is true, this line cannot be reached, since we
577
            // require that RLE Bmps have a valid number of totalBytes, and
578
            // Icos skip the header that contains totalBytes.
579
1.10k
            SkASSERT(!inIco);
580
581
1.10k
            if (codecOut) {
582
                // RLE inputs may skip pixels, leaving them as transparent.  This
583
                // is uncommon, but we cannot be certain that an RLE bmp will be
584
                // opaque or that we will be able to represent it with a palette.
585
                // For that reason, we always indicate that we are kBGRA.
586
1.10k
                auto info = SkEncodedInfo::Make(width, height, SkEncodedInfo::kBGRA_Color,
587
1.10k
                                                SkEncodedInfo::kBinary_Alpha, 8);
588
1.10k
                *codecOut = std::make_unique<SkBmpRLECodec>(std::move(info),
589
1.10k
                                                  std::unique_ptr<SkStream>(stream), bitsPerPixel,
590
1.10k
                                                  numColors, bytesPerColor, offset - bytesRead,
591
1.10k
                                                  rowOrder);
592
1.10k
            }
593
1.10k
            return kSuccess;
594
1.72k
        }
595
0
        default:
596
0
            SkASSERT(false);
597
0
            return kInvalidInput;
598
7.06k
    }
599
7.06k
}
Unexecuted instantiation: SkBmpCodec::ReadHeader(SkStream*, bool, std::__1::unique_ptr<SkCodec, std::__1::default_delete<SkCodec> >*)
600
601
/*
602
 * Creates a bmp decoder
603
 * Reads enough of the stream to determine the image format
604
 */
605
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
606
17.5k
                                                    Result* result, bool inIco) {
607
17.5k
    SkASSERT(result);
608
17.5k
    if (!stream) {
609
0
        *result = SkCodec::kInvalidInput;
610
0
        return nullptr;
611
0
    }
612
17.5k
    std::unique_ptr<SkCodec> codec;
613
17.5k
    *result = ReadHeader(stream.get(), inIco, &codec);
614
17.5k
    if (codec) {
615
        // codec has taken ownership of stream, so we do not need to delete it.
616
4.72k
        stream.release();
617
4.72k
    }
618
17.5k
    return kSuccess == *result ? std::move(codec) : nullptr;
619
17.5k
}
SkBmpCodec::MakeFromStream(std::__1::unique_ptr<SkStream, std::__1::default_delete<SkStream> >, SkCodec::Result*, bool)
Line
Count
Source
606
17.5k
                                                    Result* result, bool inIco) {
607
17.5k
    SkASSERT(result);
608
17.5k
    if (!stream) {
609
0
        *result = SkCodec::kInvalidInput;
610
0
        return nullptr;
611
0
    }
612
17.5k
    std::unique_ptr<SkCodec> codec;
613
17.5k
    *result = ReadHeader(stream.get(), inIco, &codec);
614
17.5k
    if (codec) {
615
        // codec has taken ownership of stream, so we do not need to delete it.
616
4.72k
        stream.release();
617
4.72k
    }
618
17.5k
    return kSuccess == *result ? std::move(codec) : nullptr;
619
17.5k
}
Unexecuted instantiation: SkBmpCodec::MakeFromStream(std::__1::unique_ptr<SkStream, std::__1::default_delete<SkStream> >, SkCodec::Result*, bool)
620
621
SkBmpCodec::SkBmpCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
622
        uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder)
623
    : INHERITED(std::move(info), kXformSrcColorFormat, std::move(stream))
624
    , fBitsPerPixel(bitsPerPixel)
625
    , fRowOrder(rowOrder)
626
    , fSrcRowBytes(SkAlign4(compute_row_bytes(this->dimensions().width(), fBitsPerPixel)))
627
    , fXformBuffer(nullptr)
628
4.72k
{}
629
630
86
bool SkBmpCodec::onRewind() {
631
86
    return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr) == kSuccess;
632
86
}
633
634
443k
int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
635
443k
    if (SkCodec::kTopDown_SkScanlineOrder == fRowOrder) {
636
160k
        return y;
637
160k
    }
638
282k
    SkASSERT(SkCodec::kBottomUp_SkScanlineOrder == fRowOrder);
639
282k
    return height - y - 1;
640
443k
}
641
642
SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
643
2.73k
        const SkCodec::Options& options) {
644
2.73k
    return this->onPrepareToDecode(dstInfo, options);
645
2.73k
}
646
647
SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
648
790
        const SkCodec::Options& options) {
649
790
    return prepareToDecode(dstInfo, options);
650
790
}
651
652
5.13k
int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
653
    // Create a new image info representing the portion of the image to decode
654
5.13k
    SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
655
656
    // Decode the requested rows
657
5.13k
    return this->decodeRows(rowInfo, dst, rowBytes, this->options());
658
5.13k
}
659
660
3.91k
bool SkBmpCodec::skipRows(int count) {
661
3.91k
    const size_t bytesToSkip = count * fSrcRowBytes;
662
3.91k
    return this->stream()->skip(bytesToSkip) == bytesToSkip;
663
3.91k
}
664
665
15.9k
bool SkBmpCodec::onSkipScanlines(int count) {
666
15.9k
    return this->skipRows(count);
667
15.9k
}
668
669
namespace SkBmpDecoder {
670
40.2k
bool IsBmp(const void* data, size_t len) {
671
40.2k
    return SkBmpCodec::IsBmp(data, len);
672
40.2k
}
673
674
std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream> stream,
675
                                SkCodec::Result* outResult,
676
4.58k
                                SkCodecs::DecodeContext) {
677
4.58k
    SkCodec::Result resultStorage;
678
4.58k
    if (!outResult) {
679
0
        outResult = &resultStorage;
680
0
    }
681
4.58k
    return SkBmpCodec::MakeFromStream(std::move(stream), outResult);
682
4.58k
}
683
684
std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
685
                                SkCodec::Result* outResult,
686
0
                                SkCodecs::DecodeContext) {
687
0
    if (!data) {
688
0
        if (outResult) {
689
0
            *outResult = SkCodec::kInvalidInput;
690
0
        }
691
0
        return nullptr;
692
0
    }
693
0
    return Decode(SkMemoryStream::Make(std::move(data)), outResult, nullptr);
694
0
}
695
}  // namespace SkBmpDecoder