• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "SkImage_Base.h"
9 #include "SkImagePriv.h"
10 #include "SkBitmap.h"
11 #include "SkCanvas.h"
12 #include "SkData.h"
13 #include "SkDecodingImageGenerator.h"
14 
15 class SkImage_Raster : public SkImage_Base {
16 public:
ValidArgs(const Info & info,size_t rowBytes)17     static bool ValidArgs(const Info& info, size_t rowBytes) {
18         const int maxDimension = SK_MaxS32 >> 2;
19         const size_t kMaxPixelByteSize = SK_MaxS32;
20 
21         if (info.width() < 0 || info.height() < 0) {
22             return false;
23         }
24         if (info.width() > maxDimension || info.height() > maxDimension) {
25             return false;
26         }
27         if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
28             return false;
29         }
30         if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
31             return false;
32         }
33 
34         if (kUnknown_SkColorType == info.colorType()) {
35             return false;
36         }
37 
38         // TODO: check colorspace
39 
40         if (rowBytes < SkImageMinRowBytes(info)) {
41             return false;
42         }
43 
44         int64_t size = (int64_t)info.height() * rowBytes;
45         if (size > (int64_t)kMaxPixelByteSize) {
46             return false;
47         }
48         return true;
49     }
50 
51     static SkImage* NewEmpty();
52 
53     SkImage_Raster(const SkImageInfo&, SkData*, size_t rb);
54     virtual ~SkImage_Raster();
55 
56     virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_OVERRIDE;
57     virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&,
58                                   const SkPaint*) const SK_OVERRIDE;
59     virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE;
60     virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
61     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
62 
63     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
64     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
65 
getPixelRef() const66     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
67 
68     virtual SkShader* onNewShader(SkShader::TileMode,
69                                   SkShader::TileMode,
70                                   const SkMatrix* localMatrix) const SK_OVERRIDE;
71 
72     virtual bool isOpaque() const SK_OVERRIDE;
73 
SkImage_Raster(const SkBitmap & bm)74     SkImage_Raster(const SkBitmap& bm)
75         : INHERITED(bm.width(), bm.height())
76         , fBitmap(bm) {}
77 
78 private:
SkImage_Raster()79     SkImage_Raster() : INHERITED(0, 0) {}
80 
81     SkBitmap    fBitmap;
82 
83     typedef SkImage_Base INHERITED;
84 };
85 
86 ///////////////////////////////////////////////////////////////////////////////
87 
NewEmpty()88 SkImage* SkImage_Raster::NewEmpty() {
89     // Returns lazily created singleton
90     static SkImage* gEmpty;
91     if (NULL == gEmpty) {
92         gEmpty = SkNEW(SkImage_Raster);
93     }
94     gEmpty->ref();
95     return gEmpty;
96 }
97 
release_data(void * addr,void * context)98 static void release_data(void* addr, void* context) {
99     SkData* data = static_cast<SkData*>(context);
100     data->unref();
101 }
102 
SkImage_Raster(const Info & info,SkData * data,size_t rowBytes)103 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
104     : INHERITED(info.width(), info.height())
105 {
106     data->ref();
107     void* addr = const_cast<void*>(data->data());
108     SkColorTable* ctable = NULL;
109 
110     fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
111     fBitmap.setImmutable();
112     fBitmap.lockPixels();
113 }
114 
SkImage_Raster(const Info & info,SkPixelRef * pr,size_t rowBytes)115 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
116     : INHERITED(info.width(), info.height())
117 {
118     fBitmap.setInfo(info, rowBytes);
119     fBitmap.setPixelRef(pr);
120     fBitmap.lockPixels();
121 }
122 
~SkImage_Raster()123 SkImage_Raster::~SkImage_Raster() {}
124 
onNewShader(SkShader::TileMode tileX,SkShader::TileMode tileY,const SkMatrix * localMatrix) const125 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
126                                       const SkMatrix* localMatrix) const {
127     return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
128 }
129 
onDraw(SkCanvas * canvas,SkScalar x,SkScalar y,const SkPaint * paint) const130 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
131     canvas->drawBitmap(fBitmap, x, y, paint);
132 }
133 
onDrawRectToRect(SkCanvas * canvas,const SkRect * src,const SkRect & dst,const SkPaint * paint) const134 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
135                                       const SkPaint* paint) const {
136     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
137 }
138 
onReadPixels(SkBitmap * dst,const SkIRect & subset) const139 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
140     if (dst->pixelRef()) {
141         return this->INHERITED::onReadPixels(dst, subset);
142     } else {
143         SkBitmap src;
144         if (!fBitmap.extractSubset(&src, subset)) {
145             return false;
146         }
147         return src.copyTo(dst, src.colorType());
148     }
149 }
150 
onPeekPixels(SkImageInfo * infoPtr,size_t * rowBytesPtr) const151 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
152     const SkImageInfo info = fBitmap.info();
153     if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
154         return NULL;
155     }
156     *infoPtr = info;
157     *rowBytesPtr = fBitmap.rowBytes();
158     return fBitmap.getPixels();
159 }
160 
getROPixels(SkBitmap * dst) const161 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
162     *dst = fBitmap;
163     return true;
164 }
165 
166 ///////////////////////////////////////////////////////////////////////////////
167 
NewRasterCopy(const SkImageInfo & info,const void * pixels,size_t rowBytes)168 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
169     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
170         return NULL;
171     }
172     if (0 == info.width() && 0 == info.height()) {
173         return SkImage_Raster::NewEmpty();
174     }
175     // check this after empty-check
176     if (NULL == pixels) {
177         return NULL;
178     }
179 
180     // Here we actually make a copy of the caller's pixel data
181     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes));
182     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
183 }
184 
185 
NewRasterData(const SkImageInfo & info,SkData * data,size_t rowBytes)186 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
187     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
188         return NULL;
189     }
190     if (0 == info.width() && 0 == info.height()) {
191         return SkImage_Raster::NewEmpty();
192     }
193     // check this after empty-check
194     if (NULL == data) {
195         return NULL;
196     }
197 
198     // did they give us enough data?
199     size_t size = info.height() * rowBytes;
200     if (data->size() < size) {
201         return NULL;
202     }
203 
204     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
205 }
206 
NewFromGenerator(SkImageGenerator * generator)207 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) {
208     SkBitmap bitmap;
209     if (!SkInstallDiscardablePixelRef(generator, &bitmap)) {
210         return NULL;
211     }
212     return SkNEW_ARGS(SkImage_Raster, (bitmap));
213 }
214 
SkNewImageFromPixelRef(const SkImageInfo & info,SkPixelRef * pr,size_t rowBytes)215 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
216                                 size_t rowBytes) {
217     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
218 }
219 
SkBitmapImageGetPixelRef(SkImage * image)220 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
221     return ((SkImage_Raster*)image)->getPixelRef();
222 }
223 
isOpaque() const224 bool SkImage_Raster::isOpaque() const {
225     return fBitmap.isOpaque();
226 }
227