123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- /*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/private/SkColorData.h"
- #include "src/codec/SkCodecPriv.h"
- #include "src/codec/SkMaskSwizzler.h"
- static void swizzle_mask16_to_rgba_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask16_to_bgra_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask16_to_rgba_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask16_to_bgra_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask16_to_rgba_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask16_to_bgra_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- // TODO (msarett): We have promoted a two byte per pixel image to 8888, only to
- // convert it back to 565. Instead, we should swizzle to 565 directly.
- static void swizzle_mask16_to_565(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint16_t* srcPtr = ((uint16_t*) srcRow) + startX;
- uint16_t* dstPtr = (uint16_t*) dstRow;
- for (int i = 0; i < width; i++) {
- uint16_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPack888ToRGB16(red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask24_to_rgba_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_bgra_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_rgba_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_bgra_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_rgba_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_bgra_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask24_to_565(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- srcRow += 3 * startX;
- uint16_t* dstPtr = (uint16_t*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcRow[0] | (srcRow[1] << 8) | srcRow[2] << 16;
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPack888ToRGB16(red, green, blue);
- srcRow += 3 * sampleX;
- }
- }
- static void swizzle_mask32_to_rgba_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_RGBA(0xFF, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_bgra_opaque(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPackARGB_as_BGRA(0xFF, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_rgba_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_RGBA(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_bgra_unpremul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = SkPackARGB_as_BGRA(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_rgba_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_rgba(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_bgra_premul(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- SkPMColor* dstPtr = (SkPMColor*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- uint8_t alpha = masks->getAlpha(p);
- dstPtr[i] = premultiply_argb_as_bgra(alpha, red, green, blue);
- srcPtr += sampleX;
- }
- }
- static void swizzle_mask32_to_565(
- void* dstRow, const uint8_t* srcRow, int width, SkMasks* masks,
- uint32_t startX, uint32_t sampleX) {
- // Use the masks to decode to the destination
- uint32_t* srcPtr = ((uint32_t*) srcRow) + startX;
- uint16_t* dstPtr = (uint16_t*) dstRow;
- for (int i = 0; i < width; i++) {
- uint32_t p = srcPtr[0];
- uint8_t red = masks->getRed(p);
- uint8_t green = masks->getGreen(p);
- uint8_t blue = masks->getBlue(p);
- dstPtr[i] = SkPack888ToRGB16(red, green, blue);
- srcPtr += sampleX;
- }
- }
- /*
- *
- * Create a new mask swizzler
- *
- */
- SkMaskSwizzler* SkMaskSwizzler::CreateMaskSwizzler(const SkImageInfo& dstInfo,
- bool srcIsOpaque, SkMasks* masks, uint32_t bitsPerPixel,
- const SkCodec::Options& options) {
- // Choose the appropriate row procedure
- RowProc proc = nullptr;
- switch (bitsPerPixel) {
- case 16:
- switch (dstInfo.colorType()) {
- case kRGBA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask16_to_rgba_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask16_to_rgba_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask16_to_rgba_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kBGRA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask16_to_bgra_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask16_to_bgra_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask16_to_bgra_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kRGB_565_SkColorType:
- proc = &swizzle_mask16_to_565;
- break;
- default:
- break;
- }
- break;
- case 24:
- switch (dstInfo.colorType()) {
- case kRGBA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask24_to_rgba_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask24_to_rgba_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask24_to_rgba_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kBGRA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask24_to_bgra_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask24_to_bgra_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask24_to_bgra_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kRGB_565_SkColorType:
- proc = &swizzle_mask24_to_565;
- break;
- default:
- break;
- }
- break;
- case 32:
- switch (dstInfo.colorType()) {
- case kRGBA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask32_to_rgba_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask32_to_rgba_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask32_to_rgba_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kBGRA_8888_SkColorType:
- if (srcIsOpaque) {
- proc = &swizzle_mask32_to_bgra_opaque;
- } else {
- switch (dstInfo.alphaType()) {
- case kUnpremul_SkAlphaType:
- proc = &swizzle_mask32_to_bgra_unpremul;
- break;
- case kPremul_SkAlphaType:
- proc = &swizzle_mask32_to_bgra_premul;
- break;
- default:
- break;
- }
- }
- break;
- case kRGB_565_SkColorType:
- proc = &swizzle_mask32_to_565;
- break;
- default:
- break;
- }
- break;
- default:
- SkASSERT(false);
- return nullptr;
- }
- int srcOffset = 0;
- int srcWidth = dstInfo.width();
- if (options.fSubset) {
- srcOffset = options.fSubset->left();
- srcWidth = options.fSubset->width();
- }
- return new SkMaskSwizzler(masks, proc, srcOffset, srcWidth);
- }
- /*
- *
- * Constructor for mask swizzler
- *
- */
- SkMaskSwizzler::SkMaskSwizzler(SkMasks* masks, RowProc proc, int srcOffset, int subsetWidth)
- : fMasks(masks)
- , fRowProc(proc)
- , fSubsetWidth(subsetWidth)
- , fDstWidth(subsetWidth)
- , fSampleX(1)
- , fSrcOffset(srcOffset)
- , fX0(srcOffset)
- {}
- int SkMaskSwizzler::onSetSampleX(int sampleX) {
- // FIXME: Share this function with SkSwizzler?
- SkASSERT(sampleX > 0); // Surely there is an upper limit? Should there be
- // way to report failure?
- fSampleX = sampleX;
- fX0 = get_start_coord(sampleX) + fSrcOffset;
- fDstWidth = get_scaled_dimension(fSubsetWidth, sampleX);
- // check that fX0 is valid
- SkASSERT(fX0 >= 0);
- return fDstWidth;
- }
- /*
- *
- * Swizzle the specified row
- *
- */
- void SkMaskSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
- SkASSERT(nullptr != dst && nullptr != src);
- fRowProc(dst, src, fDstWidth, fMasks, fX0, fSampleX);
- }
|