aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec
diff options
context:
space:
mode:
authorGravatar emmaleer <emmaleer@google.com>2015-08-13 11:44:05 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-08-13 11:44:05 -0700
commite5aaa07c351815f023a0842820eb769c6d4b4ed3 (patch)
treeb0ec62be476f4201fa1306c30662df70466761df /src/codec
parent0944100ac89f797714eeae0cf2875e2335ff52ee (diff)
Revert of SkScaledCodec class (patchset #32 id:620001 of https://codereview.chromium.org/1260673002/ )
Reason for revert: Segfaulting: http://build.chromium.org/p/client.skia/builders/Test-Ubuntu-GCC-GCE-CPU-AVX2-x86-Release/builds/1605/steps/dm/logs/stdio Original issue's description: > SkScaledCodec class > > This class does scaling by using a scanlineDecoder. > getScanlines and skipScanlines are used for y sampling, > the swizzler is used for x sampling > > this class is currently only working for png and jpeg images > I will update other Codec types to work soon > > For SkJpegCodec to implement width wise swizzling it now > uses a swizzler. I ran performance tests on this change. > Here are the performance test results: > https://docs.google.com/a/google.com/spreadsheets/d/1D7-Q_GXD_dI68LZO005NNvb8Wq2Ee0wEBEPG72671yw/edit?usp=sharing > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/0944100ac89f797714eeae0cf2875e2335ff52ee TBR=scroggo@google.com,msarett@google.com,djsollen@google.com,mtklein@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/1294593002
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/SkBmpStandardCodec.cpp2
-rw-r--r--src/codec/SkCodec_libgif.cpp5
-rw-r--r--src/codec/SkCodec_libpng.cpp33
-rw-r--r--src/codec/SkCodec_libpng.h2
-rw-r--r--src/codec/SkCodec_wbmp.cpp15
-rw-r--r--src/codec/SkJpegCodec.cpp117
-rw-r--r--src/codec/SkJpegCodec.h14
-rw-r--r--src/codec/SkScaledCodec.cpp261
-rw-r--r--src/codec/SkSwizzler.cpp341
-rw-r--r--src/codec/SkSwizzler.h27
10 files changed, 198 insertions, 619 deletions
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 1dfd04ee21..08146fc3e4 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -237,7 +237,7 @@ bool SkBmpStandardCodec::initializeSwizzler(const SkImageInfo& dstInfo,
// Create swizzler
fSwizzler.reset(SkSwizzler::CreateSwizzler(config,
- colorPtr, dstInfo, opts.fZeroInitialized, this->getInfo()));
+ colorPtr, dstInfo, opts.fZeroInitialized));
if (NULL == fSwizzler.get()) {
return false;
diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp
index fa267e83e9..2e348cc856 100644
--- a/src/codec/SkCodec_libgif.cpp
+++ b/src/codec/SkCodec_libgif.cpp
@@ -444,12 +444,11 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
// Create the subset swizzler
swizzler.reset(SkSwizzler::CreateSwizzler(
SkSwizzler::kIndex, colorTable, subsetDstInfo,
- zeroInit, this->getInfo()));
+ zeroInit));
} else {
// Create the fully dimensional swizzler
swizzler.reset(SkSwizzler::CreateSwizzler(
- SkSwizzler::kIndex, colorTable, dstInfo,
- zeroInit, this->getInfo()));
+ SkSwizzler::kIndex, colorTable, dstInfo, zeroInit));
}
// Stores output from dgiflib and input to the swizzler
diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp
index 159aecd7ef..c94f371399 100644
--- a/src/codec/SkCodec_libpng.cpp
+++ b/src/codec/SkCodec_libpng.cpp
@@ -11,7 +11,6 @@
#include "SkColorTable.h"
#include "SkBitmap.h"
#include "SkMath.h"
-#include "SkScaledCodec.h"
#include "SkScanlineDecoder.h"
#include "SkSize.h"
#include "SkStream.h"
@@ -463,7 +462,7 @@ SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo,
// Create the swizzler. SkPngCodec retains ownership of the color table.
const SkPMColor* colors = get_color_ptr(fColorTable.get());
fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo,
- options.fZeroInitialized, this->getInfo()));
+ options.fZeroInitialized));
if (!fSwizzler) {
// FIXME: CreateSwizzler could fail for another reason.
return kUnimplemented;
@@ -583,7 +582,8 @@ public:
SkCodec::Result onStart(const SkImageInfo& dstInfo,
const SkCodec::Options& options,
- SkPMColor ctable[], int* ctableCount) override {
+ SkPMColor ctable[], int* ctableCount) override
+ {
if (!fCodec->rewindIfNeeded()) {
return SkCodec::kCouldNotRewind;
}
@@ -594,9 +594,7 @@ public:
// Check to see if scaling was requested.
if (dstInfo.dimensions() != this->getInfo().dimensions()) {
- if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
- return SkCodec::kInvalidScale;
- }
+ return SkCodec::kInvalidScale;
}
const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, options, ctable,
@@ -606,7 +604,7 @@ public:
}
fHasAlpha = false;
- fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig));
+ fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig));
fSrcRow = static_cast<uint8_t*>(fStorage.get());
return SkCodec::kSuccess;
@@ -645,11 +643,6 @@ public:
bool onReallyHasAlpha() const override { return fHasAlpha; }
- SkEncodedFormat onGetEncodedFormat() const override {
- return kPNG_SkEncodedFormat;
- }
-
-
private:
SkAutoTDelete<SkPngCodec> fCodec;
bool fHasAlpha;
@@ -680,14 +673,12 @@ public:
}
if (!conversion_possible(dstInfo, this->getInfo())) {
- return SkCodec::kInvalidConversion;
+ return SkCodec::kInvalidConversion;
}
// Check to see if scaling was requested.
if (dstInfo.dimensions() != this->getInfo().dimensions()) {
- if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
- return SkCodec::kInvalidScale;
- }
+ return SkCodec::kInvalidScale;
}
const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, options, ctable,
@@ -699,7 +690,7 @@ public:
fHasAlpha = false;
fCurrentRow = 0;
fHeight = dstInfo.height();
- fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig);
+ fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcConfig);
fGarbageRow.reset(fSrcRowBytes);
fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
fCanSkipRewind = true;
@@ -762,14 +753,6 @@ public:
bool onReallyHasAlpha() const override { return fHasAlpha; }
- bool onRequiresPostYSampling() override {
- return true;
- }
-
- SkEncodedFormat onGetEncodedFormat() const override {
- return kPNG_SkEncodedFormat;
- }
-
private:
SkAutoTDelete<SkPngCodec> fCodec;
bool fHasAlpha;
diff --git a/src/codec/SkCodec_libpng.h b/src/codec/SkCodec_libpng.h
index e8807499ea..890402200c 100644
--- a/src/codec/SkCodec_libpng.h
+++ b/src/codec/SkCodec_libpng.h
@@ -37,7 +37,6 @@ protected:
SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedFormat; }
bool onRewind() override;
bool onReallyHasAlpha() const override { return fReallyHasAlpha; }
-
private:
png_structp fPng_ptr;
png_infop fInfo_ptr;
@@ -53,6 +52,7 @@ private:
SkPngCodec(const SkImageInfo&, SkStream*, png_structp, png_infop, int);
+
// Helper to set up swizzler and color table. Also calls png_read_update_info.
Result initializeSwizzler(const SkImageInfo& requestedInfo, const Options&,
SkPMColor*, int* ctableCount);
diff --git a/src/codec/SkCodec_wbmp.cpp b/src/codec/SkCodec_wbmp.cpp
index 3081a3bba9..6f98294fc6 100644
--- a/src/codec/SkCodec_wbmp.cpp
+++ b/src/codec/SkCodec_wbmp.cpp
@@ -9,7 +9,6 @@
#include "SkCodecPriv.h"
#include "SkColorPriv.h"
#include "SkColorTable.h"
-#include "SkScaledCodec.h"
#include "SkStream.h"
#include "SkCodec_wbmp.h"
@@ -81,8 +80,8 @@ SkSwizzler* SkWbmpCodec::initializeSwizzler(const SkImageInfo& info,
case kIndex_8_SkColorType:
case kN32_SkColorType:
case kGray_8_SkColorType:
- return SkSwizzler::CreateSwizzler(SkSwizzler::kBit, ctable, info, opts.fZeroInitialized,
- this->getInfo());
+ return SkSwizzler::CreateSwizzler(
+ SkSwizzler::kBit, ctable, info, opts.fZeroInitialized);
default:
return NULL;
}
@@ -202,9 +201,7 @@ public:
return SkCodec::kUnimplemented;
}
if (dstInfo.dimensions() != this->getInfo().dimensions()) {
- if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
- return SkCodec::kInvalidScale;
- }
+ return SkCodec::kInvalidScale;
}
if (!valid_alpha(dstInfo.alphaType(), this->getInfo().alphaType())) {
@@ -223,16 +220,12 @@ public:
fSwizzler.reset(fCodec->initializeSwizzler(dstInfo,
get_color_ptr(fColorTable.get()), options));
if (NULL == fSwizzler.get()) {
- return SkCodec::kInvalidConversion;
+ return SkCodec::kInvalidInput;
}
return SkCodec::kSuccess;
}
- SkEncodedFormat onGetEncodedFormat() const {
- return kWBMP_SkEncodedFormat;
- }
-
private:
SkAutoTDelete<SkWbmpCodec> fCodec;
SkAutoTUnref<SkColorTable> fColorTable;
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index c094d50a3b..83656da42d 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -11,7 +11,6 @@
#include "SkJpegUtility_codec.h"
#include "SkCodecPriv.h"
#include "SkColorPriv.h"
-#include "SkScaledCodec.h"
#include "SkScanlineDecoder.h"
#include "SkStream.h"
#include "SkTemplates.h"
@@ -150,14 +149,6 @@ SkJpegCodec::SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream,
{}
/*
- * Return the row bytes of a particular image type and width
- */
-static int get_row_bytes(const j_decompress_ptr dinfo) {
- int colorBytes = (dinfo->out_color_space == JCS_RGB565) ? 2 : dinfo->out_color_components;
- return dinfo->output_width * colorBytes;
-
-}
-/*
* Return a valid set of output dimensions for this decoder, given an input scale
*/
SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
@@ -267,10 +258,10 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) {
}
/*
- * Checks if we can natively scale to the requested dimensions and natively scales the
- * dimensions if possible
+ * Checks if we can scale to the requested dimensions and scales the dimensions
+ * if possible
*/
-bool SkJpegCodec::nativelyScaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) {
+bool SkJpegCodec::scaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) {
// libjpeg-turbo can scale to 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, and 1/1
fDecoderMgr->dinfo()->scale_denom = 8;
fDecoderMgr->dinfo()->scale_num = 8;
@@ -282,10 +273,7 @@ bool SkJpegCodec::nativelyScaleToDimensions(uint32_t dstWidth, uint32_t dstHeigh
if (1 == fDecoderMgr->dinfo()->scale_num ||
dstWidth > fDecoderMgr->dinfo()->output_width ||
dstHeight > fDecoderMgr->dinfo()->output_height) {
- // reset native scale settings on failure because this may be supported by the swizzler
- this->fDecoderMgr->dinfo()->scale_num = 8;
- chromium_jpeg_calc_output_dimensions(this->fDecoderMgr->dinfo());
- return false;
+ return fDecoderMgr->returnFalse("could not scale to requested dimensions");
}
// Try the next scale
@@ -325,7 +313,7 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
}
// Perform the necessary scaling
- if (!this->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) {
+ if (!this->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
return fDecoderMgr->returnFailure("cannot scale to requested dims", kInvalidScale);
}
@@ -393,47 +381,6 @@ public:
, fOpts()
{}
- /*
- * Return a valid set of output dimensions for this decoder, given an input scale
- */
- SkISize onGetScaledDimensions(float desiredScale) override {
- return fCodec->onGetScaledDimensions(desiredScale);
- }
-
- /*
- * Create the swizzler based on the encoded format.
- * The swizzler is only used for sampling in the x direction.
- */
-
- SkCodec::Result initializeSwizzler(const SkImageInfo& info, const SkCodec::Options& options) {
- SkSwizzler::SrcConfig srcConfig;
- switch (info.colorType()) {
- case kGray_8_SkColorType:
- srcConfig = SkSwizzler::kGray;
- break;
- case kRGBA_8888_SkColorType:
- srcConfig = SkSwizzler::kRGBX;
- break;
- case kBGRA_8888_SkColorType:
- srcConfig = SkSwizzler::kBGRX;
- break;
- case kRGB_565_SkColorType:
- srcConfig = SkSwizzler::kRGB_565;
- break;
- default:
- //would have exited before now if the colorType was supported by jpeg
- SkASSERT(false);
- }
-
- fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, NULL, info, options.fZeroInitialized,
- this->getInfo()));
- if (!fSwizzler) {
- // FIXME: CreateSwizzler could fail for another reason.
- return SkCodec::kUnimplemented;
- }
- return SkCodec::kSuccess;
- }
-
SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options& options,
SkPMColor ctable[], int* ctableCount) override {
@@ -454,23 +401,8 @@ public:
}
// Perform the necessary scaling
- if (!fCodec->nativelyScaleToDimensions(dstInfo.width(), dstInfo.height())) {
- // full native scaling to dstInfo dimensions not supported
-
- if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
- return SkCodec::kInvalidScale;
- }
- // create swizzler for sampling
- SkCodec::Result result = this->initializeSwizzler(dstInfo, options);
- if (SkCodec::kSuccess != result) {
- SkCodecPrintf("failed to initialize the swizzler.\n");
- return result;
- }
- fStorage.reset(get_row_bytes(fCodec->fDecoderMgr->dinfo()));
- fSrcRow = static_cast<uint8_t*>(fStorage.get());
- } else {
- fSrcRow = NULL;
- fSwizzler.reset(NULL);
+ if (!fCodec->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
+ return SkCodec::kInvalidScale;
}
// Now, given valid output dimensions, we can start the decompress
@@ -501,16 +433,9 @@ public:
if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvalidInput);
}
- // Read rows one at a time
- JSAMPLE* dstRow;
- if (fSwizzler) {
- // write data to storage row, then sample using swizzler
- dstRow = fSrcRow;
- } else {
- // write data directly to dst
- dstRow = (JSAMPLE*) dst;
- }
+ // Read rows one at a time
+ JSAMPLE* dstRow = (JSAMPLE*) dst;
for (int y = 0; y < count; y++) {
// Read row of the image
uint32_t rowsDecoded =
@@ -527,17 +452,13 @@ public:
// Convert to RGBA if necessary
if (JCS_CMYK == fCodec->fDecoderMgr->dinfo()->out_color_space) {
- convert_CMYK_to_RGBA(dstRow, fCodec->fDecoderMgr->dinfo()->output_width);
+ convert_CMYK_to_RGBA(dstRow, this->dstInfo().width());
}
- if(fSwizzler) {
- // use swizzler to sample row
- fSwizzler->swizzle(dst, dstRow);
- dst = SkTAddOffset<JSAMPLE>(dst, rowBytes);
- } else {
- dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes);
- }
+ // Move to the next row
+ dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes);
}
+
return SkCodec::kSuccess;
}
@@ -545,7 +466,7 @@ public:
// TODO (msarett): Make this a member function and avoid reallocating the
// memory buffer on each call to skip.
#define chromium_jpeg_skip_scanlines(dinfo, count) \
- SkAutoMalloc storage(get_row_bytes(dinfo)); \
+ SkAutoMalloc storage(dinfo->output_width * dinfo->out_color_components); \
uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); \
for (int y = 0; y < count; y++) { \
chromium_jpeg_read_scanlines(dinfo, &storagePtr, 1); \
@@ -563,16 +484,13 @@ public:
return SkCodec::kSuccess;
}
- SkEncodedFormat onGetEncodedFormat() const override {
- return kJPEG_SkEncodedFormat;
- }
+#ifndef TURBO_HAS_SKIP
+#undef chromium_jpeg_skip_scanlines
+#endif
private:
SkAutoTDelete<SkJpegCodec> fCodec;
- SkAutoMalloc fStorage; // Only used if sampling is needed
- uint8_t* fSrcRow; // Only used if sampling is needed
SkCodec::Options fOpts;
- SkAutoTDelete<SkSwizzler> fSwizzler;
typedef SkScanlineDecoder INHERITED;
};
@@ -584,7 +502,6 @@ SkScanlineDecoder* SkJpegCodec::NewSDFromStream(SkStream* stream) {
}
const SkImageInfo& srcInfo = codec->getInfo();
-
// Return the new scanline decoder
return SkNEW_ARGS(SkJpegScanlineDecoder, (srcInfo, codec.detach()));
}
diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h
index fac7d96075..62a5bbc4cf 100644
--- a/src/codec/SkJpegCodec.h
+++ b/src/codec/SkJpegCodec.h
@@ -110,13 +110,19 @@ private:
bool setOutputColorSpace(const SkImageInfo& dst);
/*
- * Checks if we can natively scale to the requested dimensions and natively scales the
- * dimensions if possible
+ * Checks if we can scale to the requested dimensions and scales the dimensions
+ * if possible
*/
- bool nativelyScaleToDimensions(uint32_t width, uint32_t height);
+ bool scaleToDimensions(uint32_t width, uint32_t height);
+
+ /*
+ * Create the swizzler based on the encoded format
+ */
+ void initializeSwizzler(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
+ const Options& options);
SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
-
+
friend class SkJpegScanlineDecoder;
typedef SkCodec INHERITED;
diff --git a/src/codec/SkScaledCodec.cpp b/src/codec/SkScaledCodec.cpp
deleted file mode 100644
index e0158b6b4e..0000000000
--- a/src/codec/SkScaledCodec.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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 "SkCodecPriv.h"
-#include "SkScaledCodec.h"
-#include "SkStream.h"
-#include "SkWebpCodec.h"
-
-
-SkCodec* SkScaledCodec::NewFromStream(SkStream* stream) {
- bool isWebp = SkWebpCodec::IsWebp(stream);
- if (!stream->rewind()) {
- return NULL;
- }
- if (isWebp) {
- // Webp codec supports scaling and subsetting natively
- return SkWebpCodec::NewFromStream(stream);
- }
-
- SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewFromStream(stream));
- if (NULL == scanlineDecoder) {
- return NULL;
- }
-
- // wrap in new SkScaledCodec
- return SkNEW_ARGS(SkScaledCodec, (scanlineDecoder.detach()));
-}
-
-SkCodec* SkScaledCodec::NewFromData(SkData* data) {
- if (!data) {
- return NULL;
- }
- return NewFromStream(SkNEW_ARGS(SkMemoryStream, (data)));
-}
-
-SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder)
- : INHERITED(scanlineDecoder->getInfo(), NULL)
- , fScanlineDecoder(scanlineDecoder)
-{}
-
-SkScaledCodec::~SkScaledCodec() {}
-
-// returns a scaled dimension based on the original dimension and the sampleSize
-// NOTE: we round down here for scaled dimension to match the behavior of SkImageDecoder
-static int get_scaled_dimension(int srcDimension, int sampleSize) {
- if (sampleSize > srcDimension) {
- return 1;
- }
- return srcDimension / sampleSize;
-}
-
-static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& nativeDims,
- const SkISize& scaledCodecDims, float desiredScale) {
- if (nativeDims == scaledCodecDims) {
- // does not matter which to return if equal. Return here to skip below calculations
- return nativeDims;
- }
- float idealWidth = origDims.width() * desiredScale;
- float idealHeight = origDims.height() * desiredScale;
-
- // calculate difference between native dimensions and ideal dimensions
- float nativeWDiff = SkTAbs(idealWidth - nativeDims.width());
- float nativeHDiff = SkTAbs(idealHeight - nativeDims.height());
- float nativeDiff = (nativeWDiff + nativeHDiff) / 2;
-
- // calculate difference between scaledCodec dimensions and ideal dimensions
- float scaledCodecWDiff = SkTAbs(idealWidth - scaledCodecDims.width());
- float scaledCodecHDiff = SkTAbs(idealHeight - scaledCodecDims.height());
- float scaledCodecDiff = (scaledCodecWDiff + scaledCodecHDiff) / 2;
-
- // return dimensions closest to ideal dimensions.
- // If the differences are equal, return nativeDims, as native scaling is more efficient.
- return nativeDiff > scaledCodecDiff ? scaledCodecDims : nativeDims;
-
-}
-/*
- * Return a valid set of output dimensions for this decoder, given an input scale
- */
-SkISize SkScaledCodec::onGetScaledDimensions(float desiredScale) const {
- SkISize nativeDimensions = fScanlineDecoder->getScaledDimensions(desiredScale);
- // support scaling down by integer numbers. Ex: 1/2, 1/3, 1/4 ...
- SkISize scaledCodecDimensions;
- if (desiredScale > 0.5f) {
- // sampleSize = 1
- scaledCodecDimensions = fScanlineDecoder->getInfo().dimensions();
- }
- // sampleSize determines the step size between samples
- // Ex: sampleSize = 2, sample every second pixel in x and y directions
- int sampleSize = int(1 / desiredScale);
-
- int scaledWidth = get_scaled_dimension(this->getInfo().width(), sampleSize);
- int scaledHeight = get_scaled_dimension(this->getInfo().height(), sampleSize);
-
- // Return the calculated output dimensions for the given scale
- scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight);
-
- return best_scaled_dimensions(this->getInfo().dimensions(), nativeDimensions,
- scaledCodecDimensions, desiredScale);
-}
-
-// check if scaling to dstInfo size from srcInfo size using sampleSize is possible
-static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
- int* sampleX, int* sampleY) {
- SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, sampleX, sampleY);
- const int dstWidth = dstInfo.width();
- const int dstHeight = dstInfo.height();
- const int srcWidth = srcInfo.width();
- const int srcHeight = srcInfo.height();
- // only support down sampling, not up sampling
- if (dstWidth > srcWidth || dstHeight > srcHeight) {
- return false;
- }
- // check that srcWidth is scaled down by an integer value
- if (get_scaled_dimension(srcWidth, *sampleX) != dstWidth) {
- return false;
- }
- // check that src height is scaled down by an integer value
- if (get_scaled_dimension(srcHeight, *sampleY) != dstHeight) {
- return false;
- }
- // sampleX and sampleY should be equal unless the original sampleSize requested was larger
- // than srcWidth or srcHeight. If so, the result of this is dstWidth or dstHeight = 1.
- // This functionality allows for tall thin images to still be scaled down by scaling factors.
- if (*sampleX != *sampleY){
- if (1 != dstWidth && 1 != dstHeight) {
- return false;
- }
- }
- return true;
-}
-
-// calculates sampleSize in x and y direction
-void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
- int* sampleXPtr, int* sampleYPtr) {
- int srcWidth = srcInfo.width();
- int dstWidth = dstInfo.width();
- int srcHeight = srcInfo.height();
- int dstHeight = dstInfo.height();
-
- int sampleX = srcWidth / dstWidth;
- int sampleY = srcHeight / dstHeight;
-
- // only support down sampling, not up sampling
- SkASSERT(dstWidth <= srcWidth);
- SkASSERT(dstHeight <= srcHeight);
-
- // sampleX and sampleY should be equal unless the original sampleSize requested was
- // larger than srcWidth or srcHeight.
- // If so, the result of this is dstWidth or dstHeight = 1. This functionality
- // allows for tall thin images to still be scaled down by scaling factors.
-
- if (sampleX != sampleY){
- if (1 != dstWidth && 1 != dstHeight) {
-
- // rounding during onGetScaledDimensions can cause different sampleSizes
- // Ex: srcWidth = 79, srcHeight = 20, sampleSize = 10
- // dstWidth = 7, dstHeight = 2, sampleX = 79/7 = 11, sampleY = 20/2 = 10
- // correct for this rounding by comparing width to sampleY and height to sampleX
-
- if (get_scaled_dimension(srcWidth, sampleY) == dstWidth) {
- sampleX = sampleY;
- } else if (get_scaled_dimension(srcHeight, sampleX) == dstHeight) {
- sampleY = sampleX;
- }
- }
- }
-
- if (sampleXPtr) {
- *sampleXPtr = sampleX;
- }
- if (sampleYPtr) {
- *sampleYPtr = sampleY;
- }
-}
-
-// TODO: Implement subsetting in onGetPixels which works when and when not sampling
-
-SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
- size_t rowBytes, const Options& options,
- SkPMColor ctable[], int* ctableCount) {
-
- if (options.fSubset) {
- // Subsets are not supported.
- return kUnimplemented;
- }
-
- Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, ctableCount);
- if (kSuccess == result) {
- // native decode supported
- return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBytes);
-
- }
-
- if (kInvalidScale != result) {
- // no scaling requested
- return result;
- }
-
- // scaling requested
- int sampleX;
- int sampleY;
- if (!scaling_supported(requestedInfo, fScanlineDecoder->getInfo(), &sampleX, &sampleY)) {
- return kInvalidScale;
- }
- // set first sample pixel in y direction
- int Y0 = sampleY >> 1;
-
- int dstHeight = requestedInfo.height();
- int srcHeight = fScanlineDecoder->getInfo().height();
-
- SkImageInfo info = requestedInfo;
- // use original height as scanlineDecoder does not support y sampling natively
- info = info.makeWH(requestedInfo.width(), srcHeight);
-
- // update scanlineDecoder with new info
- result = fScanlineDecoder->start(info, &options, ctable, ctableCount);
- if (kSuccess != result) {
- return result;
- }
-
- const bool requiresPostYSampling = fScanlineDecoder->requiresPostYSampling();
-
- if (requiresPostYSampling) {
- SkAutoMalloc storage(srcHeight * rowBytes);
- uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
- result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBytes);
- if (kSuccess != result) {
- return result;
- }
- storagePtr += Y0 * rowBytes;
- for (int y = 0; y < dstHeight; y++) {
- memcpy(dst, storagePtr, rowBytes);
- storagePtr += sampleY * rowBytes;
- dst = SkTAddOffset<void>(dst, rowBytes);
- }
- } else {
- // does not require post y sampling
- result = fScanlineDecoder->skipScanlines(Y0);
- if (kSuccess != result) {
- return result;
- }
- for (int y = 0; y < dstHeight; y++) {
- result = fScanlineDecoder->getScanlines(dst, 1, rowBytes);
- if (kSuccess != result) {
- return result;
- }
- if (y < dstHeight - 1) {
- result = fScanlineDecoder->skipScanlines(sampleY - 1);
- if (kSuccess != result) {
- return result;
- }
- }
- dst = SkTAddOffset<void>(dst, rowBytes);
- }
- }
- return kSuccess;
-}
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
index 5099cca4bc..b2b7f927ac 100644
--- a/src/codec/SkSwizzler.cpp
+++ b/src/codec/SkSwizzler.cpp
@@ -7,7 +7,6 @@
#include "SkCodecPriv.h"
#include "SkColorPriv.h"
-#include "SkScaledCodec.h"
#include "SkSwizzler.h"
#include "SkTemplates.h"
#include "SkUtils.h"
@@ -20,107 +19,114 @@ SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha,
return (((uint16_t) maxAlpha) << 8) | zeroAlpha;
}
-// samples the row. Does not do anything else but sampling
-static SkSwizzler::ResultAlpha sample565(void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src,
- int width, int deltaSrc, int offset, const SkPMColor ctable[]){
-
- src += offset;
- uint16_t* SK_RESTRICT dst = (uint16_t*) dstRow;
- for (int x = 0; x < width; x++) {
- dst[x] = src[1] << 8 | src[0];
- src += deltaSrc;
- }
- // 565 is always opaque
- return SkSwizzler::kOpaque_ResultAlpha;
-}
-
// kBit
// These routines exclusively choose between white and black
#define GRAYSCALE_BLACK 0
#define GRAYSCALE_WHITE 0xFF
-
-// same as swizzle_bit_to_index and swizzle_bit_to_n32 except for value assigned to dst[x]
static SkSwizzler::ResultAlpha swizzle_bit_to_grayscale(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
-
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) {
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
- // increment src by byte offset and bitIndex by bit offset
- src += offset / 8;
- int bitIndex = offset % 8;
- uint8_t currByte = *src;
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = ((currByte >> (7-bitIndex)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
- int bitOffset = bitIndex + deltaSrc;
- bitIndex = bitOffset % 8;
- currByte = *(src += bitOffset / 8);
+ // Determine how many full bytes are in the row
+ int bytesInRow = width >> 3;
+ int i;
+ for (i = 0; i < bytesInRow; i++) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < 8; j++) {
+ dst[j] = ((currByte >> (7 - j)) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
+ }
+ dst += 8;
}
+ // Finish the remaining bits
+ width &= 7;
+ if (width > 0) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < width; j++) {
+ dst[j] = ((currByte >> 7) & 1) ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
+ currByte <<= 1;
+ }
+ }
return SkSwizzler::kOpaque_ResultAlpha;
}
#undef GRAYSCALE_BLACK
#undef GRAYSCALE_WHITE
-// same as swizzle_bit_to_grayscale and swizzle_bit_to_n32 except for value assigned to dst[x]
static SkSwizzler::ResultAlpha swizzle_bit_to_index(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) {
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
- // increment src by byte offset and bitIndex by bit offset
- src += offset / 8;
- int bitIndex = offset % 8;
- uint8_t currByte = *src;
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = ((currByte >> (7-bitIndex)) & 1);
- int bitOffset = bitIndex + deltaSrc;
- bitIndex = bitOffset % 8;
- currByte = *(src += bitOffset / 8);
+ // Determine how many full bytes are in the row
+ int bytesInRow = width >> 3;
+ int i;
+ for (i = 0; i < bytesInRow; i++) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < 8; j++) {
+ dst[j] = (currByte >> (7 - j)) & 1;
+ }
+ dst += 8;
}
+ // Finish the remaining bits
+ width &= 7;
+ if (width > 0) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < width; j++) {
+ dst[j] = ((currByte >> 7) & 1);
+ currByte <<= 1;
+ }
+ }
return SkSwizzler::kOpaque_ResultAlpha;
}
-// same as swizzle_bit_to_grayscale and swizzle_bit_to_index except for value assigned to dst[x]
static SkSwizzler::ResultAlpha swizzle_bit_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor* /*ctable*/) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int /*bitsPerPixel*/, const SkPMColor* /*ctable*/) {
SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
- // increment src by byte offset and bitIndex by bit offset
- src += offset / 8;
- int bitIndex = offset % 8;
- uint8_t currByte = *src;
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = ((currByte >> (7 - bitIndex)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
- int bitOffset = bitIndex + deltaSrc;
- bitIndex = bitOffset % 8;
- currByte = *(src += bitOffset / 8);
+ // Determine how many full bytes are in the row
+ int bytesInRow = width >> 3;
+ int i;
+ for (i = 0; i < bytesInRow; i++) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < 8; j++) {
+ dst[j] = ((currByte >> (7 - j)) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
+ }
+ dst += 8;
}
+ // Finish the remaining bits
+ width &= 7;
+ if (width > 0) {
+ U8CPU currByte = src[i];
+ for (int j = 0; j < width; j++) {
+ dst[j] = ((currByte >> 7) & 1) ? SK_ColorWHITE : SK_ColorBLACK;
+ currByte <<= 1;
+ }
+ }
return SkSwizzler::kOpaque_ResultAlpha;
}
// kIndex1, kIndex2, kIndex4
static SkSwizzler::ResultAlpha swizzle_small_index_to_index(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int bitsPerPixel, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bitsPerPixel, const SkPMColor ctable[]) {
- src += offset;
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
INIT_RESULT_ALPHA;
const uint32_t pixelsPerByte = 8 / bitsPerPixel;
- const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte);
+ const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
const uint8_t mask = (1 << bitsPerPixel) - 1;
int x = 0;
for (uint32_t byte = 0; byte < rowBytes; byte++) {
uint8_t pixelData = src[byte];
- for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) {
+ for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
UPDATE_RESULT_ALPHA(ctable[index] >> SK_A32_SHIFT);
dst[x] = index;
@@ -132,19 +138,18 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_index(
}
static SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int bitsPerPixel, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bitsPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*) dstRow;
INIT_RESULT_ALPHA;
const uint32_t pixelsPerByte = 8 / bitsPerPixel;
- const size_t rowBytes = compute_row_bytes_ppb(dstWidth, pixelsPerByte);
+ const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte);
const uint8_t mask = (1 << bitsPerPixel) - 1;
int x = 0;
for (uint32_t byte = 0; byte < rowBytes; byte++) {
uint8_t pixelData = src[byte];
- for (uint32_t p = 0; p < pixelsPerByte && x < dstWidth; p++) {
+ for (uint32_t p = 0; p < pixelsPerByte && x < width; p++) {
uint8_t index = (pixelData >> (8 - bitsPerPixel)) & mask;
SkPMColor c = ctable[index];
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
@@ -159,71 +164,58 @@ static SkSwizzler::ResultAlpha swizzle_small_index_to_n32(
// kIndex
static SkSwizzler::ResultAlpha swizzle_index_to_index(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
- if (1 == deltaSrc) {
- memcpy(dst, src, dstWidth);
- } else {
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = src[0];
- src += deltaSrc;
- }
- }
+ memcpy(dst, src, width);
// TODO (msarett): Should we skip the loop here and guess that the row is opaque/not opaque?
// SkScaledBitmap sampler just guesses that it is opaque. This is dangerous
// and probably wrong since gif and bmp (rarely) may have alpha.
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT);
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_index_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
- SkPMColor c = ctable[*src];
+ for (int x = 0; x < width; x++) {
+ SkPMColor c = ctable[src[x]];
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
dst[x] = c;
- src += deltaSrc;
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
- SkPMColor c = ctable[*src];
+ for (int x = 0; x < width; x++) {
+ SkPMColor c = ctable[src[x]];
UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT);
if (c != 0) {
dst[x] = c;
}
- src += deltaSrc;
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_index_to_565(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int bytesPerPixel, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
// FIXME: Support dithering? Requires knowing y, which I think is a bigger
// change.
- src += offset;
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
dst[x] = SkPixel32ToPixel16(ctable[*src]);
src += bytesPerPixel;
}
@@ -236,42 +228,29 @@ static SkSwizzler::ResultAlpha swizzle_index_to_565(
// kGray
static SkSwizzler::ResultAlpha swizzle_gray_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src);
- src += deltaSrc;
+ for (int x = 0; x < width; x++) {
+ dst[x] = SkPackARGB32NoCheck(0xFF, src[x], src[x], src[x]);
}
return SkSwizzler::kOpaque_ResultAlpha;
}
static SkSwizzler::ResultAlpha swizzle_gray_to_gray(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
-
- src += offset;
- uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow;
- if (1 == deltaSrc) {
- memcpy(dstRow, src, dstWidth);
- } else {
- for (int x = 0; x < dstWidth; x++) {
- dst[x] = src[0];
- src += deltaSrc;
- }
- }
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
+ memcpy(dstRow, src, width);
return SkSwizzler::kOpaque_ResultAlpha;
}
static SkSwizzler::ResultAlpha swizzle_gray_to_565(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int bytesPerPixel, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
// FIXME: Support dithering?
- src += offset;
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]);
src += bytesPerPixel;
}
@@ -281,14 +260,13 @@ static SkSwizzler::ResultAlpha swizzle_gray_to_565(
// kBGRX
static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return SkSwizzler::kOpaque_ResultAlpha;
}
@@ -296,58 +274,54 @@ static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32(
// kBGRA
static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
uint8_t alpha = src[3];
UPDATE_RESULT_ALPHA(alpha);
dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
uint8_t alpha = src[3];
UPDATE_RESULT_ALPHA(alpha);
dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return COMPUTE_RESULT_ALPHA;
}
// kRGBX
static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return SkSwizzler::kOpaque_ResultAlpha;
}
static SkSwizzler::ResultAlpha swizzle_rgbx_to_565(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int bytesPerPixel, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
// FIXME: Support dithering?
- src += offset;
uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]);
src += bytesPerPixel;
}
@@ -357,51 +331,48 @@ static SkSwizzler::ResultAlpha swizzle_rgbx_to_565(
// kRGBA
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
unsigned alpha = src[3];
UPDATE_RESULT_ALPHA(alpha);
dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow);
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
unsigned alpha = src[3];
UPDATE_RESULT_ALPHA(alpha);
dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]);
- src += deltaSrc;
+ src += bytesPerPixel;
}
return COMPUTE_RESULT_ALPHA;
}
static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
- void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
- int deltaSrc, int offset, const SkPMColor ctable[]) {
+ void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width,
+ int bytesPerPixel, const SkPMColor ctable[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
INIT_RESULT_ALPHA;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
unsigned alpha = src[3];
UPDATE_RESULT_ALPHA(alpha);
if (0 != alpha) {
dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
}
- src += deltaSrc;
+ src += bytesPerPixel;
}
return COMPUTE_RESULT_ALPHA;
}
@@ -414,12 +385,11 @@ static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ(
decide whether to switch to unpremul default.
static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
const uint8_t* SK_RESTRICT src,
- int dstWidth, int bitsPerPixel, int offset,
+ int width, int bitsPerPixel,
const SkPMColor[]) {
- src += offset;
SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
unsigned alphaMask = 0xFF;
- for (int x = 0; x < dstWidth; x++) {
+ for (int x = 0; x < width; x++) {
unsigned alpha = src[3];
// NOTE: We cheat here. The caller requested unpremul and skip zeroes. It's possible
// the color components are not zero, but we skip them anyway, meaning they'll remain
@@ -436,10 +406,9 @@ static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
const SkPMColor* ctable,
- const SkImageInfo& dstInfo,
- SkCodec::ZeroInitialized zeroInit,
- const SkImageInfo& srcInfo) {
- if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) {
+ const SkImageInfo& info,
+ SkCodec::ZeroInitialized zeroInit) {
+ if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) {
return NULL;
}
if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc)
@@ -447,10 +416,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
return NULL;
}
RowProc proc = NULL;
-
switch (sc) {
case kBit:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_bit_to_n32;
break;
@@ -467,7 +435,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
case kIndex1:
case kIndex2:
case kIndex4:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_small_index_to_n32;
break;
@@ -479,7 +447,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
break;
case kIndex:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
// We assume the color premultiplied ctable (or not) as desired.
if (SkCodec::kYes_ZeroInitialized == zeroInit) {
@@ -501,7 +469,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
break;
case kGray:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_gray_to_n32;
break;
@@ -517,7 +485,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
break;
case kBGR:
case kBGRX:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_bgrx_to_n32;
break;
@@ -526,9 +494,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
break;
case kBGRA:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
- switch (dstInfo.alphaType()) {
+ switch (info.alphaType()) {
case kUnpremul_SkAlphaType:
proc = &swizzle_bgra_to_n32_unpremul;
break;
@@ -545,7 +513,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
break;
case kRGBX:
// TODO: Support other swizzles.
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_rgbx_to_n32;
break;
@@ -556,9 +524,9 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
break;
case kRGBA:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
- if (dstInfo.alphaType() == kUnpremul_SkAlphaType) {
+ if (info.alphaType() == kUnpremul_SkAlphaType) {
// Respect zeroInit?
proc = &swizzle_rgba_to_n32_unpremul;
} else {
@@ -574,7 +542,7 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
break;
case kRGB:
- switch (dstInfo.colorType()) {
+ switch (info.colorType()) {
case kN32_SkColorType:
proc = &swizzle_rgbx_to_n32;
break;
@@ -582,14 +550,6 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
break;
}
break;
- case kRGB_565:
- switch (dstInfo.colorType()) {
- case kRGB_565_SkColorType:
- proc = &sample565;
- break;
- default:
- break;
- }
default:
break;
}
@@ -598,31 +558,22 @@ SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
}
// Store deltaSrc in bytes if it is an even multiple, otherwise use bits
- int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc);
-
- // get sampleX based on srcInfo and dstInfo dimensions
- int sampleX;
- SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, &sampleX, NULL);
-
- return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, dstInfo, sampleX));
+ int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) :
+ BitsPerPixel(sc);
+ return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info));
}
SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable,
- int deltaSrc, const SkImageInfo& info, int sampleX)
+ int deltaSrc, const SkImageInfo& info)
: fRowProc(proc)
, fColorTable(ctable)
, fDeltaSrc(deltaSrc)
, fDstInfo(info)
- , fSampleX(sampleX)
- , fX0(sampleX == 1 ? 0 : sampleX >> 1)
-{
- // check that fX0 is less than original width
- SkASSERT(fX0 >= 0 && fX0 < fDstInfo.width() * fSampleX);
-}
+{}
SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) {
SkASSERT(NULL != dst && NULL != src);
- return fRowProc(dst, src, fDstInfo.width(), fSampleX * fDeltaSrc, fX0 * fDeltaSrc, fColorTable);
+ return fRowProc(dst, src, fDstInfo.width(), fDeltaSrc, fColorTable);
}
void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstRowBytes,
diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h
index b7132ce6d5..2fab7f66b6 100644
--- a/src/codec/SkSwizzler.h
+++ b/src/codec/SkSwizzler.h
@@ -117,22 +117,16 @@ public:
/**
* Create a new SkSwizzler.
* @param SrcConfig Description of the format of the source.
- * @param dstInfo describes the destination.
+ * @param SkImageInfo dimensions() describe both the src and the dst.
+ * Other fields describe the dst.
* @param ZeroInitialized Whether dst is zero-initialized. The
implementation may choose to skip writing zeroes
* if set to kYes_ZeroInitialized.
- * @param srcInfo is the info of the source. Used to calculate the width samplesize.
- * Width sampling is supported by the swizzler, by skipping pixels when
- swizzling the row. Height sampling is not supported by the swizzler,
- but is implemented in SkScaledCodec.
- Sampling in Y can be done by a client with a scanline decoder,
- but sampling in X allows the swizzler to skip swizzling pixels and
- reading from and writing to memory.
* @return A new SkSwizzler or NULL on failure.
*/
static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
- const SkImageInfo& dstInfo, SkCodec::ZeroInitialized,
- const SkImageInfo& srcInfo);
+ const SkImageInfo&, SkCodec::ZeroInitialized);
+
/**
* Fill the remainder of the destination with a single color
*
@@ -187,16 +181,14 @@ private:
* Method for converting raw data to Skia pixels.
* @param dstRow Row in which to write the resulting pixels.
* @param src Row of src data, in format specified by SrcConfig
- * @param dstWidth Width in pixels of the destination
+ * @param width Width in pixels
* @param deltaSrc if bitsPerPixel % 8 == 0, deltaSrc is bytesPerPixel
* else, deltaSrc is bitsPerPixel
* @param ctable Colors (used for kIndex source).
- * @param offset The offset before the first pixel to sample.
- Is in bytes or bits based on what deltaSrc is in.
*/
typedef ResultAlpha (*RowProc)(void* SK_RESTRICT dstRow,
const uint8_t* SK_RESTRICT src,
- int dstWidth, int deltaSrc, int offset,
+ int width, int deltaSrc,
const SkPMColor ctable[]);
const RowProc fRowProc;
@@ -207,10 +199,9 @@ private:
// deltaSrc is bitsPerPixel
const SkImageInfo fDstInfo;
int fCurrY;
- const int fX0; // first X coord to sample
- const int fSampleX; // step between X samples
- SkSwizzler(RowProc proc, const SkPMColor* ctable, int deltaSrc, const SkImageInfo& info,
- int sampleX);
+ SkSwizzler(RowProc proc, const SkPMColor* ctable, int deltaSrc,
+ const SkImageInfo& info);
+
};
#endif // SkSwizzler_DEFINED