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

Unified Diff: src/codec/SkScaledCodec.cpp

Issue 1287423002: Scanline decoding for bmp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Response to comments from previous patch sets Created 5 years, 4 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/SkScaledCodec.cpp
diff --git a/src/codec/SkScaledCodec.cpp b/src/codec/SkScaledCodec.cpp
index 0f0d12993c87f4acc645047d349e06b594cce73e..6db09fb5ceefaea49d0e97ef659d4bc9b8e8e076 100644
--- a/src/codec/SkScaledCodec.cpp
+++ b/src/codec/SkScaledCodec.cpp
@@ -139,6 +139,28 @@ static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src
return true;
}
+inline int SkScaledCodec::GetStartCoord(int sampleFactor) {
+ return sampleFactor / 2;
+}
+
+inline int SkScaledCodec::GetDstCoord(int srcCoord, int sampleFactor) {
+ return srcCoord / sampleFactor;
+}
+
+bool SkScaledCodec::IsCoordNecessary(int srcCoord, int sampleFactor, int scaledDim) {
scroggo 2015/08/27 20:14:23 Any idea whether calling all these functions slows
msarett 2015/08/27 21:21:46 We do special case on sample size == 1 by using th
scroggo 2015/08/28 13:28:47 Oh, that's even better!
+ // Get the first coordinate that we want to keep
+ int startCoord = GetStartCoord(sampleFactor);
+
+ // Return false on edge cases
+ if (srcCoord < startCoord ||
+ SkScaledCodec::GetDstCoord(srcCoord, sampleFactor) >= scaledDim) {
+ return false;
+ }
+
+ // Every sampleFactor rows are necessary
+ return ((srcCoord - startCoord) % sampleFactor) == 0;
+}
+
// calculates sampleSize in x and y direction
void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo,
int* sampleXPtr, int* sampleYPtr) {
@@ -198,7 +220,6 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi
if (kSuccess == result) {
// native decode supported
return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBytes);
-
}
if (kInvalidScale != result) {
@@ -213,7 +234,7 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi
return kInvalidScale;
}
// set first sample pixel in y direction
- int Y0 = sampleY >> 1;
+ int Y0 = SkScaledCodec::GetStartCoord(sampleY);
int dstHeight = requestedInfo.height();
int srcHeight = fScanlineDecoder->getInfo().height();
@@ -227,41 +248,64 @@ SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi
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);
+
+ switch(fScanlineDecoder->getScanlineOrder()) {
+ case SkScanlineDecoder::kTopDown_SkScanlineOrder: {
+ result = fScanlineDecoder->skipScanlines(Y0);
+ if (kSuccess != result && kIncompleteInput != result) {
+ return result;
+ }
+ for (int y = 0; y < dstHeight; y++) {
+ result = fScanlineDecoder->getScanlines(dst, 1, rowBytes);
+ if (kSuccess != result && kIncompleteInput != result) {
+ return result;
+ }
+ if (y < dstHeight - 1) {
+ result = fScanlineDecoder->skipScanlines(sampleY - 1);
+ if (kSuccess != result && kIncompleteInput != result) {
+ return result;
+ }
+ }
+ dst = SkTAddOffset<void>(dst, rowBytes);
+ }
+ return kSuccess;
}
- } else {
- // does not require post y sampling
- result = fScanlineDecoder->skipScanlines(Y0);
- if (kSuccess != result) {
- return result;
+ case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: {
+ for (int y = 0; y < srcHeight; y++) {
+ int srcY = fScanlineDecoder->getY();
+ if (SkScaledCodec::IsCoordNecessary(srcY, sampleY, dstHeight)) {
+ void* dstPtr = SkTAddOffset<void>(dst,
+ rowBytes * SkScaledCodec::GetDstCoord(srcY, sampleY));
+ result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes);
+ if (kSuccess != result && kIncompleteInput != result) {
+ return result;
+ }
+ } else {
+ result = fScanlineDecoder->skipScanlines(1);
+ if (kSuccess != result && kIncompleteInput != result) {
+ return result;
+ }
+ }
+ }
+ return kSuccess;
}
- for (int y = 0; y < dstHeight; y++) {
- result = fScanlineDecoder->getScanlines(dst, 1, rowBytes);
+ case SkScanlineDecoder::kNone_SkScanlineOrder: {
+ SkAutoMalloc storage(srcHeight * rowBytes);
+ uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
+ result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBytes);
if (kSuccess != result) {
return result;
}
- if (y < dstHeight - 1) {
- result = fScanlineDecoder->skipScanlines(sampleY - 1);
- 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);
}
- dst = SkTAddOffset<void>(dst, rowBytes);
+ return kSuccess;
}
+ default:
+ SkASSERT(false);
+ return kUnimplemented;
}
- return kSuccess;
}

Powered by Google App Engine
This is Rietveld 408576698