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