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 "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
| 11 #include "SkColorTable.h" |
11 #include "SkData.h" | 12 #include "SkData.h" |
12 #include "SkImageGeneratorPriv.h" | 13 #include "SkImageGeneratorPriv.h" |
13 #include "SkImagePriv.h" | 14 #include "SkImagePriv.h" |
14 #include "SkPixelRef.h" | 15 #include "SkPixelRef.h" |
15 #include "SkSurface.h" | 16 #include "SkSurface.h" |
16 | 17 |
17 class SkImage_Raster : public SkImage_Base { | 18 class SkImage_Raster : public SkImage_Base { |
18 public: | 19 public: |
19 static bool ValidArgs(const Info& info, size_t rowBytes, size_t* minSize) { | 20 static bool ValidArgs(const Info& info, size_t rowBytes, SkColorTable* ctabl
e, |
| 21 size_t* minSize) { |
20 const int maxDimension = SK_MaxS32 >> 2; | 22 const int maxDimension = SK_MaxS32 >> 2; |
21 | 23 |
22 if (info.width() <= 0 || info.height() <= 0) { | 24 if (info.width() <= 0 || info.height() <= 0) { |
23 return false; | 25 return false; |
24 } | 26 } |
25 if (info.width() > maxDimension || info.height() > maxDimension) { | 27 if (info.width() > maxDimension || info.height() > maxDimension) { |
26 return false; | 28 return false; |
27 } | 29 } |
28 if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) { | 30 if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) { |
29 return false; | 31 return false; |
30 } | 32 } |
31 if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) { | 33 if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) { |
32 return false; | 34 return false; |
33 } | 35 } |
34 | 36 |
35 if (kUnknown_SkColorType == info.colorType()) { | 37 if (kUnknown_SkColorType == info.colorType()) { |
36 return false; | 38 return false; |
37 } | 39 } |
38 | 40 |
39 // TODO: check colorspace | 41 const bool needsCT = kIndex_8_SkColorType == info.colorType(); |
| 42 const bool hasCT = NULL != ctable; |
| 43 if (needsCT != hasCT) { |
| 44 return false; |
| 45 } |
40 | 46 |
41 if (rowBytes < SkImageMinRowBytes(info)) { | 47 if (rowBytes < SkImageMinRowBytes(info)) { |
42 return false; | 48 return false; |
43 } | 49 } |
44 | 50 |
45 size_t size = info.getSafeSize(rowBytes); | 51 size_t size = info.getSafeSize(rowBytes); |
46 if (0 == size) { | 52 if (0 == size) { |
47 return false; | 53 return false; |
48 } | 54 } |
49 | 55 |
50 if (minSize) { | 56 if (minSize) { |
51 *minSize = size; | 57 *minSize = size; |
52 } | 58 } |
53 return true; | 59 return true; |
54 } | 60 } |
55 | 61 |
56 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, const SkSurfaceProps*
); | 62 SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, SkColorTable*, const
SkSurfaceProps*); |
57 virtual ~SkImage_Raster(); | 63 virtual ~SkImage_Raster(); |
58 | 64 |
59 SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const ove
rride; | 65 SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) const ove
rride; |
60 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) con
st override; | 66 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) con
st override; |
61 const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override; | 67 const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override; |
62 SkData* onRefEncoded() const override; | 68 SkData* onRefEncoded() const override; |
63 bool getROPixels(SkBitmap*) const override; | 69 bool getROPixels(SkBitmap*) const override; |
64 | 70 |
65 // exposed for SkSurface_Raster via SkNewImageFromPixelRef | 71 // exposed for SkSurface_Raster via SkNewImageFromPixelRef |
66 SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrig
in, size_t rowBytes, | 72 SkImage_Raster(const SkImageInfo&, SkPixelRef*, const SkIPoint& pixelRefOrig
in, size_t rowBytes, |
(...skipping 20 matching lines...) Expand all Loading... |
87 }; | 93 }; |
88 | 94 |
89 /////////////////////////////////////////////////////////////////////////////// | 95 /////////////////////////////////////////////////////////////////////////////// |
90 | 96 |
91 static void release_data(void* addr, void* context) { | 97 static void release_data(void* addr, void* context) { |
92 SkData* data = static_cast<SkData*>(context); | 98 SkData* data = static_cast<SkData*>(context); |
93 data->unref(); | 99 data->unref(); |
94 } | 100 } |
95 | 101 |
96 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes, | 102 SkImage_Raster::SkImage_Raster(const Info& info, SkData* data, size_t rowBytes, |
97 const SkSurfaceProps* props) | 103 SkColorTable* ctable, const SkSurfaceProps* props
) |
98 : INHERITED(info.width(), info.height(), props) | 104 : INHERITED(info.width(), info.height(), props) |
99 { | 105 { |
100 data->ref(); | 106 data->ref(); |
101 void* addr = const_cast<void*>(data->data()); | 107 void* addr = const_cast<void*>(data->data()); |
102 SkColorTable* ctable = NULL; | |
103 | 108 |
104 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data); | 109 fBitmap.installPixels(info, addr, rowBytes, ctable, release_data, data); |
105 fBitmap.setImmutable(); | 110 fBitmap.setImmutable(); |
106 fBitmap.lockPixels(); | 111 fBitmap.lockPixels(); |
107 } | 112 } |
108 | 113 |
109 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint&
pixelRefOrigin, | 114 SkImage_Raster::SkImage_Raster(const Info& info, SkPixelRef* pr, const SkIPoint&
pixelRefOrigin, |
110 size_t rowBytes, const SkSurfaceProps* props) | 115 size_t rowBytes, const SkSurfaceProps* props) |
111 : INHERITED(info.width(), info.height(), props) | 116 : INHERITED(info.width(), info.height(), props) |
112 { | 117 { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 return NULL; | 159 return NULL; |
155 } | 160 } |
156 | 161 |
157 bool SkImage_Raster::getROPixels(SkBitmap* dst) const { | 162 bool SkImage_Raster::getROPixels(SkBitmap* dst) const { |
158 *dst = fBitmap; | 163 *dst = fBitmap; |
159 return true; | 164 return true; |
160 } | 165 } |
161 | 166 |
162 /////////////////////////////////////////////////////////////////////////////// | 167 /////////////////////////////////////////////////////////////////////////////// |
163 | 168 |
164 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes) { | 169 SkImage* SkImage::NewRasterCopy(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, |
| 170 SkColorTable* ctable) { |
165 size_t size; | 171 size_t size; |
166 if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) { | 172 if (!SkImage_Raster::ValidArgs(info, rowBytes, ctable, &size) || !pixels) { |
167 return NULL; | 173 return NULL; |
168 } | 174 } |
169 | 175 |
170 // Here we actually make a copy of the caller's pixel data | 176 // Here we actually make a copy of the caller's pixel data |
171 SkAutoDataUnref data(SkData::NewWithCopy(pixels, size)); | 177 SkAutoDataUnref data(SkData::NewWithCopy(pixels, size)); |
172 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL)); | 178 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL)); |
173 } | 179 } |
174 | 180 |
175 | 181 |
176 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro
wBytes) { | 182 SkImage* SkImage::NewRasterData(const SkImageInfo& info, SkData* data, size_t ro
wBytes) { |
177 size_t size; | 183 size_t size; |
178 if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !data) { | 184 if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !data) { |
179 return NULL; | 185 return NULL; |
180 } | 186 } |
181 | 187 |
182 // did they give us enough data? | 188 // did they give us enough data? |
183 if (data->size() < size) { | 189 if (data->size() < size) { |
184 return NULL; | 190 return NULL; |
185 } | 191 } |
186 | 192 |
187 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL)); | 193 SkColorTable* ctable = NULL; |
| 194 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL)); |
188 } | 195 } |
189 | 196 |
190 SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, | 197 SkImage* SkImage::NewFromRaster(const SkImageInfo& info, const void* pixels, siz
e_t rowBytes, |
191 RasterReleaseProc proc, ReleaseContext ctx) { | 198 RasterReleaseProc proc, ReleaseContext ctx) { |
192 size_t size; | 199 size_t size; |
193 if (!SkImage_Raster::ValidArgs(info, rowBytes, &size) || !pixels) { | 200 if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, &size) || !pixels) { |
194 return NULL; | 201 return NULL; |
195 } | 202 } |
196 | 203 |
| 204 SkColorTable* ctable = NULL; |
197 SkAutoDataUnref data(SkData::NewWithProc(pixels, size, proc, ctx)); | 205 SkAutoDataUnref data(SkData::NewWithProc(pixels, size, proc, ctx)); |
198 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, NULL)); | 206 return SkNEW_ARGS(SkImage_Raster, (info, data, rowBytes, ctable, NULL)); |
199 } | 207 } |
200 | 208 |
201 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* s
ubset) { | 209 SkImage* SkImage::NewFromGenerator(SkImageGenerator* generator, const SkIRect* s
ubset) { |
202 SkBitmap bitmap; | 210 SkBitmap bitmap; |
203 if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, NULL)) { | 211 if (!SkInstallDiscardablePixelRef(generator, subset, &bitmap, NULL)) { |
204 return NULL; | 212 return NULL; |
205 } | 213 } |
206 if (0 == bitmap.width() || 0 == bitmap.height()) { | 214 if (0 == bitmap.width() || 0 == bitmap.height()) { |
207 return NULL; | 215 return NULL; |
208 } | 216 } |
209 | 217 |
210 return SkNEW_ARGS(SkImage_Raster, (bitmap, NULL)); | 218 return SkNEW_ARGS(SkImage_Raster, (bitmap, NULL)); |
211 } | 219 } |
212 | 220 |
213 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, | 221 SkImage* SkNewImageFromPixelRef(const SkImageInfo& info, SkPixelRef* pr, |
214 const SkIPoint& pixelRefOrigin, size_t rowBytes, | 222 const SkIPoint& pixelRefOrigin, size_t rowBytes, |
215 const SkSurfaceProps* props) { | 223 const SkSurfaceProps* props) { |
216 if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL)) { | 224 if (!SkImage_Raster::ValidArgs(info, rowBytes, NULL, NULL)) { |
217 return NULL; | 225 return NULL; |
218 } | 226 } |
219 return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props
)); | 227 return SkNEW_ARGS(SkImage_Raster, (info, pr, pixelRefOrigin, rowBytes, props
)); |
220 } | 228 } |
221 | 229 |
222 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef, | 230 SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef, |
223 const SkSurfaceProps* props) { | 231 const SkSurfaceProps* props) { |
224 if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL)) { | 232 if (!SkImage_Raster::ValidArgs(bm.info(), bm.rowBytes(), NULL, NULL)) { |
225 return NULL; | 233 return NULL; |
226 } | 234 } |
227 | 235 |
228 SkImage* image = NULL; | 236 SkImage* image = NULL; |
229 if (canSharePixelRef || bm.isImmutable()) { | 237 if (canSharePixelRef || bm.isImmutable()) { |
230 image = SkNEW_ARGS(SkImage_Raster, (bm, props)); | 238 image = SkNEW_ARGS(SkImage_Raster, (bm, props)); |
231 } else { | 239 } else { |
232 bm.lockPixels(); | 240 bm.lockPixels(); |
233 if (bm.getPixels()) { | 241 if (bm.getPixels()) { |
234 image = SkImage::NewRasterCopy(bm.info(), bm.getPixels(), bm.rowByte
s()); | 242 image = SkImage::NewRasterCopy(bm.info(), bm.getPixels(), bm.rowByte
s()); |
235 } | 243 } |
236 bm.unlockPixels(); | 244 bm.unlockPixels(); |
237 | 245 |
238 // we don't expose props to NewRasterCopy (need a private vers) so post-
init it here | 246 // we don't expose props to NewRasterCopy (need a private vers) so post-
init it here |
239 if (image && props) { | 247 if (image && props) { |
240 as_IB(image)->initWithProps(*props); | 248 as_IB(image)->initWithProps(*props); |
241 } | 249 } |
242 } | 250 } |
243 return image; | 251 return image; |
244 } | 252 } |
245 | 253 |
246 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) { | 254 const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) { |
247 return ((const SkImage_Raster*)image)->getPixelRef(); | 255 return ((const SkImage_Raster*)image)->getPixelRef(); |
248 } | 256 } |
249 | 257 |
250 bool SkImage_Raster::isOpaque() const { | 258 bool SkImage_Raster::isOpaque() const { |
251 return fBitmap.isOpaque(); | 259 return fBitmap.isOpaque(); |
252 } | 260 } |
253 | 261 |
OLD | NEW |