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 "SkCodec_libbmp.h"
9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h"
11 #include "SkStream.h"
12 
13 /*
14  *
15  * Checks if the conversion between the input image and the requested output
16  * image has been implemented
17  *
18  */
conversion_possible(const SkImageInfo & dst,const SkImageInfo & src)19 static bool conversion_possible(const SkImageInfo& dst,
20                                 const SkImageInfo& src) {
21     // Ensure that the profile type is unchanged
22     if (dst.profileType() != src.profileType()) {
23         return false;
24     }
25 
26     // Check for supported alpha types
27     if (src.alphaType() != dst.alphaType()) {
28         if (kOpaque_SkAlphaType == src.alphaType()) {
29             // If the source is opaque, we must decode to opaque
30             return false;
31         }
32 
33         // The source is not opaque
34         switch (dst.alphaType()) {
35             case kPremul_SkAlphaType:
36             case kUnpremul_SkAlphaType:
37                 // The source is not opaque, so either of these is okay
38                 break;
39             default:
40                 // We cannot decode a non-opaque image to opaque (or unknown)
41                 return false;
42         }
43     }
44 
45     // Check for supported color types
46     switch (dst.colorType()) {
47         // Allow output to kN32 from any type of input
48         case kN32_SkColorType:
49             return true;
50         // Allow output to kIndex_8 from compatible inputs
51         case kIndex_8_SkColorType:
52             return kIndex_8_SkColorType == src.colorType();
53         default:
54             return false;
55     }
56 }
57 
58 /*
59  *
60  * Defines the version and type of the second bitmap header
61  *
62  */
63 enum BitmapHeaderType {
64     kInfoV1_BitmapHeaderType,
65     kInfoV2_BitmapHeaderType,
66     kInfoV3_BitmapHeaderType,
67     kInfoV4_BitmapHeaderType,
68     kInfoV5_BitmapHeaderType,
69     kOS2V1_BitmapHeaderType,
70     kOS2VX_BitmapHeaderType,
71     kUnknown_BitmapHeaderType
72 };
73 
74 /*
75  *
76  * Possible bitmap compression types
77  *
78  */
79 enum BitmapCompressionMethod {
80     kNone_BitmapCompressionMethod =          0,
81     k8BitRLE_BitmapCompressionMethod =       1,
82     k4BitRLE_BitmapCompressionMethod =       2,
83     kBitMasks_BitmapCompressionMethod =      3,
84     kJpeg_BitmapCompressionMethod =          4,
85     kPng_BitmapCompressionMethod =           5,
86     kAlphaBitMasks_BitmapCompressionMethod = 6,
87     kCMYK_BitmapCompressionMethod =          11,
88     kCMYK8BitRLE_BitmapCompressionMethod =   12,
89     kCMYK4BitRLE_BitmapCompressionMethod =   13
90 };
91 
92 /*
93  *
94  * Checks the start of the stream to see if the image is a bitmap
95  *
96  */
IsBmp(SkStream * stream)97 bool SkBmpCodec::IsBmp(SkStream* stream) {
98     // TODO: Support "IC", "PT", "CI", "CP", "BA"
99     const char bmpSig[] = { 'B', 'M' };
100     char buffer[sizeof(bmpSig)];
101     return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
102             !memcmp(buffer, bmpSig, sizeof(bmpSig));
103 }
104 
105 /*
106  *
107  * Assumes IsBmp was called and returned true
108  * Creates a bmp decoder
109  * Reads enough of the stream to determine the image format
110  *
111  */
NewFromStream(SkStream * stream)112 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
113     return SkBmpCodec::NewFromStream(stream, false);
114 }
115 
116 /*
117  *
118  * Creates a bmp decoder for a bmp embedded in ico
119  * Reads enough of the stream to determine the image format
120  *
121  */
NewFromIco(SkStream * stream)122 SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
123     return SkBmpCodec::NewFromStream(stream, true);
124 }
125 
126 /*
127  *
128  * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
129  * representing success or failure. If it returned true, and codecOut was
130  * not NULL, it will be set to a new SkBmpCodec.
131  * Does *not* take ownership of the passed in SkStream.
132  *
133  */
ReadHeader(SkStream * stream,bool isIco,SkCodec ** codecOut)134 bool SkBmpCodec::ReadHeader(SkStream* stream, bool isIco, SkCodec** codecOut) {
135     // Header size constants
136     static const uint32_t kBmpHeaderBytes = 14;
137     static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
138     static const uint32_t kBmpOS2V1Bytes = 12;
139     static const uint32_t kBmpOS2V2Bytes = 64;
140     static const uint32_t kBmpInfoBaseBytes = 16;
141     static const uint32_t kBmpInfoV1Bytes = 40;
142     static const uint32_t kBmpInfoV2Bytes = 52;
143     static const uint32_t kBmpInfoV3Bytes = 56;
144     static const uint32_t kBmpInfoV4Bytes = 108;
145     static const uint32_t kBmpInfoV5Bytes = 124;
146     static const uint32_t kBmpMaskBytes = 12;
147 
148     // The total bytes in the bmp file
149     // We only need to use this value for RLE decoding, so we will only
150     // check that it is valid in the RLE case.
151     uint32_t totalBytes;
152     // The offset from the start of the file where the pixel data begins
153     uint32_t offset;
154     // The size of the second (info) header in bytes
155     uint32_t infoBytes;
156 
157     // Bmps embedded in Icos skip the first Bmp header
158     if (!isIco) {
159         // Read the first header and the size of the second header
160         SkAutoTDeleteArray<uint8_t> hBuffer(
161                 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
162         if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
163                 kBmpHeaderBytesPlusFour) {
164             SkCodecPrintf("Error: unable to read first bitmap header.\n");
165             return false;
166         }
167 
168         totalBytes = get_int(hBuffer.get(), 2);
169         offset = get_int(hBuffer.get(), 10);
170         if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
171             SkCodecPrintf("Error: invalid starting location for pixel data\n");
172             return false;
173         }
174 
175         // The size of the second (info) header in bytes
176         // The size is the first field of the second header, so we have already
177         // read the first four infoBytes.
178         infoBytes = get_int(hBuffer.get(), 14);
179         if (infoBytes < kBmpOS2V1Bytes) {
180             SkCodecPrintf("Error: invalid second header size.\n");
181             return false;
182         }
183     } else {
184         // This value is only used by RLE compression.  Bmp in Ico files do not
185         // use RLE.  If the compression field is incorrectly signaled as RLE,
186         // we will catch this and signal an error below.
187         totalBytes = 0;
188 
189         // Bmps in Ico cannot specify an offset.  We will always assume that
190         // pixel data begins immediately after the color table.  This value
191         // will be corrected below.
192         offset = 0;
193 
194         // Read the size of the second header
195         SkAutoTDeleteArray<uint8_t> hBuffer(
196                 SkNEW_ARRAY(uint8_t, 4));
197         if (stream->read(hBuffer.get(), 4) != 4) {
198             SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
199             return false;
200         }
201         infoBytes = get_int(hBuffer.get(), 0);
202         if (infoBytes < kBmpOS2V1Bytes) {
203             SkCodecPrintf("Error: invalid second header size.\n");
204             return false;
205         }
206     }
207 
208     // We already read the first four bytes of the info header to get the size
209     const uint32_t infoBytesRemaining = infoBytes - 4;
210 
211     // Read the second header
212     SkAutoTDeleteArray<uint8_t> iBuffer(
213             SkNEW_ARRAY(uint8_t, infoBytesRemaining));
214     if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
215         SkCodecPrintf("Error: unable to read second bitmap header.\n");
216         return false;
217     }
218 
219     // The number of bits used per pixel in the pixel data
220     uint16_t bitsPerPixel;
221 
222     // The compression method for the pixel data
223     uint32_t compression = kNone_BitmapCompressionMethod;
224 
225     // Number of colors in the color table, defaults to 0 or max (see below)
226     uint32_t numColors = 0;
227 
228     // Bytes per color in the color table, early versions use 3, most use 4
229     uint32_t bytesPerColor;
230 
231     // The image width and height
232     int width, height;
233 
234     // Determine image information depending on second header format
235     BitmapHeaderType headerType;
236     if (infoBytes >= kBmpInfoBaseBytes) {
237         // Check the version of the header
238         switch (infoBytes) {
239             case kBmpInfoV1Bytes:
240                 headerType = kInfoV1_BitmapHeaderType;
241                 break;
242             case kBmpInfoV2Bytes:
243                 headerType = kInfoV2_BitmapHeaderType;
244                 break;
245             case kBmpInfoV3Bytes:
246                 headerType = kInfoV3_BitmapHeaderType;
247                 break;
248             case kBmpInfoV4Bytes:
249                 headerType = kInfoV4_BitmapHeaderType;
250                 break;
251             case kBmpInfoV5Bytes:
252                 headerType = kInfoV5_BitmapHeaderType;
253                 break;
254             case 16:
255             case 20:
256             case 24:
257             case 28:
258             case 32:
259             case 36:
260             case 42:
261             case 46:
262             case 48:
263             case 60:
264             case kBmpOS2V2Bytes:
265                 headerType = kOS2VX_BitmapHeaderType;
266                 break;
267             default:
268                 // We do not signal an error here because there is the
269                 // possibility of new or undocumented bmp header types.  Most
270                 // of the newer versions of bmp headers are similar to and
271                 // build off of the older versions, so we may still be able to
272                 // decode the bmp.
273                 SkCodecPrintf("Warning: unknown bmp header format.\n");
274                 headerType = kUnknown_BitmapHeaderType;
275                 break;
276         }
277         // We check the size of the header before entering the if statement.
278         // We should not reach this point unless the size is large enough for
279         // these required fields.
280         SkASSERT(infoBytesRemaining >= 12);
281         width = get_int(iBuffer.get(), 0);
282         height = get_int(iBuffer.get(), 4);
283         bitsPerPixel = get_short(iBuffer.get(), 10);
284 
285         // Some versions do not have these fields, so we check before
286         // overwriting the default value.
287         if (infoBytesRemaining >= 16) {
288             compression = get_int(iBuffer.get(), 12);
289             if (infoBytesRemaining >= 32) {
290                 numColors = get_int(iBuffer.get(), 28);
291             }
292         }
293 
294         // All of the headers that reach this point, store color table entries
295         // using 4 bytes per pixel.
296         bytesPerColor = 4;
297     } else if (infoBytes >= kBmpOS2V1Bytes) {
298         // The OS2V1 is treated separately because it has a unique format
299         headerType = kOS2V1_BitmapHeaderType;
300         width = (int) get_short(iBuffer.get(), 0);
301         height = (int) get_short(iBuffer.get(), 2);
302         bitsPerPixel = get_short(iBuffer.get(), 6);
303         bytesPerColor = 3;
304     } else {
305         // There are no valid bmp headers
306         SkCodecPrintf("Error: second bitmap header size is invalid.\n");
307         return false;
308     }
309 
310     // Check for valid dimensions from header
311     RowOrder rowOrder = kBottomUp_RowOrder;
312     if (height < 0) {
313         height = -height;
314         rowOrder = kTopDown_RowOrder;
315     }
316     // The height field for bmp in ico is double the actual height because they
317     // contain an XOR mask followed by an AND mask
318     if (isIco) {
319         height /= 2;
320     }
321     if (width <= 0 || height <= 0) {
322         // TODO: Decide if we want to disable really large bmps as well.
323         // https://code.google.com/p/skia/issues/detail?id=3617
324         SkCodecPrintf("Error: invalid bitmap dimensions.\n");
325         return false;
326     }
327 
328     // Create mask struct
329     SkMasks::InputMasks inputMasks;
330     memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));
331 
332     // Determine the input compression format and set bit masks if necessary
333     uint32_t maskBytes = 0;
334     BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat;
335     switch (compression) {
336         case kNone_BitmapCompressionMethod:
337             inputFormat = kStandard_BitmapInputFormat;
338             break;
339         case k8BitRLE_BitmapCompressionMethod:
340             if (bitsPerPixel != 8) {
341                 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
342                 bitsPerPixel = 8;
343             }
344             inputFormat = kRLE_BitmapInputFormat;
345             break;
346         case k4BitRLE_BitmapCompressionMethod:
347             if (bitsPerPixel != 4) {
348                 SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
349                 bitsPerPixel = 4;
350             }
351             inputFormat = kRLE_BitmapInputFormat;
352             break;
353         case kAlphaBitMasks_BitmapCompressionMethod:
354         case kBitMasks_BitmapCompressionMethod:
355             // Load the masks
356             inputFormat = kBitMask_BitmapInputFormat;
357             switch (headerType) {
358                 case kInfoV1_BitmapHeaderType: {
359                     // The V1 header stores the bit masks after the header
360                     SkAutoTDeleteArray<uint8_t> mBuffer(
361                             SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
362                     if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
363                             kBmpMaskBytes) {
364                         SkCodecPrintf("Error: unable to read bit inputMasks.\n");
365                         return false;
366                     }
367                     maskBytes = kBmpMaskBytes;
368                     inputMasks.red = get_int(mBuffer.get(), 0);
369                     inputMasks.green = get_int(mBuffer.get(), 4);
370                     inputMasks.blue = get_int(mBuffer.get(), 8);
371                     break;
372                 }
373                 case kInfoV2_BitmapHeaderType:
374                 case kInfoV3_BitmapHeaderType:
375                 case kInfoV4_BitmapHeaderType:
376                 case kInfoV5_BitmapHeaderType:
377                     // Header types are matched based on size.  If the header
378                     // is V2+, we are guaranteed to be able to read at least
379                     // this size.
380                     SkASSERT(infoBytesRemaining >= 48);
381                     inputMasks.red = get_int(iBuffer.get(), 36);
382                     inputMasks.green = get_int(iBuffer.get(), 40);
383                     inputMasks.blue = get_int(iBuffer.get(), 44);
384                     break;
385                 case kOS2VX_BitmapHeaderType:
386                     // TODO: Decide if we intend to support this.
387                     //       It is unsupported in the previous version and
388                     //       in chromium.  I have not come across a test case
389                     //       that uses this format.
390                     SkCodecPrintf("Error: huffman format unsupported.\n");
391                     return false;
392                 default:
393                    SkCodecPrintf("Error: invalid bmp bit masks header.\n");
394                    return false;
395             }
396             break;
397         case kJpeg_BitmapCompressionMethod:
398             if (24 == bitsPerPixel) {
399                 inputFormat = kRLE_BitmapInputFormat;
400                 break;
401             }
402             // Fall through
403         case kPng_BitmapCompressionMethod:
404             // TODO: Decide if we intend to support this.
405             //       It is unsupported in the previous version and
406             //       in chromium.  I think it is used mostly for printers.
407             SkCodecPrintf("Error: compression format not supported.\n");
408             return false;
409         case kCMYK_BitmapCompressionMethod:
410         case kCMYK8BitRLE_BitmapCompressionMethod:
411         case kCMYK4BitRLE_BitmapCompressionMethod:
412             // TODO: Same as above.
413             SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
414             return false;
415         default:
416             SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
417             return false;
418     }
419 
420     // Most versions of bmps should be rendered as opaque.  Either they do
421     // not have an alpha channel, or they expect the alpha channel to be
422     // ignored.  V3+ bmp files introduce an alpha mask and allow the creator
423     // of the image to use the alpha channels.  However, many of these images
424     // leave the alpha channel blank and expect to be rendered as opaque.  This
425     // is the case for almost all V3 images, so we render these as opaque.  For
426     // V4+, we will use the alpha channel, and fix the image later if it turns
427     // out to be fully transparent.
428     // As an exception, V3 bmp-in-ico may use an alpha mask.
429     SkAlphaType alphaType = kOpaque_SkAlphaType;
430     if ((kInfoV3_BitmapHeaderType == headerType && isIco) ||
431             kInfoV4_BitmapHeaderType == headerType ||
432             kInfoV5_BitmapHeaderType == headerType) {
433         // Header types are matched based on size.  If the header is
434         // V3+, we are guaranteed to be able to read at least this size.
435         SkASSERT(infoBytesRemaining > 52);
436         inputMasks.alpha = get_int(iBuffer.get(), 48);
437         if (inputMasks.alpha != 0) {
438             alphaType = kUnpremul_SkAlphaType;
439         }
440     }
441     iBuffer.free();
442 
443     // Additionally, 32 bit bmp-in-icos use the alpha channel.
444     // And, RLE inputs may skip pixels, leaving them as transparent.  This
445     // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
446     if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat)) {
447         alphaType = kUnpremul_SkAlphaType;
448     }
449 
450     // Check for valid bits per pixel.
451     // At the same time, use this information to choose a suggested color type
452     // and to set default masks.
453     SkColorType colorType = kN32_SkColorType;
454     switch (bitsPerPixel) {
455         // In addition to more standard pixel compression formats, bmp supports
456         // the use of bit masks to determine pixel components.  The standard
457         // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
458         // which does not map well to any Skia color formats.  For this reason,
459         // we will always enable mask mode with 16 bits per pixel.
460         case 16:
461             if (kBitMask_BitmapInputFormat != inputFormat) {
462                 inputMasks.red = 0x7C00;
463                 inputMasks.green = 0x03E0;
464                 inputMasks.blue = 0x001F;
465                 inputFormat = kBitMask_BitmapInputFormat;
466             }
467             break;
468         // We want to decode to kIndex_8 for input formats that are already
469         // designed in index format.
470         case 1:
471         case 2:
472         case 4:
473         case 8:
474             // However, we cannot in RLE format since we may need to leave some
475             // pixels as transparent.  Similarly, we also cannot for ICO images
476             // since we may need to apply a transparent mask.
477             if (kRLE_BitmapInputFormat != inputFormat && !isIco) {
478                 colorType = kIndex_8_SkColorType;
479             }
480         case 24:
481         case 32:
482             break;
483         default:
484             SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
485             return false;
486     }
487 
488     // Check that input bit masks are valid and create the masks object
489     SkAutoTDelete<SkMasks>
490             masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
491     if (NULL == masks) {
492         SkCodecPrintf("Error: invalid input masks.\n");
493         return false;
494     }
495 
496     // Check for a valid number of total bytes when in RLE mode
497     if (totalBytes <= offset && kRLE_BitmapInputFormat == inputFormat) {
498         SkCodecPrintf("Error: RLE requires valid input size.\n");
499         return false;
500     }
501     const size_t RLEBytes = totalBytes - offset;
502 
503     // Calculate the number of bytes read so far
504     const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
505     if (!isIco && offset < bytesRead) {
506         SkCodecPrintf("Error: pixel data offset less than header size.\n");
507         return false;
508     }
509 
510     if (codecOut) {
511         // Return the codec
512         // We will use ImageInfo to store width, height, suggested color type, and
513         // suggested alpha type.
514         const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
515                 colorType, alphaType);
516         *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
517                                             inputFormat, masks.detach(),
518                                             numColors, bytesPerColor,
519                                             offset - bytesRead, rowOrder,
520                                             RLEBytes, isIco));
521     }
522     return true;
523 }
524 
525 /*
526  *
527  * Creates a bmp decoder
528  * Reads enough of the stream to determine the image format
529  *
530  */
NewFromStream(SkStream * stream,bool isIco)531 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
532     SkAutoTDelete<SkStream> streamDeleter(stream);
533     SkCodec* codec = NULL;
534     if (ReadHeader(stream, isIco, &codec)) {
535         // codec has taken ownership of stream, so we do not need to
536         // delete it.
537         SkASSERT(codec);
538         streamDeleter.detach();
539         return codec;
540     }
541     return NULL;
542 }
543 
544 /*
545  *
546  * Creates an instance of the decoder
547  * Called only by NewFromStream
548  *
549  */
SkBmpCodec(const SkImageInfo & info,SkStream * stream,uint16_t bitsPerPixel,BitmapInputFormat inputFormat,SkMasks * masks,uint32_t numColors,uint32_t bytesPerColor,uint32_t offset,RowOrder rowOrder,size_t RLEBytes,bool isIco)550 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
551                        uint16_t bitsPerPixel, BitmapInputFormat inputFormat,
552                        SkMasks* masks, uint32_t numColors,
553                        uint32_t bytesPerColor, uint32_t offset,
554                        RowOrder rowOrder, size_t RLEBytes, bool isIco)
555     : INHERITED(info, stream)
556     , fBitsPerPixel(bitsPerPixel)
557     , fInputFormat(inputFormat)
558     , fMasks(masks)
559     , fColorTable(NULL)
560     , fNumColors(numColors)
561     , fBytesPerColor(bytesPerColor)
562     , fOffset(offset)
563     , fRowOrder(rowOrder)
564     , fRLEBytes(RLEBytes)
565     , fIsIco(isIco)
566 
567 {}
568 
569 /*
570  *
571  * Initiates the bitmap decode
572  *
573  */
onGetPixels(const SkImageInfo & dstInfo,void * dst,size_t dstRowBytes,const Options & opts,SkPMColor * inputColorPtr,int * inputColorCount)574 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
575                                         void* dst, size_t dstRowBytes,
576                                         const Options& opts,
577                                         SkPMColor* inputColorPtr,
578                                         int* inputColorCount) {
579     // Check for proper input and output formats
580     SkCodec::RewindState rewindState = this->rewindIfNeeded();
581     if (rewindState == kCouldNotRewind_RewindState) {
582         return kCouldNotRewind;
583     } else if (rewindState == kRewound_RewindState) {
584         if (!ReadHeader(this->stream(), fIsIco, NULL)) {
585             return kCouldNotRewind;
586         }
587     }
588     if (dstInfo.dimensions() != this->getInfo().dimensions()) {
589         SkCodecPrintf("Error: scaling not supported.\n");
590         return kInvalidScale;
591     }
592     if (!conversion_possible(dstInfo, this->getInfo())) {
593         SkCodecPrintf("Error: cannot convert input type to output type.\n");
594         return kInvalidConversion;
595     }
596 
597     // Create the color table if necessary and prepare the stream for decode
598     // Note that if it is non-NULL, inputColorCount will be modified
599     if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
600         SkCodecPrintf("Error: could not create color table.\n");
601         return kInvalidInput;
602     }
603 
604     // Copy the color table to the client if necessary
605     copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount);
606 
607     // Perform the decode
608     switch (fInputFormat) {
609         case kBitMask_BitmapInputFormat:
610             return decodeMask(dstInfo, dst, dstRowBytes, opts);
611         case kRLE_BitmapInputFormat:
612             return decodeRLE(dstInfo, dst, dstRowBytes, opts);
613         case kStandard_BitmapInputFormat:
614             return decode(dstInfo, dst, dstRowBytes, opts);
615         default:
616             SkASSERT(false);
617             return kInvalidInput;
618     }
619 }
620 
621 /*
622  *
623  * Process the color table for the bmp input
624  *
625  */
createColorTable(SkAlphaType alphaType,int * numColors)626  bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
627     // Allocate memory for color table
628     uint32_t colorBytes = 0;
629     uint32_t maxColors = 0;
630     SkPMColor colorTable[256];
631     if (fBitsPerPixel <= 8) {
632         // Zero is a default for maxColors
633         // Also set fNumColors to maxColors when it is too large
634         maxColors = 1 << fBitsPerPixel;
635         if (fNumColors == 0 || fNumColors >= maxColors) {
636             fNumColors = maxColors;
637         }
638 
639         // Inform the caller of the number of colors
640         if (NULL != numColors) {
641             // We set the number of colors to maxColors in order to ensure
642             // safe memory accesses.  Otherwise, an invalid pixel could
643             // access memory outside of our color table array.
644             *numColors = maxColors;
645         }
646 
647         // Read the color table from the stream
648         colorBytes = fNumColors * fBytesPerColor;
649         SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
650         if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
651             SkCodecPrintf("Error: unable to read color table.\n");
652             return false;
653         }
654 
655         // Choose the proper packing function
656         SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
657         switch (alphaType) {
658             case kOpaque_SkAlphaType:
659             case kUnpremul_SkAlphaType:
660                 packARGB = &SkPackARGB32NoCheck;
661                 break;
662             case kPremul_SkAlphaType:
663                 packARGB = &SkPreMultiplyARGB;
664                 break;
665             default:
666                 // This should not be reached because conversion possible
667                 // should fail if the alpha type is not one of the above
668                 // values.
669                 SkASSERT(false);
670                 packARGB = NULL;
671                 break;
672         }
673 
674         // Fill in the color table
675         uint32_t i = 0;
676         for (; i < fNumColors; i++) {
677             uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
678             uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
679             uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
680             uint8_t alpha;
681             if (kOpaque_SkAlphaType == alphaType || kRLE_BitmapInputFormat == fInputFormat) {
682                 alpha = 0xFF;
683             } else {
684                 alpha = (fMasks->getAlphaMask() >> 24) &
685                         get_byte(cBuffer.get(), i*fBytesPerColor + 3);
686             }
687             colorTable[i] = packARGB(alpha, red, green, blue);
688         }
689 
690         // To avoid segmentation faults on bad pixel data, fill the end of the
691         // color table with black.  This is the same the behavior as the
692         // chromium decoder.
693         for (; i < maxColors; i++) {
694             colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0);
695         }
696 
697         // Set the color table
698         fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors)));
699     }
700 
701     // Bmp-in-Ico files do not use an offset to indicate where the pixel data
702     // begins.  Pixel data always begins immediately after the color table.
703     if (!fIsIco) {
704         // Check that we have not read past the pixel array offset
705         if(fOffset < colorBytes) {
706             // This may occur on OS 2.1 and other old versions where the color
707             // table defaults to max size, and the bmp tries to use a smaller
708             // color table.  This is invalid, and our decision is to indicate
709             // an error, rather than try to guess the intended size of the
710             // color table.
711             SkCodecPrintf("Error: pixel data offset less than color table size.\n");
712             return false;
713         }
714 
715         // After reading the color table, skip to the start of the pixel array
716         if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
717             SkCodecPrintf("Error: unable to skip to image data.\n");
718             return false;
719         }
720     }
721 
722     // Return true on success
723     return true;
724 }
725 
726 /*
727  *
728  * Get the destination row to start filling from
729  * Used to fill the remainder of the image on incomplete input
730  *
731  */
get_dst_start_row(void * dst,size_t dstRowBytes,int32_t y,SkBmpCodec::RowOrder rowOrder)732 static inline void* get_dst_start_row(void* dst, size_t dstRowBytes, int32_t y,
733             SkBmpCodec::RowOrder rowOrder) {
734     return (SkBmpCodec::kTopDown_RowOrder == rowOrder) ?
735             SkTAddOffset<void*>(dst, y * dstRowBytes) : dst;
736 }
737 
738 /*
739  *
740  * Performs the bitmap decoding for bit masks input format
741  *
742  */
decodeMask(const SkImageInfo & dstInfo,void * dst,size_t dstRowBytes,const Options & opts)743 SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo,
744                                        void* dst, size_t dstRowBytes,
745                                        const Options& opts) {
746     // Set constant values
747     const int width = dstInfo.width();
748     const int height = dstInfo.height();
749     const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
750 
751     // Allocate a buffer large enough to hold the full image
752     SkAutoTDeleteArray<uint8_t>
753         srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes));
754     uint8_t* srcRow = srcBuffer.get();
755 
756     // Create the swizzler
757     SkAutoTDelete<SkMaskSwizzler> maskSwizzler(
758             SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes,
759             fMasks, fBitsPerPixel));
760 
761     // Iterate over rows of the image
762     bool transparent = true;
763     for (int y = 0; y < height; y++) {
764         // Read a row of the input
765         if (stream()->read(srcRow, rowBytes) != rowBytes) {
766             SkCodecPrintf("Warning: incomplete input stream.\n");
767             // Fill the destination image on failure
768             SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ?
769                     SK_ColorBLACK : SK_ColorTRANSPARENT;
770             if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) {
771                 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
772                 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, fillColor,
773                         NULL);
774             }
775             return kIncompleteInput;
776         }
777 
778         // Decode the row in destination format
779         int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
780         SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row);
781         transparent &= SkSwizzler::IsTransparent(r);
782 
783         // Move to the next row
784         srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
785     }
786 
787     // Some fully transparent bmp images are intended to be opaque.  Here, we
788     // correct for this possibility.
789     if (transparent) {
790         const SkImageInfo& opaqueInfo =
791                 dstInfo.makeAlphaType(kOpaque_SkAlphaType);
792         SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler(
793                 SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, dst, dstRowBytes,
794                                                    fMasks, fBitsPerPixel));
795         srcRow = srcBuffer.get();
796         for (int y = 0; y < height; y++) {
797             // Decode the row in opaque format
798             int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
799             opaqueSwizzler->next(srcRow, row);
800 
801             // Move to the next row
802             srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
803         }
804     }
805 
806     // Finished decoding the entire image
807     return kSuccess;
808 }
809 
810 /*
811  *
812  * Set an RLE pixel using the color table
813  *
814  */
setRLEPixel(void * dst,size_t dstRowBytes,const SkImageInfo & dstInfo,uint32_t x,uint32_t y,uint8_t index)815 void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
816                              const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
817                              uint8_t index) {
818     // Set the row
819     int height = dstInfo.height();
820     int row;
821     if (kBottomUp_RowOrder == fRowOrder) {
822         row = height - y - 1;
823     } else {
824         row = y;
825     }
826 
827     // Set the pixel based on destination color type
828     switch (dstInfo.colorType()) {
829         case kN32_SkColorType: {
830             SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
831                     row * (int) dstRowBytes);
832             dstRow[x] = fColorTable->operator[](index);
833             break;
834         }
835         default:
836             // This case should not be reached.  We should catch an invalid
837             // color type when we check that the conversion is possible.
838             SkASSERT(false);
839             break;
840     }
841 }
842 
843 /*
844  *
845  * Set an RLE pixel from R, G, B values
846  *
847  */
setRLE24Pixel(void * dst,size_t dstRowBytes,const SkImageInfo & dstInfo,uint32_t x,uint32_t y,uint8_t red,uint8_t green,uint8_t blue)848 void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
849                                const SkImageInfo& dstInfo, uint32_t x,
850                                uint32_t y, uint8_t red, uint8_t green,
851                                uint8_t blue) {
852     // Set the row
853     int height = dstInfo.height();
854     int row;
855     if (kBottomUp_RowOrder == fRowOrder) {
856         row = height - y - 1;
857     } else {
858         row = y;
859     }
860 
861     // Set the pixel based on destination color type
862     switch (dstInfo.colorType()) {
863         case kN32_SkColorType: {
864             SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
865                     row * (int) dstRowBytes);
866             dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
867             break;
868         }
869         default:
870             // This case should not be reached.  We should catch an invalid
871             // color type when we check that the conversion is possible.
872             SkASSERT(false);
873             break;
874     }
875 }
876 
877 /*
878  *
879  * Performs the bitmap decoding for RLE input format
880  * RLE decoding is performed all at once, rather than a one row at a time
881  *
882  */
decodeRLE(const SkImageInfo & dstInfo,void * dst,size_t dstRowBytes,const Options & opts)883 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
884                                       void* dst, size_t dstRowBytes,
885                                       const Options& opts) {
886     // Set RLE flags
887     static const uint8_t RLE_ESCAPE = 0;
888     static const uint8_t RLE_EOL = 0;
889     static const uint8_t RLE_EOF = 1;
890     static const uint8_t RLE_DELTA = 2;
891 
892     // Set constant values
893     const int width = dstInfo.width();
894     const int height = dstInfo.height();
895 
896     // Input buffer parameters
897     uint32_t currByte = 0;
898     SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
899     size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
900     if (totalBytes < fRLEBytes) {
901         SkCodecPrintf("Warning: incomplete RLE file.\n");
902     } else if (totalBytes <= 0) {
903         SkCodecPrintf("Error: could not read RLE image data.\n");
904         return kInvalidInput;
905     }
906 
907     // Destination parameters
908     int x = 0;
909     int y = 0;
910 
911     // Set the background as transparent.  Then, if the RLE code skips pixels,
912     // the skipped pixels will be transparent.
913     // Because of the need for transparent pixels, kN32 is the only color
914     // type that makes sense for the destination format.
915     SkASSERT(kN32_SkColorType == dstInfo.colorType());
916     if (kNo_ZeroInitialized == opts.fZeroInitialized) {
917         SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL);
918     }
919 
920     while (true) {
921         // Every entry takes at least two bytes
922         if ((int) totalBytes - currByte < 2) {
923             SkCodecPrintf("Warning: incomplete RLE input.\n");
924             return kIncompleteInput;
925         }
926 
927         // Read the next two bytes.  These bytes have different meanings
928         // depending on their values.  In the first interpretation, the first
929         // byte is an escape flag and the second byte indicates what special
930         // task to perform.
931         const uint8_t flag = buffer.get()[currByte++];
932         const uint8_t task = buffer.get()[currByte++];
933 
934         // If we have reached a row that is beyond the image size, and the RLE
935         // code does not indicate end of file, abort and signal a warning.
936         if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
937             SkCodecPrintf("Warning: invalid RLE input.\n");
938             return kIncompleteInput;
939         }
940 
941         // Perform decoding
942         if (RLE_ESCAPE == flag) {
943             switch (task) {
944                 case RLE_EOL:
945                     x = 0;
946                     y++;
947                     break;
948                 case RLE_EOF:
949                     return kSuccess;
950                 case RLE_DELTA: {
951                     // Two bytes are needed to specify delta
952                     if ((int) totalBytes - currByte < 2) {
953                         SkCodecPrintf("Warning: incomplete RLE input\n");
954                         return kIncompleteInput;
955                     }
956                     // Modify x and y
957                     const uint8_t dx = buffer.get()[currByte++];
958                     const uint8_t dy = buffer.get()[currByte++];
959                     x += dx;
960                     y += dy;
961                     if (x > width || y > height) {
962                         SkCodecPrintf("Warning: invalid RLE input.\n");
963                         return kIncompleteInput;
964                     }
965                     break;
966                 }
967                 default: {
968                     // If task does not match any of the above signals, it
969                     // indicates that we have a sequence of non-RLE pixels.
970                     // Furthermore, the value of task is equal to the number
971                     // of pixels to interpret.
972                     uint8_t numPixels = task;
973                     const size_t rowBytes = compute_row_bytes(numPixels,
974                             fBitsPerPixel);
975                     // Abort if setting numPixels moves us off the edge of the
976                     // image.  Also abort if there are not enough bytes
977                     // remaining in the stream to set numPixels.
978                     if (x + numPixels > width ||
979                             (int) totalBytes - currByte < SkAlign2(rowBytes)) {
980                         SkCodecPrintf("Warning: invalid RLE input.\n");
981                         return kIncompleteInput;
982                     }
983                     // Set numPixels number of pixels
984                     while (numPixels > 0) {
985                         switch(fBitsPerPixel) {
986                             case 4: {
987                                 SkASSERT(currByte < totalBytes);
988                                 uint8_t val = buffer.get()[currByte++];
989                                 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
990                                         y, val >> 4);
991                                 numPixels--;
992                                 if (numPixels != 0) {
993                                     setRLEPixel(dst, dstRowBytes, dstInfo,
994                                             x++, y, val & 0xF);
995                                     numPixels--;
996                                 }
997                                 break;
998                             }
999                             case 8:
1000                                 SkASSERT(currByte < totalBytes);
1001                                 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
1002                                         y, buffer.get()[currByte++]);
1003                                 numPixels--;
1004                                 break;
1005                             case 24: {
1006                                 SkASSERT(currByte + 2 < totalBytes);
1007                                 uint8_t blue = buffer.get()[currByte++];
1008                                 uint8_t green = buffer.get()[currByte++];
1009                                 uint8_t red = buffer.get()[currByte++];
1010                                 setRLE24Pixel(dst, dstRowBytes, dstInfo,
1011                                             x++, y, red, green, blue);
1012                                 numPixels--;
1013                             }
1014                             default:
1015                                 SkASSERT(false);
1016                                 return kInvalidInput;
1017                         }
1018                     }
1019                     // Skip a byte if necessary to maintain alignment
1020                     if (!SkIsAlign2(rowBytes)) {
1021                         currByte++;
1022                     }
1023                     break;
1024                 }
1025             }
1026         } else {
1027             // If the first byte read is not a flag, it indicates the number of
1028             // pixels to set in RLE mode.
1029             const uint8_t numPixels = flag;
1030             const int endX = SkTMin<int>(x + numPixels, width);
1031 
1032             if (24 == fBitsPerPixel) {
1033                 // In RLE24, the second byte read is part of the pixel color.
1034                 // There are two more required bytes to finish encoding the
1035                 // color.
1036                 if ((int) totalBytes - currByte < 2) {
1037                     SkCodecPrintf("Warning: incomplete RLE input\n");
1038                     return kIncompleteInput;
1039                 }
1040 
1041                 // Fill the pixels up to endX with the specified color
1042                 uint8_t blue = task;
1043                 uint8_t green = buffer.get()[currByte++];
1044                 uint8_t red = buffer.get()[currByte++];
1045                 while (x < endX) {
1046                     setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
1047                             green, blue);
1048                 }
1049             } else {
1050                 // In RLE8 or RLE4, the second byte read gives the index in the
1051                 // color table to look up the pixel color.
1052                 // RLE8 has one color index that gets repeated
1053                 // RLE4 has two color indexes in the upper and lower 4 bits of
1054                 // the bytes, which are alternated
1055                 uint8_t indices[2] = { task, task };
1056                 if (4 == fBitsPerPixel) {
1057                     indices[0] >>= 4;
1058                     indices[1] &= 0xf;
1059                 }
1060 
1061                 // Set the indicated number of pixels
1062                 for (int which = 0; x < endX; x++) {
1063                     setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
1064                             indices[which]);
1065                     which = !which;
1066                 }
1067             }
1068         }
1069     }
1070 }
1071 
1072 /*
1073  *
1074  * Performs the bitmap decoding for standard input format
1075  *
1076  */
decode(const SkImageInfo & dstInfo,void * dst,size_t dstRowBytes,const Options & opts)1077 SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
1078                                    void* dst, size_t dstRowBytes,
1079                                    const Options& opts) {
1080     // Set constant values
1081     const int width = dstInfo.width();
1082     const int height = dstInfo.height();
1083     const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));
1084 
1085     // Get swizzler configuration and choose the fill value for failures.  We will use
1086     // zero as the default palette index, black for opaque images, and transparent for
1087     // non-opaque images.
1088     SkSwizzler::SrcConfig config;
1089     uint32_t fillColorOrIndex;
1090     bool zeroFill = true;
1091     switch (fBitsPerPixel) {
1092         case 1:
1093             config = SkSwizzler::kIndex1;
1094             fillColorOrIndex = 0;
1095             break;
1096         case 2:
1097             config = SkSwizzler::kIndex2;
1098             fillColorOrIndex = 0;
1099             break;
1100         case 4:
1101             config = SkSwizzler::kIndex4;
1102             fillColorOrIndex = 0;
1103             break;
1104         case 8:
1105             config = SkSwizzler::kIndex;
1106             fillColorOrIndex = 0;
1107             break;
1108         case 24:
1109             config = SkSwizzler::kBGR;
1110             fillColorOrIndex = SK_ColorBLACK;
1111             zeroFill = false;
1112             break;
1113         case 32:
1114             if (kOpaque_SkAlphaType == dstInfo.alphaType()) {
1115                 config = SkSwizzler::kBGRX;
1116                 fillColorOrIndex = SK_ColorBLACK;
1117                 zeroFill = false;
1118             } else {
1119                 config = SkSwizzler::kBGRA;
1120                 fillColorOrIndex = SK_ColorTRANSPARENT;
1121             }
1122             break;
1123         default:
1124             SkASSERT(false);
1125             return kInvalidInput;
1126     }
1127 
1128     // Get a pointer to the color table if it exists
1129     const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readColors() : NULL;
1130 
1131     // Create swizzler
1132     SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config,
1133             colorPtr, dstInfo, dst, dstRowBytes,
1134             SkImageGenerator::kNo_ZeroInitialized));
1135 
1136     // Allocate space for a row buffer and a source for the swizzler
1137     SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
1138 
1139     // Iterate over rows of the image
1140     // FIXME: bool transparent = true;
1141     for (int y = 0; y < height; y++) {
1142         // Read a row of the input
1143         if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1144             SkCodecPrintf("Warning: incomplete input stream.\n");
1145             // Fill the destination image on failure
1146             if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) {
1147                 void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
1148                 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y,
1149                         fillColorOrIndex, colorPtr);
1150             }
1151             return kIncompleteInput;
1152         }
1153 
1154         // Decode the row in destination format
1155         uint32_t row;
1156         if (kTopDown_RowOrder == fRowOrder) {
1157             row = y;
1158         } else {
1159             row = height - 1 - y;
1160         }
1161 
1162         swizzler->next(srcBuffer.get(), row);
1163         // FIXME: SkSwizzler::ResultAlpha r =
1164         //        swizzler->next(srcBuffer.get(), row);
1165         // FIXME: transparent &= SkSwizzler::IsTransparent(r);
1166     }
1167 
1168     // FIXME: This code exists to match the behavior in the chromium decoder
1169     // and to follow the bmp specification as it relates to alpha masks.  It is
1170     // commented out because we have yet to discover a test image that provides
1171     // an alpha mask and uses this decode mode.
1172 
1173     // Now we adjust the output image with some additional behavior that
1174     // SkSwizzler does not support.  Firstly, all bmp images that contain
1175     // alpha are masked by the alpha mask.  Secondly, many fully transparent
1176     // bmp images are intended to be opaque.  Here, we make those corrections
1177     // in the kN32 case.
1178     /*
1179     SkPMColor* dstRow = (SkPMColor*) dst;
1180     if (SkSwizzler::kBGRA == config) {
1181         for (int y = 0; y < height; y++) {
1182             for (int x = 0; x < width; x++) {
1183                 if (transparent) {
1184                     dstRow[x] |= 0xFF000000;
1185                 } else {
1186                     dstRow[x] &= alphaMask;
1187                 }
1188                 dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
1189             }
1190         }
1191     }
1192     */
1193 
1194     // Finally, apply the AND mask for bmp-in-ico images
1195     if (fIsIco) {
1196         // The AND mask is always 1 bit per pixel
1197         const size_t rowBytes = SkAlign4(compute_row_bytes(width, 1));
1198 
1199         SkPMColor* dstPtr = (SkPMColor*) dst;
1200         for (int y = 0; y < height; y++) {
1201             // The srcBuffer will at least be large enough
1202             if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
1203                 SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n");
1204                 return kIncompleteInput;
1205             }
1206 
1207             int row;
1208             if (kBottomUp_RowOrder == fRowOrder) {
1209                 row = height - y - 1;
1210             } else {
1211                 row = y;
1212             }
1213 
1214             SkPMColor* dstRow =
1215                     SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);
1216 
1217             for (int x = 0; x < width; x++) {
1218                 int quotient;
1219                 int modulus;
1220                 SkTDivMod(x, 8, &quotient, &modulus);
1221                 uint32_t shift = 7 - modulus;
1222                 uint32_t alphaBit =
1223                         (srcBuffer.get()[quotient] >> shift) & 0x1;
1224                 dstRow[x] &= alphaBit - 1;
1225             }
1226         }
1227     }
1228 
1229     // Finished decoding the entire image
1230     return kSuccess;
1231 }
1232