blob: 691dc77aa6a99f20cc676f7b3f854b8655a060f1 [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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#ifndef SkSwizzler_DEFINED
9#define SkSwizzler_DEFINED
10
scroggo95526622015-03-17 05:02:17 -070011#include "SkCodec.h"
scroggof24f2242015-03-03 08:59:20 -080012#include "SkColor.h"
13#include "SkImageInfo.h"
scroggoe7fc14b2015-10-02 13:14:46 -070014#include "SkSampler.h"
scroggof24f2242015-03-03 08:59:20 -080015
scroggoe7fc14b2015-10-02 13:14:46 -070016class SkSwizzler : public SkSampler {
scroggof24f2242015-03-03 08:59:20 -080017public:
18 /**
19 * Enum describing the config of the source data.
20 */
21 enum SrcConfig {
scroggo05245902015-03-25 11:11:52 -070022 kUnknown, // Invalid type.
msarett99f567e2015-08-05 12:58:26 -070023 kBit, // A single bit to distinguish between white and black
msarett74114382015-03-16 11:55:18 -070024 kGray,
25 kIndex1,
26 kIndex2,
27 kIndex4,
28 kIndex,
29 kRGB,
30 kBGR,
31 kRGBX,
32 kBGRX,
33 kRGBA,
34 kBGRA,
35 kRGB_565,
scroggoef27d892015-10-23 09:29:22 -070036 kCMYK,
scroggof24f2242015-03-03 08:59:20 -080037 };
38
msarett74114382015-03-16 11:55:18 -070039 /*
40 *
41 * Result code for the alpha components of a row.
42 *
43 */
44 typedef uint16_t ResultAlpha;
45 static const ResultAlpha kOpaque_ResultAlpha = 0xFFFF;
46 static const ResultAlpha kTransparent_ResultAlpha = 0x0000;
47
48 /*
49 *
50 * Checks if the result of decoding a row indicates that the row was
51 * transparent.
52 *
53 */
54 static bool IsTransparent(ResultAlpha r) {
55 return kTransparent_ResultAlpha == r;
56 }
57
58 /*
59 *
60 * Checks if the result of decoding a row indicates that the row was
61 * opaque.
62 *
63 */
64 static bool IsOpaque(ResultAlpha r) {
65 return kOpaque_ResultAlpha == r;
66 }
msarett438b2ad2015-04-09 12:43:10 -070067
msarett74114382015-03-16 11:55:18 -070068 /*
69 *
70 * Constructs the proper result code based on accumulated alpha masks
71 *
72 */
73 static ResultAlpha GetResult(uint8_t zeroAlpha, uint8_t maxAlpha);
74
75 /*
76 *
77 * Returns bits per pixel for source config
78 *
79 */
80 static int BitsPerPixel(SrcConfig sc) {
scroggof24f2242015-03-03 08:59:20 -080081 switch (sc) {
msarett99f567e2015-08-05 12:58:26 -070082 case kBit:
msarett74114382015-03-16 11:55:18 -070083 case kIndex1:
84 return 1;
85 case kIndex2:
86 return 2;
87 case kIndex4:
88 return 4;
scroggof24f2242015-03-03 08:59:20 -080089 case kGray:
90 case kIndex:
msarett74114382015-03-16 11:55:18 -070091 return 8;
92 case kRGB_565:
93 return 16;
scroggof24f2242015-03-03 08:59:20 -080094 case kRGB:
msarett74114382015-03-16 11:55:18 -070095 case kBGR:
96 return 24;
scroggof24f2242015-03-03 08:59:20 -080097 case kRGBX:
98 case kRGBA:
msarett74114382015-03-16 11:55:18 -070099 case kBGRX:
100 case kBGRA:
scroggoef27d892015-10-23 09:29:22 -0700101 case kCMYK:
msarett74114382015-03-16 11:55:18 -0700102 return 32;
scroggof24f2242015-03-03 08:59:20 -0800103 default:
msarett74114382015-03-16 11:55:18 -0700104 SkASSERT(false);
105 return 0;
scroggof24f2242015-03-03 08:59:20 -0800106 }
107 }
108
msarett74114382015-03-16 11:55:18 -0700109 /*
110 *
111 * Returns bytes per pixel for source config
112 * Raises an error if each pixel is not stored in an even number of bytes
113 *
114 */
115 static int BytesPerPixel(SrcConfig sc) {
116 SkASSERT(SkIsAlign8(BitsPerPixel(sc)));
117 return BitsPerPixel(sc) >> 3;
118 }
119
scroggof24f2242015-03-03 08:59:20 -0800120 /**
121 * Create a new SkSwizzler.
scroggo95526622015-03-17 05:02:17 -0700122 * @param SrcConfig Description of the format of the source.
scroggoe7fc14b2015-10-02 13:14:46 -0700123 * @param ctable Unowned pointer to an array of up to 256 colors for an
124 * index source.
125 * @param dstInfo Describes the destination.
msarettfdb47572015-10-13 12:50:14 -0700126 * @param options Indicates if dst is zero-initialized. The
scroggoe7fc14b2015-10-02 13:14:46 -0700127 * implementation may choose to skip writing zeroes
scroggo95526622015-03-17 05:02:17 -0700128 * if set to kYes_ZeroInitialized.
msarettfdb47572015-10-13 12:50:14 -0700129 * Contains subset information.
halcanary96fcdcc2015-08-27 07:41:13 -0700130 * @return A new SkSwizzler or nullptr on failure.
scroggof24f2242015-03-03 08:59:20 -0800131 */
scroggo95526622015-03-17 05:02:17 -0700132 static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
msarettfdb47572015-10-13 12:50:14 -0700133 const SkImageInfo& dstInfo, const SkCodec::Options&);
scroggoe7fc14b2015-10-02 13:14:46 -0700134
msarett438b2ad2015-04-09 12:43:10 -0700135 /**
msarett614aa072015-07-27 15:13:17 -0700136 * Swizzle a line. Generally this will be called height times, once
137 * for each row of source.
138 * By allowing the caller to pass in the dst pointer, we give the caller
139 * flexibility to use the swizzler even when the encoded data does not
140 * store the rows in order. This also improves usability for scaled and
141 * subset decodes.
142 * @param dst Where we write the output.
scroggof24f2242015-03-03 08:59:20 -0800143 * @param src The next row of the source data.
msarett74114382015-03-16 11:55:18 -0700144 * @return A result code describing if the row was fully opaque, fully
145 * transparent, or neither
scroggof24f2242015-03-03 08:59:20 -0800146 */
msarett614aa072015-07-27 15:13:17 -0700147 ResultAlpha swizzle(void* dst, const uint8_t* SK_RESTRICT src);
msarett3c309db2015-04-10 14:36:48 -0700148
msarette6dd0042015-10-09 11:07:34 -0700149 /**
150 * Implement fill using a custom width.
151 */
152 void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint32_t colorOrIndex,
153 SkCodec::ZeroInitialized zeroInit) override {
154 const SkImageInfo fillInfo = info.makeWH(fDstWidth, info.height());
155 SkSampler::Fill(fillInfo, dst, rowBytes, colorOrIndex, zeroInit);
156 }
157
scroggof24f2242015-03-03 08:59:20 -0800158private:
msarett74114382015-03-16 11:55:18 -0700159
scroggof24f2242015-03-03 08:59:20 -0800160 /**
161 * Method for converting raw data to Skia pixels.
162 * @param dstRow Row in which to write the resulting pixels.
163 * @param src Row of src data, in format specified by SrcConfig
emmaleer8f4ba762015-08-14 07:44:46 -0700164 * @param dstWidth Width in pixels of the destination
msarett5406d6f2015-08-31 06:55:13 -0700165 * @param bpp if bitsPerPixel % 8 == 0, deltaSrc is bytesPerPixel
166 * else, deltaSrc is bitsPerPixel
167 * @param deltaSrc bpp * sampleX
scroggof24f2242015-03-03 08:59:20 -0800168 * @param ctable Colors (used for kIndex source).
emmaleer8f4ba762015-08-14 07:44:46 -0700169 * @param offset The offset before the first pixel to sample.
170 Is in bytes or bits based on what deltaSrc is in.
scroggof24f2242015-03-03 08:59:20 -0800171 */
msarett74114382015-03-16 11:55:18 -0700172 typedef ResultAlpha (*RowProc)(void* SK_RESTRICT dstRow,
173 const uint8_t* SK_RESTRICT src,
msarett5406d6f2015-08-31 06:55:13 -0700174 int dstWidth, int bpp, int deltaSrc, int offset,
msarett74114382015-03-16 11:55:18 -0700175 const SkPMColor ctable[]);
scroggof24f2242015-03-03 08:59:20 -0800176
177 const RowProc fRowProc;
msarett74114382015-03-16 11:55:18 -0700178 const SkPMColor* fColorTable; // Unowned pointer
msarettfdb47572015-10-13 12:50:14 -0700179 const int fSrcOffset; // Offset of the src in pixels, allows for partial
180 // scanline decodes.
181 int fX0; // Start coordinate for the src, may be different than
182 // fSrcOffset if we are sampling.
msarett80803ff2015-10-16 10:54:12 -0700183 const int fSubsetWidth; // Width of the subset of the source before any sampling.
scroggoe7fc14b2015-10-02 13:14:46 -0700184 int fDstWidth; // Width of dst, which may differ with sampling.
scroggoe7fc14b2015-10-02 13:14:46 -0700185 int fSampleX; // step between X samples
msarettfdb47572015-10-13 12:50:14 -0700186 const int fBPP; // if bitsPerPixel % 8 == 0
187 // fBPP is bytesPerPixel
188 // else
189 // fBPP is bitsPerPixel
scroggof24f2242015-03-03 08:59:20 -0800190
msarett80803ff2015-10-16 10:54:12 -0700191 SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int subsetWidth, int bpp);
scroggoe7fc14b2015-10-02 13:14:46 -0700192
193 int onSetSampleX(int) override;
msarette6dd0042015-10-09 11:07:34 -0700194
scroggof24f2242015-03-03 08:59:20 -0800195};
196#endif // SkSwizzler_DEFINED