blob: b7132ce6d5b38b68e1a5b9832083108d9669948e [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"
14
15class SkSwizzler : public SkNoncopyable {
16public:
17 /**
18 * Enum describing the config of the source data.
19 */
20 enum SrcConfig {
scroggo05245902015-03-25 11:11:52 -070021 kUnknown, // Invalid type.
msarett99f567e2015-08-05 12:58:26 -070022 kBit, // A single bit to distinguish between white and black
msarett74114382015-03-16 11:55:18 -070023 kGray,
24 kIndex1,
25 kIndex2,
26 kIndex4,
27 kIndex,
28 kRGB,
29 kBGR,
30 kRGBX,
31 kBGRX,
32 kRGBA,
33 kBGRA,
34 kRGB_565,
scroggof24f2242015-03-03 08:59:20 -080035 };
36
msarett74114382015-03-16 11:55:18 -070037 /*
38 *
39 * Result code for the alpha components of a row.
40 *
41 */
42 typedef uint16_t ResultAlpha;
43 static const ResultAlpha kOpaque_ResultAlpha = 0xFFFF;
44 static const ResultAlpha kTransparent_ResultAlpha = 0x0000;
45
46 /*
47 *
48 * Checks if the result of decoding a row indicates that the row was
49 * transparent.
50 *
51 */
52 static bool IsTransparent(ResultAlpha r) {
53 return kTransparent_ResultAlpha == r;
54 }
55
56 /*
57 *
58 * Checks if the result of decoding a row indicates that the row was
59 * opaque.
60 *
61 */
62 static bool IsOpaque(ResultAlpha r) {
63 return kOpaque_ResultAlpha == r;
64 }
msarett438b2ad2015-04-09 12:43:10 -070065
msarett74114382015-03-16 11:55:18 -070066 /*
67 *
68 * Constructs the proper result code based on accumulated alpha masks
69 *
70 */
71 static ResultAlpha GetResult(uint8_t zeroAlpha, uint8_t maxAlpha);
72
73 /*
74 *
75 * Returns bits per pixel for source config
76 *
77 */
78 static int BitsPerPixel(SrcConfig sc) {
scroggof24f2242015-03-03 08:59:20 -080079 switch (sc) {
msarett99f567e2015-08-05 12:58:26 -070080 case kBit:
msarett74114382015-03-16 11:55:18 -070081 case kIndex1:
82 return 1;
83 case kIndex2:
84 return 2;
85 case kIndex4:
86 return 4;
scroggof24f2242015-03-03 08:59:20 -080087 case kGray:
88 case kIndex:
msarett74114382015-03-16 11:55:18 -070089 return 8;
90 case kRGB_565:
91 return 16;
scroggof24f2242015-03-03 08:59:20 -080092 case kRGB:
msarett74114382015-03-16 11:55:18 -070093 case kBGR:
94 return 24;
scroggof24f2242015-03-03 08:59:20 -080095 case kRGBX:
96 case kRGBA:
msarett74114382015-03-16 11:55:18 -070097 case kBGRX:
98 case kBGRA:
99 return 32;
scroggof24f2242015-03-03 08:59:20 -0800100 default:
msarett74114382015-03-16 11:55:18 -0700101 SkASSERT(false);
102 return 0;
scroggof24f2242015-03-03 08:59:20 -0800103 }
104 }
105
msarett74114382015-03-16 11:55:18 -0700106 /*
107 *
108 * Returns bytes per pixel for source config
109 * Raises an error if each pixel is not stored in an even number of bytes
110 *
111 */
112 static int BytesPerPixel(SrcConfig sc) {
113 SkASSERT(SkIsAlign8(BitsPerPixel(sc)));
114 return BitsPerPixel(sc) >> 3;
115 }
116
scroggof24f2242015-03-03 08:59:20 -0800117 /**
118 * Create a new SkSwizzler.
scroggo95526622015-03-17 05:02:17 -0700119 * @param SrcConfig Description of the format of the source.
emmaleer8f4ba762015-08-14 07:44:46 -0700120 * @param dstInfo describes the destination.
scroggo95526622015-03-17 05:02:17 -0700121 * @param ZeroInitialized Whether dst is zero-initialized. The
122 implementation may choose to skip writing zeroes
123 * if set to kYes_ZeroInitialized.
emmaleer8f4ba762015-08-14 07:44:46 -0700124 * @param srcInfo is the info of the source. Used to calculate the width samplesize.
125 * Width sampling is supported by the swizzler, by skipping pixels when
126 swizzling the row. Height sampling is not supported by the swizzler,
127 but is implemented in SkScaledCodec.
128 Sampling in Y can be done by a client with a scanline decoder,
129 but sampling in X allows the swizzler to skip swizzling pixels and
130 reading from and writing to memory.
scroggof24f2242015-03-03 08:59:20 -0800131 * @return A new SkSwizzler or NULL on failure.
132 */
scroggo95526622015-03-17 05:02:17 -0700133 static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
emmaleer8f4ba762015-08-14 07:44:46 -0700134 const SkImageInfo& dstInfo, SkCodec::ZeroInitialized,
135 const SkImageInfo& srcInfo);
msarett438b2ad2015-04-09 12:43:10 -0700136 /**
137 * Fill the remainder of the destination with a single color
138 *
msarett3c309db2015-04-10 14:36:48 -0700139 * @param dstStartRow
140 * The destination row to fill from.
141 *
142 * @param numRows
143 * The number of rows to fill.
msarett438b2ad2015-04-09 12:43:10 -0700144 *
145 * @param colorOrIndex
146 * @param colorTable
147 * If dstInfo.colorType() is kIndex8, colorOrIndex is assumed to be a uint8_t
148 * index, and colorTable is ignored. Each 8-bit pixel will be set to (uint8_t)
149 * index.
150 *
151 * If dstInfo.colorType() is kN32, colorOrIndex is treated differently depending on
152 * whether colorTable is NULL:
153 *
154 * A NULL colorTable means colorOrIndex is treated as an SkPMColor (premul or
155 * unpremul, depending on dstInfo.alphaType()). Each 4-byte pixel will be set to
156 * colorOrIndex.
157
158 * A non-NULL colorTable means colorOrIndex is treated as a uint8_t index into
159 * the colorTable. i.e. each 4-byte pixel will be set to
160 * colorTable[(uint8_t) colorOrIndex].
161 *
msarette16b04a2015-04-15 07:32:19 -0700162 * If dstInfo.colorType() is kGray, colorOrIndex is always treated as an 8-bit color.
163 *
msarett438b2ad2015-04-09 12:43:10 -0700164 * Other SkColorTypes are not supported.
165 *
166 */
msarett3c309db2015-04-10 14:36:48 -0700167 static void Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstRowBytes,
168 uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable);
msarett438b2ad2015-04-09 12:43:10 -0700169
scroggof24f2242015-03-03 08:59:20 -0800170 /**
msarett614aa072015-07-27 15:13:17 -0700171 * Swizzle a line. Generally this will be called height times, once
172 * for each row of source.
173 * By allowing the caller to pass in the dst pointer, we give the caller
174 * flexibility to use the swizzler even when the encoded data does not
175 * store the rows in order. This also improves usability for scaled and
176 * subset decodes.
177 * @param dst Where we write the output.
scroggof24f2242015-03-03 08:59:20 -0800178 * @param src The next row of the source data.
msarett74114382015-03-16 11:55:18 -0700179 * @return A result code describing if the row was fully opaque, fully
180 * transparent, or neither
scroggof24f2242015-03-03 08:59:20 -0800181 */
msarett614aa072015-07-27 15:13:17 -0700182 ResultAlpha swizzle(void* dst, const uint8_t* SK_RESTRICT src);
msarett3c309db2015-04-10 14:36:48 -0700183
scroggof24f2242015-03-03 08:59:20 -0800184private:
msarett74114382015-03-16 11:55:18 -0700185
scroggof24f2242015-03-03 08:59:20 -0800186 /**
187 * Method for converting raw data to Skia pixels.
188 * @param dstRow Row in which to write the resulting pixels.
189 * @param src Row of src data, in format specified by SrcConfig
emmaleer8f4ba762015-08-14 07:44:46 -0700190 * @param dstWidth Width in pixels of the destination
msarett74114382015-03-16 11:55:18 -0700191 * @param deltaSrc if bitsPerPixel % 8 == 0, deltaSrc is bytesPerPixel
192 * else, deltaSrc is bitsPerPixel
scroggof24f2242015-03-03 08:59:20 -0800193 * @param ctable Colors (used for kIndex source).
emmaleer8f4ba762015-08-14 07:44:46 -0700194 * @param offset The offset before the first pixel to sample.
195 Is in bytes or bits based on what deltaSrc is in.
scroggof24f2242015-03-03 08:59:20 -0800196 */
msarett74114382015-03-16 11:55:18 -0700197 typedef ResultAlpha (*RowProc)(void* SK_RESTRICT dstRow,
198 const uint8_t* SK_RESTRICT src,
emmaleer8f4ba762015-08-14 07:44:46 -0700199 int dstWidth, int deltaSrc, int offset,
msarett74114382015-03-16 11:55:18 -0700200 const SkPMColor ctable[]);
scroggof24f2242015-03-03 08:59:20 -0800201
202 const RowProc fRowProc;
msarett74114382015-03-16 11:55:18 -0700203 const SkPMColor* fColorTable; // Unowned pointer
204 const int fDeltaSrc; // if bitsPerPixel % 8 == 0
205 // deltaSrc is bytesPerPixel
206 // else
207 // deltaSrc is bitsPerPixel
scroggof24f2242015-03-03 08:59:20 -0800208 const SkImageInfo fDstInfo;
scroggof24f2242015-03-03 08:59:20 -0800209 int fCurrY;
emmaleer8f4ba762015-08-14 07:44:46 -0700210 const int fX0; // first X coord to sample
211 const int fSampleX; // step between X samples
scroggof24f2242015-03-03 08:59:20 -0800212
emmaleer8f4ba762015-08-14 07:44:46 -0700213 SkSwizzler(RowProc proc, const SkPMColor* ctable, int deltaSrc, const SkImageInfo& info,
214 int sampleX);
scroggof24f2242015-03-03 08:59:20 -0800215};
216#endif // SkSwizzler_DEFINED