blob: 244aa3b873385a99ac8258302ddc1f865b7ee8ea [file] [log] [blame]
msarette6dd0042015-10-09 11:07:34 -07001/*
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
13void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes,
msarettf7eb6fc2016-09-13 09:04:11 -070014 uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {
msarette6dd0042015-10-09 11:07:34 -070015 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()) {
msarett34e0ec42016-04-22 16:27:24 -070024 case kRGBA_8888_SkColorType:
25 case kBGRA_8888_SkColorType: {
msarette6dd0042015-10-09 11:07:34 -070026 // If memory is zero initialized, we may not need to fill
msarettf7eb6fc2016-09-13 09:04:11 -070027 uint32_t color = (uint32_t) colorOrIndex;
msarette6dd0042015-10-09 11:07:34 -070028 if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
29 return;
30 }
31
msarettf7eb6fc2016-09-13 09:04:11 -070032 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);
msarette6dd0042015-10-09 11:07:34 -070036 }
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
msarettf7eb6fc2016-09-13 09:04:11 -070053 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);
msarette6dd0042015-10-09 11:07:34 -070057 }
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;
msarettf7eb6fc2016-09-13 09:04:11 -070078 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 }
msarette6dd0042015-10-09 11:07:34 -070091 default:
92 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n");
93 SkASSERT(false);
94 break;
95 }
96}