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 |