2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkImage_Base.h"
12 #include "SkImageGenerator.h"
13 #include "SkImagePriv.h"
14 #include "SkPixelRef.h"
15 #include "SkSurface.h"
17 class SkImage_Raster : public SkImage_Base {
19 static bool ValidArgs(const Info& info, size_t rowBytes) {
20 const int maxDimension = SK_MaxS32 >> 2;
21 const size_t kMaxPixelByteSize = SK_MaxS32;
23 if (info.width() <= 0 || info.height() <= 0) {
26 if (info.width() > maxDimension || info.height() > maxDimension) {
29 if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
32 if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
36 if (kUnknown_SkColorType == info.colorType()) {
40 // TODO: check colorspace
42 if (rowBytes < SkImageMinRowBytes(info)) {
46 int64_t size = (int64_t)info.height() * rowBytes;
47 if (size > (int64_t)kMaxPixelByteSize) {
53 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*);
54 virtual ~SkImage_Raster();
56 void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_OVERRIDE;
57 void onDrawRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) const SK_OVERRIDE;
58 SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const SK_OVERRIDE;
59 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const SK_OVERRIDE;
60 const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
61 bool getROPixels(SkBitmap*) const SK_OVERRIDE;
63 // exposed for SkSurface_Raster via SkNewImageFromPixelRef
64 SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrigin, size_t rowBytes,
65 const SkSurfaceProps*);
67 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
69 virtual SkShader* onNewShader(SkShader::TileMode,
71 const SkMatrix* localMatrix) const SK_OVERRIDE;
73 bool isOpaque() const SK_OVERRIDE;
75 SkImage_Raster(const SkBitmap& bm, const SkSurfaceProps* props)
76 : INHERITED(bm.width(), bm.height(), props)
80 SkImage_Raster() : INHERITED(0, 0, NULL) {}
84 typedef SkImage_Base INHERITED;
87 ///////////////////////////////////////////////////////////////////////////////
89 static void release_data(void* addr, void* context) {
90 SkData* data = static_cast<SkData*>(context);
94 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes,
95 const SkSurfaceProps* props)
96 : INHERITED(info.width(), info.height(), props)
99 void* addr = const_cast<void*>(data->data());
100 SkColorTable* ctable = NULL;
102 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
103 fBitmap.setImmutable();
104 fBitmap.lockPixels();
107 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint& pixelRefOrigin,
108 size_t rowBytes, const SkSurfaceProps* props)
109 : INHERITED(info.width(), info.height(), props)
111 fBitmap.setInfo(info, rowBytes);
112 fBitmap.setPixelRef(pr, pixelRefOrigin);
113 fBitmap.lockPixels();
116 SkImage_Raster::~SkImage_Raster() {}
118 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
119 const SkMatrix* localMatrix) const {
120 return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
123 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
124 SkBitmap shallowCopy(fBitmap);
125 canvas->drawBitmap(shallowCopy, x, y, paint);
128 void SkImage_Raster::onDrawRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
129 const SkPaint* paint) const {
130 SkBitmap shallowCopy(fBitmap);
131 canvas->drawBitmapRectToRect(shallowCopy, src, dst, paint);
134 SkSurface* SkImage_Raster::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
135 return SkSurface::NewRaster(info, &props);
138 bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
139 int srcX, int srcY) const {
140 SkBitmap shallowCopy(fBitmap);
141 return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
144 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
145 const SkImageInfo info = fBitmap.info();
146 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
150 *rowBytesPtr = fBitmap.rowBytes();
151 return fBitmap.getPixels();
154 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
159 ///////////////////////////////////////////////////////////////////////////////
161 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
162 if (!SkImage_Raster::ValidArgs(info, rowBytes) || !pixels) {
166 // Here we actually make a copy of the caller's pixel data
167 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.height() * rowBytes));
168 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
172 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
173 if (!SkImage_Raster::ValidArgs(info, rowBytes) || !data) {
177 // did they give us enough data?
178 size_t size = info.height() * rowBytes;
179 if (data->size() < size) {
183 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL));
186 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator) {
188 if (!SkInstallDiscardablePixelRef(generator, &bitmap)) {
191 if (0 == bitmap.width() || 0 == bitmap.height()) {
195 return SkNEW_ARGS(SkImage_Raster, (bitmap, NULL));
198 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
199 const SkIPoint& pixelRefOrigin, size_t rowBytes,
200 const SkSurfaceProps* props) {
201 if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
204 return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props));
207 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef,
208 const SkSurfaceProps* props) {
209 if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes())) {
213 SkImage* image = NULL;
214 if (canSharePixelRef || bm.isImmutable()) {
215 image = SkNEW_ARGS(SkImage_Raster, (bm, props));
218 if (bm.getPixels()) {
219 image = SkImage::NewRasterCopy(bm.info(), bm.getPixels(), bm.rowBytes());
223 // we don't expose props to NewRasterCopy (need a private vers) so post-init it here
224 if (image && props) {
225 as_IB(image)->initWithProps(*props);
231 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) {
232 return ((const SkImage_Raster*)image)->getPixelRef();
235 bool SkImage_Raster::isOpaque() const {
236 return fBitmap.isOpaque();