SkSampler.cpp revision 2880df2609eba09b555ca37be04b6ad89290c765
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        uint32_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 kN32_SkColorType: {
25            // If memory is zero initialized, we may not need to fill
26            uint32_t color = colorOrIndex;
27            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
28                return;
29            }
30
31            // We must fill row by row in the case of unaligned row bytes
32            if (SkIsAlign4((size_t) dst) && SkIsAlign4(rowBytes)) {
33                sk_memset32((uint32_t*) dst, color,
34                        (uint32_t) bytesToFill / sizeof(SkPMColor));
35            } else {
36                // We must fill row by row in the case of unaligned row bytes.  This is an
37                // unlikely, slow case.
38                SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
39                uint32_t* dstRow = (uint32_t*) dst;
40                for (int row = 0; row < numRows; row++) {
41                    for (int col = 0; col < width; col++) {
42                        dstRow[col] = color;
43                    }
44                    dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes);
45                }
46            }
47            break;
48        }
49        case kRGB_565_SkColorType: {
50            // If the destination is k565, the caller passes in a 16-bit color.
51            // We will not assert that the high bits of colorOrIndex must be zeroed.
52            // This allows us to take advantage of the fact that the low 16 bits of an
53            // SKPMColor may be a valid a 565 color.  For example, the low 16
54            // bits of SK_ColorBLACK are identical to the 565 representation
55            // for black.
56
57            // If memory is zero initialized, we may not need to fill
58            uint16_t color = (uint16_t) colorOrIndex;
59            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
60                return;
61            }
62
63            if (SkIsAlign2((size_t) dst) && SkIsAlign2(rowBytes)) {
64                sk_memset16((uint16_t*) dst, color, (uint32_t) bytesToFill / sizeof(uint16_t));
65            } else {
66                // We must fill row by row in the case of unaligned row bytes.  This is an
67                // unlikely, slow case.
68                SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
69                uint16_t* dstRow = (uint16_t*) dst;
70                for (int row = 0; row < numRows; row++) {
71                    for (int col = 0; col < width; col++) {
72                        dstRow[col] = color;
73                    }
74                    dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes);
75                }
76            }
77            break;
78        }
79        case kIndex_8_SkColorType:
80            // On an index destination color type, always assume the input is an index.
81            // Fall through
82        case kGray_8_SkColorType:
83            // If the destination is kGray, the caller passes in an 8-bit color.
84            // We will not assert that the high bits of colorOrIndex must be zeroed.
85            // This allows us to take advantage of the fact that the low 8 bits of an
86            // SKPMColor may be a valid a grayscale color.  For example, the low 8
87            // bits of SK_ColorBLACK are identical to the grayscale representation
88            // for black.
89
90            // If memory is zero initialized, we may not need to fill
91            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == (uint8_t) colorOrIndex) {
92                return;
93            }
94
95            memset(dst, (uint8_t) colorOrIndex, bytesToFill);
96            break;
97        default:
98            SkCodecPrintf("Error: Unsupported dst color type for fill().  Doing nothing.\n");
99            SkASSERT(false);
100            break;
101    }
102}
103