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