Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: src/image/SkImage_Raster.cpp

Issue 460823002: SkImage_Codec is Lazy (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: big refactor Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/image/SkImage_Codec.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « src/image/SkImage_Codec.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698