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

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

Issue 1372973002: Move all knowledge of X sampling into SkScaledCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@codecSDmerge
Patch Set: Attempt to fix RLE overflow Created 5 years, 2 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
« no previous file with comments | « src/codec/SkSampler.h ('k') | src/codec/SkSwizzler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 int scaledHeight = get_scaled_dimension(this->getInfo().height(), sampleSize ); 93 int scaledHeight = get_scaled_dimension(this->getInfo().height(), sampleSize );
94 94
95 // Return the calculated output dimensions for the given scale 95 // Return the calculated output dimensions for the given scale
96 scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight); 96 scaledCodecDimensions = SkISize::Make(scaledWidth, scaledHeight);
97 97
98 return best_scaled_dimensions(this->getInfo().dimensions(), nativeDimensions , 98 return best_scaled_dimensions(this->getInfo().dimensions(), nativeDimensions ,
99 scaledCodecDimensions, desiredScale); 99 scaledCodecDimensions, desiredScale);
100 } 100 }
101 101
102 // 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
103 static bool scaling_supported(const SkImageInfo& dstInfo, const SkImageInfo& src Info, 103 static bool scaling_supported(const SkISize& dstDim, const SkISize& srcDim,
104 int* sampleX, int* sampleY) { 104 int* sampleX, int* sampleY) {
105 SkScaledCodec::ComputeSampleSize(dstInfo, srcInfo, sampleX, sampleY); 105 SkScaledCodec::ComputeSampleSize(dstDim, srcDim, sampleX, sampleY);
106 const int dstWidth = dstInfo.width(); 106 const int dstWidth = dstDim.width();
107 const int dstHeight = dstInfo.height(); 107 const int dstHeight = dstDim.height();
108 const int srcWidth = srcInfo.width(); 108 const int srcWidth = srcDim.width();
109 const int srcHeight = srcInfo.height(); 109 const int srcHeight = srcDim.height();
110 // only support down sampling, not up sampling 110 // only support down sampling, not up sampling
111 if (dstWidth > srcWidth || dstHeight > srcHeight) { 111 if (dstWidth > srcWidth || dstHeight > srcHeight) {
112 return false; 112 return false;
113 } 113 }
114 // check that srcWidth is scaled down by an integer value 114 // check that srcWidth is scaled down by an integer value
115 if (get_scaled_dimension(srcWidth, *sampleX) != dstWidth) { 115 if (get_scaled_dimension(srcWidth, *sampleX) != dstWidth) {
116 return false; 116 return false;
117 } 117 }
118 // check that src height is scaled down by an integer value 118 // check that src height is scaled down by an integer value
119 if (get_scaled_dimension(srcHeight, *sampleY) != dstHeight) { 119 if (get_scaled_dimension(srcHeight, *sampleY) != dstHeight) {
120 return false; 120 return false;
121 } 121 }
122 // 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
123 // 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.
124 // 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.
125 if (*sampleX != *sampleY){ 125 if (*sampleX != *sampleY){
126 if (1 != dstWidth && 1 != dstHeight) { 126 if (1 != dstWidth && 1 != dstHeight) {
127 return false; 127 return false;
128 } 128 }
129 } 129 }
130 return true; 130 return true;
131 } 131 }
132 132
133 bool SkScaledCodec::onDimensionsSupported(const SkISize& dim) {
134 // Check with fCodec first. No need to call the non-virtual version, which
135 // just checks if it matches the original, since a match means this method
136 // will not be called.
137 if (fCodec->onDimensionsSupported(dim)) {
138 return true;
139 }
140
141 // FIXME: These variables are unused, but are needed by scaling_supported.
142 // This class could also cache these values, and avoid calling this in
143 // onGetPixels (since getPixels already calls it).
144 int sampleX;
145 int sampleY;
146 return scaling_supported(dim, this->getInfo().dimensions(), &sampleX, &sampl eY);
147 }
148
133 // calculates sampleSize in x and y direction 149 // calculates sampleSize in x and y direction
134 void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageI nfo& srcInfo, 150 void SkScaledCodec::ComputeSampleSize(const SkISize& dstDim, const SkISize& srcD im,
135 int* sampleXPtr, int* sampleYPtr) { 151 int* sampleXPtr, int* sampleYPtr) {
136 int srcWidth = srcInfo.width(); 152 int srcWidth = srcDim.width();
137 int dstWidth = dstInfo.width(); 153 int dstWidth = dstDim.width();
138 int srcHeight = srcInfo.height(); 154 int srcHeight = srcDim.height();
139 int dstHeight = dstInfo.height(); 155 int dstHeight = dstDim.height();
140 156
141 int sampleX = srcWidth / dstWidth; 157 int sampleX = srcWidth / dstWidth;
142 int sampleY = srcHeight / dstHeight; 158 int sampleY = srcHeight / dstHeight;
143 159
144 // only support down sampling, not up sampling 160 // only support down sampling, not up sampling
145 SkASSERT(dstWidth <= srcWidth); 161 SkASSERT(dstWidth <= srcWidth);
146 SkASSERT(dstHeight <= srcHeight); 162 SkASSERT(dstHeight <= srcHeight);
147 163
148 // sampleX and sampleY should be equal unless the original sampleSize reques ted was 164 // sampleX and sampleY should be equal unless the original sampleSize reques ted was
149 // larger than srcWidth or srcHeight. 165 // larger than srcWidth or srcHeight.
(...skipping 26 matching lines...) Expand all
176 192
177 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing 193 // TODO: Implement subsetting in onGetPixels which works when and when not sampl ing
178 194
179 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst, 195 SkCodec::Result SkScaledCodec::onGetPixels(const SkImageInfo& requestedInfo, voi d* dst,
180 size_t rowBytes, const Options& optio ns, 196 size_t rowBytes, const Options& optio ns,
181 SkPMColor ctable[], int* ctableCount) { 197 SkPMColor ctable[], int* ctableCount) {
182 198
183 if (options.fSubset) { 199 if (options.fSubset) {
184 // Subsets are not supported. 200 // Subsets are not supported.
185 return kUnimplemented; 201 return kUnimplemented;
186 }
187
188 // FIXME: If no scaling/subsets are requested, we can call fCodec->getPixels .
189 Result result = fCodec->startScanlineDecode(requestedInfo, &options, ctable, ctableCount);
190 if (kSuccess == result) {
191 // native decode supported
192 switch (fCodec->getScanlineOrder()) {
193 case SkCodec::kTopDown_SkScanlineOrder:
194 case SkCodec::kBottomUp_SkScanlineOrder:
195 case SkCodec::kNone_SkScanlineOrder:
196 return fCodec->getScanlines(dst, requestedInfo.height(), rowByte s);
197 case SkCodec::kOutOfOrder_SkScanlineOrder: {
198 for (int y = 0; y < requestedInfo.height(); y++) {
199 int dstY = fCodec->nextScanline();
200 void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY);
201 result = fCodec->getScanlines(dstPtr, 1, rowBytes);
202 // FIXME (msarett): Make the SkCodec base class take care of filling
203 // uninitialized pixels so we can return immediately on kInc ompleteInput.
204 if (kSuccess != result && kIncompleteInput != result) {
205 return result;
206 }
207 }
208 return result;
209 }
210 }
211 } 202 }
212 203
213 if (kInvalidScale != result) { 204 if (fCodec->dimensionsSupported(requestedInfo.dimensions())) {
214 // no scaling requested 205 return fCodec->getPixels(requestedInfo, dst, rowBytes, &options, ctable, ctableCount);
215 return result;
216 } 206 }
217 207
218 // scaling requested 208 // scaling requested
219 int sampleX; 209 int sampleX;
220 int sampleY; 210 int sampleY;
221 if (!scaling_supported(requestedInfo, fCodec->getInfo(), &sampleX, &sampleY) ) { 211 if (!scaling_supported(requestedInfo.dimensions(), fCodec->getInfo().dimensi ons(),
212 &sampleX, &sampleY)) {
213 // onDimensionsSupported would have returned false, meaning we should ne ver reach here.
214 SkASSERT(false);
222 return kInvalidScale; 215 return kInvalidScale;
223 } 216 }
217
224 // set first sample pixel in y direction 218 // set first sample pixel in y direction
225 int Y0 = get_start_coord(sampleY); 219 const int Y0 = get_start_coord(sampleY);
226 220
227 int dstHeight = requestedInfo.height(); 221 const int dstHeight = requestedInfo.height();
228 int srcHeight = fCodec->getInfo().height(); 222 const int srcWidth = fCodec->getInfo().width();
229 223 const int srcHeight = fCodec->getInfo().height();
230 SkImageInfo info = requestedInfo;
231 // use original height as codec does not support y sampling natively
232 info = info.makeWH(requestedInfo.width(), srcHeight);
233 224
234 // update codec with new info 225 const SkImageInfo info = requestedInfo.makeWH(srcWidth, srcHeight);
235 // FIXME: The previous call to start returned kInvalidScale. This call may 226
236 // require a rewind. (skbug.com/4284) 227 Result result = fCodec->startScanlineDecode(info, &options, ctable, ctableCo unt);
237 result = fCodec->startScanlineDecode(info, &options, ctable, ctableCount); 228
238 if (kSuccess != result) { 229 if (kSuccess != result) {
239 return result; 230 return result;
240 } 231 }
241 232
233 SkSampler* sampler = fCodec->getSampler();
234 if (!sampler) {
235 return kUnimplemented;
236 }
237
238 if (sampler->setSampleX(sampleX) != requestedInfo.width()) {
239 return kInvalidScale;
240 }
241
242 switch(fCodec->getScanlineOrder()) { 242 switch(fCodec->getScanlineOrder()) {
243 case SkCodec::kTopDown_SkScanlineOrder: { 243 case SkCodec::kTopDown_SkScanlineOrder: {
244 result = fCodec->skipScanlines(Y0); 244 result = fCodec->skipScanlines(Y0);
245 if (kSuccess != result && kIncompleteInput != result) { 245 if (kSuccess != result && kIncompleteInput != result) {
246 return result; 246 return result;
247 } 247 }
248 for (int y = 0; y < dstHeight; y++) { 248 for (int y = 0; y < dstHeight; y++) {
249 result = fCodec->getScanlines(dst, 1, rowBytes); 249 result = fCodec->getScanlines(dst, 1, rowBytes);
250 if (kSuccess != result && kIncompleteInput != result) { 250 if (kSuccess != result && kIncompleteInput != result) {
251 return result; 251 return result;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 storagePtr += sampleY * rowBytes; 292 storagePtr += sampleY * rowBytes;
293 dst = SkTAddOffset<void>(dst, rowBytes); 293 dst = SkTAddOffset<void>(dst, rowBytes);
294 } 294 }
295 return result; 295 return result;
296 } 296 }
297 default: 297 default:
298 SkASSERT(false); 298 SkASSERT(false);
299 return kUnimplemented; 299 return kUnimplemented;
300 } 300 }
301 } 301 }
OLDNEW
« no previous file with comments | « src/codec/SkSampler.h ('k') | src/codec/SkSwizzler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698