blob: 7630a7b59f063b403cee46295ee1d59380a88456 [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:
msarettebf44082016-02-03 13:12:38 -0800238 if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
239 proc = &swizzle_mask16_to_n32_opaque;
240 } else {
241 switch (dstInfo.alphaType()) {
242 case kUnpremul_SkAlphaType:
243 proc = &swizzle_mask16_to_n32_unpremul;
244 break;
245 case kPremul_SkAlphaType:
246 proc = &swizzle_mask16_to_n32_premul;
247 break;
248 default:
249 break;
250 }
msaretteed039b2015-03-18 11:11:19 -0700251 }
252 break;
scroggocc2feb12015-08-14 08:32:46 -0700253 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800254 proc = &swizzle_mask16_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700255 break;
msaretteed039b2015-03-18 11:11:19 -0700256 default:
257 break;
msarett74114382015-03-16 11:55:18 -0700258 }
259 break;
260 case 24:
msarett5406d6f2015-08-31 06:55:13 -0700261 switch (dstInfo.colorType()) {
msaretteed039b2015-03-18 11:11:19 -0700262 case kN32_SkColorType:
msarettebf44082016-02-03 13:12:38 -0800263 if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
264 proc = &swizzle_mask24_to_n32_opaque;
265 } else {
266 switch (dstInfo.alphaType()) {
267 case kUnpremul_SkAlphaType:
268 proc = &swizzle_mask24_to_n32_unpremul;
269 break;
270 case kPremul_SkAlphaType:
271 proc = &swizzle_mask24_to_n32_premul;
272 break;
273 default:
274 break;
275 }
msaretteed039b2015-03-18 11:11:19 -0700276 }
277 break;
scroggocc2feb12015-08-14 08:32:46 -0700278 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800279 proc = &swizzle_mask24_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700280 break;
msaretteed039b2015-03-18 11:11:19 -0700281 default:
282 break;
msarett74114382015-03-16 11:55:18 -0700283 }
284 break;
285 case 32:
msarett5406d6f2015-08-31 06:55:13 -0700286 switch (dstInfo.colorType()) {
msaretteed039b2015-03-18 11:11:19 -0700287 case kN32_SkColorType:
msarettebf44082016-02-03 13:12:38 -0800288 if (kOpaque_SkAlphaType == srcInfo.alphaType()) {
289 proc = &swizzle_mask32_to_n32_opaque;
290 } else {
291 switch (dstInfo.alphaType()) {
292 case kUnpremul_SkAlphaType:
293 proc = &swizzle_mask32_to_n32_unpremul;
294 break;
295 case kPremul_SkAlphaType:
296 proc = &swizzle_mask32_to_n32_premul;
297 break;
298 default:
299 break;
300 }
msaretteed039b2015-03-18 11:11:19 -0700301 }
302 break;
scroggocc2feb12015-08-14 08:32:46 -0700303 case kRGB_565_SkColorType:
scroggoc5560be2016-02-03 09:42:42 -0800304 proc = &swizzle_mask32_to_565;
scroggocc2feb12015-08-14 08:32:46 -0700305 break;
msaretteed039b2015-03-18 11:11:19 -0700306 default:
307 break;
msarett74114382015-03-16 11:55:18 -0700308 }
309 break;
310 default:
311 SkASSERT(false);
halcanary96fcdcc2015-08-27 07:41:13 -0700312 return nullptr;
msarett74114382015-03-16 11:55:18 -0700313 }
msarett5406d6f2015-08-31 06:55:13 -0700314
msarettfdb47572015-10-13 12:50:14 -0700315 int srcOffset = 0;
316 int srcWidth = dstInfo.width();
317 if (options.fSubset) {
318 srcOffset = options.fSubset->left();
319 srcWidth = options.fSubset->width();
320 }
321
322 return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth);
msarett74114382015-03-16 11:55:18 -0700323}
324
325/*
326 *
327 * Constructor for mask swizzler
328 *
329 */
msarett80803ff2015-10-16 10:54:12 -0700330SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int subsetWidth)
scroggoe7fc14b2015-10-02 13:14:46 -0700331 : fMasks(masks)
msarett74114382015-03-16 11:55:18 -0700332 , fRowProc(proc)
msarett80803ff2015-10-16 10:54:12 -0700333 , fSubsetWidth(subsetWidth)
334 , fDstWidth(subsetWidth)
scroggoe7fc14b2015-10-02 13:14:46 -0700335 , fSampleX(1)
msarettfdb47572015-10-13 12:50:14 -0700336 , fSrcOffset(srcOffset)
337 , fX0(srcOffset)
msarett74114382015-03-16 11:55:18 -0700338{}
339
scroggoe7fc14b2015-10-02 13:14:46 -0700340int SkMaskSwizzler::onSetSampleX(int sampleX) {
341 // FIXME: Share this function with SkSwizzler?
342 SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
343 // way to report failure?
344 fSampleX = sampleX;
msarettfdb47572015-10-13 12:50:14 -0700345 fX0 = get_start_coord(sampleX) + fSrcOffset;
msarett80803ff2015-10-16 10:54:12 -0700346 fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX);
scroggoe7fc14b2015-10-02 13:14:46 -0700347
msarett80803ff2015-10-16 10:54:12 -0700348 // check that fX0 is valid
349 SkASSERT(fX0 >= 0);
scroggoe7fc14b2015-10-02 13:14:46 -0700350 return fDstWidth;
351}
352
msarett74114382015-03-16 11:55:18 -0700353/*
354 *
msaretteed039b2015-03-18 11:11:19 -0700355 * Swizzle the specified row
msarett74114382015-03-16 11:55:18 -0700356 *
357 */
msaretta4970dc2016-01-11 07:23:23 -0800358void SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
halcanary96fcdcc2015-08-27 07:41:13 -0700359 SkASSERT(nullptr != dst && nullptr != src);
msaretta4970dc2016-01-11 07:23:23 -0800360 fRowProc(dst, src, fDstWidth, fMasks, fX0, fSampleX);
msarett74114382015-03-16 11:55:18 -0700361}