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

Side by Side Diff: src/core/SkBitmapConfig.cpp

Issue 137753017: move all Config specific APIs into SkBitmapConfig.cpp -- Config is deprecated (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkMipMap.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2014 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 "SkBitmap.h"
9 #include "SkCanvas.h"
10 #include "SkColorPriv.h"
11 #include "SkDither.h"
12 #include "SkImagePriv.h"
13 #include "SkPixelRef.h"
14
15 #ifdef SK_SUPPORT_LEGACY_BITMAP_COMPUTESIZE
16 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
17 int bpp;
18 switch (config) {
19 case kNo_Config:
20 bpp = 0; // not applicable
21 break;
22 case kA8_Config:
23 case kIndex8_Config:
24 bpp = 1;
25 break;
26 case kRGB_565_Config:
27 case kARGB_4444_Config:
28 bpp = 2;
29 break;
30 case kARGB_8888_Config:
31 bpp = 4;
32 break;
33 default:
34 SkDEBUGFAIL("unknown config");
35 bpp = 0; // error
36 break;
37 }
38 return bpp;
39 }
40
41 size_t SkBitmap::ComputeRowBytes(Config c, int width) {
42 return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width);
43 }
44
45 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
46 SkColorType ct = SkBitmapConfigToColorType(config);
47 int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width);
48 return rowBytes * height;
49 }
50
51 size_t SkBitmap::ComputeSize(Config c, int width, int height) {
52 int64_t size = SkBitmap::ComputeSize64(c, width, height);
53 return sk_64_isS32(size) ? sk_64_asS32(size) : 0;
54 }
55
56 int64_t SkBitmap::ComputeSafeSize64(Config config,
57 uint32_t width,
58 uint32_t height,
59 size_t rowBytes) {
60 SkImageInfo info = SkImageInfo::Make(width, height,
61 SkBitmapConfigToColorType(config),
62 kPremul_SkAlphaType);
63 return info.getSafeSize64(rowBytes);
64 }
65
66 size_t SkBitmap::ComputeSafeSize(Config config,
67 uint32_t width,
68 uint32_t height,
69 size_t rowBytes) {
70 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes);
71 int32_t safeSize32 = (int32_t)safeSize;
72
73 if (safeSize32 != safeSize) {
74 safeSize32 = 0;
75 }
76 return safeSize32;
77 }
78 #endif
79
80 #ifdef SK_SUPPORT_LEGACY_BITMAPCONFIG
81
82 SkBitmap::Config SkBitmap::config() const {
83 return SkColorTypeToBitmapConfig(fInfo.colorType());
84 }
85
86 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
87 SkAlphaType alphaType) {
88 SkColorType ct = SkBitmapConfigToColorType(config);
89 return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType),
90 rowBytes);
91 }
92
93 bool SkBitmap::allocConfigPixels(Config config, int width, int height,
94 bool isOpaque) {
95 SkColorType ct = SkBitmapConfigToColorType(config);
96 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
97 return this->allocPixels(SkImageInfo::Make(width, height, ct, at));
98 }
99
100 ///////////////////////////////////////////////////////////////////////////////
101
102 bool SkBitmap::canCopyTo(Config dstConfig) const {
103 return this->canCopyTo(SkBitmapConfigToColorType(dstConfig));
104 }
105
106 bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
107 if (!this->canCopyTo(dstConfig)) {
108 return false;
109 }
110
111 // if we have a texture, first get those pixels
112 SkBitmap tmpSrc;
113 const SkBitmap* src = this;
114
115 if (fPixelRef) {
116 SkIRect subset;
117 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
118 fInfo.width(), fInfo.height());
119 if (fPixelRef->readPixels(&tmpSrc, &subset)) {
120 SkASSERT(tmpSrc.width() == this->width());
121 SkASSERT(tmpSrc.height() == this->height());
122
123 // did we get lucky and we can just return tmpSrc?
124 if (tmpSrc.config() == dstConfig && NULL == alloc) {
125 dst->swap(tmpSrc);
126 // If the result is an exact copy, clone the gen ID.
127 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) {
128 dst->pixelRef()->cloneGenID(*fPixelRef);
129 }
130 return true;
131 }
132
133 // fall through to the raster case
134 src = &tmpSrc;
135 }
136 }
137
138 // we lock this now, since we may need its colortable
139 SkAutoLockPixels srclock(*src);
140 if (!src->readyToDraw()) {
141 return false;
142 }
143
144 // The only way to be readyToDraw is if fPixelRef is non NULL.
145 SkASSERT(fPixelRef != NULL);
146
147 SkBitmap tmpDst;
148 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0,
149 src->alphaType());
150
151 // allocate colortable if srcConfig == kIndex8_Config
152 SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
153 new SkColorTable(*src->getColorTable()) : NULL;
154 SkAutoUnref au(ctable);
155 if (!tmpDst.allocPixels(alloc, ctable)) {
156 return false;
157 }
158
159 if (!tmpDst.readyToDraw()) {
160 // allocator/lock failed
161 return false;
162 }
163
164 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
165 // returned false.
166 SkASSERT(tmpDst.pixelRef() != NULL);
167
168 /* do memcpy for the same configs cases, else use drawing
169 */
170 if (src->config() == dstConfig) {
171 if (tmpDst.getSize() == src->getSize()) {
172 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
173 SkPixelRef* pixelRef = tmpDst.pixelRef();
174
175 // In order to reach this point, we know that the width, config and
176 // rowbytes of the SkPixelRefs are the same, but it is possible for
177 // the heights to differ, if this SkBitmap's height is a subset of
178 // fPixelRef. Only if the SkPixelRefs' heights match are we
179 // guaranteed that this is an exact copy, meaning we should clone
180 // the genID.
181 if (pixelRef->info().fHeight == fPixelRef->info().fHeight) {
182 // TODO: what to do if the two infos match, BUT
183 // fPixelRef is premul and pixelRef is opaque?
184 // skipping assert for now
185 // https://code.google.com/p/skia/issues/detail?id=2012
186 // SkASSERT(pixelRef->info() == fPixelRef->info() );
187 SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth);
188 SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColor Type);
189 pixelRef->cloneGenID(*fPixelRef);
190 }
191 } else {
192 const char* srcP = reinterpret_cast<const char*>(src->getPixels());
193 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
194 // to be sure we don't read too much, only copy our logical pixels
195 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
196 for (int y = 0; y < tmpDst.height(); y++) {
197 memcpy(dstP, srcP, bytesToCopy);
198 srcP += src->rowBytes();
199 dstP += tmpDst.rowBytes();
200 }
201 }
202 } else if (SkBitmap::kARGB_4444_Config == dstConfig
203 && SkBitmap::kARGB_8888_Config == src->config()) {
204 SkASSERT(src->height() == tmpDst.height());
205 SkASSERT(src->width() == tmpDst.width());
206 for (int y = 0; y < src->height(); ++y) {
207 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
208 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
209 DITHER_4444_SCAN(y);
210 for (int x = 0; x < src->width(); ++x) {
211 dstRow[x] = SkDitherARGB32To4444(srcRow[x],
212 DITHER_VALUE(x));
213 }
214 }
215 } else {
216 // Always clear the dest in case one of the blitters accesses it
217 // TODO: switch the allocation of tmpDst to call sk_calloc_throw
218 tmpDst.eraseColor(SK_ColorTRANSPARENT);
219
220 SkCanvas canvas(tmpDst);
221 SkPaint paint;
222
223 paint.setDither(true);
224 canvas.drawBitmap(*src, 0, 0, &paint);
225 }
226
227 dst->swap(tmpDst);
228 return true;
229 }
230
231 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
232 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig);
233
234 if (!this->canCopyTo(dstConfig)) {
235 return false;
236 }
237
238 // If we have a PixelRef, and it supports deep copy, use it.
239 // Currently supported only by texture-backed bitmaps.
240 if (fPixelRef) {
241 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
242 if (pixelRef) {
243 uint32_t rowBytes;
244 if (this->colorType() == dstCT) {
245 // Since there is no subset to pass to deepCopy, and deepCopy
246 // succeeded, the new pixel ref must be identical.
247 SkASSERT(fPixelRef->info() == pixelRef->info());
248 pixelRef->cloneGenID(*fPixelRef);
249 // Use the same rowBytes as the original.
250 rowBytes = fRowBytes;
251 } else {
252 // With the new config, an appropriate fRowBytes will be compute d by setConfig.
253 rowBytes = 0;
254 }
255
256 SkImageInfo info = fInfo;
257 info.fColorType = dstCT;
258 if (!dst->setConfig(info, rowBytes)) {
259 return false;
260 }
261 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
262 return true;
263 }
264 }
265
266 if (this->getTexture()) {
267 return false;
268 } else {
269 return this->copyTo(dst, dstConfig, NULL);
270 }
271 }
272
273 #endif
OLDNEW
« no previous file with comments | « src/core/SkBitmap.cpp ('k') | src/core/SkMipMap.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698