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

Side by Side Diff: dm/DMSrcSink.cpp

Issue 1194703002: onGetScanlines and onSkipScanlines for interlaced pngs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fixing size_t to int conversion warning Created 5 years, 6 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 | « no previous file | src/codec/SkCodec_libpng.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 "DMSrcSink.h" 8 #include "DMSrcSink.h"
9 #include "SamplePipeControllers.h" 9 #include "SamplePipeControllers.h"
10 #include "SkCodec.h" 10 #include "SkCodec.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); 133 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType);
134 } 134 }
135 135
136 SkBitmap bitmap; 136 SkBitmap bitmap;
137 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) { 137 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) {
138 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ), 138 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ),
139 decodeInfo.width(), decodeInfo.height()); 139 decodeInfo.width(), decodeInfo.height());
140 } 140 }
141 141
142 switch (fMode) { 142 switch (fMode) {
143 case kNormal_Mode: 143 case kNormal_Mode: {
144 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), NULL, 144 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), NULL,
145 colorPtr, colorCountPtr)) { 145 colorPtr, colorCountPtr)) {
146 case SkImageGenerator::kSuccess: 146 case SkImageGenerator::kSuccess:
147 // We consider incomplete to be valid, since we should still decode what is 147 // We consider incomplete to be valid, since we should still decode what is
148 // available. 148 // available.
149 case SkImageGenerator::kIncompleteInput: 149 case SkImageGenerator::kIncompleteInput:
150 break; 150 break;
151 case SkImageGenerator::kInvalidConversion: 151 case SkImageGenerator::kInvalidConversion:
152 return Error::Nonfatal("Incompatible colortype conversion"); 152 return Error::Nonfatal("Incompatible colortype conversion");
153 default: 153 default:
154 // Everything else is considered a failure. 154 // Everything else is considered a failure.
155 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); 155 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( ));
156 } 156 }
157 canvas->drawBitmap(bitmap, 0, 0); 157 canvas->drawBitmap(bitmap, 0, 0);
158 break; 158 break;
159 }
159 case kScanline_Mode: { 160 case kScanline_Mode: {
160 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL, 161 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(decod eInfo, NULL,
161 colorPtr, colorCountPtr); 162 colorPtr, colorCountPtr);
162 if (NULL == scanlineDecoder) { 163 if (NULL == scanlineDecoder) {
163 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); 164 return Error::Nonfatal("Cannot use scanline decoder for all imag es");
164 } 165 }
165 for (int y = 0; y < decodeInfo.height(); ++y) { 166 const SkImageGenerator::Result result = scanlineDecoder->getScanline s(
166 const SkImageGenerator::Result result = scanlineDecoder->getScan lines( 167 bitmap.getAddr(0, 0), decodeInfo.height(), bitmap.rowBytes() );
167 bitmap.getAddr(0, y), 1, 0); 168 switch (result) {
168 switch (result) { 169 case SkImageGenerator::kSuccess:
169 case SkImageGenerator::kSuccess: 170 case SkImageGenerator::kIncompleteInput:
170 case SkImageGenerator::kIncompleteInput: 171 break;
171 break; 172 default:
172 default: 173 return SkStringPrintf("%s failed with error message %d",
173 return SkStringPrintf("%s failed after %d scanlines with error message %d", 174 fPath.c_str(), (int) result);
174 fPath.c_str(), y-1, (int) result);
175 }
176 } 175 }
177 canvas->drawBitmap(bitmap, 0, 0); 176 canvas->drawBitmap(bitmap, 0, 0);
178 break; 177 break;
179 } 178 }
180 case kScanline_Subset_Mode: { 179 case kScanline_Subset_Mode: {
181 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder 180 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder
182 const int divisor = 2; 181 const int divisor = 2;
183 const int w = decodeInfo.width(); 182 const int w = decodeInfo.width();
184 const int h = decodeInfo.height(); 183 const int h = decodeInfo.height();
185 if (w*h == 1) { 184 if (w*h == 1) {
(...skipping 17 matching lines...) Expand all
203 * subsetBm's size is determined based on the current subset and may be larger for end 202 * subsetBm's size is determined based on the current subset and may be larger for end
204 * subsets. 203 * subsets.
205 */ 204 */
206 SkImageInfo largestSubsetDecodeInfo = 205 SkImageInfo largestSubsetDecodeInfo =
207 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); 206 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y);
208 SkBitmap largestSubsetBm; 207 SkBitmap largestSubsetBm;
209 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { 208 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) {
210 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), 209 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(),
211 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); 210 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height());
212 } 211 }
213 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); 212 const size_t rowBytes = decodeInfo.minRowBytes();
214 SkAutoTDeleteArray<char> lineDeleter(line); 213 char* buffer = SkNEW_ARRAY(char, largestSubsetDecodeInfo.height() * rowBytes);
214 SkAutoTDeleteArray<char> lineDeleter(buffer);
215 for (int col = 0; col < divisor; col++) { 215 for (int col = 0; col < divisor; col++) {
216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets 216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets
217 const int currentSubsetWidth = (col + 1 == divisor) ? 217 const int currentSubsetWidth = (col + 1 == divisor) ?
218 subsetWidth + extraX : subsetWidth; 218 subsetWidth + extraX : subsetWidth;
219 const int x = col * subsetWidth; 219 const int x = col * subsetWidth;
220 for (int row = 0; row < divisor; row++) { 220 for (int row = 0; row < divisor; row++) {
221 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets 221 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets
222 const int currentSubsetHeight = (row + 1 == divisor) ? 222 const int currentSubsetHeight = (row + 1 == divisor) ?
223 subsetHeight + extraY : subsetHeight; 223 subsetHeight + extraY : subsetHeight;
224 const int y = row * subsetHeight; 224 const int y = row * subsetHeight;
(...skipping 18 matching lines...) Expand all
243 default: 243 default:
244 return SkStringPrintf("%s failed after attempting to skip %d scanlines" 244 return SkStringPrintf("%s failed after attempting to skip %d scanlines"
245 "with error message %d", fPath.c_str(), y, ( int) skipResult); 245 "with error message %d", fPath.c_str(), y, ( int) skipResult);
246 } 246 }
247 //create and set size of subsetBm 247 //create and set size of subsetBm
248 SkBitmap subsetBm; 248 SkBitmap subsetBm;
249 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); 249 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight);
250 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); 250 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight );
251 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); 251 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds));
252 SkAutoLockPixels autlockSubsetBm(subsetBm, true); 252 SkAutoLockPixels autlockSubsetBm(subsetBm, true);
253 const SkImageGenerator::Result subsetResult =
254 subsetScanlineDecoder->getScanlines(buffer, currentSubse tHeight, rowBytes);
255 switch (subsetResult) {
256 case SkImageGenerator::kSuccess:
257 case SkImageGenerator::kIncompleteInput:
258 break;
259 default:
260 return SkStringPrintf("%s failed with error message %d",
261 fPath.c_str(), (int) subsetResult);
262 }
263 const size_t bpp = decodeInfo.bytesPerPixel();
264 /*
265 * we copy all the lines at once becuase when calling getSca nlines for
266 * interlaced pngs the entire image must be read regardless of the number
267 * of lines requested. Reading an interlaced png in a loop, line-by-line, would
268 * decode the entire image height times, which is very slow
269 * it is aknowledged that copying each line as you read it i n a loop
270 * may be faster for other types of images. Since this is a correctness test
271 * that's okay.
272 */
273 char* bufferRow = buffer;
253 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) { 274 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) {
254 const SkImageGenerator::Result subsetResult = 275 memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp,
255 subsetScanlineDecoder->getScanlines(line, 1, 0); 276 currentSubsetWidth*bpp);
256 const size_t bpp = decodeInfo.bytesPerPixel(); 277 bufferRow += rowBytes;
257 //copy section of line based on x value
258 memcpy(subsetBm.getAddr(0, subsetY), line + x*bpp, curre ntSubsetWidth*bpp);
259 switch (subsetResult) {
260 case SkImageGenerator::kSuccess:
261 case SkImageGenerator::kIncompleteInput:
262 break;
263 default:
264 return SkStringPrintf("%s failed after %d scanli nes with error"
265 "message %d", fPath.c_str(), y-1, (int) subsetResult);
266 }
267 } 278 }
279
268 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); 280 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y));
269 } 281 }
270 } 282 }
271 break; 283 break;
272 } 284 }
273 case kStripe_Mode: { 285 case kStripe_Mode: {
274 const int height = decodeInfo.height(); 286 const int height = decodeInfo.height();
275 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that 287 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that
276 // does not align with image blocks. 288 // does not align with image blocks.
277 const int stripeHeight = 37; 289 const int stripeHeight = 37;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 switch (result) { 349 switch (result) {
338 case SkImageGenerator::kSuccess: 350 case SkImageGenerator::kSuccess:
339 case SkImageGenerator::kIncompleteInput: 351 case SkImageGenerator::kIncompleteInput:
340 break; 352 break;
341 default: 353 default:
342 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str()); 354 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str());
343 } 355 }
344 } 356 }
345 } 357 }
346 canvas->drawBitmap(bitmap, 0, 0); 358 canvas->drawBitmap(bitmap, 0, 0);
359 break;
347 } 360 }
348 } 361 }
349 return ""; 362 return "";
350 } 363 }
351 364
352 SkISize CodecSrc::size() const { 365 SkISize CodecSrc::size() const {
353 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); 366 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
354 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); 367 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded));
355 if (NULL != codec) { 368 if (NULL != codec) {
356 SkISize size = codec->getScaledDimensions(fScale); 369 SkISize size = codec->getScaledDimensions(fScale);
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 skr.visit<void>(i, drawsAsSingletonPictures); 983 skr.visit<void>(i, drawsAsSingletonPictures);
971 } 984 }
972 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); 985 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture());
973 986
974 canvas->drawPicture(macroPic); 987 canvas->drawPicture(macroPic);
975 return ""; 988 return "";
976 }); 989 });
977 } 990 }
978 991
979 } // namespace DM 992 } // namespace DM
OLDNEW
« no previous file with comments | « no previous file | src/codec/SkCodec_libpng.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698