blob: 1b77a85b139c591736e9edd5e6f152b11d6e232f [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkCodecPriv.h"
9#include "SkColorPriv.h"
10#include "SkMaskSwizzler.h"
11
msaretta4970dc2016-01-11 07:23:23 -080012static void swizzle_mask16_to_n32_opaque(
msarett5406d6f2015-08-31 06:55:13 -070013 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
14 uint32_t startX, uint32_t sampleX) {
msarett74114382015-03-16 11:55:18 -070015
16 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -070017 uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
msarett74114382015-03-16 11:55:18 -070018 SkPMColor* dstPtr = (SkPMColor*) dstRow;
19 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -070020 uint16_t p = srcPtr[0];
msarett74114382015-03-16 11:55:18 -070021 uint8_t red = masks->getRed(p);
22 uint8_t green = masks->getGreen(p);
23 uint8_t blue = masks->getBlue(p);
24 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -070025 srcPtr += sampleX;
msarett74114382015-03-16 11:55:18 -070026 }
msarett74114382015-03-16 11:55:18 -070027}
28
msaretta4970dc2016-01-11 07:23:23 -080029static void swizzle_mask16_to_n32_unpremul(
msarett5406d6f2015-08-31 06:55:13 -070030 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
31 uint32_t startX, uint32_t sampleX) {
msarett74114382015-03-16 11:55:18 -070032
33 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -070034 uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
msarett74114382015-03-16 11:55:18 -070035 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msarett74114382015-03-16 11:55:18 -070036 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -070037 uint16_t p = srcPtr[0];
msarett74114382015-03-16 11:55:18 -070038 uint8_t red = masks->getRed(p);
39 uint8_t green = masks->getGreen(p);
40 uint8_t blue = masks->getBlue(p);
41 uint8_t alpha = masks->getAlpha(p);
msarett74114382015-03-16 11:55:18 -070042 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -070043 srcPtr += sampleX;
msarett74114382015-03-16 11:55:18 -070044 }
msarett74114382015-03-16 11:55:18 -070045}
46
msaretta4970dc2016-01-11 07:23:23 -080047static void swizzle_mask16_to_n32_premul(
msarett5406d6f2015-08-31 06:55:13 -070048 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
49 uint32_t startX, uint32_t sampleX) {
msaretteed039b2015-03-18 11:11:19 -070050
51 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -070052 uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
msaretteed039b2015-03-18 11:11:19 -070053 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msaretteed039b2015-03-18 11:11:19 -070054 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -070055 uint16_t p = srcPtr[0];
msaretteed039b2015-03-18 11:11:19 -070056 uint8_t red = masks->getRed(p);
57 uint8_t green = masks->getGreen(p);
58 uint8_t blue = masks->getBlue(p);
59 uint8_t alpha = masks->getAlpha(p);
msaretteed039b2015-03-18 11:11:19 -070060 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -070061 srcPtr += sampleX;
msaretteed039b2015-03-18 11:11:19 -070062 }
msaretteed039b2015-03-18 11:11:19 -070063}
64
scroggocc2feb12015-08-14 08:32:46 -070065// TODO (msarett): We have promoted a two byte per pixel image to 8888, only to
66// convert it back to 565. Instead, we should swizzle to 565 directly.
msaretta4970dc2016-01-11 07:23:23 -080067static void swizzle_mask16_to_565(
msarett5406d6f2015-08-31 06:55:13 -070068 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
69 uint32_t startX, uint32_t sampleX) {
scroggocc2feb12015-08-14 08:32:46 -070070
71 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -070072 uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
scroggocc2feb12015-08-14 08:32:46 -070073 uint16_t* dstPtr = (uint16_t*) dstRow;
74 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -070075 uint16_t p = srcPtr[0];
scroggocc2feb12015-08-14 08:32:46 -070076 uint8_t red = masks->getRed(p);
77 uint8_t green = masks->getGreen(p);
78 uint8_t blue = masks->getBlue(p);
79 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -070080 srcPtr += sampleX;
scroggocc2feb12015-08-14 08:32:46 -070081 }
scroggocc2feb12015-08-14 08:32:46 -070082}
83
msaretta4970dc2016-01-11 07:23:23 -080084static void swizzle_mask24_to_n32_opaque(
msarett5406d6f2015-08-31 06:55:13 -070085 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
86 uint32_t startX, uint32_t sampleX) {
msarett74114382015-03-16 11:55:18 -070087
88 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -070089 srcRow += 3 * startX;
msarett74114382015-03-16 11:55:18 -070090 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -070091 for (int i = 0; i < width; i++) {
92 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
msarett74114382015-03-16 11:55:18 -070093 uint8_t red = masks->getRed(p);
94 uint8_t green = masks->getGreen(p);
95 uint8_t blue = masks->getBlue(p);
msarett5406d6f2015-08-31 06:55:13 -070096 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
97 srcRow += 3 * sampleX;
msarett74114382015-03-16 11:55:18 -070098 }
msarett74114382015-03-16 11:55:18 -070099}
100
msaretta4970dc2016-01-11 07:23:23 -0800101static void swizzle_mask24_to_n32_unpremul(
msarett5406d6f2015-08-31 06:55:13 -0700102 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
103 uint32_t startX, uint32_t sampleX) {
msarett74114382015-03-16 11:55:18 -0700104
105 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -0700106 srcRow += 3 * startX;
msarett74114382015-03-16 11:55:18 -0700107 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msarett74114382015-03-16 11:55:18 -0700108 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -0700109 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
msarett74114382015-03-16 11:55:18 -0700110 uint8_t red = masks->getRed(p);
111 uint8_t green = masks->getGreen(p);
112 uint8_t blue = masks->getBlue(p);
113 uint8_t alpha = masks->getAlpha(p);
msarett74114382015-03-16 11:55:18 -0700114 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -0700115 srcRow += 3 * sampleX;
msarett74114382015-03-16 11:55:18 -0700116 }
msarett74114382015-03-16 11:55:18 -0700117}
118
msaretta4970dc2016-01-11 07:23:23 -0800119static void swizzle_mask24_to_n32_premul(
msarett5406d6f2015-08-31 06:55:13 -0700120 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
121 uint32_t startX, uint32_t sampleX) {
msaretteed039b2015-03-18 11:11:19 -0700122
123 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -0700124 srcRow += 3 * startX;
msaretteed039b2015-03-18 11:11:19 -0700125 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msaretteed039b2015-03-18 11:11:19 -0700126 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -0700127 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
msaretteed039b2015-03-18 11:11:19 -0700128 uint8_t red = masks->getRed(p);
129 uint8_t green = masks->getGreen(p);
130 uint8_t blue = masks->getBlue(p);
131 uint8_t alpha = masks->getAlpha(p);
msaretteed039b2015-03-18 11:11:19 -0700132 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -0700133 srcRow += 3 * sampleX;
134 }
msarett5406d6f2015-08-31 06:55:13 -0700135}
136
msaretta4970dc2016-01-11 07:23:23 -0800137static void swizzle_mask24_to_565(
msarett5406d6f2015-08-31 06:55:13 -0700138 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
139 uint32_t startX, uint32_t sampleX) {
140
141 // Use the masks to decode to the destination
142 srcRow += 3 * startX;
143 uint16_t* dstPtr = (uint16_t*) dstRow;
144 for (int i = 0; i < width; i++) {
145 uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
146 uint8_t red = masks->getRed(p);
147 uint8_t green = masks->getGreen(p);
148 uint8_t blue = masks->getBlue(p);
149 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
150 srcRow += 3 * sampleX;
151 }
msarett5406d6f2015-08-31 06:55:13 -0700152}
153
msaretta4970dc2016-01-11 07:23:23 -0800154static void swizzle_mask32_to_n32_opaque(
msarett5406d6f2015-08-31 06:55:13 -0700155 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
156 uint32_t startX, uint32_t sampleX) {
157
158 // Use the masks to decode to the destination
159 uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
160 SkPMColor* dstPtr = (SkPMColor*) dstRow;
161 for (int i = 0; i < width; i++) {
162 uint32_t p = srcPtr[0];
163 uint8_t red = masks->getRed(p);
164 uint8_t green = masks->getGreen(p);
165 uint8_t blue = masks->getBlue(p);
166 dstPtr[i] = SkPackARGB32NoCheck(0xFF, red, green, blue);
167 srcPtr += sampleX;
168 }
msarett5406d6f2015-08-31 06:55:13 -0700169}
170
msaretta4970dc2016-01-11 07:23:23 -0800171static void swizzle_mask32_to_n32_unpremul(
msarett5406d6f2015-08-31 06:55:13 -0700172 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
173 uint32_t startX, uint32_t sampleX) {
174
175 // Use the masks to decode to the destination
176 uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
177 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700178 for (int i = 0; i < width; i++) {
179 uint32_t p = srcPtr[0];
180 uint8_t red = masks->getRed(p);
181 uint8_t green = masks->getGreen(p);
182 uint8_t blue = masks->getBlue(p);
183 uint8_t alpha = masks->getAlpha(p);
msarett5406d6f2015-08-31 06:55:13 -0700184 dstPtr[i] = SkPackARGB32NoCheck(alpha, red, green, blue);
185 srcPtr += sampleX;
186 }
msarett5406d6f2015-08-31 06:55:13 -0700187}
188
msaretta4970dc2016-01-11 07:23:23 -0800189static void swizzle_mask32_to_n32_premul(
msarett5406d6f2015-08-31 06:55:13 -0700190 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
191 uint32_t startX, uint32_t sampleX) {
192
193 // Use the masks to decode to the destination
194 uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
195 SkPMColor* dstPtr = (SkPMColor*) dstRow;
msarett5406d6f2015-08-31 06:55:13 -0700196 for (int i = 0; i < width; i++) {
197 uint32_t p = srcPtr[0];
198 uint8_t red = masks->getRed(p);
199 uint8_t green = masks->getGreen(p);
200 uint8_t blue = masks->getBlue(p);
201 uint8_t alpha = masks->getAlpha(p);
msarett5406d6f2015-08-31 06:55:13 -0700202 dstPtr[i] = SkPreMultiplyARGB(alpha, red, green, blue);
203 srcPtr += sampleX;
msaretteed039b2015-03-18 11:11:19 -0700204 }
msaretteed039b2015-03-18 11:11:19 -0700205}
206
msaretta4970dc2016-01-11 07:23:23 -0800207static void swizzle_mask32_to_565(
msarett5406d6f2015-08-31 06:55:13 -0700208 void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
209 uint32_t startX, uint32_t sampleX) {
scroggocc2feb12015-08-14 08:32:46 -0700210 // Use the masks to decode to the destination
msarett5406d6f2015-08-31 06:55:13 -0700211 uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
scroggocc2feb12015-08-14 08:32:46 -0700212 uint16_t* dstPtr = (uint16_t*) dstRow;
213 for (int i = 0; i < width; i++) {
msarett5406d6f2015-08-31 06:55:13 -0700214 uint32_t p = srcPtr[0];
scroggocc2feb12015-08-14 08:32:46 -0700215 uint8_t red = masks->getRed(p);
216 uint8_t green = masks->getGreen(p);
217 uint8_t blue = masks->getBlue(p);
218 dstPtr[i] = SkPack888ToRGB16(red, green, blue);
msarett5406d6f2015-08-31 06:55:13 -0700219 srcPtr += sampleX;
scroggocc2feb12015-08-14 08:32:46 -0700220 }
scroggocc2feb12015-08-14 08:32:46 -0700221}
222
msarett74114382015-03-16 11:55:18 -0700223/*
224 *
225 * Create a new mask swizzler
226 *
227 */
msarettfdb47572015-10-13 12:50:14 -0700228SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
229 const SkImageInfo& srcInfo, SkMasks* masks, uint32_t bitsPerPixel,
230 const SkCodec::Options& options) {
msarett74114382015-03-16 11:55:18 -0700231
232 // Choose the appropriate row procedure
halcanary96fcdcc2015-08-27 07:41:13 -0700233 RowProc proc = nullptr;
msarett74114382015-03-16 11:55:18 -0700234 switch (bitsPerPixel) {
235 case 16:
msarett5406d6f2015-08-31 06:55:13 -0700236 switch (dstInfo.colorType()) {
msaretteed039b2015-03-18 11:11:19 -0700237 case kN32_SkColorType:
msarett5406d6f2015-08-31 06:55:13 -0700238 switch (dstInfo.alphaType()) {
msaretteed039b2015-03-18 11:11:19 -0700239 case kUnpremul_SkAlphaType:
240 proc = &swizzle_mask16_to_n32_unpremul;
241 break;
242 case kPremul_SkAlphaType:
243 proc = &swizzle_mask16_to_n32_premul;
244 break;
245 case kOpaque_SkAlphaType:
246 proc = &swizzle_mask16_to_n32_opaque;
247 break;
248 default:
249 break;
250 }
251 break;
scroggocc2feb12015-08-14 08:32:46 -0700252 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800253 proc = &swizzle_mask16_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700254 break;
msaretteed039b2015-03-18 11:11:19 -0700255 default:
256 break;
msarett74114382015-03-16 11:55:18 -0700257 }
258 break;
259 case 24:
msarett5406d6f2015-08-31 06:55:13 -0700260 switch (dstInfo.colorType()) {
msaretteed039b2015-03-18 11:11:19 -0700261 case kN32_SkColorType:
msarett5406d6f2015-08-31 06:55:13 -0700262 switch (dstInfo.alphaType()) {
msaretteed039b2015-03-18 11:11:19 -0700263 case kUnpremul_SkAlphaType:
264 proc = &swizzle_mask24_to_n32_unpremul;
265 break;
266 case kPremul_SkAlphaType:
267 proc = &swizzle_mask24_to_n32_premul;
268 break;
269 case kOpaque_SkAlphaType:
270 proc = &swizzle_mask24_to_n32_opaque;
271 break;
272 default:
273 break;
274 }
275 break;
scroggocc2feb12015-08-14 08:32:46 -0700276 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800277 proc = &swizzle_mask24_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700278 break;
msaretteed039b2015-03-18 11:11:19 -0700279 default:
280 break;
msarett74114382015-03-16 11:55:18 -0700281 }
282 break;
283 case 32:
msarett5406d6f2015-08-31 06:55:13 -0700284 switch (dstInfo.colorType()) {
msaretteed039b2015-03-18 11:11:19 -0700285 case kN32_SkColorType:
msarett5406d6f2015-08-31 06:55:13 -0700286 switch (dstInfo.alphaType()) {
msaretteed039b2015-03-18 11:11:19 -0700287 case kUnpremul_SkAlphaType:
288 proc = &swizzle_mask32_to_n32_unpremul;
289 break;
290 case kPremul_SkAlphaType:
291 proc = &swizzle_mask32_to_n32_premul;
292 break;
293 case kOpaque_SkAlphaType:
294 proc = &swizzle_mask32_to_n32_opaque;
295 break;
296 default:
297 break;
298 }
299 break;
scroggocc2feb12015-08-14 08:32:46 -0700300 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800301 proc = &swizzle_mask32_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700302 break;
msaretteed039b2015-03-18 11:11:19 -0700303 default:
304 break;
msarett74114382015-03-16 11:55:18 -0700305 }
306 break;
307 default:
308 SkASSERT(false);
halcanary96fcdcc2015-08-27 07:41:13 -0700309 return nullptr;
msarett74114382015-03-16 11:55:18 -0700310 }
msarett5406d6f2015-08-31 06:55:13 -0700311
msarettfdb47572015-10-13 12:50:14 -0700312 int srcOffset = 0;
313 int srcWidth = dstInfo.width();
314 if (options.fSubset) {
315 srcOffset = options.fSubset->left();
316 srcWidth = options.fSubset->width();
317 }
318
319 return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth);
msarett74114382015-03-16 11:55:18 -0700320}
321
322/*
323 *
324 * Constructor for mask swizzler
325 *
326 */
msarett80803ff2015-10-16 10:54:12 -0700327SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int subsetWidth)
scroggoe7fc14b2015-10-02 13:14:46 -0700328 : fMasks(masks)
msarett74114382015-03-16 11:55:18 -0700329 , fRowProc(proc)
msarett80803ff2015-10-16 10:54:12 -0700330 , fSubsetWidth(subsetWidth)
331 , fDstWidth(subsetWidth)
scroggoe7fc14b2015-10-02 13:14:46 -0700332 , fSampleX(1)
msarettfdb47572015-10-13 12:50:14 -0700333 , fSrcOffset(srcOffset)
334 , fX0(srcOffset)
msarett74114382015-03-16 11:55:18 -0700335{}
336
scroggoe7fc14b2015-10-02 13:14:46 -0700337int SkMaskSwizzler::onSetSampleX(int sampleX) {
338 // FIXME: Share this function with SkSwizzler?
339 SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
340 // way to report failure?
341 fSampleX = sampleX;
msarettfdb47572015-10-13 12:50:14 -0700342 fX0 = get_start_coord(sampleX) + fSrcOffset;
msarett80803ff2015-10-16 10:54:12 -0700343 fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX);
scroggoe7fc14b2015-10-02 13:14:46 -0700344
msarett80803ff2015-10-16 10:54:12 -0700345 // check that fX0 is valid
346 SkASSERT(fX0 >= 0);
scroggoe7fc14b2015-10-02 13:14:46 -0700347 return fDstWidth;
348}
349
msarett74114382015-03-16 11:55:18 -0700350/*
351 *
msaretteed039b2015-03-18 11:11:19 -0700352 * Swizzle the specified row
msarett74114382015-03-16 11:55:18 -0700353 *
354 */
msaretta4970dc2016-01-11 07:23:23 -0800355void SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -0700356 SkASSERT(nullptr != dst && nullptr != src);
msaretta4970dc2016-01-11 07:23:23 -0800357 fRowProc(dst, src, fDstWidth, fMasks, fX0, fSampleX);
msarett74114382015-03-16 11:55:18 -0700358}