blob: da88316654ab3d58b7776bb12307cc5e406ba5e2 [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"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +00005#include "SkReadBuffer.h"
6#include "SkWriteBuffer.h"
reed@google.com32d25b62011-12-20 16:19:00 +00007
reed@google.come7639512012-08-07 14:25:44 +00008// Simple helper canvas that "takes ownership" of the provided device, so that
9// when this canvas goes out of scope, so will its device. Could be replaced
10// with the following:
11//
12// SkCanvas canvas(device);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000013// SkAutoTUnref<SkBaseDevice> aur(device);
reed@google.come7639512012-08-07 14:25:44 +000014//
reed@google.com76dd2772012-01-05 21:15:07 +000015class OwnDeviceCanvas : public SkCanvas {
16public:
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000017 OwnDeviceCanvas(SkBaseDevice* device) : SkCanvas(device) {
reed@google.com76dd2772012-01-05 21:15:07 +000018 SkSafeUnref(device);
19 }
20};
21
reed@google.com32d25b62011-12-20 16:19:00 +000022///////////////////////////////////////////////////////////////////////////////
23
reed@google.com76dd2772012-01-05 21:15:07 +000024bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
senorblanco@chromium.org4cb543d2014-03-14 15:44:01 +000025 const Context&,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +000026 SkBitmap* result, SkIPoint*) const {
reed@google.com32d25b62011-12-20 16:19:00 +000027 SkScalar scale = fScale;
28 if (scale > SK_Scalar1 || scale <= 0) {
29 return false;
30 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000031
reed@google.com32d25b62011-12-20 16:19:00 +000032 int dstW = SkScalarRoundToInt(src.width() * scale);
33 int dstH = SkScalarRoundToInt(src.height() * scale);
34 if (dstW < 1) {
35 dstW = 1;
36 }
37 if (dstH < 1) {
38 dstH = 1;
39 }
reed@google.com76dd2772012-01-05 21:15:07 +000040
41 SkBitmap tmp;
42
reed@google.com32d25b62011-12-20 16:19:00 +000043 // downsample
44 {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000045 SkBaseDevice* dev = proxy->createDevice(dstW, dstH);
reed@google.com76dd2772012-01-05 21:15:07 +000046 if (NULL == dev) {
47 return false;
48 }
49 OwnDeviceCanvas canvas(dev);
reed@google.com32d25b62011-12-20 16:19:00 +000050 SkPaint paint;
reed@google.com76dd2772012-01-05 21:15:07 +000051
reed@google.com44699382013-10-31 17:28:30 +000052 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
reed@google.com32d25b62011-12-20 16:19:00 +000053 canvas.scale(scale, scale);
54 canvas.drawBitmap(src, 0, 0, &paint);
reed@google.com76dd2772012-01-05 21:15:07 +000055 tmp = dev->accessBitmap(false);
reed@google.com32d25b62011-12-20 16:19:00 +000056 }
reed@google.com76dd2772012-01-05 21:15:07 +000057
reed@google.com32d25b62011-12-20 16:19:00 +000058 // upscale
59 {
robertphillips@google.com1f2f3382013-08-29 11:54:56 +000060 SkBaseDevice* dev = proxy->createDevice(src.width(), src.height());
reed@google.com76dd2772012-01-05 21:15:07 +000061 if (NULL == dev) {
62 return false;
63 }
64 OwnDeviceCanvas canvas(dev);
65
66 SkRect r = SkRect::MakeWH(SkIntToScalar(src.width()),
67 SkIntToScalar(src.height()));
68 canvas.drawBitmapRect(tmp, NULL, r, NULL);
69 *result = dev->accessBitmap(false);
reed@google.com32d25b62011-12-20 16:19:00 +000070 }
71 return true;
72}
73
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000074void SkDownSampleImageFilter::flatten(SkWriteBuffer& buffer) const {
reed@google.com32d25b62011-12-20 16:19:00 +000075 this->INHERITED::flatten(buffer);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000076
reed@google.com32d25b62011-12-20 16:19:00 +000077 buffer.writeScalar(fScale);
78}
79
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000080SkDownSampleImageFilter::SkDownSampleImageFilter(SkReadBuffer& buffer)
commit-bot@chromium.orgce33d602013-11-25 21:46:31 +000081 : INHERITED(1, buffer) {
reed@google.com32d25b62011-12-20 16:19:00 +000082 fScale = buffer.readScalar();
commit-bot@chromium.orgc0b7e102013-10-23 17:06:21 +000083 buffer.validate(SkScalarIsFinite(fScale));
reed@google.com32d25b62011-12-20 16:19:00 +000084}