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"
9 #include "SkImagePriv.h"
13 #include "SkMallocPixelRef.h"
15 class SkImage_Raster : public SkImage_Base {
17 static bool ValidArgs(const Info& info, size_t rowBytes) {
18 const int maxDimension = SK_MaxS32 >> 2;
19 const size_t kMaxPixelByteSize = SK_MaxS32;
21 if (info.fWidth < 0 || info.fHeight < 0) {
24 if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
27 if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) {
30 if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) {
34 if (kUnknown_SkColorType == info.colorType()) {
38 // TODO: check colorspace
40 if (rowBytes < SkImageMinRowBytes(info)) {
44 int64_t size = (int64_t)info.fHeight * rowBytes;
45 if (size > (int64_t)kMaxPixelByteSize) {
51 static SkImage* NewEmpty();
53 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb);
54 virtual ~SkImage_Raster();
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;
63 // exposed for SkSurface_Raster via SkNewImageFromPixelRef
64 SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
66 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
68 virtual SkShader* onNewShader(SkShader::TileMode,
70 const SkMatrix* localMatrix) const SK_OVERRIDE;
73 SkImage_Raster() : INHERITED(0, 0) {}
77 typedef SkImage_Base INHERITED;
80 ///////////////////////////////////////////////////////////////////////////////
82 SkImage* SkImage_Raster::NewEmpty() {
83 // Returns lazily created singleton
84 static SkImage* gEmpty;
86 gEmpty = SkNEW(SkImage_Raster);
92 static void release_data(void* addr, void* context) {
93 SkData* data = static_cast<SkData*>(context);
97 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
98 : INHERITED(info.fWidth, info.fHeight)
101 void* addr = const_cast<void*>(data->data());
102 SkColorTable* ctable = NULL;
104 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data);
105 fBitmap.setImmutable();
106 fBitmap.lockPixels();
109 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
110 : INHERITED(info.fWidth, info.fHeight)
112 fBitmap.setInfo(info, rowBytes);
113 fBitmap.setPixelRef(pr);
114 fBitmap.lockPixels();
117 SkImage_Raster::~SkImage_Raster() {}
119 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
120 const SkMatrix* localMatrix) const {
121 return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix);
124 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
125 canvas->drawBitmap(fBitmap, x, y, paint);
128 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
129 const SkPaint* paint) const {
130 canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
133 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
134 if (dst->pixelRef()) {
135 return this->INHERITED::onReadPixels(dst, subset);
138 if (!fBitmap.extractSubset(&src, subset)) {
141 return src.copyTo(dst, src.colorType());
145 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr, size_t* rowBytesPtr) const {
146 const SkImageInfo info = fBitmap.info();
147 if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
151 *rowBytesPtr = fBitmap.rowBytes();
152 return fBitmap.getPixels();
155 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
160 ///////////////////////////////////////////////////////////////////////////////
162 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
163 if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
166 if (0 == info.fWidth && 0 == info.fHeight) {
167 return SkImage_Raster::NewEmpty();
169 // check this after empty-check
170 if (NULL == pixels) {
174 // Here we actually make a copy of the caller's pixel data
175 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
176 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
180 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
181 if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
184 if (0 == info.fWidth && 0 == info.fHeight) {
185 return SkImage_Raster::NewEmpty();
187 // check this after empty-check
192 // did they give us enough data?
193 size_t size = info.fHeight * rowBytes;
194 if (data->size() < size) {
198 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
201 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
203 return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
206 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
207 return ((SkImage_Raster*)image)->getPixelRef();