1 2 #include "SkTestImageFilters.h" 3 #include "SkCanvas.h" 4 #include "SkDevice.h" 5 #include "SkFlattenableBuffers.h" 6 7 // Simple helper canvas that "takes ownership" of the provided device, so that 8 // when this canvas goes out of scope, so will its device. Could be replaced 9 // with the following: 10 // 11 // SkCanvas canvas(device); 12 // SkAutoTUnref<SkBaseDevice> aur(device); 13 // 14 class OwnDeviceCanvas : public SkCanvas { 15 public: 16 OwnDeviceCanvas(SkBaseDevice* device) : SkCanvas(device) { 17 SkSafeUnref(device); 18 } 19 }; 20 21 /////////////////////////////////////////////////////////////////////////////// 22 23 bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, 24 const SkMatrix&, 25 SkBitmap* result, SkIPoint*) { 26 SkScalar scale = fScale; 27 if (scale > SK_Scalar1 || scale <= 0) { 28 return false; 29 } 30 31 int dstW = SkScalarRoundToInt(src.width() * scale); 32 int dstH = SkScalarRoundToInt(src.height() * scale); 33 if (dstW < 1) { 34 dstW = 1; 35 } 36 if (dstH < 1) { 37 dstH = 1; 38 } 39 40 SkBitmap tmp; 41 42 // downsample 43 { 44 SkBaseDevice* dev = proxy->createDevice(dstW, dstH); 45 if (NULL == dev) { 46 return false; 47 } 48 OwnDeviceCanvas canvas(dev); 49 SkPaint paint; 50 51 paint.setFilterLevel(SkPaint::kLow_FilterLevel); 52 canvas.scale(scale, scale); 53 canvas.drawBitmap(src, 0, 0, &paint); 54 tmp = dev->accessBitmap(false); 55 } 56 57 // upscale 58 { 59 SkBaseDevice* dev = proxy->createDevice(src.width(), src.height()); 60 if (NULL == dev) { 61 return false; 62 } 63 OwnDeviceCanvas canvas(dev); 64 65 SkRect r = SkRect::MakeWH(SkIntToScalar(src.width()), 66 SkIntToScalar(src.height())); 67 canvas.drawBitmapRect(tmp, NULL, r, NULL); 68 *result = dev->accessBitmap(false); 69 } 70 return true; 71 } 72 73 void SkDownSampleImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { 74 this->INHERITED::flatten(buffer); 75 76 buffer.writeScalar(fScale); 77 } 78 79 SkDownSampleImageFilter::SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer) 80 : INHERITED(1, buffer) { 81 fScale = buffer.readScalar(); 82 buffer.validate(SkScalarIsFinite(fScale)); 83 } 84