• 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 "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkData.h"
12 #include "SkImageGenerator.h"
13 #include "SkImagePriv.h"
14 #include "SkPixelRef.h"
15 #include "SkSurface.h"
16 
17 class SkImage_Raster : public SkImage_Base {
18 public:
ValidArgs(const Info & info,size_t rowBytes)19     static bool ValidArgs(const Info& info, size_t rowBytes) {
20         const int maxDimension = SK_MaxS32 >> 2;
21         const size_t kMaxPixelByteSize = SK_MaxS32;
22 
23         if (info.width() <= 0 || info.height() <= 0) {
24             return false;
25         }
26         if (info.width() > maxDimension || info.height() > maxDimension) {
27             return false;
28         }
29         if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
30             return false;
31         }
32         if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
33             return false;
34         }
35 
36         if (kUnknown_SkColorType == info.colorType()) {
37             return false;
38         }
39 
40         // TODO: check colorspace
41 
42         if (rowBytes < SkImageMinRowBytes(info)) {
43             return false;
44         }
45 
46         int64_t size = (int64_t)info.height() * rowBytes;
47         if (size > (int64_t)kMaxPixelByteSize) {
48             return false;
49         }
50         return true;
51     }
52 
53     SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*);
54     virtual ~SkImage_Raster();
55 
56     SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const override;
57     bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override;
58     const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override;
59     bool getROPixels(SkBitmap*) const override;
60 
61     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
62     SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrigin, size_t rowBytes,
63                    const SkSurfaceProps*);
64 
getPixelRef() const65     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
66 
67     SkShader* onNewShader(SkShader::TileMode,
68                           SkShader::TileMode,
69                           const SkMatrix* localMatrix) const override;
70 
71     bool isOpaque() const override;
72 
SkImage_Raster(const SkBitmap & bm,const SkSurfaceProps * props)73     SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props)
74         : INHERITED(bm.width(), bm.height(), props)
75         , fBitmap(bm) {}
76 
77 private:
SkImage_Raster()78     SkImage_Raster() : INHERITED(0, 0, NULL) {}
79 
80     SkBitmap    fBitmap;
81 
82     typedef SkImage_Base INHERITED;
83 };
84 
85 ///////////////////////////////////////////////////////////////////////////////
86 
release_data(void * addr,void * context)87 static void release_data(void* addr, void* context) {
88     SkData* data = static_cast<SkData*>(context);
89     data->unref();
90 }
91 
SkImage_Raster(const Info & info,SkData * data,size_t rowBytes,const SkSurfaceProps * props)92 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes,
93                                const SkSurfaceProps* props)
94     : INHERITED(info.width(), info.height(), props)
95 {
96     data->ref();
97     void* addr = const_cast<void*>(data->data());
98     SkColorTable* ctable = NULL;
99 
100     fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
101     fBitmap.setImmutable();
102     fBitmap.lockPixels();
103 }
104 
SkImage_Raster(const Info & info,SkPixelRef * pr,const SkIPoint & pixelRefOrigin,size_t rowBytes,const SkSurfaceProps * props)105 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint& pixelRefOrigin,
106                                size_t rowBytes,  const SkSurfaceProps* props)
107     : INHERITED(info.width(), info.height(), props)
108 {
109     fBitmap.setInfo(info, rowBytes);
110     fBitmap.setPixelRef(pr, pixelRefOrigin);
111     fBitmap.lockPixels();
112 }
113 
~SkImage_Raster()114 SkImage_Raster::~SkImage_Raster() {}
115 
onNewShader(SkShader::TileMode tileX,SkShader::TileMode tileY,const SkMatrix * localMatrix) const116 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
117                                       const SkMatrix* localMatrix) const {
118     return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
119 }
120 
onNewSurface(const SkImageInfo & info,const SkSurfaceProps & props) const121 SkSurface* SkImage_Raster::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
122     return SkSurface::NewRaster(info, &props);
123 }
124 
onReadPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY) const125 bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
126                                   int srcX, int srcY) const {
127     SkBitmap shallowCopy(fBitmap);
128     return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
129 }
130 
onPeekPixels(SkImageInfo * infoPtr,size_t * rowBytesPtr) const131 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
132     const SkImageInfo info = fBitmap.info();
133     if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
134         return NULL;
135     }
136     *infoPtr = info;
137     *rowBytesPtr = fBitmap.rowBytes();
138     return fBitmap.getPixels();
139 }
140 
getROPixels(SkBitmap * dst) const141 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
142     *dst = fBitmap;
143     return true;
144 }
145 
146 ///////////////////////////////////////////////////////////////////////////////
147 
NewRasterCopy(const SkImageInfo & info,const void * pixels,size_t rowBytes)148 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
149     if (!SkImage_Raster::ValidArgs(info, rowBytes) || !pixels) {
150         return NULL;
151     }
152 
153     // Here we actually make a copy of the caller's pixel data
154     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes));
155     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
156 }
157 
158 
NewRasterData(const SkImageInfo & info,SkData * data,size_t rowBytes)159 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
160     if (!SkImage_Raster::ValidArgs(info, rowBytes) || !data) {
161         return NULL;
162     }
163 
164     // did they give us enough data?
165     size_t size = info.height() * rowBytes;
166     if (data->size() < size) {
167         return NULL;
168     }
169 
170     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
171 }
172 
NewFromGenerator(SkImageGenerator * generator)173 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) {
174     SkBitmap bitmap;
175     if (!SkInstallDiscardablePixelRef(generator, &bitmap)) {
176         return NULL;
177     }
178     if (0 == bitmap.width() || 0 == bitmap.height()) {
179         return NULL;
180     }
181 
182     return SkNEW_ARGS(SkImage_Raster, (bitmap, NULL));
183 }
184 
SkNewImageFromPixelRef(const SkImageInfo & info,SkPixelRef * pr,const SkIPoint & pixelRefOrigin,size_t rowBytes,const SkSurfaceProps * props)185 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
186                                 const SkIPoint& pixelRefOrigin, size_t rowBytes,
187                                 const SkSurfaceProps* props) {
188     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
189         return NULL;
190     }
191     return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props));
192 }
193 
SkNewImageFromBitmap(const SkBitmap & bm,bool canSharePixelRef,const SkSurfaceProps * props)194 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef,
195                               const SkSurfaceProps* props) {
196     if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes())) {
197         return NULL;
198     }
199 
200     SkImage* image = NULL;
201     if (canSharePixelRef || bm.isImmutable()) {
202         image = SkNEW_ARGS(SkImage_Raster, (bm, props));
203     } else {
204         bm.lockPixels();
205         if (bm.getPixels()) {
206             image = SkImage::NewRasterCopy(bm.info(), bm.getPixels(), bm.rowBytes());
207         }
208         bm.unlockPixels();
209 
210         // we don't expose props to NewRasterCopy (need a private vers) so post-init it here
211         if (image && props) {
212             as_IB(image)->initWithProps(*props);
213         }
214     }
215     return image;
216 }
217 
SkBitmapImageGetPixelRef(const SkImage * image)218 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) {
219     return ((const SkImage_Raster*)image)->getPixelRef();
220 }
221 
isOpaque() const222 bool SkImage_Raster::isOpaque() const {
223     return fBitmap.isOpaque();
224 }
225 
226