Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: src/codec/SkJpegCodec.cpp

Issue 1260673002: SkScaledCodec class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Swizzler and SkScaledCodec use same get_sample_size() function Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/codec/SkJpegCodec.cpp
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 5acc0b396c54d34abb922f80687104b54f85990a..ea2834297ca77f3c484d9e0e263d1385549541a3 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -189,6 +189,41 @@ SkISize SkJpegCodec::onGetScaledDimensions(float desiredScale) const {
return SkISize::Make(dinfo.output_width, dinfo.output_height);
}
+SkCodec::Result SkJpegCodec::initializeSwizzler(const SkImageInfo& requestedInfo,
+ void* dst, size_t rowBytes,
+ const Options& options,
+ SkPMColor ctable[],
+ int* ctableCount) {
+
+ const SkColorType srcColorType = requestedInfo.colorType();
+ SkSwizzler::SrcConfig srcConfig;
+ switch (srcColorType) {
+ 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, requestedInfo, dst, rowBytes,
+ options.fZeroInitialized, this->getInfo().width()));
+ if (!fSwizzler) {
+ // FIXME: CreateSwizzler could fail for another reason.
+ return kUnimplemented;
+ }
+ return kSuccess;
+}
+
/*
* Handles rewinding the input stream if it is necessary
*/
@@ -287,6 +322,9 @@ bool SkJpegCodec::scaleToDimensions(uint32_t dstWidth, uint32_t dstHeight) {
if (1 == fDecoderMgr->dinfo()->scale_num ||
dstWidth > fDecoderMgr->dinfo()->output_width ||
dstHeight > fDecoderMgr->dinfo()->output_height) {
+ // reset scale settings on failure
+ this->fDecoderMgr->dinfo()->scale_num = 8;
+ turbo_jpeg_calc_output_dimensions(this->fDecoderMgr->dinfo());
return fDecoderMgr->returnFalse("could not scale to requested dimensions");
}
@@ -385,7 +423,12 @@ public:
SkJpegScanlineDecoder(const SkImageInfo& dstInfo, SkJpegCodec* codec)
: INHERITED(dstInfo)
, fCodec(codec)
- {}
+ {
+ if(fCodec->fSwizzler) {
+ fStorage.reset(fCodec->getInfo().width() * dstInfo.minRowBytes());
+ fSrcRow = static_cast<uint8_t*>(fStorage.get());
+ }
+ }
virtual ~SkJpegScanlineDecoder() {
if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
@@ -404,9 +447,16 @@ public:
if (setjmp(fCodec->fDecoderMgr->getJmpBuf())) {
return fCodec->fDecoderMgr->returnFailure("setjmp", SkCodec::kInvalidInput);
}
-
// Read rows one at a time
- JSAMPLE* dstRow = (JSAMPLE*) dst;
+ JSAMPLE* dstRow;
+ if (fCodec->fSwizzler) {
+ // write data to storage row, then sample using swizzler
+ dstRow = fSrcRow;
+ } else {
+ // write data directly to dst
+ dstRow = (JSAMPLE*) dst;
+ }
+
for (int y = 0; y < count; y++) {
// Read row of the image
uint32_t rowsDecoded =
@@ -423,10 +473,15 @@ public:
convert_CMYK_to_RGBA(dstRow, this->dstInfo().width());
}
- // Move to the next row
- dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes);
+ if(fCodec->fSwizzler) {
+ // use swizzler to sample row
+ fCodec->fSwizzler->setDstRow(dst);
+ fCodec->fSwizzler->next(dstRow);
+ dst = SkTAddOffset<JSAMPLE>(dst, rowBytes);
+ } else {
+ dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes);
+ }
}
-
return SkCodec::kSuccess;
}
@@ -452,6 +507,8 @@ public:
private:
SkAutoTDelete<SkJpegCodec> fCodec;
+ SkAutoMalloc fStorage;
scroggo 2015/07/31 13:35:33 This one is only needed for sampling, too, right?
emmaleer 2015/07/31 18:41:56 Yep! I've added a comment.
+ uint8_t* fSrcRow; // Only used if sampling is needed
typedef SkScanlineDecoder INHERITED;
};
@@ -488,8 +545,22 @@ SkScanlineDecoder* SkJpegCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
// Perform the necessary scaling
if (!codec->scaleToDimensions(dstInfo.width(), dstInfo.height())) {
- SkCodecPrintf("Cannot scale to output dimensions\n");
- return NULL;
+ // native scaling to dstInfo dimensions not supported
+
+ if (dstInfo.height() != this->getInfo().height()) {
scroggo 2015/07/31 13:35:33 This should call DimensionsSupportedForSampling
emmaleer 2015/07/31 18:41:56 Acknowledged.
+ // no non-native height sampling supported
+ return NULL;
+ }
+ // only support down sampling, dstWidth cannot be larger that srcWidth
+ if(dstInfo.width() > this->getInfo().width()) {
+ return NULL;
+ }
+ // create swizzler for sampling
+ if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable,
+ ctableCount) != kSuccess) {
+ SkCodecPrintf("failed to initialize the swizzler.\n");
+ return NULL;
+ }
}
// Now, given valid output dimensions, we can start the decompress

Powered by Google App Engine
This is Rietveld 408576698