OLD | NEW |
---|---|
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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 case SkCodec::kIncompleteInput: | 348 case SkCodec::kIncompleteInput: |
349 break; | 349 break; |
350 default: | 350 default: |
351 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str()); | 351 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str()); |
352 } | 352 } |
353 } | 353 } |
354 } | 354 } |
355 canvas->drawBitmap(bitmap, 0, 0); | 355 canvas->drawBitmap(bitmap, 0, 0); |
356 break; | 356 break; |
357 } | 357 } |
358 case kSubset_Mode: { | |
359 // Arbitrarily choose a divisor. | |
360 int divisor = 2; | |
361 // Total width/height of the image. | |
362 const int W = codec->getInfo().width(); | |
363 const int H = codec->getInfo().height(); | |
364 if (divisor > W || divisor > H) { | |
365 return Error::Nonfatal(SkStringPrintf("Cannot codec subset: divi sor %d is too big " | |
366 "for %s with dimensions (% d x %d)", divisor, | |
367 fPath.c_str(), W, H)); | |
368 } | |
369 // subset dimensions | |
370 // SkWebpCodec, the only one that supports subsets, requires even to p/left boundaries. | |
371 const int w = SkAlign2(W / divisor); | |
372 const int h = SkAlign2(H / divisor); | |
373 SkCodec::Options opts; | |
374 SkBitmap subsetBm; | |
375 // We will reuse pixel memory from bitmap. | |
376 void* pixels = bitmap.getPixels(); | |
377 // Keep track of left and top (for drawing subsetBm into canvas). We could use | |
378 // fScale * x and fScale * y, but we want integers such that the nex t subset will start | |
379 // where the last one ended. So we'll add decodeInfo.width() and hei ght(). | |
380 int left = 0; | |
381 for (int x = 0; x < W; x += w) { | |
382 int top = 0; | |
383 for (int y = 0; y < H; y+= h) { | |
384 // Do not make the subset go off the edge of the image. | |
385 decodeInfo = decodeInfo.makeWH(SkTMin(w, W - x), SkTMin(h, H - y)); | |
386 opts.fSubset.setXYWH(x, y, decodeInfo.width(), decodeInfo.he ight()); | |
387 // And scale | |
388 decodeInfo = decodeInfo.makeWH(decodeInfo.width() * fScale, | |
emmaleer
2015/07/17 22:31:05
You could only call decodeInfo.makeWH() once inste
scroggo
2015/07/20 14:25:42
SkImageInfo::makeWH() is likely pretty cheap (func
| |
389 decodeInfo.height() * fScale) ; | |
390 size_t rowBytes = decodeInfo.minRowBytes(); | |
391 if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes, co lorTable.get(), | |
392 NULL, NULL)) { | |
393 return SkStringPrintf("could not install pixels for %s." , fPath.c_str()); | |
394 } | |
395 const SkCodec::Result result = codec->getPixels(decodeInfo, pixels, rowBytes, | |
396 &opts, colorPtr, colorCountPtr); | |
397 switch (result) { | |
398 case SkCodec::kSuccess: | |
399 break; | |
emmaleer
2015/07/17 22:31:05
What about the case SkCodec::kIncompleteInput.
All
scroggo
2015/07/20 14:25:42
I think this goes back to my general concern about
| |
400 case SkCodec::kUnimplemented: | |
401 if (0 == (x|y)) { | |
402 // First subset is okay to return unimplemented. | |
403 return Error::Nonfatal("subset codec not support ed"); | |
404 } | |
405 // If the first subset succeeded, why would a later one fail? | |
406 // fall through to failure | |
407 default: | |
408 return SkStringPrintf("subset codec failed to decode (%d, %d, %d, %d) " | |
409 "from %s with dimensions (%d x %d)\t error %d", | |
410 x, y, decodeInfo.width(), deco deInfo.height(), | |
411 fPath.c_str(), W, H, result); | |
412 } | |
413 canvas->drawBitmap(subsetBm, left, top); | |
414 // translate by the scaled height. | |
415 top += decodeInfo.height(); | |
416 } | |
417 // translate by the scaled width. | |
418 left += decodeInfo.width(); | |
419 } | |
420 return ""; | |
421 } | |
358 } | 422 } |
359 return ""; | 423 return ""; |
360 } | 424 } |
361 | 425 |
362 SkISize CodecSrc::size() const { | 426 SkISize CodecSrc::size() const { |
363 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 427 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
364 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 428 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
365 if (NULL != codec) { | 429 if (NULL != codec) { |
366 SkISize size = codec->getScaledDimensions(fScale); | 430 SkISize size = codec->getScaledDimensions(fScale); |
367 return size; | 431 return size; |
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
989 skr.visit<void>(i, drawsAsSingletonPictures); | 1053 skr.visit<void>(i, drawsAsSingletonPictures); |
990 } | 1054 } |
991 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1055 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
992 | 1056 |
993 canvas->drawPicture(macroPic); | 1057 canvas->drawPicture(macroPic); |
994 return ""; | 1058 return ""; |
995 }); | 1059 }); |
996 } | 1060 } |
997 | 1061 |
998 } // namespace DM | 1062 } // namespace DM |
OLD | NEW |