- add third_party src.
[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 "SkDataPixelRef.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 getROPixels(SkBitmap*) const SK_OVERRIDE;
59
60     // exposed for SkSurface_Raster via SkNewImageFromPixelRef
61     SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes);
62
63     SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
64
65 private:
66     SkImage_Raster() : INHERITED(0, 0) {}
67
68     SkBitmap    fBitmap;
69
70     typedef SkImage_Base INHERITED;
71 };
72
73 ///////////////////////////////////////////////////////////////////////////////
74
75 SkImage* SkImage_Raster::NewEmpty() {
76     // Returns lazily created singleton
77     static SkImage* gEmpty;
78     if (NULL == gEmpty) {
79         gEmpty = SkNEW(SkImage_Raster);
80     }
81     gEmpty->ref();
82     return gEmpty;
83 }
84
85 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes)
86         : INHERITED(info.fWidth, info.fHeight) {
87     SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
88
89     fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlphaType);
90     fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref();
91     fBitmap.setImmutable();
92 }
93
94 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes)
95 : INHERITED(info.fWidth, info.fHeight) {
96     SkBitmap::Config config = SkImageInfoToBitmapConfig(info);
97
98     fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes, info.fAlphaType);
99     fBitmap.setPixelRef(pr);
100 }
101
102 SkImage_Raster::~SkImage_Raster() {}
103
104 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
105     canvas->drawBitmap(fBitmap, x, y, paint);
106 }
107
108 void SkImage_Raster::onDrawRectToRect(SkCanvas* canvas, const SkRect* src, const SkRect& dst, const SkPaint* paint) {
109     canvas->drawBitmapRectToRect(fBitmap, src, dst, paint);
110 }
111
112 bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
113     *dst = fBitmap;
114     return true;
115 }
116
117 ///////////////////////////////////////////////////////////////////////////////
118
119 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
120     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
121         return NULL;
122     }
123     if (0 == info.fWidth && 0 == info.fHeight) {
124         return SkImage_Raster::NewEmpty();
125     }
126     // check this after empty-check
127     if (NULL == pixels) {
128         return NULL;
129     }
130
131     // Here we actually make a copy of the caller's pixel data
132     SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
133     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
134 }
135
136
137 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* pixelData, size_t rowBytes) {
138     if (!SkImage_Raster::ValidArgs(info, rowBytes)) {
139         return NULL;
140     }
141     if (0 == info.fWidth && 0 == info.fHeight) {
142         return SkImage_Raster::NewEmpty();
143     }
144     // check this after empty-check
145     if (NULL == pixelData) {
146         return NULL;
147     }
148
149     // did they give us enough data?
150     size_t size = info.fHeight * rowBytes;
151     if (pixelData->size() < size) {
152         return NULL;
153     }
154
155     SkAutoDataUnref data(pixelData);
156     return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes));
157 }
158
159 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr,
160                                 size_t rowBytes) {
161     return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes));
162 }
163
164 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) {
165     return ((SkImage_Raster*)image)->getPixelRef();
166 }