Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / image / SkImage_Raster.cpp
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 "SkMallocPixelRef.h"
14
15 class SkImage_Raster : public SkImage_Base {
16 public:
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.fWidth < 0 || info.fHeight < 0) {
22             return false;
23         }
24         if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
25             return false;
26         }
27         if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) {
28             return false;
29         }
30         if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) {
31             return false;
32         }
33
34         if (SkImageInfoToBitmapConfig(info) == SkBitmap::kNo_Config) {
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.fHeight * 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*) SK_OVERRIDE;
57     virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, const SkPaint*) SK_OVERRIDE;
58     virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE;
59     virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const SK_OVERRIDE;
60     virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE;
61
62     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
63     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
64
65     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
66
67 private:
68     SkImage_Raster() : INHERITED(0, 0) {}
69
70     SkBitmap    fBitmap;
71
72     typedef SkImage_Base INHERITED;
73 };
74
75 ///////////////////////////////////////////////////////////////////////////////
76
77 SkImage* SkImage_Raster::NewEmpty() {
78     // Returns lazily created singleton
79     static SkImage* gEmpty;
80     if (NULL == gEmpty) {
81         gEmpty = SkNEW(SkImage_Raster);
82     }
83     gEmpty->ref();
84     return gEmpty;
85 }
86
87 static void release_data(void* addr, void* context) {
88     SkData* data = static_cast<SkData*>(context);
89     data->unref();
90 }
91
92 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
93     : INHERITED(info.fWidth, info.fHeight)
94 {
95     data->ref();
96     void* addr = const_cast<void*>(data->data());
97
98     fBitmap.installPixels(info, addr, rowBytes, release_data, data);
99     fBitmap.setImmutable();
100     fBitmap.lockPixels();
101 }
102
103 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
104     : INHERITED(info.fWidth, info.fHeight)
105 {
106     fBitmap.setConfig(info, rowBytes);
107     fBitmap.setPixelRef(pr);
108     fBitmap.lockPixels();
109 }
110
111 SkImage_Raster::~SkImage_Raster() {}
112
113 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
114     canvas->drawBitmap(fBitmap, x, y, paint);
115 }
116
117 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src,
118                                       const SkRect& dst, const SkPaint* paint) {
119     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
120 }
121
122 bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const {
123     if (dst->pixelRef()) {
124         return this->INHERITED::onReadPixels(dst, subset);
125     } else {
126         SkBitmap src;
127         if (!fBitmap.extractSubset(&src, subset)) {
128             return false;
129         }
130         return src.copyTo(dst, src.config());
131     }
132 }
133
134 const void* SkImage_Raster::onPeekPixels(SkImageInfo* infoPtr,
135                                          size_t* rowBytesPtr) const {
136     SkImageInfo info;
137     if (!fBitmap.asImageInfo(&info) || !fBitmap.getPixels()) {
138         return NULL;
139     }
140     *infoPtr = info;
141     *rowBytesPtr = fBitmap.rowBytes();
142     return fBitmap.getPixels();
143 }
144
145 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
146     *dst = fBitmap;
147     return true;
148 }
149
150 ///////////////////////////////////////////////////////////////////////////////
151
152 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
153     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
154         return NULL;
155     }
156     if (0 == info.fWidth && 0 == info.fHeight) {
157         return SkImage_Raster::NewEmpty();
158     }
159     // check this after empty-check
160     if (NULL == pixels) {
161         return NULL;
162     }
163
164     // Here we actually make a copy of the caller's pixel data
165     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
166     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
167 }
168
169
170 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t rowBytes) {
171     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
172         return NULL;
173     }
174     if (0 == info.fWidth && 0 == info.fHeight) {
175         return SkImage_Raster::NewEmpty();
176     }
177     // check this after empty-check
178     if (NULL == data) {
179         return NULL;
180     }
181
182     // did they give us enough data?
183     size_t size = info.fHeight * rowBytes;
184     if (data->size() < size) {
185         return NULL;
186     }
187
188     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
189 }
190
191 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
192                                 size_t rowBytes) {
193     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
194 }
195
196 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
197     return ((SkImage_Raster*)image)->getPixelRef();
198 }