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
13void 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.
18    const size_t bytesToFill = info.computeByteSize(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 kGray_8_SkColorType:
61            // If the destination is kGray, the caller passes in an 8-bit color.
62            // We will not assert that the high bits of colorOrIndex must be zeroed.
63            // This allows us to take advantage of the fact that the low 8 bits of an
64            // SKPMColor may be a valid a grayscale color.  For example, the low 8
65            // bits of SK_ColorBLACK are identical to the grayscale representation
66            // for black.
67
68            // If memory is zero initialized, we may not need to fill
69            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == (uint8_t) colorOrIndex) {
70                return;
71            }
72
73            memset(dst, (uint8_t) colorOrIndex, bytesToFill);
74            break;
75        case kRGBA_F16_SkColorType: {
76            uint64_t color = colorOrIndex;
77            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
78                return;
79            }
80
81            uint64_t* dstRow = (uint64_t*) dst;
82            for (int row = 0; row < numRows; row++) {
83                sk_memset64((uint64_t*) dstRow, color, width);
84                dstRow = SkTAddOffset<uint64_t>(dstRow, rowBytes);
85            }
86            break;
87        }
88        default:
89            SkCodecPrintf("Error: Unsupported dst color type for fill().  Doing nothing.\n");
90            SkASSERT(false);
91            break;
92    }
93}
94