Index: include/codec/SkCodec.h |
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h |
index fecd3d44ea171aa0492a3e007dd5cd41d1f007aa..9d97e5d193d5131311dce3063bd8ca21e3bd98e0 100644 |
--- a/include/codec/SkCodec.h |
+++ b/include/codec/SkCodec.h |
@@ -55,20 +55,7 @@ public: |
* The returned value is the codec's suggestion for the closest valid |
* scale that it can natively support |
*/ |
- SkISize getScaledDimensions(float desiredScale) const { |
- // Negative and zero scales are errors. |
- SkASSERT(desiredScale > 0.0f); |
- if (desiredScale <= 0.0f) { |
- return SkISize::Make(0, 0); |
- } |
- |
- // Upscaling is not supported. Return the original size if the client |
- // requests an upscale. |
- if (desiredScale >= 1.0f) { |
- return this->getInfo().dimensions(); |
- } |
- return this->onGetScaledDimensions(desiredScale); |
- } |
+ SkISize getScaledDimensions(float desiredScale) const; |
/** |
* Return (via desiredSubset) a subset which can decoded from this codec, |
@@ -85,9 +72,7 @@ public: |
* @return true if this codec supports decoding desiredSubset (as |
* returned, potentially modified) |
*/ |
- bool getValidSubset(SkIRect* desiredSubset) const { |
- return this->onGetValidSubset(desiredSubset); |
- } |
+ bool getValidSubset(SkIRect* desiredSubset) const; |
/** |
* Format of the encoded data. |
@@ -163,21 +148,79 @@ public: |
Options() |
: fZeroInitialized(kNo_ZeroInitialized) |
, fSubset(NULL) |
+ , fScaledDimensions(SkISize::Make(0, 0)) |
+ , fScaledSubset(SkIRect::MakeEmpty()) |
{} |
ZeroInitialized fZeroInitialized; |
+ |
/** |
- * If not NULL, represents a subset of the original image to decode. |
+ * fSubset represents a subset of the original image to decode. |
+ * It must be within the bounds returned by getInfo(). |
+ * If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left |
+ * values must be even. |
+ * If fSubset is NULL, we are not performing a subset decode. |
+ * |
+ * fScaledDimensions and fScaledSubset are used together to help |
+ * specify a scaled subset decode. Both should be specified for a |
+ * scaled subset decode, and both should be zeroed otherwise. |
* |
- * Must be within the bounds returned by getInfo(). |
+ * If fScaledDimensions and fScaledSubset are zeroed, we are not |
+ * performing a scaled subset decode: |
+ * (1) If fSubset is non-NULL, we are performing an unscaled |
+ * subset decode, and the subset dimensions must match the |
+ * dstInfo dimensions. |
+ * (2) If fSubset is NULL and the dstInfo dimensions do not |
+ * match the original dimensions, we are performing a |
+ * scaled decode. |
+ * (3) If fSubset is NULL and the dstInfo dimensions match the |
+ * original dimensions, we are performing an unscaled, full |
+ * image decode. |
* |
- * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which |
- * currently supports subsets), the top and left values must be even. |
+ * If both are non-NULL we are performing a scaled subset decode: |
+ * fSubset must be non-NULL. |
+ * fScaledSubset must be within the bounds of fScaledDimensions. |
+ * The dimensions of fScaledSubset must match the dimensions |
+ * specified by dstInfo. |
+ * |
+ * Usage: |
+ * Call getScaledSubsetDimensions() with the desired fSubset of |
+ * the original image and the desired scale. The function will |
+ * populate the options object with valid values of |
+ * fScaledDimensions and fScaledSubset that can be decoded |
+ * efficiently. |
*/ |
SkIRect* fSubset; |
+ SkISize fScaledDimensions; |
+ SkIRect fScaledSubset; |
}; |
/** |
+ * @param desiredScale The requested scale factor. |
+ * @param options In/out parameter. |
+ * options->fSubset (in/out) specifies the |
+ * requested subset in terms of the original image |
+ * dimensions. This may be modified to a subset |
+ * that can be decoded more efficiently. |
+ * options->fScaledDimensions is an output and |
+ * specifies the best scaled (full image) output |
+ * dimensions that can be achieved for the |
+ * desiredScale. |
+ * options->fScaledSubset is an output and specifies |
+ * the fSubset in terms of fScaledDimensions. |
+ * |
+ * The codec may not be able to scale and subset efficiently to the exact |
+ * scale and subset requested, so fScaledDimensions and fScaledSubset may |
+ * be approximate. These output values are the codec's suggestion for |
+ * the closest valid scaled subset that it can support. |
+ * |
+ * @return true if fScaledDimensions and fScaledSubset have been |
+ * successfully set to values that the codec supports. |
+ * false otherwise. |
+ */ |
+ bool getScaledSubsetDimensions(float desiredScale, Options* options) const; |
+ |
+ /** |
* Decode into the given pixels, a block of memory of size at |
* least (info.fHeight - 1) * rowBytes + (info.fWidth * |
* bytesPerPixel) |
@@ -256,14 +299,25 @@ public: |
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will |
* be modified to the true size of the color table (<= 256) after |
* decoding the palette. |
+ * @param subsetLeft The left offset at which to begin decoding each |
+ * scanline. This enables partial scanline decodes. |
+ * @param subsetWidth The number of pixels to decode in each scanline row. |
* @return Enum representing success or reason for failure. |
*/ |
Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options, |
- SkPMColor ctable[], int* ctableCount); |
+ SkPMColor ctable[], int* ctableCount, int subsetLeft, int subsetWidth); |
+ |
+ /** |
+ * Simplified version of startScanlineDecode() that does not enable partial |
+ * scanline decoding. |
+ */ |
+ Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options, |
+ SkPMColor ctable[], int* ctableCount); |
/** |
* Simplified version of startScanlineDecode() that asserts that info is NOT |
- * kIndex8_SkColorType and uses the default Options. |
+ * kIndex8_SkColorType, uses the default Options, and does not enable |
+ * partial scanline decoding. |
*/ |
Result startScanlineDecode(const SkImageInfo& dstInfo); |
@@ -398,6 +452,16 @@ protected: |
return this->getInfo().dimensions(); |
} |
+ virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { |
+ // By default, subsets are not supported. |
+ return false; |
+ } |
+ |
+ virtual bool onGetScaledSubsetDimensions(float desiredScale, Options* options) const { |
+ // By default, scaled subsetting is not supported. |
+ return false; |
+ } |
+ |
// FIXME: What to do about subsets?? |
/** |
* Subclasses should override if they support dimensions other than the |
@@ -420,11 +484,6 @@ protected: |
SkPMColor ctable[], int* ctableCount, |
int* rowsDecoded) = 0; |
- virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { |
- // By default, subsets are not supported. |
- return false; |
- } |
- |
virtual bool onReallyHasAlpha() const { return false; } |
/** |
@@ -529,7 +588,8 @@ private: |
// Methods for scanline decoding. |
virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& dstInfo, |
- const SkCodec::Options& options, SkPMColor ctable[], int* ctableCount) { |
+ const SkCodec::Options& options, SkPMColor ctable[], int* ctableCount, int subsetLeft, |
+ int subsetWidth) { |
return kUnimplemented; |
} |