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

Side by Side Diff: src/codec/SkScaledCodec.cpp

Issue 1305123002: Scanline decoding for gifs (Closed) Base URL: https://skia.googlesource.com/skia.git@real-bmp-scan
Patch Set: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodecPriv.h" 8 #include "SkCodecPriv.h"
9 #include "SkScaledCodec.h" 9 #include "SkScaledCodec.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 26 matching lines...) Expand all
37 return NewFromStream(SkNEW_ARGS(SkMemoryStream, (data))); 37 return NewFromStream(SkNEW_ARGS(SkMemoryStream, (data)));
38 } 38 }
39 39
40 SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder) 40 SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder)
41 : INHERITED(scanlineDecoder->getInfo(), NULL) 41 : INHERITED(scanlineDecoder->getInfo(), NULL)
42 , fScanlineDecoder(scanlineDecoder) 42 , fScanlineDecoder(scanlineDecoder)
43 {} 43 {}
44 44
45 SkScaledCodec::~SkScaledCodec() {} 45 SkScaledCodec::~SkScaledCodec() {}
46 46
47 // returns a scaled dimension based on the original dimension and the sampleSize
48 // NOTE: we round down here for scaled dimension to match the behavior of SkImag eDecoder
49 static int get_scaled_dimension(int srcDimension, int sampleSize) {
50 if (sampleSize > srcDimension) {
51 return 1;
52 }
53 return srcDimension / sampleSize;
54 }
55
56 static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& na tiveDims, 47 static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& na tiveDims,
57 const SkISize& scaledCodecDims, float desi redScale) { 48 const SkISize& scaledCodecDims, float desi redScale) {
58 if (nativeDims == scaledCodecDims) { 49 if (nativeDims == scaledCodecDims) {
59 // does not matter which to return if equal. Return here to skip below c alculations 50 // does not matter which to return if equal. Return here to skip below c alculations
60 return nativeDims; 51 return nativeDims;
61 } 52 }
62 float idealWidth = origDims.width() * desiredScale; 53 float idealWidth = origDims.width() * desiredScale;
63 float idealHeight = origDims.height() * desiredScale; 54 float idealHeight = origDims.height() * desiredScale;
64 55
65 // calculate difference between native dimensions and ideal dimensions 56 // calculate difference between native dimensions and ideal dimensions
(...skipping 25 matching lines...) Expand all
91 // support scaling down by integer numbers. Ex: 1/2, 1/3, 1/4 ... 82 // support scaling down by integer numbers. Ex: 1/2, 1/3, 1/4 ...
92 SkISize scaledCodecDimensions; 83 SkISize scaledCodecDimensions;
93 if (desiredScale > 0.5f) { 84 if (desiredScale > 0.5f) {
94 // sampleSize = 1 85 // sampleSize = 1
95 scaledCodecDimensions = fScanlineDecoder->getInfo().dimensions(); 86 scaledCodecDimensions = fScanlineDecoder->getInfo().dimensions();
96 } 87 }
97 // sampleSize determines the step size between samples 88 // sampleSize determines the step size between samples
98 // Ex: sampleSize = 2, sample every second pixel in x and y directions 89 // Ex: sampleSize = 2, sample every second pixel in x and y directions
99 int sampleSize = int(1 / desiredScale); 90 int sampleSize = int(1 / desiredScale);
100 91
101 int scaledWidth = get_scaled_dimension(this->getInfo().width(), sampleSize); 92 int scaledWidth = SkScaledCodec::GetScaledDimension(this->getInfo().width(), sampleSize);
102 int scaledHeight = get_scaled_dimension(this->getInfo().height(), sampleSize ); 93 int scaledHeight = SkScaledCodec::GetScaledDimension(this->getInfo().height( ), sampleSize);
103 94
104 // Return the calculated output dimensions for the given scale 95 // Return the calculated output dimensions for the given scale
105 scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight); 96 scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight);
106 97
107 return best_scaled_dimensions(this->getInfo().dimensions(), nativeDimensions , 98 return best_scaled_dimensions(this->getInfo().dimensions(), nativeDimensions ,
108 scaledCodecDimensions, desiredScale); 99 scaledCodecDimensions, desiredScale);
109 } 100 }
110 101
111 // check if scaling to dstInfo size from srcInfo size using sampleSize is possib le 102 // check if scaling to dstInfo size from srcInfo size using sampleSize is possib le
112 static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src Info, 103 static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src Info,
113 int* sampleX, int* sampleY) { 104 int* sampleX, int* sampleY) {
114 SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, sampleX, sampleY); 105 SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, sampleX, sampleY);
115 const int dstWidth = dstInfo.width(); 106 const int dstWidth = dstInfo.width();
116 const int dstHeight = dstInfo.height(); 107 const int dstHeight = dstInfo.height();
117 const int srcWidth = srcInfo.width(); 108 const int srcWidth = srcInfo.width();
118 const int srcHeight = srcInfo.height(); 109 const int srcHeight = srcInfo.height();
119 // only support down sampling, not up sampling 110 // only support down sampling, not up sampling
120 if (dstWidth > srcWidth || dstHeight > srcHeight) { 111 if (dstWidth > srcWidth || dstHeight > srcHeight) {
121 return false; 112 return false;
122 } 113 }
123 // check that srcWidth is scaled down by an integer value 114 // check that srcWidth is scaled down by an integer value
124 if (get_scaled_dimension(srcWidth, *sampleX) != dstWidth) { 115 if (SkScaledCodec::GetScaledDimension(srcWidth, *sampleX) != dstWidth) {
125 return false; 116 return false;
126 } 117 }
127 // check that src height is scaled down by an integer value 118 // check that src height is scaled down by an integer value
128 if (get_scaled_dimension(srcHeight, *sampleY) != dstHeight) { 119 if (SkScaledCodec::GetScaledDimension(srcHeight, *sampleY) != dstHeight) {
129 return false; 120 return false;
130 } 121 }
131 // sampleX and sampleY should be equal unless the original sampleSize reques ted was larger 122 // sampleX and sampleY should be equal unless the original sampleSize reques ted was larger
132 // than srcWidth or srcHeight. If so, the result of this is dstWidth or dstH eight = 1. 123 // than srcWidth or srcHeight. If so, the result of this is dstWidth or dstH eight = 1.
133 // This functionality allows for tall thin images to still be scaled down by scaling factors. 124 // This functionality allows for tall thin images to still be scaled down by scaling factors.
134 if (*sampleX != *sampleY){ 125 if (*sampleX != *sampleY){
135 if (1 != dstWidth && 1 != dstHeight) { 126 if (1 != dstWidth && 1 != dstHeight) {
136 return false; 127 return false;
137 } 128 }
138 } 129 }
139 return true; 130 return true;
140 } 131 }
141 132
133 // returns a scaled dimension based on the original dimension and the sampleSize
134 // NOTE: we round down here for scaled dimension to match the behavior of SkImag eDecoder
135 inline int SkScaledCodec::GetScaledDimension(int srcDimension, int sampleSize) {
136 if (sampleSize > srcDimension) {
137 return 1;
138 }
139 return srcDimension / sampleSize;
140 }
141
142 inline int SkScaledCodec::GetStartCoord(int sampleFactor) { 142 inline int SkScaledCodec::GetStartCoord(int sampleFactor) {
143 return sampleFactor / 2; 143 return sampleFactor / 2;
144 } 144 }
145 145
146 inline int SkScaledCodec::GetDstCoord(int srcCoord, int sampleFactor) { 146 inline int SkScaledCodec::GetDstCoord(int srcCoord, int sampleFactor) {
147 return srcCoord / sampleFactor; 147 return srcCoord / sampleFactor;
148 } 148 }
149 149
150 bool SkScaledCodec::IsCoordNecessary(int srcCoord, int sampleFactor, int scaledD im) { 150 bool SkScaledCodec::IsCoordNecessary(int srcCoord, int sampleFactor, int scaledD im) {
151 // Get the first coordinate that we want to keep 151 // Get the first coordinate that we want to keep
(...skipping 30 matching lines...) Expand all
182 // allows for tall thin images to still be scaled down by scaling factors. 182 // allows for tall thin images to still be scaled down by scaling factors.
183 183
184 if (sampleX != sampleY){ 184 if (sampleX != sampleY){
185 if (1 != dstWidth && 1 != dstHeight) { 185 if (1 != dstWidth && 1 != dstHeight) {
186 186
187 // rounding during onGetScaledDimensions can cause different sampleS izes 187 // rounding during onGetScaledDimensions can cause different sampleS izes
188 // Ex: srcWidth = 79, srcHeight = 20, sampleSize = 10 188 // Ex: srcWidth = 79, srcHeight = 20, sampleSize = 10
189 // dstWidth = 7, dstHeight = 2, sampleX = 79/7 = 11, sampleY = 20/2 = 10 189 // dstWidth = 7, dstHeight = 2, sampleX = 79/7 = 11, sampleY = 20/2 = 10
190 // correct for this rounding by comparing width to sampleY and heigh t to sampleX 190 // correct for this rounding by comparing width to sampleY and heigh t to sampleX
191 191
192 if (get_scaled_dimension(srcWidth, sampleY) == dstWidth) { 192 if (SkScaledCodec::GetScaledDimension(srcWidth, sampleY) == dstWidth ) {
193 sampleX = sampleY; 193 sampleX = sampleY;
194 } else if (get_scaled_dimension(srcHeight, sampleX) == dstHeight) { 194 } else if (SkScaledCodec::GetScaledDimension(srcHeight, sampleX) == dstHeight) {
195 sampleY = sampleX; 195 sampleY = sampleX;
196 } 196 }
197 } 197 }
198 } 198 }
199 199
200 if (sampleXPtr) { 200 if (sampleXPtr) {
201 *sampleXPtr = sampleX; 201 *sampleXPtr = sampleX;
202 } 202 }
203 if (sampleYPtr) { 203 if (sampleYPtr) {
204 *sampleYPtr = sampleY; 204 *sampleYPtr = sampleY;
205 } 205 }
206 } 206 }
207 207
208 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing 208 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing
209 209
210 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst, 210 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst,
211 size_t rowBytes, const Options& optio ns, 211 size_t rowBytes, const Options& optio ns,
212 SkPMColor ctable[], int* ctableCount) { 212 SkPMColor ctable[], int* ctableCount) {
213 213
214 if (options.fSubset) { 214 if (options.fSubset) {
215 // Subsets are not supported. 215 // Subsets are not supported.
216 return kUnimplemented; 216 return kUnimplemented;
217 } 217 }
218 218
219 Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta bleCount); 219 Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta bleCount);
220 if (kSuccess == result) { 220 if (kSuccess == result) {
221 // native decode supported 221 // native decode supported
222 return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBy tes); 222 return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBy tes);
msarett 2015/08/24 23:20:13 I need to add a switch statement here. Interlaced
223 } 223 }
224 224
225 if (kInvalidScale != result) { 225 if (kInvalidScale != result) {
226 // no scaling requested 226 // no scaling requested
227 return result; 227 return result;
228 } 228 }
229 229
230 // scaling requested 230 // scaling requested
231 int sampleX; 231 int sampleX;
232 int sampleY; 232 int sampleY;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 storagePtr += sampleY * rowBytes; 302 storagePtr += sampleY * rowBytes;
303 dst = SkTAddOffset<void>(dst, rowBytes); 303 dst = SkTAddOffset<void>(dst, rowBytes);
304 } 304 }
305 return kSuccess; 305 return kSuccess;
306 } 306 }
307 default: 307 default:
308 SkASSERT(false); 308 SkASSERT(false);
309 return kUnimplemented; 309 return kUnimplemented;
310 } 310 }
311 } 311 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698