1c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com
232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com#include "SkTestImageFilters.h"
332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com#include "SkCanvas.h"
476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com#include "SkDevice.h"
58b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
68b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
8e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com// Simple helper canvas that "takes ownership" of the provided device, so that
9e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com// when this canvas goes out of scope, so will its device. Could be replaced
10e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com// with the following:
11e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com//
12e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com//  SkCanvas canvas(device);
131f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com//  SkAutoTUnref<SkBaseDevice> aur(device);
14e763951a5c0a9130eb6a7a9f05ab848eb9b3acf8reed@google.com//
1576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.comclass OwnDeviceCanvas : public SkCanvas {
1676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.compublic:
171f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    OwnDeviceCanvas(SkBaseDevice* device) : SkCanvas(device) {
1876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        SkSafeUnref(device);
1976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    }
2076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com};
2176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
2232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com///////////////////////////////////////////////////////////////////////////////
2332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
2476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.combool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
254cb543d6057b692e1099e9f115155f0bf323a0c8senorblanco@chromium.org                                            const Context&,
26ae761f7545d8ebf181d220169afac2056b057b8ccommit-bot@chromium.org                                            SkBitmap* result, SkIPoint*) const {
2732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    SkScalar scale = fScale;
2832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    if (scale > SK_Scalar1 || scale <= 0) {
2932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        return false;
3032d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    }
31fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    int dstW = SkScalarRoundToInt(src.width() * scale);
3332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    int dstH = SkScalarRoundToInt(src.height() * scale);
3432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    if (dstW < 1) {
3532d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        dstW = 1;
3632d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    }
3732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    if (dstH < 1) {
3832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        dstH = 1;
3932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    }
4076dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
4176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com    SkBitmap tmp;
4276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
4332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    // downsample
4432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    {
451f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        SkBaseDevice* dev = proxy->createDevice(dstW, dstH);
4676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        if (NULL == dev) {
4776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com            return false;
4876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        }
4976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        OwnDeviceCanvas canvas(dev);
5032d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        SkPaint paint;
5176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
524469938e92d779dff05e745559e67907bbf21e78reed@google.com        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
5332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        canvas.scale(scale, scale);
5432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com        canvas.drawBitmap(src, 0, 0, &paint);
5576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        tmp = dev->accessBitmap(false);
5632d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    }
5776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
5832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    // upscale
5932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    {
601f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com        SkBaseDevice* dev = proxy->createDevice(src.width(), src.height());
6176dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        if (NULL == dev) {
6276dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com            return false;
6376dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        }
6476dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        OwnDeviceCanvas canvas(dev);
6576dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com
6676dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        SkRect r = SkRect::MakeWH(SkIntToScalar(src.width()),
6776dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com                                  SkIntToScalar(src.height()));
6876dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        canvas.drawBitmapRect(tmp, NULL, r, NULL);
6976dd277b1fa021c42fc3acdd8d61e7dc05f9c267reed@google.com        *result = dev->accessBitmap(false);
7032d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    }
7132d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    return true;
7232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com}
7332d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
748b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkDownSampleImageFilter::flatten(SkWriteBuffer& buffer) const {
7532d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    this->INHERITED::flatten(buffer);
76fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7732d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    buffer.writeScalar(fScale);
7832d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com}
7932d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com
808b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkDownSampleImageFilter::SkDownSampleImageFilter(SkReadBuffer& buffer)
81ce33d60187718e7bb01944ee130c9f5d9fb335eccommit-bot@chromium.org  : INHERITED(1, buffer) {
8232d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com    fScale = buffer.readScalar();
83c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org    buffer.validate(SkScalarIsFinite(fScale));
8432d25b6f5f4355d4c5281694034ba3a5aa2cf571reed@google.com}
85