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