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

Side by Side 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 Patch Set 15 Created 5 years, 3 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 // than srcWidth or srcHeight. If so, the result of this is dstWidth or dstH eight = 1. 132 // 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. 133 // This functionality allows for tall thin images to still be scaled down by scaling factors.
134 if (*sampleX != *sampleY){ 134 if (*sampleX != *sampleY){
135 if (1 != dstWidth && 1 != dstHeight) { 135 if (1 != dstWidth && 1 != dstHeight) {
136 return false; 136 return false;
137 } 137 }
138 } 138 }
139 return true; 139 return true;
140 } 140 }
141 141
142 bool SkScaledCodec::IsCoordNecessary(int srcCoord, int sampleFactor, int scaledD im) {
143 // Get the first coordinate that we want to keep
144 int startCoord = GetStartCoord(sampleFactor);
145
146 // Return false on edge cases
147 if (srcCoord < startCoord ||
148 SkScaledCodec::GetDstCoord(srcCoord, sampleFactor) >= scaledDim) {
149 return false;
150 }
151
152 // Every sampleFactor rows are necessary
153 return ((srcCoord - startCoord) % sampleFactor) == 0;
154 }
155
142 // calculates sampleSize in x and y direction 156 // calculates sampleSize in x and y direction
143 void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageI nfo& srcInfo, 157 void SkScaledCodec::ComputeSampleSize(const SkImageInfo& dstInfo, const SkImageI nfo& srcInfo,
144 int* sampleXPtr, int* sampleYPtr) { 158 int* sampleXPtr, int* sampleYPtr) {
145 int srcWidth = srcInfo.width(); 159 int srcWidth = srcInfo.width();
146 int dstWidth = dstInfo.width(); 160 int dstWidth = dstInfo.width();
147 int srcHeight = srcInfo.height(); 161 int srcHeight = srcInfo.height();
148 int dstHeight = dstInfo.height(); 162 int dstHeight = dstInfo.height();
149 163
150 int sampleX = srcWidth / dstWidth; 164 int sampleX = srcWidth / dstWidth;
151 int sampleY = srcHeight / dstHeight; 165 int sampleY = srcHeight / dstHeight;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 205
192 if (options.fSubset) { 206 if (options.fSubset) {
193 // Subsets are not supported. 207 // Subsets are not supported.
194 return kUnimplemented; 208 return kUnimplemented;
195 } 209 }
196 210
197 Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta bleCount); 211 Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta bleCount);
198 if (kSuccess == result) { 212 if (kSuccess == result) {
199 // native decode supported 213 // native decode supported
200 return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBy tes); 214 return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBy tes);
201
202 } 215 }
203 216
204 if (kInvalidScale != result) { 217 if (kInvalidScale != result) {
205 // no scaling requested 218 // no scaling requested
206 return result; 219 return result;
207 } 220 }
208 221
209 // scaling requested 222 // scaling requested
210 int sampleX; 223 int sampleX;
211 int sampleY; 224 int sampleY;
212 if (!scaling_supported(requestedInfo, fScanlineDecoder->getInfo(), &sampleX, &sampleY)) { 225 if (!scaling_supported(requestedInfo, fScanlineDecoder->getInfo(), &sampleX, &sampleY)) {
213 return kInvalidScale; 226 return kInvalidScale;
214 } 227 }
215 // set first sample pixel in y direction 228 // set first sample pixel in y direction
216 int Y0 = sampleY >> 1; 229 int Y0 = SkScaledCodec::GetStartCoord(sampleY);
217 230
218 int dstHeight = requestedInfo.height(); 231 int dstHeight = requestedInfo.height();
219 int srcHeight = fScanlineDecoder->getInfo().height(); 232 int srcHeight = fScanlineDecoder->getInfo().height();
220 233
221 SkImageInfo info = requestedInfo; 234 SkImageInfo info = requestedInfo;
222 // use original height as scanlineDecoder does not support y sampling native ly 235 // use original height as scanlineDecoder does not support y sampling native ly
223 info = info.makeWH(requestedInfo.width(), srcHeight); 236 info = info.makeWH(requestedInfo.width(), srcHeight);
224 237
225 // update scanlineDecoder with new info 238 // update scanlineDecoder with new info
226 result = fScanlineDecoder->start(info, &options, ctable, ctableCount); 239 result = fScanlineDecoder->start(info, &options, ctable, ctableCount);
227 if (kSuccess != result) { 240 if (kSuccess != result) {
228 return result; 241 return result;
229 } 242 }
230
231 const bool requiresPostYSampling = fScanlineDecoder->requiresPostYSampling() ;
232 243
233 if (requiresPostYSampling) { 244 switch(fScanlineDecoder->getScanlineOrder()) {
234 SkAutoMalloc storage(srcHeight * rowBytes); 245 case SkScanlineDecoder::kTopDown_SkScanlineOrder: {
235 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); 246 result = fScanlineDecoder->skipScanlines(Y0);
236 result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBytes) ; 247 if (kSuccess != result && kIncompleteInput != result) {
237 if (kSuccess != result) { 248 return result;
238 return result; 249 }
250 for (int y = 0; y < dstHeight; y++) {
251 result = fScanlineDecoder->getScanlines(dst, 1, rowBytes);
252 if (kSuccess != result && kIncompleteInput != result) {
253 return result;
254 }
255 if (y < dstHeight - 1) {
256 result = fScanlineDecoder->skipScanlines(sampleY - 1);
257 if (kSuccess != result && kIncompleteInput != result) {
258 return result;
259 }
260 }
261 dst = SkTAddOffset<void>(dst, rowBytes);
262 }
263 return kSuccess;
239 } 264 }
240 storagePtr += Y0 * rowBytes; 265 case SkScanlineDecoder::kBottomUp_SkScanlineOrder:
241 for (int y = 0; y < dstHeight; y++) { 266 case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: {
242 memcpy(dst, storagePtr, rowBytes); 267 for (int y = 0; y < srcHeight; y++) {
243 storagePtr += sampleY * rowBytes; 268 int srcY = fScanlineDecoder->getY();
244 dst = SkTAddOffset<void>(dst, rowBytes); 269 if (SkScaledCodec::IsCoordNecessary(srcY, sampleY, dstHeight)) {
270 void* dstPtr = SkTAddOffset<void>(dst,
271 rowBytes * SkScaledCodec::GetDstCoord(srcY, sampleY) );
272 result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes) ;
273 if (kSuccess != result && kIncompleteInput != result) {
274 return result;
275 }
276 } else {
277 result = fScanlineDecoder->skipScanlines(1);
278 if (kSuccess != result && kIncompleteInput != result) {
279 return result;
280 }
281 }
282 }
283 return kSuccess;
245 } 284 }
246 } else { 285 case SkScanlineDecoder::kNone_SkScanlineOrder: {
247 // does not require post y sampling 286 SkAutoMalloc storage(srcHeight * rowBytes);
248 result = fScanlineDecoder->skipScanlines(Y0); 287 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
249 if (kSuccess != result) { 288 result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBy tes);
250 return result;
251 }
252 for (int y = 0; y < dstHeight; y++) {
253 result = fScanlineDecoder->getScanlines(dst, 1, rowBytes);
254 if (kSuccess != result) { 289 if (kSuccess != result) {
255 return result; 290 return result;
256 } 291 }
257 if (y < dstHeight - 1) { 292 storagePtr += Y0 * rowBytes;
258 result = fScanlineDecoder->skipScanlines(sampleY - 1); 293 for (int y = 0; y < dstHeight; y++) {
259 if (kSuccess != result) { 294 memcpy(dst, storagePtr, rowBytes);
260 return result; 295 storagePtr += sampleY * rowBytes;
261 } 296 dst = SkTAddOffset<void>(dst, rowBytes);
262 } 297 }
263 dst = SkTAddOffset<void>(dst, rowBytes); 298 return kSuccess;
264 } 299 }
300 default:
301 SkASSERT(false);
302 return kUnimplemented;
265 } 303 }
266 return kSuccess;
267 } 304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698