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

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

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

Powered by Google App Engine
This is Rietveld 408576698