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.h"
9 #include "SkCodecPriv.h"
10 #include "SkSampler.h"
11 #include "SkUtils.h"
12 
Fill(const SkImageInfo & info,void * dst,size_t rowBytes,uint64_t colorOrIndex,SkCodec::ZeroInitialized zeroInit)13 void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes,
14         uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {
15     SkASSERT(dst != nullptr);
16 
17     // Calculate bytes to fill.  We use getSafeSize since the last row may not be padded.
18     const size_t bytesToFill = info.getSafeSize(rowBytes);
19     const int width = info.width();
20     const int numRows = info.height();
21 
22     // Use the proper memset routine to fill the remaining bytes
23     switch (info.colorType()) {
24         case kRGBA_8888_SkColorType:
25         case kBGRA_8888_SkColorType: {
26             // If memory is zero initialized, we may not need to fill
27             uint32_t color = (uint32_t) colorOrIndex;
28             if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
29                 return;
30             }
31 
32             uint32_t* dstRow = (uint32_t*) dst;
33             for (int row = 0; row < numRows; row++) {
34                 sk_memset32((uint32_t*) dstRow, color, width);
35                 dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes);
36             }
37             break;
38         }
39         case kRGB_565_SkColorType: {
40             // If the destination is k565, the caller passes in a 16-bit color.
41             // We will not assert that the high bits of colorOrIndex must be zeroed.
42             // This allows us to take advantage of the fact that the low 16 bits of an
43             // SKPMColor may be a valid a 565 color.  For example, the low 16
44             // bits of SK_ColorBLACK are identical to the 565 representation
45             // for black.
46 
47             // If memory is zero initialized, we may not need to fill
48             uint16_t color = (uint16_t) colorOrIndex;
49             if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
50                 return;
51             }
52 
53             uint16_t* dstRow = (uint16_t*) dst;
54             for (int row = 0; row < numRows; row++) {
55                 sk_memset16((uint16_t*) dstRow, color, width);
56                 dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes);
57             }
58             break;
59         }
60         case kIndex_8_SkColorType:
61             // On an index destination color type, always assume the input is an index.
62             // Fall through
63         case kGray_8_SkColorType:
64             // If the destination is kGray, the caller passes in an 8-bit color.
65             // We will not assert that the high bits of colorOrIndex must be zeroed.
66             // This allows us to take advantage of the fact that the low 8 bits of an
67             // SKPMColor may be a valid a grayscale color.  For example, the low 8
68             // bits of SK_ColorBLACK are identical to the grayscale representation
69             // for black.
70 
71             // If memory is zero initialized, we may not need to fill
72             if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == (uint8_t) colorOrIndex) {
73                 return;
74             }
75 
76             memset(dst, (uint8_t) colorOrIndex, bytesToFill);
77             break;
78         case kRGBA_F16_SkColorType: {
79             uint64_t color = colorOrIndex;
80             if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
81                 return;
82             }
83 
84             uint64_t* dstRow = (uint64_t*) dst;
85             for (int row = 0; row < numRows; row++) {
86                 sk_memset64((uint64_t*) dstRow, color, width);
87                 dstRow = SkTAddOffset<uint64_t>(dstRow, rowBytes);
88             }
89             break;
90         }
91         default:
92             SkCodecPrintf("Error: Unsupported dst color type for fill().  Doing nothing.\n");
93             SkASSERT(false);
94             break;
95     }
96 }
97