xref: /aosp_15_r20/external/skia/src/codec/SkBmpCodec.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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  */
IsBmp(const void * buffer,size_t bytesRead)71 bool SkBmpCodec::IsBmp(const void* buffer, size_t bytesRead) {
72     // TODO: Support "IC", "PT", "CI", "CP", "BA"
73     const char bmpSig[] = { 'B', 'M' };
74     return bytesRead >= sizeof(bmpSig) && !memcmp(buffer, bmpSig, sizeof(bmpSig));
75 }
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  */
MakeFromStream(std::unique_ptr<SkStream> stream,Result * result)82 std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
83                                                     Result* result) {
84     return SkBmpCodec::MakeFromStream(std::move(stream), result, false);
85 }
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  */
MakeFromIco(std::unique_ptr<SkStream> stream,Result * result)91 std::unique_ptr<SkCodec> SkBmpCodec::MakeFromIco(std::unique_ptr<SkStream> stream, Result* result) {
92     return SkBmpCodec::MakeFromStream(std::move(stream), result, true);
93 }
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 
get_header_type(size_t infoBytes)108 static BmpHeaderType get_header_type(size_t infoBytes) {
109     if (infoBytes >= kBmpInfoBaseBytes) {
110         // Check the version of the header
111         switch (infoBytes) {
112             case kBmpInfoV1Bytes:
113                 return kInfoV1_BmpHeaderType;
114             case kBmpInfoV2Bytes:
115                 return kInfoV2_BmpHeaderType;
116             case kBmpInfoV3Bytes:
117                 return kInfoV3_BmpHeaderType;
118             case kBmpInfoV4Bytes:
119                 return kInfoV4_BmpHeaderType;
120             case kBmpInfoV5Bytes:
121                 return kInfoV5_BmpHeaderType;
122             case 16:
123             case 20:
124             case 24:
125             case 28:
126             case 32:
127             case 36:
128             case 42:
129             case 46:
130             case 48:
131             case 60:
132             case kBmpOS2V2Bytes:
133                 return kOS2VX_BmpHeaderType;
134             default:
135                 SkCodecPrintf("Error: unknown bmp header format.\n");
136                 return kUnknown_BmpHeaderType;
137         }
138     } if (infoBytes >= kBmpOS2V1Bytes) {
139         // The OS2V1 is treated separately because it has a unique format
140         return kOS2V1_BmpHeaderType;
141     } else {
142         // There are no valid bmp headers
143         SkCodecPrintf("Error: second bitmap header size is invalid.\n");
144         return kUnknown_BmpHeaderType;
145     }
146 }
147 
ReadHeader(SkStream * stream,bool inIco,std::unique_ptr<SkCodec> * codecOut)148 SkCodec::Result SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
149         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     uint32_t totalBytes;
154     // The offset from the start of the file where the pixel data begins
155     uint32_t offset;
156     // The size of the second (info) header in bytes
157     uint32_t infoBytes;
158 
159     // Bmps embedded in Icos skip the first Bmp header
160     if (!inIco) {
161         // Read the first header and the size of the second header
162         uint8_t hBuffer[kBmpHeaderBytesPlusFour];
163         if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
164                 kBmpHeaderBytesPlusFour) {
165             SkCodecPrintf("Error: unable to read first bitmap header.\n");
166             return kIncompleteInput;
167         }
168 
169         totalBytes = get_int(hBuffer, 2);
170         offset = get_int(hBuffer, 10);
171         if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
172             SkCodecPrintf("Error: invalid starting location for pixel data\n");
173             return kInvalidInput;
174         }
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         infoBytes = get_int(hBuffer, 14);
180         if (infoBytes < kBmpOS2V1Bytes) {
181             SkCodecPrintf("Error: invalid second header size.\n");
182             return kInvalidInput;
183         }
184     } 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         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         offset = 0;
194 
195         // Read the size of the second header
196         uint8_t hBuffer[4];
197         if (stream->read(hBuffer, 4) != 4) {
198             SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
199             return kIncompleteInput;
200         }
201         infoBytes = get_int(hBuffer, 0);
202         if (infoBytes < kBmpOS2V1Bytes) {
203             SkCodecPrintf("Error: invalid second header size.\n");
204             return kInvalidInput;
205         }
206     }
207 
208     // Determine image information depending on second header format
209     const BmpHeaderType headerType = get_header_type(infoBytes);
210     if (kUnknown_BmpHeaderType == headerType) {
211         return kInvalidInput;
212     }
213 
214     // We already read the first four bytes of the info header to get the size
215     const uint32_t infoBytesRemaining = infoBytes - 4;
216 
217     // Read the second header
218     std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
219     if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
220         SkCodecPrintf("Error: unable to read second bitmap header.\n");
221         return kIncompleteInput;
222     }
223 
224     // The number of bits used per pixel in the pixel data
225     uint16_t bitsPerPixel;
226 
227     // The compression method for the pixel data
228     uint32_t compression = kNone_BmpCompressionMethod;
229 
230     // Number of colors in the color table, defaults to 0 or max (see below)
231     uint32_t numColors = 0;
232 
233     // Bytes per color in the color table, early versions use 3, most use 4
234     uint32_t bytesPerColor;
235 
236     // The image width and height
237     int width, height;
238 
239     switch (headerType) {
240         case kInfoV1_BmpHeaderType:
241         case kInfoV2_BmpHeaderType:
242         case kInfoV3_BmpHeaderType:
243         case kInfoV4_BmpHeaderType:
244         case kInfoV5_BmpHeaderType:
245         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             SkASSERT(infoBytesRemaining >= 12);
250             width = get_int(iBuffer.get(), 0);
251             height = get_int(iBuffer.get(), 4);
252             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             if (infoBytesRemaining >= 16) {
257                 compression = get_int(iBuffer.get(), 12);
258                 if (infoBytesRemaining >= 32) {
259                     numColors = get_int(iBuffer.get(), 28);
260                 }
261             }
262 
263             // All of the headers that reach this point, store color table entries
264             // using 4 bytes per pixel.
265             bytesPerColor = 4;
266             break;
267         case kOS2V1_BmpHeaderType:
268             // The OS2V1 is treated separately because it has a unique format
269             width = (int) get_short(iBuffer.get(), 0);
270             height = (int) get_short(iBuffer.get(), 2);
271             bitsPerPixel = get_short(iBuffer.get(), 6);
272             bytesPerColor = 3;
273             break;
274         case kUnknown_BmpHeaderType:
275             // We'll exit above in this case.
276             SkASSERT(false);
277             return kInvalidInput;
278     }
279 
280     // Check for valid dimensions from header
281     SkCodec::SkScanlineOrder rowOrder = SkCodec::kBottomUp_SkScanlineOrder;
282     if (height < 0) {
283         // We can't negate INT32_MIN.
284         if (height == INT32_MIN) {
285             return kInvalidInput;
286         }
287 
288         height = -height;
289         rowOrder = SkCodec::kTopDown_SkScanlineOrder;
290     }
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     if (inIco) {
294         height /= 2;
295     }
296 
297     // Arbitrary maximum. Matches Chromium.
298     constexpr int kMaxDim = 1 << 16;
299     if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
300         SkCodecPrintf("Error: invalid bitmap dimensions.\n");
301         return kInvalidInput;
302     }
303 
304     // Create mask struct
305     SkMasks::InputMasks inputMasks;
306     memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
307 
308     // Determine the input compression format and set bit masks if necessary
309     uint32_t maskBytes = 0;
310     BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
311     switch (compression) {
312         case kNone_BmpCompressionMethod:
313             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             if (16 == bitsPerPixel) {
321                 inputMasks.red = 0x7C00;
322                 inputMasks.green = 0x03E0;
323                 inputMasks.blue = 0x001F;
324                 inputFormat = kBitMask_BmpInputFormat;
325             }
326             break;
327         case k8BitRLE_BmpCompressionMethod:
328             if (bitsPerPixel != 8) {
329                 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
330                 bitsPerPixel = 8;
331             }
332             inputFormat = kRLE_BmpInputFormat;
333             break;
334         case k4BitRLE_BmpCompressionMethod:
335             if (bitsPerPixel != 4) {
336                 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
337                 bitsPerPixel = 4;
338             }
339             inputFormat = kRLE_BmpInputFormat;
340             break;
341         case kAlphaBitMasks_BmpCompressionMethod:
342         case kBitMasks_BmpCompressionMethod:
343             // Load the masks
344             inputFormat = kBitMask_BmpInputFormat;
345             switch (headerType) {
346                 case kInfoV1_BmpHeaderType: {
347                     // The V1 header stores the bit masks after the header
348                     uint8_t buffer[kBmpMaskBytes];
349                     if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
350                         SkCodecPrintf("Error: unable to read bit inputMasks.\n");
351                         return kIncompleteInput;
352                     }
353                     maskBytes = kBmpMaskBytes;
354                     inputMasks.red = get_int(buffer, 0);
355                     inputMasks.green = get_int(buffer, 4);
356                     inputMasks.blue = get_int(buffer, 8);
357                     break;
358                 }
359                 case kInfoV2_BmpHeaderType:
360                 case kInfoV3_BmpHeaderType:
361                 case kInfoV4_BmpHeaderType:
362                 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                     SkASSERT(infoBytesRemaining >= 48);
367                     inputMasks.red = get_int(iBuffer.get(), 36);
368                     inputMasks.green = get_int(iBuffer.get(), 40);
369                     inputMasks.blue = get_int(iBuffer.get(), 44);
370 
371                     if (kInfoV2_BmpHeaderType == headerType ||
372                             (kInfoV3_BmpHeaderType == headerType && !inIco)) {
373                         break;
374                     }
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                     SkASSERT(infoBytesRemaining >= 52);
390                     inputMasks.alpha = get_int(iBuffer.get(), 48);
391                     break;
392                 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                     SkCodecPrintf("Error: huffman format unsupported.\n");
398                     return kUnimplemented;
399                 default:
400                    SkCodecPrintf("Error: invalid bmp bit masks header.\n");
401                    return kInvalidInput;
402             }
403             break;
404         case kJpeg_BmpCompressionMethod:
405             if (24 == bitsPerPixel) {
406                 inputFormat = kRLE_BmpInputFormat;
407                 break;
408             }
409             [[fallthrough]];
410         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             SkCodecPrintf("Error: compression format not supported.\n");
415             return kUnimplemented;
416         case kCMYK_BmpCompressionMethod:
417         case kCMYK8BitRLE_BmpCompressionMethod:
418         case kCMYK4BitRLE_BmpCompressionMethod:
419             // TODO: Same as above.
420             SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
421             return kUnimplemented;
422         default:
423             SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
424             return kInvalidInput;
425     }
426     iBuffer.reset();
427 
428     // Calculate the number of bytes read so far
429     const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
430     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         SkCodecPrintf("Error: pixel data offset less than header size.\n");
435         return kInvalidInput;
436     }
437 
438 
439 
440     switch (inputFormat) {
441         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             SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
447                     SkEncodedInfo::kOpaque_Alpha;
448             bool isOpaque = true;
449 
450             SkEncodedInfo::Color color;
451             uint8_t bitsPerComponent;
452             switch (bitsPerPixel) {
453                 // Palette formats
454                 case 1:
455                 case 2:
456                 case 4:
457                 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                     if (inIco) {
461                         color = SkEncodedInfo::kBGRA_Color;
462                         bitsPerComponent = 8;
463                     } else {
464                         color = SkEncodedInfo::kPalette_Color;
465                         bitsPerComponent = (uint8_t) bitsPerPixel;
466                     }
467                     break;
468                 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                     color = inIco ? SkEncodedInfo::kBGRA_Color : SkEncodedInfo::kBGR_Color;
472                     bitsPerComponent = 8;
473                     break;
474                 case 32:
475                     // 32-bit BMP-in-ICOs actually use the alpha channel in place of a
476                     // transparency mask.
477                     if (inIco) {
478                         isOpaque = false;
479                         alpha = SkEncodedInfo::kUnpremul_Alpha;
480                         color = SkEncodedInfo::kBGRA_Color;
481                     } else {
482                         color = SkEncodedInfo::kBGRX_Color;
483                     }
484                     bitsPerComponent = 8;
485                     break;
486                 default:
487                     SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
488                     return kInvalidInput;
489             }
490 
491             if (codecOut) {
492                 // We require streams to have a memory base for Bmp-in-Ico decodes.
493                 SkASSERT(!inIco || nullptr != stream->getMemoryBase());
494 
495                 // Set the image info and create a codec.
496                 auto info = SkEncodedInfo::Make(width, height, color, alpha, bitsPerComponent);
497                 *codecOut = std::make_unique<SkBmpStandardCodec>(std::move(info),
498                                                        std::unique_ptr<SkStream>(stream),
499                                                        bitsPerPixel, numColors, bytesPerColor,
500                                                        offset - bytesRead, rowOrder, isOpaque,
501                                                        inIco);
502                 return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
503                         ? kSuccess : kInvalidInput;
504             }
505             return kSuccess;
506         }
507 
508         case kBitMask_BmpInputFormat: {
509             // Bmp-in-Ico must be standard mode
510             if (inIco) {
511                 SkCodecPrintf("Error: Icos may not use bit mask format.\n");
512                 return kInvalidInput;
513             }
514 
515             switch (bitsPerPixel) {
516                 case 16:
517                 case 24:
518                 case 32:
519                     break;
520                 default:
521                     SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
522                     return kInvalidInput;
523             }
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             if (stream->skip(offset - bytesRead) != offset - bytesRead) {
529                 SkCodecPrintf("Error: unable to skip to image data.\n");
530                 return kIncompleteInput;
531             }
532 
533             if (codecOut) {
534                 // Check that input bit masks are valid and create the masks object
535                 SkASSERT(bitsPerPixel % 8 == 0);
536                 std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel/8));
537                 if (nullptr == masks) {
538                     SkCodecPrintf("Error: invalid input masks.\n");
539                     return kInvalidInput;
540                 }
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                 SkEncodedInfo::Color color;
547                 SkEncodedInfo::Alpha alpha;
548                 if (masks->getAlphaMask()) {
549                     color = SkEncodedInfo::kBGRA_Color;
550                     alpha = SkEncodedInfo::kUnpremul_Alpha;
551                 } else {
552                     color = SkEncodedInfo::kBGR_Color;
553                     alpha = SkEncodedInfo::kOpaque_Alpha;
554                 }
555                 auto info = SkEncodedInfo::Make(width, height, color, alpha, 8);
556                 *codecOut = std::make_unique<SkBmpMaskCodec>(std::move(info),
557                                                    std::unique_ptr<SkStream>(stream), bitsPerPixel,
558                                                    masks.release(), rowOrder);
559                 return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
560                         ? kSuccess : kInvalidInput;
561             }
562             return kSuccess;
563         }
564 
565         case kRLE_BmpInputFormat: {
566             // We should not reach this point without a valid value of bitsPerPixel.
567             SkASSERT(4 == bitsPerPixel || 8 == bitsPerPixel || 24 == bitsPerPixel);
568 
569             // Check for a valid number of total bytes when in RLE mode
570             if (totalBytes <= offset) {
571                 SkCodecPrintf("Error: RLE requires valid input size.\n");
572                 return kInvalidInput;
573             }
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             SkASSERT(!inIco);
580 
581             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                 auto info = SkEncodedInfo::Make(width, height, SkEncodedInfo::kBGRA_Color,
587                                                 SkEncodedInfo::kBinary_Alpha, 8);
588                 *codecOut = std::make_unique<SkBmpRLECodec>(std::move(info),
589                                                   std::unique_ptr<SkStream>(stream), bitsPerPixel,
590                                                   numColors, bytesPerColor, offset - bytesRead,
591                                                   rowOrder);
592             }
593             return kSuccess;
594         }
595         default:
596             SkASSERT(false);
597             return kInvalidInput;
598     }
599 }
600 
601 /*
602  * Creates a bmp decoder
603  * Reads enough of the stream to determine the image format
604  */
MakeFromStream(std::unique_ptr<SkStream> stream,Result * result,bool inIco)605 std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
606                                                     Result* result, bool inIco) {
607     SkASSERT(result);
608     if (!stream) {
609         *result = SkCodec::kInvalidInput;
610         return nullptr;
611     }
612     std::unique_ptr<SkCodec> codec;
613     *result = ReadHeader(stream.get(), inIco, &codec);
614     if (codec) {
615         // codec has taken ownership of stream, so we do not need to delete it.
616         stream.release();
617     }
618     return kSuccess == *result ? std::move(codec) : nullptr;
619 }
620 
SkBmpCodec(SkEncodedInfo && info,std::unique_ptr<SkStream> stream,uint16_t bitsPerPixel,SkCodec::SkScanlineOrder rowOrder)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 {}
629 
onRewind()630 bool SkBmpCodec::onRewind() {
631     return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr) == kSuccess;
632 }
633 
getDstRow(int32_t y,int32_t height) const634 int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
635     if (SkCodec::kTopDown_SkScanlineOrder == fRowOrder) {
636         return y;
637     }
638     SkASSERT(SkCodec::kBottomUp_SkScanlineOrder == fRowOrder);
639     return height - y - 1;
640 }
641 
prepareToDecode(const SkImageInfo & dstInfo,const SkCodec::Options & options)642 SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
643         const SkCodec::Options& options) {
644     return this->onPrepareToDecode(dstInfo, options);
645 }
646 
onStartScanlineDecode(const SkImageInfo & dstInfo,const SkCodec::Options & options)647 SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
648         const SkCodec::Options& options) {
649     return prepareToDecode(dstInfo, options);
650 }
651 
onGetScanlines(void * dst,int count,size_t rowBytes)652 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     SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
655 
656     // Decode the requested rows
657     return this->decodeRows(rowInfo, dst, rowBytes, this->options());
658 }
659 
skipRows(int count)660 bool SkBmpCodec::skipRows(int count) {
661     const size_t bytesToSkip = count * fSrcRowBytes;
662     return this->stream()->skip(bytesToSkip) == bytesToSkip;
663 }
664 
onSkipScanlines(int count)665 bool SkBmpCodec::onSkipScanlines(int count) {
666     return this->skipRows(count);
667 }
668 
669 namespace SkBmpDecoder {
IsBmp(const void * data,size_t len)670 bool IsBmp(const void* data, size_t len) {
671     return SkBmpCodec::IsBmp(data, len);
672 }
673 
Decode(std::unique_ptr<SkStream> stream,SkCodec::Result * outResult,SkCodecs::DecodeContext)674 std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream> stream,
675                                 SkCodec::Result* outResult,
676                                 SkCodecs::DecodeContext) {
677     SkCodec::Result resultStorage;
678     if (!outResult) {
679         outResult = &resultStorage;
680     }
681     return SkBmpCodec::MakeFromStream(std::move(stream), outResult);
682 }
683 
Decode(sk_sp<SkData> data,SkCodec::Result * outResult,SkCodecs::DecodeContext)684 std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
685                                 SkCodec::Result* outResult,
686                                 SkCodecs::DecodeContext) {
687     if (!data) {
688         if (outResult) {
689             *outResult = SkCodec::kInvalidInput;
690         }
691         return nullptr;
692     }
693     return Decode(SkMemoryStream::Make(std::move(data)), outResult, nullptr);
694 }
695 }  // namespace SkBmpDecoder
696