diff options
author | Matt Sarett <msarett@google.com> | 2016-11-07 10:26:17 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-07 16:00:11 +0000 |
commit | a225e9be53001a8397344ce1e272a7df2fced499 (patch) | |
tree | bb99b48a9cccfa82e4da7dff98ac60fd63c58b45 | |
parent | 84a812061f1d16aa6d349ca065bf67d06767bbc2 (diff) |
Finish color space support for SkCodec
Implements color space xforms and F16 for SkRawCodec and SkWbmpCodec.
BUG=skia:4895
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4459
Change-Id: I8c72918e46387350b49a9811ce654d26b1ab352a
Reviewed-on: https://skia-review.googlesource.com/4459
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
-rw-r--r-- | infra/bots/assets/skimage/VERSION | 2 | ||||
-rw-r--r-- | infra/bots/tasks.json | 6 | ||||
-rw-r--r-- | src/android/SkBitmapRegionCodec.cpp | 2 | ||||
-rw-r--r-- | src/codec/SkCodecPriv.h | 30 | ||||
-rw-r--r-- | src/codec/SkRawCodec.cpp | 33 | ||||
-rw-r--r-- | src/codec/SkSwizzler.cpp | 33 | ||||
-rw-r--r-- | src/codec/SkWbmpCodec.cpp | 14 |
7 files changed, 72 insertions, 48 deletions
diff --git a/infra/bots/assets/skimage/VERSION b/infra/bots/assets/skimage/VERSION index b4de394767..3cacc0b93c 100644 --- a/infra/bots/assets/skimage/VERSION +++ b/infra/bots/assets/skimage/VERSION @@ -1 +1 @@ -11 +12
\ No newline at end of file diff --git a/infra/bots/tasks.json b/infra/bots/tasks.json index 764d1ec720..6ff2106a88 100644 --- a/infra/bots/tasks.json +++ b/infra/bots/tasks.json @@ -168,7 +168,7 @@ { "name": "skia/bots/skimage", "path": "skimage", - "version": "version:11" + "version": "version:12" }, { "name": "skia/bots/skp", @@ -214,7 +214,7 @@ { "name": "skia/bots/skimage", "path": "skimage", - "version": "version:11" + "version": "version:12" }, { "name": "skia/bots/skp", @@ -259,7 +259,7 @@ { "name": "skia/bots/skimage", "path": "skimage", - "version": "version:11" + "version": "version:12" }, { "name": "skia/bots/skp", diff --git a/src/android/SkBitmapRegionCodec.cpp b/src/android/SkBitmapRegionCodec.cpp index df0a32ca31..7c51fc80d3 100644 --- a/src/android/SkBitmapRegionCodec.cpp +++ b/src/android/SkBitmapRegionCodec.cpp @@ -138,5 +138,5 @@ bool SkBitmapRegionCodec::conversionSupported(SkColorType colorType) { // Enable legacy behavior. sk_sp<SkColorSpace> colorSpace = nullptr; SkImageInfo dstInfo = fCodec->getInfo().makeColorType(colorType).makeColorSpace(colorSpace); - return conversion_possible_ignore_color_space(dstInfo, fCodec->getInfo()); + return conversion_possible(dstInfo, fCodec->getInfo()); } diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h index bf3ab291e2..75fbcf224e 100644 --- a/src/codec/SkCodecPriv.h +++ b/src/codec/SkCodecPriv.h @@ -109,36 +109,6 @@ static inline bool valid_alpha(SkAlphaType dstAlpha, SkAlphaType srcAlpha) { } /* - * Original version of conversion_possible that does not account for color spaces. - * Used by codecs that have not been updated to support color spaces. - * - * Most of our codecs support the same conversions: - * - opaque to any alpha type - * - 565 only if opaque - * - premul to unpremul and vice versa - * - always support RGBA, BGRA - * - otherwise match the src color type - */ -static inline bool conversion_possible_ignore_color_space(const SkImageInfo& dst, - const SkImageInfo& src) { - // Ensure the alpha type is valid - if (!valid_alpha(dst.alphaType(), src.alphaType())) { - return false; - } - - // Check for supported color types - switch (dst.colorType()) { - case kRGBA_8888_SkColorType: - case kBGRA_8888_SkColorType: - return true; - case kRGB_565_SkColorType: - return kOpaque_SkAlphaType == src.alphaType(); - default: - return dst.colorType() == src.colorType(); - } -} - -/* * If there is a color table, get a pointer to the colors, otherwise return nullptr */ static inline const SkPMColor* get_color_ptr(SkColorTable* colorTable) { diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp index 26519e6f03..151363239c 100644 --- a/src/codec/SkRawCodec.cpp +++ b/src/codec/SkRawCodec.cpp @@ -679,21 +679,28 @@ SkCodec* SkRawCodec::NewFromStream(SkStream* stream) { return new SkRawCodec(dngImage.release()); } -SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst, +SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options& options, SkPMColor ctable[], int* ctableCount, int* rowsDecoded) { - if (!conversion_possible_ignore_color_space(requestedInfo, this->getInfo())) { + if (!conversion_possible(dstInfo, this->getInfo()) || !this->initializeColorXform(dstInfo)) { SkCodecPrintf("Error: cannot convert input type to output type.\n"); return kInvalidConversion; } + SkImageInfo swizzlerInfo = dstInfo; + std::unique_ptr<uint32_t[]> xformBuffer = nullptr; + if (this->colorXform()) { + swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType); + xformBuffer.reset(new uint32_t[dstInfo.width()]); + } + std::unique_ptr<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler( - this->getEncodedInfo(), nullptr, requestedInfo, options)); + this->getEncodedInfo(), nullptr, swizzlerInfo, options)); SkASSERT(swizzler); - const int width = requestedInfo.width(); - const int height = requestedInfo.height(); + const int width = dstInfo.width(); + const int height = dstInfo.height(); std::unique_ptr<dng_image> image(fDngImage->render(width, height)); if (!image) { return kInvalidInput; @@ -731,8 +738,20 @@ SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& requestedInfo, void* return kIncompleteInput; } - swizzler->swizzle(dstRow, &srcRow[0]); - dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); + if (this->colorXform()) { + swizzler->swizzle(xformBuffer.get(), &srcRow[0]); + + const SkColorSpaceXform::ColorFormat srcFormat = + SkColorSpaceXform::kRGBA_8888_ColorFormat; + const SkColorSpaceXform::ColorFormat dstFormat = + select_xform_format(dstInfo.colorType()); + this->colorXform()->apply(dstFormat, dstRow, srcFormat, xformBuffer.get(), + dstInfo.width(), kOpaque_SkAlphaType); + dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); + } else { + swizzler->swizzle(dstRow, &srcRow[0]); + dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); + } } return kSuccess; } diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp index c9eb923053..0bbe824dc2 100644 --- a/src/codec/SkSwizzler.cpp +++ b/src/codec/SkSwizzler.cpp @@ -7,6 +7,7 @@ #include "SkCodecPriv.h" #include "SkColorPriv.h" +#include "SkHalf.h" #include "SkOpts.h" #include "SkSwizzler.h" #include "SkTemplates.h" @@ -150,6 +151,35 @@ static void swizzle_bit_to_565( #undef RGB565_BLACK #undef RGB565_WHITE +static void swizzle_bit_to_f16( + void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, + int bpp, int deltaSrc, int offset, const SkPMColor* /*ctable*/) { + static const uint64_t kWhite = (((uint64_t) SK_Half1) << 0) | + (((uint64_t) SK_Half1) << 16) | + (((uint64_t) SK_Half1) << 32) | + (((uint64_t) SK_Half1) << 48); + static const uint64_t kBlack = (((uint64_t) 0) << 0) | + (((uint64_t) 0) << 16) | + (((uint64_t) 0) << 32) | + (((uint64_t) SK_Half1) << 48); + + uint64_t* SK_RESTRICT dst = (uint64_t*) dstRow; + + // increment src by byte offset and bitIndex by bit offset + src += offset / 8; + int bitIndex = offset % 8; + uint8_t currByte = *src; + + dst[0] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack; + + for (int x = 1; x < dstWidth; x++) { + int bitOffset = bitIndex + deltaSrc; + bitIndex = bitOffset % 8; + currByte = *(src += bitOffset / 8); + dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? kWhite : kBlack; + } +} + // kIndex1, kIndex2, kIndex4 static void swizzle_small_index_to_index( @@ -700,6 +730,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(const SkEncodedInfo& encodedInfo, case kGray_8_SkColorType: proc = &swizzle_bit_to_grayscale; break; + case kRGBA_F16_SkColorType: + proc = &swizzle_bit_to_f16; + break; default: return nullptr; } diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp index 4102bf2607..19c8c7db37 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -30,14 +30,16 @@ static inline void setup_color_table(SkColorType colorType, } } -static inline bool valid_color_type(SkColorType colorType) { - switch (colorType) { +static inline bool valid_color_type(const SkImageInfo& dstInfo) { + switch (dstInfo.colorType()) { case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: case kIndex_8_SkColorType: case kGray_8_SkColorType: case kRGB_565_SkColorType: return true; + case kRGBA_F16_SkColorType: + return dstInfo.colorSpace() && dstInfo.colorSpace()->gammaIsLinear(); default: return false; } @@ -127,8 +129,7 @@ SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info, return kUnimplemented; } - if (!valid_color_type(info.colorType()) || - !valid_alpha(info.alphaType(), this->getInfo().alphaType())) { + if (!valid_color_type(info) || !valid_alpha(info.alphaType(), this->getInfo().alphaType())) { return kInvalidConversion; } @@ -194,8 +195,9 @@ SkCodec::Result SkWbmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kUnimplemented; } - if (!valid_color_type(dstInfo.colorType()) || - !valid_alpha(dstInfo.alphaType(), this->getInfo().alphaType())) { + if (!valid_color_type(dstInfo) || + !valid_alpha(dstInfo.alphaType(), this->getInfo().alphaType())) + { return kInvalidConversion; } |