Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: src/codec/SkSwizzler.cpp

Issue 1260673002: SkScaledCodec class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Stop DM from running large interlaced images on 32-bit Ubuntu GCE bots b/c they are running out of … Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | tools/dm_flags.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodecPriv.h" 8 #include "SkCodecPriv.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkScaledCodec.h"
10 #include "SkSwizzler.h" 11 #include "SkSwizzler.h"
11 #include "SkTemplates.h" 12 #include "SkTemplates.h"
12 #include "SkUtils.h" 13 #include "SkUtils.h"
13 14
14 SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha, 15 SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
15 uint8_t maxAlpha) { 16 uint8_t maxAlpha) {
16 // In the transparent case, this returns 0x0000 17 // In the transparent case, this returns 0x0000
17 // In the opaque case, this returns 0xFFFF 18 // In the opaque case, this returns 0xFFFF
18 // If the row is neither transparent nor opaque, returns something else 19 // If the row is neither transparent nor opaque, returns something else
19 return (((uint16_t) maxAlpha) << 8) | zeroAlpha; 20 return (((uint16_t) maxAlpha) << 8) | zeroAlpha;
20 } 21 }
21 22
23 // samples the row. Does not do anything else but sampling
24 static SkSwizzler::ResultAlpha sample565(void* SK_RESTRICT dstRow, const uint8_t * SK_RESTRICT src,
25 int width, int deltaSrc, int offset, const SkPMColor ctable[]){
26
27 src += offset;
28 uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
29 for (int x = 0; x < width; x++) {
30 dst[x] = src[1] << 8 | src[0];
31 src += deltaSrc;
32 }
33 // 565 is always opaque
34 return SkSwizzler::kOpaque_ResultAlpha;
35 }
36
22 // kBit 37 // kBit
23 // These routines exclusively choose between white and black 38 // These routines exclusively choose between white and black
24 39
25 #define GRAYSCALE_BLACK 0 40 #define GRAYSCALE_BLACK 0
26 #define GRAYSCALE_WHITE 0xFF 41 #define GRAYSCALE_WHITE 0xFF
27 42
43
44 // same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
28 static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale( 45 static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale(
29 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 46 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
30 int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { 47 int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
48
31 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; 49 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
32 50
33 // Determine how many full bytes are in the row 51 // increment src by byte offset and bitIndex by bit offset
34 int bytesInRow = width >> 3; 52 src += offset / 8;
35 int i; 53 int bitIndex = offset % 8;
36 for (i = 0; i < bytesInRow; i++) { 54 uint8_t currByte = *src;
37 U8CPU currByte = src[i]; 55
38 for (int j = 0; j < 8; j++) { 56 dst[0] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLAC K;
39 dst[j] = ((currByte >> (7 - j)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_B LACK; 57
40 } 58 for (int x = 1; x < dstWidth; x++) {
41 dst += 8; 59 int bitOffset = bitIndex + deltaSrc;
60 bitIndex = bitOffset % 8;
61 currByte = *(src += bitOffset / 8);
62 dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_ BLACK;
42 } 63 }
43 64
44 // Finish the remaining bits
45 width &= 7;
46 if (width > 0) {
47 U8CPU currByte = src[i];
48 for (int j = 0; j < width; j++) {
49 dst[j] = ((currByte >> 7) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
50 currByte <<= 1;
51 }
52 }
53 return SkSwizzler::kOpaque_ResultAlpha; 65 return SkSwizzler::kOpaque_ResultAlpha;
54 } 66 }
55 67
56 #undef GRAYSCALE_BLACK 68 #undef GRAYSCALE_BLACK
57 #undef GRAYSCALE_WHITE 69 #undef GRAYSCALE_WHITE
58 70
71 // same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assi gned to dst[x]
59 static SkSwizzler::ResultAlpha swizzle_bit_to_index( 72 static SkSwizzler::ResultAlpha swizzle_bit_to_index(
60 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 73 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
61 int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { 74 int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
62 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; 75 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
63 76
64 // Determine how many full bytes are in the row 77 // increment src by byte offset and bitIndex by bit offset
65 int bytesInRow = width >> 3; 78 src += offset / 8;
66 int i; 79 int bitIndex = offset % 8;
67 for (i = 0; i < bytesInRow; i++) { 80 uint8_t currByte = *src;
68 U8CPU currByte = src[i]; 81
69 for (int j = 0; j < 8; j++) { 82 dst[0] = ((currByte >> (7-bitIndex)) & 1);
70 dst[j] = (currByte >> (7 - j)) & 1; 83
71 } 84 for (int x = 1; x < dstWidth; x++) {
72 dst += 8; 85 int bitOffset = bitIndex + deltaSrc;
86 bitIndex = bitOffset % 8;
87 currByte = *(src += bitOffset / 8);
88 dst[x] = ((currByte >> (7-bitIndex)) & 1);
73 } 89 }
74 90
75 // Finish the remaining bits
76 width &= 7;
77 if (width > 0) {
78 U8CPU currByte = src[i];
79 for (int j = 0; j < width; j++) {
80 dst[j] = ((currByte >> 7) & 1);
81 currByte <<= 1;
82 }
83 }
84 return SkSwizzler::kOpaque_ResultAlpha; 91 return SkSwizzler::kOpaque_ResultAlpha;
85 } 92 }
86 93
94 // same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value as signed to dst[x]
87 static SkSwizzler::ResultAlpha swizzle_bit_to_n32( 95 static SkSwizzler::ResultAlpha swizzle_bit_to_n32(
88 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 96 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
89 int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) { 97 int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
90 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; 98 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
91 99
92 // Determine how many full bytes are in the row 100 // increment src by byte offset and bitIndex by bit offset
93 int bytesInRow = width >> 3; 101 src += offset / 8;
94 int i; 102 int bitIndex = offset % 8;
95 for (i = 0; i < bytesInRow; i++) { 103 uint8_t currByte = *src;
96 U8CPU currByte = src[i]; 104
97 for (int j = 0; j < 8; j++) { 105 dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
98 dst[j] = ((currByte >> (7 - j)) & 1) ? SK_ColorWHITE : SK_ColorBLACK ; 106
99 } 107 for (int x = 1; x < dstWidth; x++) {
100 dst += 8; 108 int bitOffset = bitIndex + deltaSrc;
109 bitIndex = bitOffset % 8;
110 currByte = *(src += bitOffset / 8);
111 dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBL ACK;
101 } 112 }
102 113
103 // Finish the remaining bits
104 width &= 7;
105 if (width > 0) {
106 U8CPU currByte = src[i];
107 for (int j = 0; j < width; j++) {
108 dst[j] = ((currByte >> 7) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
109 currByte <<= 1;
110 }
111 }
112 return SkSwizzler::kOpaque_ResultAlpha; 114 return SkSwizzler::kOpaque_ResultAlpha;
113 } 115 }
114 116
115 // kIndex1, kIndex2, kIndex4 117 // kIndex1, kIndex2, kIndex4
116 118
117 static SkSwizzler::ResultAlpha swizzle_small_index_to_index( 119 static SkSwizzler::ResultAlpha swizzle_small_index_to_index(
118 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 120 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
119 int bitsPerPixel, const SkPMColor ctable[]) { 121 int bitsPerPixel, int offset, const SkPMColor ctable[]) {
120 122
123 src += offset;
121 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; 124 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
122 INIT_RESULT_ALPHA; 125 INIT_RESULT_ALPHA;
123 const uint32_t pixelsPerByte = 8 / bitsPerPixel; 126 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
124 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); 127 const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte);
125 const uint8_t mask = (1 << bitsPerPixel) - 1; 128 const uint8_t mask = (1 << bitsPerPixel) - 1;
126 int x = 0; 129 int x = 0;
127 for (uint32_t byte = 0; byte < rowBytes; byte++) { 130 for (uint32_t byte = 0; byte < rowBytes; byte++) {
128 uint8_t pixelData = src[byte]; 131 uint8_t pixelData = src[byte];
129 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) { 132 for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) {
130 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; 133 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
131 UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT); 134 UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT);
132 dst[x] = index; 135 dst[x] = index;
133 pixelData <<= bitsPerPixel; 136 pixelData <<= bitsPerPixel;
134 x++; 137 x++;
135 } 138 }
136 } 139 }
137 return COMPUTE_RESULT_ALPHA; 140 return COMPUTE_RESULT_ALPHA;
138 } 141 }
139 142
140 static SkSwizzler::ResultAlpha swizzle_small_index_to_n32( 143 static SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
141 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 144 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
142 int bitsPerPixel, const SkPMColor ctable[]) { 145 int bitsPerPixel, int offset, const SkPMColor ctable[]) {
143 146
147 src += offset;
144 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow; 148 SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
145 INIT_RESULT_ALPHA; 149 INIT_RESULT_ALPHA;
146 const uint32_t pixelsPerByte = 8 / bitsPerPixel; 150 const uint32_t pixelsPerByte = 8 / bitsPerPixel;
147 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); 151 const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte);
148 const uint8_t mask = (1 << bitsPerPixel) - 1; 152 const uint8_t mask = (1 << bitsPerPixel) - 1;
149 int x = 0; 153 int x = 0;
150 for (uint32_t byte = 0; byte < rowBytes; byte++) { 154 for (uint32_t byte = 0; byte < rowBytes; byte++) {
151 uint8_t pixelData = src[byte]; 155 uint8_t pixelData = src[byte];
152 for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) { 156 for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) {
153 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask; 157 uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
154 SkPMColor c = ctable[index]; 158 SkPMColor c = ctable[index];
155 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); 159 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
156 dst[x] = c; 160 dst[x] = c;
157 pixelData <<= bitsPerPixel; 161 pixelData <<= bitsPerPixel;
158 x++; 162 x++;
159 } 163 }
160 } 164 }
161 return COMPUTE_RESULT_ALPHA; 165 return COMPUTE_RESULT_ALPHA;
162 } 166 }
163 167
164 // kIndex 168 // kIndex
165 169
166 static SkSwizzler::ResultAlpha swizzle_index_to_index( 170 static SkSwizzler::ResultAlpha swizzle_index_to_index(
167 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 171 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
168 int bytesPerPixel, const SkPMColor ctable[]) { 172 int deltaSrc, int offset, const SkPMColor ctable[]) {
169 173
174 src += offset;
170 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; 175 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
171 memcpy(dst, src, width); 176 INIT_RESULT_ALPHA;
172 // TODO (msarett): Should we skip the loop here and guess that the row is op aque/not opaque? 177 // TODO (msarett): Should we skip the loop here and guess that the row is op aque/not opaque?
173 // SkScaledBitmap sampler just guesses that it is opaque. T his is dangerous 178 // SkScaledBitmap sampler just guesses that it is opaque. T his is dangerous
174 // and probably wrong since gif and bmp (rarely) may have al pha. 179 // and probably wrong since gif and bmp (rarely) may have al pha.
175 INIT_RESULT_ALPHA; 180 if (1 == deltaSrc) {
176 for (int x = 0; x < width; x++) { 181 // A non-zero offset is only used when sampling, meaning that deltaSrc w ill be
177 UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); 182 // greater than 1. The below loop relies on the fact that src remains un changed.
183 SkASSERT(0 == offset);
184 memcpy(dst, src, dstWidth);
185 for (int x = 0; x < dstWidth; x++) {
186 UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT);
187 }
188 } else {
189 for (int x = 0; x < dstWidth; x++) {
190 dst[x] = *src;
191 UPDATE_RESULT_ALPHA(ctable[*src] >> SK_A32_SHIFT);
192 src += deltaSrc;
193 }
178 } 194 }
179 return COMPUTE_RESULT_ALPHA; 195 return COMPUTE_RESULT_ALPHA;
180 } 196 }
181 197
182 static SkSwizzler::ResultAlpha swizzle_index_to_n32( 198 static SkSwizzler::ResultAlpha swizzle_index_to_n32(
183 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 199 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
184 int bytesPerPixel, const SkPMColor ctable[]) { 200 int deltaSrc, int offset, const SkPMColor ctable[]) {
185 201
202 src += offset;
186 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 203 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
187 INIT_RESULT_ALPHA; 204 INIT_RESULT_ALPHA;
188 for (int x = 0; x < width; x++) { 205 for (int x = 0; x < dstWidth; x++) {
189 SkPMColor c = ctable[src[x]]; 206 SkPMColor c = ctable[*src];
190 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); 207 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
191 dst[x] = c; 208 dst[x] = c;
209 src += deltaSrc;
192 } 210 }
193 return COMPUTE_RESULT_ALPHA; 211 return COMPUTE_RESULT_ALPHA;
194 } 212 }
195 213
196 static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( 214 static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
197 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 215 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
198 int bytesPerPixel, const SkPMColor ctable[]) { 216 int deltaSrc, int offset, const SkPMColor ctable[]) {
199 217
218 src += offset;
200 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 219 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
201 INIT_RESULT_ALPHA; 220 INIT_RESULT_ALPHA;
202 for (int x = 0; x < width; x++) { 221 for (int x = 0; x < dstWidth; x++) {
203 SkPMColor c = ctable[src[x]]; 222 SkPMColor c = ctable[*src];
204 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); 223 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
205 if (c != 0) { 224 if (c != 0) {
206 dst[x] = c; 225 dst[x] = c;
207 } 226 }
227 src += deltaSrc;
208 } 228 }
209 return COMPUTE_RESULT_ALPHA; 229 return COMPUTE_RESULT_ALPHA;
210 } 230 }
211 231
212 static SkSwizzler::ResultAlpha swizzle_index_to_565( 232 static SkSwizzler::ResultAlpha swizzle_index_to_565(
213 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 233 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
214 int bytesPerPixel, const SkPMColor ctable[]) { 234 int bytesPerPixel, int offset, const SkPMColor ctable[]) {
215 // FIXME: Support dithering? Requires knowing y, which I think is a bigger 235 // FIXME: Support dithering? Requires knowing y, which I think is a bigger
216 // change. 236 // change.
237 src += offset;
217 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 238 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
218 for (int x = 0; x < width; x++) { 239 for (int x = 0; x < dstWidth; x++) {
219 dst[x] = SkPixel32ToPixel16(ctable[*src]); 240 dst[x] = SkPixel32ToPixel16(ctable[*src]);
220 src += bytesPerPixel; 241 src += bytesPerPixel;
221 } 242 }
222 return SkSwizzler::kOpaque_ResultAlpha; 243 return SkSwizzler::kOpaque_ResultAlpha;
223 } 244 }
224 245
225 246
226 #undef A32_MASK_IN_PLACE 247 #undef A32_MASK_IN_PLACE
227 248
228 // kGray 249 // kGray
229 250
230 static SkSwizzler::ResultAlpha swizzle_gray_to_n32( 251 static SkSwizzler::ResultAlpha swizzle_gray_to_n32(
231 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 252 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
232 int bytesPerPixel, const SkPMColor ctable[]) { 253 int deltaSrc, int offset, const SkPMColor ctable[]) {
233 254
255 src += offset;
234 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 256 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
235 for (int x = 0; x < width; x++) { 257 for (int x = 0; x < dstWidth; x++) {
236 dst[x] = SkPackARGB32NoCheck(0xFF, src[x], src[x], src[x]); 258 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
259 src += deltaSrc;
237 } 260 }
238 return SkSwizzler::kOpaque_ResultAlpha; 261 return SkSwizzler::kOpaque_ResultAlpha;
239 } 262 }
240 263
241 static SkSwizzler::ResultAlpha swizzle_gray_to_gray( 264 static SkSwizzler::ResultAlpha swizzle_gray_to_gray(
242 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 265 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
243 int bytesPerPixel, const SkPMColor ctable[]) { 266 int deltaSrc, int offset, const SkPMColor ctable[]) {
244 memcpy(dstRow, src, width); 267
268 src += offset;
269 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
270 if (1 == deltaSrc) {
271 memcpy(dstRow, src, dstWidth);
272 } else {
273 for (int x = 0; x < dstWidth; x++) {
274 dst[x] = src[0];
275 src += deltaSrc;
276 }
277 }
245 return SkSwizzler::kOpaque_ResultAlpha; 278 return SkSwizzler::kOpaque_ResultAlpha;
246 } 279 }
247 280
248 static SkSwizzler::ResultAlpha swizzle_gray_to_565( 281 static SkSwizzler::ResultAlpha swizzle_gray_to_565(
249 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 282 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
250 int bytesPerPixel, const SkPMColor ctable[]) { 283 int bytesPerPixel, int offset, const SkPMColor ctable[]) {
251 // FIXME: Support dithering? 284 // FIXME: Support dithering?
285 src += offset;
252 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 286 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
253 for (int x = 0; x < width; x++) { 287 for (int x = 0; x < dstWidth; x++) {
254 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); 288 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
255 src += bytesPerPixel; 289 src += bytesPerPixel;
256 } 290 }
257 return SkSwizzler::kOpaque_ResultAlpha; 291 return SkSwizzler::kOpaque_ResultAlpha;
258 } 292 }
259 293
260 // kBGRX 294 // kBGRX
261 295
262 static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( 296 static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
263 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 297 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
264 int bytesPerPixel, const SkPMColor ctable[]) { 298 int deltaSrc, int offset, const SkPMColor ctable[]) {
265 299
300 src += offset;
266 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 301 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
267 for (int x = 0; x < width; x++) { 302 for (int x = 0; x < dstWidth; x++) {
268 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]); 303 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
269 src += bytesPerPixel; 304 src += deltaSrc;
270 } 305 }
271 return SkSwizzler::kOpaque_ResultAlpha; 306 return SkSwizzler::kOpaque_ResultAlpha;
272 } 307 }
273 308
274 // kBGRA 309 // kBGRA
275 310
276 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( 311 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul(
277 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 312 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
278 int bytesPerPixel, const SkPMColor ctable[]) { 313 int deltaSrc, int offset, const SkPMColor ctable[]) {
279 314
315 src += offset;
280 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 316 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
281 INIT_RESULT_ALPHA; 317 INIT_RESULT_ALPHA;
282 for (int x = 0; x < width; x++) { 318 for (int x = 0; x < dstWidth; x++) {
283 uint8_t alpha = src[3]; 319 uint8_t alpha = src[3];
284 UPDATE_RESULT_ALPHA(alpha); 320 UPDATE_RESULT_ALPHA(alpha);
285 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]); 321 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
286 src += bytesPerPixel; 322 src += deltaSrc;
287 } 323 }
288 return COMPUTE_RESULT_ALPHA; 324 return COMPUTE_RESULT_ALPHA;
289 } 325 }
290 326
291 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( 327 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul(
292 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 328 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
293 int bytesPerPixel, const SkPMColor ctable[]) { 329 int deltaSrc, int offset, const SkPMColor ctable[]) {
294 330
331 src += offset;
295 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 332 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
296 INIT_RESULT_ALPHA; 333 INIT_RESULT_ALPHA;
297 for (int x = 0; x < width; x++) { 334 for (int x = 0; x < dstWidth; x++) {
298 uint8_t alpha = src[3]; 335 uint8_t alpha = src[3];
299 UPDATE_RESULT_ALPHA(alpha); 336 UPDATE_RESULT_ALPHA(alpha);
300 dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]); 337 dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]);
301 src += bytesPerPixel; 338 src += deltaSrc;
302 } 339 }
303 return COMPUTE_RESULT_ALPHA; 340 return COMPUTE_RESULT_ALPHA;
304 } 341 }
305 342
306 // kRGBX 343 // kRGBX
307 static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( 344 static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
308 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 345 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
309 int bytesPerPixel, const SkPMColor ctable[]) { 346 int deltaSrc, int offset, const SkPMColor ctable[]) {
310 347
348 src += offset;
311 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 349 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
312 for (int x = 0; x < width; x++) { 350 for (int x = 0; x < dstWidth; x++) {
313 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); 351 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
314 src += bytesPerPixel; 352 src += deltaSrc;
315 } 353 }
316 return SkSwizzler::kOpaque_ResultAlpha; 354 return SkSwizzler::kOpaque_ResultAlpha;
317 } 355 }
318 356
319 static SkSwizzler::ResultAlpha swizzle_rgbx_to_565( 357 static SkSwizzler::ResultAlpha swizzle_rgbx_to_565(
320 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 358 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
321 int bytesPerPixel, const SkPMColor ctable[]) { 359 int bytesPerPixel, int offset, const SkPMColor ctable[]) {
322 // FIXME: Support dithering? 360 // FIXME: Support dithering?
361 src += offset;
323 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; 362 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
324 for (int x = 0; x < width; x++) { 363 for (int x = 0; x < dstWidth; x++) {
325 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); 364 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
326 src += bytesPerPixel; 365 src += bytesPerPixel;
327 } 366 }
328 return SkSwizzler::kOpaque_ResultAlpha; 367 return SkSwizzler::kOpaque_ResultAlpha;
329 } 368 }
330 369
331 370
332 // kRGBA 371 // kRGBA
333 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( 372 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
334 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 373 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
335 int bytesPerPixel, const SkPMColor ctable[]) { 374 int deltaSrc, int offset, const SkPMColor ctable[]) {
336 375
376 src += offset;
337 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 377 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
338 INIT_RESULT_ALPHA; 378 INIT_RESULT_ALPHA;
339 for (int x = 0; x < width; x++) { 379 for (int x = 0; x < dstWidth; x++) {
340 unsigned alpha = src[3]; 380 unsigned alpha = src[3];
341 UPDATE_RESULT_ALPHA(alpha); 381 UPDATE_RESULT_ALPHA(alpha);
342 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 382 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
343 src += bytesPerPixel; 383 src += deltaSrc;
344 } 384 }
345 return COMPUTE_RESULT_ALPHA; 385 return COMPUTE_RESULT_ALPHA;
346 } 386 }
347 387
348 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( 388 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
349 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 389 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
350 int bytesPerPixel, const SkPMColor ctable[]) { 390 int deltaSrc, int offset, const SkPMColor ctable[]) {
351 391
392 src += offset;
352 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); 393 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
353 INIT_RESULT_ALPHA; 394 INIT_RESULT_ALPHA;
354 for (int x = 0; x < width; x++) { 395 for (int x = 0; x < dstWidth; x++) {
355 unsigned alpha = src[3]; 396 unsigned alpha = src[3];
356 UPDATE_RESULT_ALPHA(alpha); 397 UPDATE_RESULT_ALPHA(alpha);
357 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 398 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
358 src += bytesPerPixel; 399 src += deltaSrc;
359 } 400 }
360 return COMPUTE_RESULT_ALPHA; 401 return COMPUTE_RESULT_ALPHA;
361 } 402 }
362 403
363 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( 404 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
364 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, 405 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
365 int bytesPerPixel, const SkPMColor ctable[]) { 406 int deltaSrc, int offset, const SkPMColor ctable[]) {
366 407
408 src += offset;
367 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 409 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
368 INIT_RESULT_ALPHA; 410 INIT_RESULT_ALPHA;
369 for (int x = 0; x < width; x++) { 411 for (int x = 0; x < dstWidth; x++) {
370 unsigned alpha = src[3]; 412 unsigned alpha = src[3];
371 UPDATE_RESULT_ALPHA(alpha); 413 UPDATE_RESULT_ALPHA(alpha);
372 if (0 != alpha) { 414 if (0 != alpha) {
373 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 415 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
374 } 416 }
375 src += bytesPerPixel; 417 src += deltaSrc;
376 } 418 }
377 return COMPUTE_RESULT_ALPHA; 419 return COMPUTE_RESULT_ALPHA;
378 } 420 }
379 421
380 /** 422 /**
381 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. 423 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes.
382 This would be fine for drawing normally, but not for drawing with transfer m odes. Being 424 This would be fine for drawing normally, but not for drawing with transfer m odes. Being
383 honest means we can draw correctly with transfer modes, with the cost of not being able 425 honest means we can draw correctly with transfer modes, with the cost of not being able
384 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we 426 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we
385 decide whether to switch to unpremul default. 427 decide whether to switch to unpremul default.
386 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, 428 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
387 const uint8_t* SK_RESTRICT src, 429 const uint8_t* SK_RESTRICT src,
388 int width, int bitsPerPixel, 430 int dstWidth, int bitsPerPixel, i nt offset,
389 const SkPMColor[]) { 431 const SkPMColor[]) {
432 src += offset;
390 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; 433 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
391 unsigned alphaMask = 0xFF; 434 unsigned alphaMask = 0xFF;
392 for (int x = 0; x < width; x++) { 435 for (int x = 0; x < dstWidth; x++) {
393 unsigned alpha = src[3]; 436 unsigned alpha = src[3];
394 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible 437 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible
395 // the color components are not zero, but we skip them anyway, meaning t hey'll remain 438 // the color components are not zero, but we skip them anyway, meaning t hey'll remain
396 // zero (implied by the request to skip zeroes). 439 // zero (implied by the request to skip zeroes).
397 if (0 != alpha) { 440 if (0 != alpha) {
398 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); 441 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
399 } 442 }
400 src += deltaSrc; 443 src += deltaSrc;
401 alphaMask &= alpha; 444 alphaMask &= alpha;
402 } 445 }
403 return alphaMask != 0xFF; 446 return alphaMask != 0xFF;
404 } 447 }
405 */ 448 */
406 449
407 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, 450 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
408 const SkPMColor* ctable, 451 const SkPMColor* ctable,
409 const SkImageInfo& info, 452 const SkImageInfo& dstInfo,
410 SkCodec::ZeroInitialized zeroInit) { 453 SkCodec::ZeroInitialized zeroInit,
411 if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) { 454 const SkImageInfo& srcInfo) {
455 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
412 return NULL; 456 return NULL;
413 } 457 }
414 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) 458 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
415 && NULL == ctable) { 459 && NULL == ctable) {
416 return NULL; 460 return NULL;
417 } 461 }
418 RowProc proc = NULL; 462 RowProc proc = NULL;
463
419 switch (sc) { 464 switch (sc) {
420 case kBit: 465 case kBit:
421 switch (info.colorType()) { 466 switch (dstInfo.colorType()) {
422 case kN32_SkColorType: 467 case kN32_SkColorType:
423 proc = &swizzle_bit_to_n32; 468 proc = &swizzle_bit_to_n32;
424 break; 469 break;
425 case kIndex_8_SkColorType: 470 case kIndex_8_SkColorType:
426 proc = &swizzle_bit_to_index; 471 proc = &swizzle_bit_to_index;
427 break; 472 break;
428 case kGray_8_SkColorType: 473 case kGray_8_SkColorType:
429 proc = &swizzle_bit_to_grayscale; 474 proc = &swizzle_bit_to_grayscale;
430 break; 475 break;
431 default: 476 default:
432 break; 477 break;
433 } 478 }
434 break; 479 break;
435 case kIndex1: 480 case kIndex1:
436 case kIndex2: 481 case kIndex2:
437 case kIndex4: 482 case kIndex4:
438 switch (info.colorType()) { 483 switch (dstInfo.colorType()) {
439 case kN32_SkColorType: 484 case kN32_SkColorType:
440 proc = &swizzle_small_index_to_n32; 485 proc = &swizzle_small_index_to_n32;
441 break; 486 break;
442 case kIndex_8_SkColorType: 487 case kIndex_8_SkColorType:
443 proc = &swizzle_small_index_to_index; 488 proc = &swizzle_small_index_to_index;
444 break; 489 break;
445 default: 490 default:
446 break; 491 break;
447 } 492 }
448 break; 493 break;
449 case kIndex: 494 case kIndex:
450 switch (info.colorType()) { 495 switch (dstInfo.colorType()) {
451 case kN32_SkColorType: 496 case kN32_SkColorType:
452 // We assume the color premultiplied ctable (or not) as desi red. 497 // We assume the color premultiplied ctable (or not) as desi red.
453 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 498 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
454 proc = &swizzle_index_to_n32_skipZ; 499 proc = &swizzle_index_to_n32_skipZ;
455 break; 500 break;
456 } else { 501 } else {
457 proc = &swizzle_index_to_n32; 502 proc = &swizzle_index_to_n32;
458 break; 503 break;
459 } 504 }
460 break; 505 break;
461 case kRGB_565_SkColorType: 506 case kRGB_565_SkColorType:
462 proc = &swizzle_index_to_565; 507 proc = &swizzle_index_to_565;
463 break; 508 break;
464 case kIndex_8_SkColorType: 509 case kIndex_8_SkColorType:
465 proc = &swizzle_index_to_index; 510 proc = &swizzle_index_to_index;
466 break; 511 break;
467 default: 512 default:
468 break; 513 break;
469 } 514 }
470 break; 515 break;
471 case kGray: 516 case kGray:
472 switch (info.colorType()) { 517 switch (dstInfo.colorType()) {
473 case kN32_SkColorType: 518 case kN32_SkColorType:
474 proc = &swizzle_gray_to_n32; 519 proc = &swizzle_gray_to_n32;
475 break; 520 break;
476 case kGray_8_SkColorType: 521 case kGray_8_SkColorType:
477 proc = &swizzle_gray_to_gray; 522 proc = &swizzle_gray_to_gray;
478 break; 523 break;
479 case kRGB_565_SkColorType: 524 case kRGB_565_SkColorType:
480 proc = &swizzle_gray_to_565; 525 proc = &swizzle_gray_to_565;
481 break; 526 break;
482 default: 527 default:
483 break; 528 break;
484 } 529 }
485 break; 530 break;
486 case kBGR: 531 case kBGR:
487 case kBGRX: 532 case kBGRX:
488 switch (info.colorType()) { 533 switch (dstInfo.colorType()) {
489 case kN32_SkColorType: 534 case kN32_SkColorType:
490 proc = &swizzle_bgrx_to_n32; 535 proc = &swizzle_bgrx_to_n32;
491 break; 536 break;
492 default: 537 default:
493 break; 538 break;
494 } 539 }
495 break; 540 break;
496 case kBGRA: 541 case kBGRA:
497 switch (info.colorType()) { 542 switch (dstInfo.colorType()) {
498 case kN32_SkColorType: 543 case kN32_SkColorType:
499 switch (info.alphaType()) { 544 switch (dstInfo.alphaType()) {
500 case kUnpremul_SkAlphaType: 545 case kUnpremul_SkAlphaType:
501 proc = &swizzle_bgra_to_n32_unpremul; 546 proc = &swizzle_bgra_to_n32_unpremul;
502 break; 547 break;
503 case kPremul_SkAlphaType: 548 case kPremul_SkAlphaType:
504 proc = &swizzle_bgra_to_n32_premul; 549 proc = &swizzle_bgra_to_n32_premul;
505 break; 550 break;
506 default: 551 default:
507 break; 552 break;
508 } 553 }
509 break; 554 break;
510 default: 555 default:
511 break; 556 break;
512 } 557 }
513 break; 558 break;
514 case kRGBX: 559 case kRGBX:
515 // TODO: Support other swizzles. 560 // TODO: Support other swizzles.
516 switch (info.colorType()) { 561 switch (dstInfo.colorType()) {
517 case kN32_SkColorType: 562 case kN32_SkColorType:
518 proc = &swizzle_rgbx_to_n32; 563 proc = &swizzle_rgbx_to_n32;
519 break; 564 break;
520 case kRGB_565_SkColorType: 565 case kRGB_565_SkColorType:
521 proc = &swizzle_rgbx_to_565; 566 proc = &swizzle_rgbx_to_565;
522 default: 567 default:
523 break; 568 break;
524 } 569 }
525 break; 570 break;
526 case kRGBA: 571 case kRGBA:
527 switch (info.colorType()) { 572 switch (dstInfo.colorType()) {
528 case kN32_SkColorType: 573 case kN32_SkColorType:
529 if (info.alphaType() == kUnpremul_SkAlphaType) { 574 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
530 // Respect zeroInit? 575 // Respect zeroInit?
531 proc = &swizzle_rgba_to_n32_unpremul; 576 proc = &swizzle_rgba_to_n32_unpremul;
532 } else { 577 } else {
533 if (SkCodec::kYes_ZeroInitialized == zeroInit) { 578 if (SkCodec::kYes_ZeroInitialized == zeroInit) {
534 proc = &swizzle_rgba_to_n32_premul_skipZ; 579 proc = &swizzle_rgba_to_n32_premul_skipZ;
535 } else { 580 } else {
536 proc = &swizzle_rgba_to_n32_premul; 581 proc = &swizzle_rgba_to_n32_premul;
537 } 582 }
538 } 583 }
539 break; 584 break;
540 default: 585 default:
541 break; 586 break;
542 } 587 }
543 break; 588 break;
544 case kRGB: 589 case kRGB:
545 switch (info.colorType()) { 590 switch (dstInfo.colorType()) {
546 case kN32_SkColorType: 591 case kN32_SkColorType:
547 proc = &swizzle_rgbx_to_n32; 592 proc = &swizzle_rgbx_to_n32;
548 break; 593 break;
549 default: 594 default:
550 break; 595 break;
551 } 596 }
552 break; 597 break;
598 case kRGB_565:
599 switch (dstInfo.colorType()) {
600 case kRGB_565_SkColorType:
601 proc = &sample565;
602 break;
603 default:
604 break;
605 }
553 default: 606 default:
554 break; 607 break;
555 } 608 }
556 if (NULL == proc) { 609 if (NULL == proc) {
557 return NULL; 610 return NULL;
558 } 611 }
559 612
560 // Store deltaSrc in bytes if it is an even multiple, otherwise use bits 613 // Store deltaSrc in bytes if it is an even multiple, otherwise use bits
561 int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : 614 int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPix el(sc);
562 BitsPerPixel(sc); 615
563 return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info)); 616 // get sampleX based on srcInfo and dstInfo dimensions
617 int sampleX;
618 SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, &sampleX, NULL);
619
620 return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, dstInfo, sampleX));
564 } 621 }
565 622
566 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, 623 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
567 int deltaSrc, const SkImageInfo& info) 624 int deltaSrc, const SkImageInfo& info, int sampleX)
568 : fRowProc(proc) 625 : fRowProc(proc)
569 , fColorTable(ctable) 626 , fColorTable(ctable)
570 , fDeltaSrc(deltaSrc) 627 , fDeltaSrc(deltaSrc)
571 , fDstInfo(info) 628 , fDstInfo(info)
572 {} 629 , fSampleX(sampleX)
630 , fX0(sampleX == 1 ? 0 : sampleX >> 1)
631 {
632 // check that fX0 is less than original width
633 SkASSERT(fX0 >= 0 && fX0 < fDstInfo.width() * fSampleX);
634 }
573 635
574 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) { 636 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) {
575 SkASSERT(NULL != dst && NULL != src); 637 SkASSERT(NULL != dst && NULL != src);
576 return fRowProc(dst, src, fDstInfo.width(), fDeltaSrc, fColorTable); 638 return fRowProc(dst, src, fDstInfo.width(), fSampleX * fDeltaSrc, fX0 * fDel taSrc, fColorTable);
577 } 639 }
578 640
579 void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstR owBytes, 641 void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstR owBytes,
580 uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable) { 642 uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable) {
581 SkASSERT(dstStartRow != NULL); 643 SkASSERT(dstStartRow != NULL);
582 SkASSERT(numRows <= (uint32_t) dstInfo.height()); 644 SkASSERT(numRows <= (uint32_t) dstInfo.height());
583 645
584 // Calculate bytes to fill. We use getSafeSize since the last row may not b e padded. 646 // Calculate bytes to fill. We use getSafeSize since the last row may not b e padded.
585 const size_t bytesToFill = dstInfo.makeWH(dstInfo.width(), numRows).getSafeS ize(dstRowBytes); 647 const size_t bytesToFill = dstInfo.makeWH(dstInfo.width(), numRows).getSafeS ize(dstRowBytes);
586 648
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 // bits of SK_ColorBLACK are identical to the 565 representation 697 // bits of SK_ColorBLACK are identical to the 565 representation
636 // for black. 698 // for black.
637 memset(dstStartRow, (uint16_t) colorOrIndex, bytesToFill); 699 memset(dstStartRow, (uint16_t) colorOrIndex, bytesToFill);
638 break; 700 break;
639 default: 701 default:
640 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n"); 702 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n");
641 SkASSERT(false); 703 SkASSERT(false);
642 break; 704 break;
643 } 705 }
644 } 706 }
OLDNEW
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | tools/dm_flags.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698