Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2015 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 #ifndef SkScaledCodec_DEFINED | |
| 8 #define SkScaledCodec_DEFINED | |
| 9 | |
| 10 #include "SkCodec.h" | |
| 11 #include "SkScanlineDecoder.h" | |
| 12 | |
| 13 class SkScanlineDecoder; | |
| 14 class SkStream; | |
| 15 | |
| 16 /** | |
| 17 * This class implements scaling, by sampling scanlines in the y direction. | |
| 18 * x-wise sampling is implemented in the swizzler, when getScanlines() is called . | |
| 19 */ | |
| 20 class SkScaledCodec : public SkCodec { | |
| 21 public: | |
| 22 static SkCodec* NewFromStream(SkStream*); | |
| 23 static SkCodec* NewFromData(SkData*); | |
| 24 | |
| 25 virtual ~SkScaledCodec(); | |
| 26 | |
| 27 /** | |
| 28 * returns whether a destination's dimensions are supported for down samplin g | |
| 29 */ | |
| 30 static bool DimensionsSupportedForSampling(const SkImageInfo& srcInfo, | |
| 31 const SkImageInfo& dstInfo) { | |
| 32 // heights must be equal as no native y sampling is supported | |
| 33 if (dstInfo.height() != srcInfo.height()) { | |
| 34 return false; | |
| 35 } | |
| 36 // only support down sampling, dstWidth cannot be larger that srcWidth | |
| 37 if(dstInfo.width() > srcInfo.width()) { | |
| 38 return false; | |
| 39 } | |
| 40 return true; | |
| 41 } | |
| 42 | |
| 43 // returns a scaled dimension based on the original dimension and the sample Size | |
| 44 // NOTE: we round down here for scaled dimension to match the behavior of Sk ImageDecoder | |
| 45 static int getScaledDimension(int srcDimension, int sampleSize) { | |
|
msarett
2015/08/13 15:45:10
nit: GetScaledDimension because it is static.
Leo
scroggo
2015/08/13 16:10:45
In general, that is a sign it may not need to be a
emmaleer
2015/08/13 17:49:11
This is no longer a member function.
| |
| 46 if (sampleSize > srcDimension) { | |
| 47 return 1; | |
| 48 } | |
| 49 return srcDimension / sampleSize; | |
| 50 } | |
| 51 | |
| 52 struct SampleSize { | |
|
scroggo
2015/08/13 16:10:45
I do not think this object is necessary. It has a
emmaleer
2015/08/13 17:49:11
Okay, I like that way better too.
| |
| 53 int sampleX; // sampleSize in the x direction | |
| 54 int sampleY; // sampleSize in the y direction | |
| 55 | |
| 56 // calculates sampleSize in x and y direction | |
| 57 SampleSize(const SkImageInfo& srcInfo, const SkImageInfo& dstInfo) { | |
| 58 int srcWidth = srcInfo.width(); | |
| 59 int dstWidth = dstInfo.width(); | |
| 60 int srcHeight = srcInfo.height(); | |
| 61 int dstHeight = dstInfo.height(); | |
| 62 | |
| 63 sampleX = srcWidth / dstWidth; | |
| 64 sampleY = srcHeight / dstHeight; | |
| 65 | |
| 66 // only support down sampling, not up sampling | |
| 67 SkASSERT(dstWidth <= srcWidth); | |
| 68 SkASSERT(dstHeight <= srcHeight); | |
| 69 | |
| 70 // sampleX and sampleY should be equal unless the original sampleSiz e requested was | |
| 71 // larger than srcWidth or srcHeight. | |
| 72 // If so, the result of this is dstWidth or dstHeight = 1. This func tionality | |
| 73 // allows for tall thin images to still be scaled down by scaling fa ctors. | |
| 74 | |
| 75 if (sampleX != sampleY){ | |
| 76 if (1 != dstWidth && 1 != dstHeight) { | |
| 77 | |
| 78 // rounding during onGetScaledDimensions can cause different sampleSizes | |
| 79 // Ex: srcWidth = 79, srcHeight = 20, sampleSize = 10 | |
| 80 // dstWidth = 7, dstHeight = 2, sampleX = 79/7 = 11, sampleY = 20/2 = 10 | |
| 81 // correct for this rounding by comparing width to sampleY a nd height to sampleX | |
| 82 | |
| 83 if (getScaledDimension(srcWidth, sampleY) == dstWidth) { | |
| 84 sampleX = sampleY; | |
| 85 } else if (getScaledDimension(srcHeight, sampleX) == dstHeig ht) { | |
| 86 sampleY = sampleX; | |
| 87 } | |
| 88 } | |
| 89 } | |
| 90 } | |
| 91 }; | |
| 92 | |
| 93 protected: | |
| 94 /** | |
| 95 * Recommend a set of destination dimensions given a requested scale | |
| 96 */ | |
| 97 SkISize onGetScaledDimensions(float desiredScale) const override; | |
| 98 | |
| 99 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMCo lor*, int*) | |
| 100 override; | |
| 101 SkEncodedFormat onGetEncodedFormat() const override { | |
| 102 return fScanlineDecoder->getEncodedFormat(); | |
| 103 } | |
| 104 | |
| 105 bool onReallyHasAlpha() const override { | |
| 106 return fScanlineDecoder->reallyHasAlpha(); | |
| 107 } | |
| 108 | |
| 109 private: | |
| 110 | |
| 111 SkAutoTDelete<SkScanlineDecoder> fScanlineDecoder; | |
| 112 | |
| 113 explicit SkScaledCodec(SkScanlineDecoder*); | |
| 114 | |
| 115 typedef SkCodec INHERITED; | |
| 116 }; | |
| 117 #endif // SkScaledCodec_DEFINED | |
| OLD | NEW |