OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkImage_Base.h" | 8 #include "SkImage_Base.h" |
9 #include "SkImagePriv.h" | 9 #include "SkImagePriv.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkData.h" | 12 #include "SkData.h" |
13 #include "SkDecodingImageGenerator.h" | |
13 #include "SkMallocPixelRef.h" | 14 #include "SkMallocPixelRef.h" |
14 | 15 |
16 namespace { | |
15 class SkImage_Raster : public SkImage_Base { | 17 class SkImage_Raster : public SkImage_Base { |
16 public: | 18 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 (kUnknown_SkColorType == info.colorType()) { | |
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(); | 19 static SkImage* NewEmpty(); |
52 | 20 |
53 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb); | |
54 virtual ~SkImage_Raster(); | 21 virtual ~SkImage_Raster(); |
55 | 22 |
56 virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_ OVERRIDE; | 23 virtual void onDraw(SkCanvas*, SkScalar, SkScalar, const SkPaint*) const SK_ OVERRIDE; |
57 virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, | 24 virtual void onDrawRectToRect(SkCanvas*, const SkRect*, const SkRect&, |
58 const SkPaint*) const SK_OVERRIDE; | 25 const SkPaint*) const SK_OVERRIDE; |
59 virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE; | 26 virtual bool onReadPixels(SkBitmap*, const SkIRect&) const SK_OVERRIDE; |
60 virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const S K_OVERRIDE; | 27 virtual const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const S K_OVERRIDE; |
61 virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE; | 28 virtual bool getROPixels(SkBitmap*) const SK_OVERRIDE; |
62 | 29 |
63 // exposed for SkSurface_Raster via SkNewImageFromPixelRef | |
64 SkImage_Raster(const SkImageInfo&, SkPixelRef*, size_t rowBytes); | |
65 | |
66 SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } | |
67 | |
68 virtual SkShader* onNewShader(SkShader::TileMode, | 30 virtual SkShader* onNewShader(SkShader::TileMode, |
69 SkShader::TileMode, | 31 SkShader::TileMode, |
70 const SkMatrix* localMatrix) const SK_OVERRIDE ; | 32 const SkMatrix* localMatrix) const SK_OVERRIDE ; |
71 | 33 |
72 private: | 34 SkImage_Raster(const SkBitmap& bitmap) |
73 SkImage_Raster() : INHERITED(0, 0) {} | 35 : INHERITED(bitmap.width(), bitmap.height()) |
36 , fBitmap(bitmap) { | |
37 if (fBitmap.pixelRef() && fBitmap.pixelRef()->isLocked()) { | |
38 fBitmap.lockPixels(); | |
39 } | |
40 } | |
74 | 41 |
75 SkBitmap fBitmap; | 42 SkBitmap fBitmap; |
76 | 43 |
77 typedef SkImage_Base INHERITED; | 44 typedef SkImage_Base INHERITED; |
78 }; | 45 }; |
79 | 46 |
80 /////////////////////////////////////////////////////////////////////////////// | 47 /////////////////////////////////////////////////////////////////////////////// |
81 | 48 |
49 static bool valid_args(const SkImageInfo& info, size_t rowBytes) { | |
50 const int maxDimension = SK_MaxS32 >> 2; | |
51 const size_t kMaxPixelByteSize = SK_MaxS32; | |
52 | |
53 if (info.fWidth < 0 || info.fHeight < 0) { | |
54 return false; | |
55 } | |
56 if (info.fWidth > maxDimension || info.fHeight > maxDimension) { | |
57 return false; | |
58 } | |
59 if ((unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType) { | |
60 return false; | |
61 } | |
62 if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) { | |
63 return false; | |
64 } | |
65 | |
66 if (kUnknown_SkColorType == info.colorType()) { | |
67 return false; | |
68 } | |
69 | |
70 // TODO: check colorspace | |
71 | |
72 if (rowBytes < SkImageMinRowBytes(info)) { | |
73 return false; | |
74 } | |
75 | |
76 int64_t size = (int64_t)info.fHeight * rowBytes; | |
77 if (size > (int64_t)kMaxPixelByteSize) { | |
78 return false; | |
79 } | |
80 return true; | |
81 } | |
82 | |
82 SkImage* SkImage_Raster::NewEmpty() { | 83 SkImage* SkImage_Raster::NewEmpty() { |
83 // Returns lazily created singleton | 84 // Returns lazily created singleton |
84 static SkImage* gEmpty; | 85 static SkImage* gEmpty; |
85 if (NULL == gEmpty) { | 86 if (NULL == gEmpty) { |
86 gEmpty = SkNEW(SkImage_Raster); | 87 SkBitmap emptyBitmap; |
88 emptyBitmap.setImmutable(); | |
89 gEmpty = SkNEW_ARGS(SkImage_Raster, (emptyBitmap)); | |
87 } | 90 } |
88 gEmpty->ref(); | 91 return SkRef(gEmpty); |
89 return gEmpty; | |
90 } | 92 } |
91 | 93 |
92 static void release_data(void* addr, void* context) { | 94 static void release_data(void*, void* context) { |
93 SkData* data = static_cast<SkData*>(context); | 95 static_cast<SkData*>(context)->unref(); |
94 data->unref(); | |
95 } | |
96 | |
97 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes) | |
98 : INHERITED(info.fWidth, info.fHeight) | |
99 { | |
100 data->ref(); | |
101 void* addr = const_cast<void*>(data->data()); | |
102 SkColorTable* ctable = NULL; | |
103 | |
104 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data); | |
105 fBitmap.setImmutable(); | |
106 fBitmap.lockPixels(); | |
107 } | |
108 | |
109 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, size_t rowBytes ) | |
110 : INHERITED(info.fWidth, info.fHeight) | |
111 { | |
112 fBitmap.setInfo(info, rowBytes); | |
113 fBitmap.setPixelRef(pr); | |
114 fBitmap.lockPixels(); | |
115 } | 96 } |
116 | 97 |
117 SkImage_Raster::~SkImage_Raster() {} | 98 SkImage_Raster::~SkImage_Raster() {} |
118 | 99 |
119 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMo de tileY, | 100 SkShader* SkImage_Raster::onNewShader(SkShader::TileMode tileX, SkShader::TileMo de tileY, |
120 const SkMatrix* localMatrix) const { | 101 const SkMatrix* localMatrix) const { |
121 return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix); | 102 return SkShader::CreateBitmapShader(fBitmap, tileX, tileY, localMatrix); |
122 } | 103 } |
123 | 104 |
124 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPa int* paint) const { | 105 void SkImage_Raster::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPa int* paint) const { |
(...skipping 24 matching lines...) Expand all Loading... | |
149 } | 130 } |
150 *infoPtr = info; | 131 *infoPtr = info; |
151 *rowBytesPtr = fBitmap.rowBytes(); | 132 *rowBytesPtr = fBitmap.rowBytes(); |
152 return fBitmap.getPixels(); | 133 return fBitmap.getPixels(); |
153 } | 134 } |
154 | 135 |
155 bool SkImage_Raster::getROPixels(SkBitmap* dst) const { | 136 bool SkImage_Raster::getROPixels(SkBitmap* dst) const { |
156 *dst = fBitmap; | 137 *dst = fBitmap; |
157 return true; | 138 return true; |
158 } | 139 } |
140 } // namespace | |
159 | 141 |
160 /////////////////////////////////////////////////////////////////////////////// | 142 /////////////////////////////////////////////////////////////////////////////// |
161 | 143 |
162 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, siz e_t rowBytes) { | 144 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, siz e_t rowBytes) { |
163 if (!SkImage_Raster::ValidArgs(info, rowBytes)) { | 145 if (!valid_args(info, rowBytes)) { |
164 return NULL; | 146 return NULL; |
165 } | 147 } |
166 if (0 == info.fWidth && 0 == info.fHeight) { | 148 if (0 == info.fWidth && 0 == info.fHeight) { |
167 return SkImage_Raster::NewEmpty(); | 149 return SkImage_Raster::NewEmpty(); |
168 } | 150 } |
169 // check this after empty-check | 151 // check this after empty-check |
170 if (NULL == pixels) { | 152 if (NULL == pixels) { |
171 return NULL; | 153 return NULL; |
172 } | 154 } |
173 | 155 |
174 // Here we actually make a copy of the caller's pixel data | 156 // Here we actually make a copy of the caller's pixel data |
175 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes)); | 157 SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes)); |
176 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); | 158 SkASSERT(data.get()); |
reed1
2014/08/11 21:14:08
assert not needed, we will crash if NewWithCopy fa
| |
159 void* addr = const_cast<void*>(data->data()); | |
160 SkColorTable* ctable = NULL; | |
161 SkBitmap bitmap; | |
162 bitmap.installPixels(info, addr, rowBytes, ctable, | |
163 release_data, data.detach()); | |
164 bitmap.setImmutable(); | |
165 return SkNEW_ARGS(SkImage_Raster, (bitmap)); | |
177 } | 166 } |
178 | 167 |
179 | 168 |
180 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro wBytes) { | 169 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro wBytes) { |
181 if (!SkImage_Raster::ValidArgs(info, rowBytes)) { | 170 if (!valid_args(info, rowBytes)) { |
182 return NULL; | 171 return NULL; |
183 } | 172 } |
184 if (0 == info.fWidth && 0 == info.fHeight) { | 173 if (0 == info.fWidth && 0 == info.fHeight) { |
185 return SkImage_Raster::NewEmpty(); | 174 return SkImage_Raster::NewEmpty(); |
186 } | 175 } |
187 // check this after empty-check | 176 // check this after empty-check |
188 if (NULL == data) { | 177 if (NULL == data) { |
189 return NULL; | 178 return NULL; |
190 } | 179 } |
191 | 180 |
192 // did they give us enough data? | 181 // did they give us enough data? |
193 size_t size = info.fHeight * rowBytes; | 182 size_t size = info.fHeight * rowBytes; |
194 if (data->size() < size) { | 183 if (data->size() < size) { |
195 return NULL; | 184 return NULL; |
196 } | 185 } |
197 | 186 |
198 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes)); | 187 void* addr = const_cast<void*>(data->data()); |
188 SkColorTable* ctable = NULL; | |
189 SkBitmap bitmap; | |
190 bitmap.installPixels(info, addr, rowBytes, ctable, release_data, SkRef(data) ); | |
191 bitmap.setImmutable(); | |
192 return SkNEW_ARGS(SkImage_Raster, (bitmap)); | |
199 } | 193 } |
200 | 194 |
201 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, | 195 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, |
202 size_t rowBytes) { | 196 size_t rowBytes) { |
203 return SkNEW_ARGS(SkImage_Raster, (info, pr, rowBytes)); | 197 SkBitmap bitmap; |
198 bitmap.setInfo(info, rowBytes); | |
199 bitmap.setPixelRef(pr); | |
200 return SkNEW_ARGS(SkImage_Raster, (bitmap)); | |
204 } | 201 } |
205 | 202 |
206 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { | 203 SkPixelRef* SkBitmapImageGetPixelRef(SkImage* image) { |
207 return ((SkImage_Raster*)image)->getPixelRef(); | 204 return ((SkImage_Raster*)image)->fBitmap.pixelRef(); |
208 } | 205 } |
206 | |
207 SkImage* SkImage::NewEncodedData(SkData* data) { | |
208 if (NULL == data) { | |
209 return NULL; | |
210 } | |
211 SkBitmap bitmap; | |
212 if (!SkInstallDiscardablePixelRef( | |
213 SkDecodingImageGenerator::Create( | |
214 data, SkDecodingImageGenerator::Options()), | |
215 &bitmap)) { | |
216 return NULL; | |
217 } | |
218 return SkNEW_ARGS(SkImage_Raster, (bitmap)); | |
219 } | |
220 | |
221 | |
OLD | NEW |