blob: d0e21a3920067b62b0372374502e4637f0be6e58 [file] [log] [blame]
djsollen@google.comc73dd5c2012-08-07 15:54:32 +00001
reed@google.com32d25b62011-12-20 16:19:00 +00002#include "SkTestImageFilters.h"
3#include "SkCanvas.h"
reed@google.com76dd2772012-01-05 21:15:07 +00004#include "SkDevice.h"
djsollen@google.comc73dd5c2012-08-07 15:54:32 +00005#include "SkFlattenableBuffers.h"
reed@google.com32d25b62011-12-20 16:19:00 +00006
reed@google.come7639512012-08-07 14:25:44 +00007// 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);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000012// SkAutoTUnref<SkBaseDevice> aur(device);
reed@google.come7639512012-08-07 14:25:44 +000013//
reed@google.com76dd2772012-01-05 21:15:07 +000014class OwnDeviceCanvas : public SkCanvas {
15public:
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000016 OwnDeviceCanvas(SkBaseDevice* device) : SkCanvas(device) {
reed@google.com76dd2772012-01-05 21:15:07 +000017 SkSafeUnref(device);
18 }
19};
20
reed@google.com32d25b62011-12-20 16:19:00 +000021///////////////////////////////////////////////////////////////////////////////
22
reed@google.com76dd2772012-01-05 21:15:07 +000023bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
sugoi@google.come0e385c2013-03-11 18:50:03 +000024 const SkMatrix&,
reed@google.com32d25b62011-12-20 16:19:00 +000025 SkBitmap* result, SkIPoint*) {
26 SkScalar scale = fScale;
27 if (scale > SK_Scalar1 || scale <= 0) {
28 return false;
29 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000030
reed@google.com32d25b62011-12-20 16:19:00 +000031 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 }
reed@google.com76dd2772012-01-05 21:15:07 +000039
40 SkBitmap tmp;
41
reed@google.com32d25b62011-12-20 16:19:00 +000042 // downsample
43 {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000044 SkBaseDevice* dev = proxy->createDevice(dstW, dstH);
reed@google.com76dd2772012-01-05 21:15:07 +000045 if (NULL == dev) {
46 return false;
47 }
48 OwnDeviceCanvas canvas(dev);
reed@google.com32d25b62011-12-20 16:19:00 +000049 SkPaint paint;
reed@google.com76dd2772012-01-05 21:15:07 +000050
reed@google.com32d25b62011-12-20 16:19:00 +000051 paint.setFilterBitmap(true);
reed@google.com32d25b62011-12-20 16:19:00 +000052 canvas.scale(scale, scale);
53 canvas.drawBitmap(src, 0, 0, &paint);
reed@google.com76dd2772012-01-05 21:15:07 +000054 tmp = dev->accessBitmap(false);
reed@google.com32d25b62011-12-20 16:19:00 +000055 }
reed@google.com76dd2772012-01-05 21:15:07 +000056
reed@google.com32d25b62011-12-20 16:19:00 +000057 // upscale
58 {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000059 SkBaseDevice* dev = proxy->createDevice(src.width(), src.height());
reed@google.com76dd2772012-01-05 21:15:07 +000060 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);
reed@google.com32d25b62011-12-20 16:19:00 +000069 }
70 return true;
71}
72
djsollen@google.com54924242012-03-29 15:18:04 +000073void SkDownSampleImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
reed@google.com32d25b62011-12-20 16:19:00 +000074 this->INHERITED::flatten(buffer);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000075
reed@google.com32d25b62011-12-20 16:19:00 +000076 buffer.writeScalar(fScale);
77}
78
79SkDownSampleImageFilter::SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
80 fScale = buffer.readScalar();
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +000081 buffer.validate(SkScalarIsFinite(fScale));
reed@google.com32d25b62011-12-20 16:19:00 +000082}