blob: c812f58eff6dc632f2df0ea4260ea2ea78390f48 [file] [log] [blame]
reed@google.com6997ebb2012-07-30 19:50:31 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
reed@google.comf6627b72012-07-27 18:02:50 +00008#include "SkBitmap.h"
mike@reedtribe.org70e35902012-07-29 20:38:16 +00009#include "SkCanvas.h"
scroggo@google.com7def5e12013-05-31 14:00:10 +000010#include "SkImagePriv.h"
11#include "SkImage_Base.h"
reed@google.comf6627b72012-07-27 18:02:50 +000012
scroggo@google.com7def5e12013-05-31 14:00:10 +000013static SkImage_Base* as_IB(SkImage* image) {
reed@google.comf6627b72012-07-27 18:02:50 +000014 return static_cast<SkImage_Base*>(image);
15}
16
scroggo@google.com7def5e12013-05-31 14:00:10 +000017static const SkImage_Base* as_IB(const SkImage* image) {
18 return static_cast<const SkImage_Base*>(image);
19}
20
reed@google.comf6627b72012-07-27 18:02:50 +000021uint32_t SkImage::NextUniqueID() {
22 static int32_t gUniqueID;
23
24 // never return 0;
25 uint32_t id;
26 do {
27 id = sk_atomic_inc(&gUniqueID) + 1;
28 } while (0 == id);
29 return id;
30}
31
32void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
33 const SkPaint* paint) {
scroggo@google.com7def5e12013-05-31 14:00:10 +000034 as_IB(this)->onDraw(canvas, x, y, paint);
reed@google.comf6627b72012-07-27 18:02:50 +000035}
junov@chromium.orgda904742013-05-01 22:38:16 +000036
commit-bot@chromium.orgdfec28d2013-07-23 15:52:16 +000037void SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
38 const SkPaint* paint) {
39 as_IB(this)->onDrawRectToRect(canvas, src, dst, paint);
40}
41
reed@google.com4f7c6152014-02-06 14:11:56 +000042const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const {
43 SkImageInfo infoStorage;
44 size_t rowBytesStorage;
45 if (NULL == info) {
46 info = &infoStorage;
47 }
48 if (NULL == rowBytes) {
49 rowBytes = &rowBytesStorage;
50 }
51 return as_IB(this)->onPeekPixels(info, rowBytes);
52}
53
54bool SkImage::readPixels(SkBitmap* bitmap, const SkIRect* subset) const {
55 if (NULL == bitmap) {
56 return false;
57 }
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +000058
reed@google.com4f7c6152014-02-06 14:11:56 +000059 SkIRect bounds = SkIRect::MakeWH(this->width(), this->height());
60
61 // trim against the bitmap, if its already been allocated
62 if (bitmap->pixelRef()) {
63 bounds.fRight = SkMin32(bounds.fRight, bitmap->width());
64 bounds.fBottom = SkMin32(bounds.fBottom, bitmap->height());
65 if (bounds.isEmpty()) {
66 return false;
67 }
68 }
69
70 if (subset && !bounds.intersect(*subset)) {
71 // perhaps we could return true + empty-bitmap?
72 return false;
73 }
74 return as_IB(this)->onReadPixels(bitmap, bounds);
75}
76
junov@chromium.orgda904742013-05-01 22:38:16 +000077GrTexture* SkImage::getTexture() {
scroggo@google.com7def5e12013-05-31 14:00:10 +000078 return as_IB(this)->onGetTexture();
79}
80
piotaixr76d5b472014-07-22 15:02:05 -070081SkShader* SkImage::newShader(SkShader::TileMode tileX,
82 SkShader::TileMode tileY,
83 const SkMatrix* localMatrix) const {
84 return as_IB(this)->onNewShader(tileX, tileY, localMatrix);
piotaixrcef04f82014-07-14 07:48:04 -070085}
86
scroggo@google.com7def5e12013-05-31 14:00:10 +000087SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
88 SkBitmap bm;
89 if (as_IB(this)->getROPixels(&bm)) {
90 return SkImageEncoder::EncodeData(bm, type, quality);
91 }
92 return NULL;
junov@chromium.orgda904742013-05-01 22:38:16 +000093}
reed@google.com4f7c6152014-02-06 14:11:56 +000094
95///////////////////////////////////////////////////////////////////////////////
96
97static bool raster_canvas_supports(const SkImageInfo& info) {
98 switch (info.fColorType) {
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000099 case kN32_SkColorType:
reed@google.com4f7c6152014-02-06 14:11:56 +0000100 return kUnpremul_SkAlphaType != info.fAlphaType;
101 case kRGB_565_SkColorType:
102 return true;
103 case kAlpha_8_SkColorType:
104 return true;
105 default:
106 break;
107 }
108 return false;
109}
110
111bool SkImage_Base::onReadPixels(SkBitmap* bitmap, const SkIRect& subset) const {
reed@google.com4f7c6152014-02-06 14:11:56 +0000112 if (bitmap->pixelRef()) {
commit-bot@chromium.org466f5f32014-05-27 21:30:37 +0000113 const SkImageInfo info = bitmap->info();
114 if (kUnknown_SkColorType == info.colorType()) {
reed@google.com4f7c6152014-02-06 14:11:56 +0000115 return false;
116 }
117 if (!raster_canvas_supports(info)) {
118 return false;
119 }
120 } else {
commit-bot@chromium.org466f5f32014-05-27 21:30:37 +0000121 const SkImageInfo info = SkImageInfo::MakeN32Premul(subset.width(), subset.height());
reed@google.com4f7c6152014-02-06 14:11:56 +0000122 SkBitmap tmp;
123 if (!tmp.allocPixels(info)) {
124 return false;
125 }
126 *bitmap = tmp;
127 }
128
129 SkRect srcR, dstR;
130 srcR.set(subset);
131 dstR = srcR;
132 dstR.offset(-dstR.left(), -dstR.top());
commit-bot@chromium.org5e0995e2014-02-07 12:20:04 +0000133
reed@google.com4f7c6152014-02-06 14:11:56 +0000134 SkCanvas canvas(*bitmap);
135
136 SkPaint paint;
137 paint.setXfermodeMode(SkXfermode::kClear_Mode);
138 canvas.drawRect(dstR, paint);
139
140 const_cast<SkImage_Base*>(this)->onDrawRectToRect(&canvas, &srcR, dstR, NULL);
141 return true;
142}