• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkBitmap.h"
9 #include "SkCanvas.h"
10 #include "SkImageGenerator.h"
11 #include "SkImagePriv.h"
12 #include "SkImage_Base.h"
13 #include "SkReadPixelsRec.h"
14 #include "SkString.h"
15 #include "SkSurface.h"
16 
NextUniqueID()17 uint32_t SkImage::NextUniqueID() {
18     static int32_t gUniqueID;
19 
20     // never return 0;
21     uint32_t id;
22     do {
23         id = sk_atomic_inc(&gUniqueID) + 1;
24     } while (0 == id);
25     return id;
26 }
27 
peekPixels(SkImageInfo * info,size_t * rowBytes) const28 const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const {
29     SkImageInfo infoStorage;
30     size_t rowBytesStorage;
31     if (NULL == info) {
32         info = &infoStorage;
33     }
34     if (NULL == rowBytes) {
35         rowBytes = &rowBytesStorage;
36     }
37     return as_IB(this)->onPeekPixels(info, rowBytes);
38 }
39 
readPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY) const40 bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
41                            int srcX, int srcY) const {
42     SkReadPixelsRec rec(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
43     if (!rec.trim(this->width(), this->height())) {
44         return false;
45     }
46     return as_IB(this)->onReadPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY);
47 }
48 
getTexture() const49 GrTexture* SkImage::getTexture() const {
50     return as_IB(this)->onGetTexture();
51 }
52 
newShader(SkShader::TileMode tileX,SkShader::TileMode tileY,const SkMatrix * localMatrix) const53 SkShader* SkImage::newShader(SkShader::TileMode tileX,
54                              SkShader::TileMode tileY,
55                              const SkMatrix* localMatrix) const {
56     return as_IB(this)->onNewShader(tileX, tileY, localMatrix);
57 }
58 
encode(SkImageEncoder::Type type,int quality) const59 SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
60     SkBitmap bm;
61     if (as_IB(this)->getROPixels(&bm)) {
62         return SkImageEncoder::EncodeData(bm, type, quality);
63     }
64     return NULL;
65 }
66 
NewFromData(SkData * data)67 SkImage* SkImage::NewFromData(SkData* data) {
68     if (NULL == data) {
69         return NULL;
70     }
71     SkImageGenerator* generator = SkImageGenerator::NewFromData(data);
72     return generator ? SkImage::NewFromGenerator(generator) : NULL;
73 }
74 
newSurface(const SkImageInfo & info,const SkSurfaceProps * props) const75 SkSurface* SkImage::newSurface(const SkImageInfo& info, const SkSurfaceProps* props) const {
76     if (NULL == props) {
77         props = &as_IB(this)->props();
78     }
79     return as_IB(this)->onNewSurface(info, *props);
80 }
81 
toString(SkString * str) const82 const char* SkImage::toString(SkString* str) const {
83     str->appendf("image: (id:%d (%d, %d) %s)", this->uniqueID(), this->width(), this->height(),
84                  this->isOpaque() ? "opaque" : "");
85     return str->c_str();
86 }
87 
newImage(int newWidth,int newHeight,const SkIRect * subset,SkFilterQuality quality) const88 SkImage* SkImage::newImage(int newWidth, int newHeight, const SkIRect* subset,
89                            SkFilterQuality quality) const {
90     if (newWidth <= 0 || newHeight <= 0) {
91         return NULL;
92     }
93 
94     const SkIRect bounds = SkIRect::MakeWH(this->width(), this->height());
95 
96     if (subset) {
97         if (!bounds.contains(*subset)) {
98             return NULL;
99         }
100         if (bounds == *subset) {
101             subset = NULL;  // and fall through to check below
102         }
103     }
104 
105     if (NULL == subset && this->width() == newWidth && this->height() == newHeight) {
106         return SkRef(const_cast<SkImage*>(this));
107     }
108 
109     return as_IB(this)->onNewImage(newWidth, newHeight, subset, quality);
110 }
111 
112 ///////////////////////////////////////////////////////////////////////////////
113 
raster_canvas_supports(const SkImageInfo & info)114 static bool raster_canvas_supports(const SkImageInfo& info) {
115     switch (info.colorType()) {
116         case kN32_SkColorType:
117             return kUnpremul_SkAlphaType != info.alphaType();
118         case kRGB_565_SkColorType:
119             return true;
120         case kAlpha_8_SkColorType:
121             return true;
122         default:
123             break;
124     }
125     return false;
126 }
127 
onReadPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY) const128 bool SkImage_Base::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
129                                 int srcX, int srcY) const {
130     if (!raster_canvas_supports(dstInfo)) {
131         return false;
132     }
133 
134     SkBitmap bm;
135     bm.installPixels(dstInfo, dstPixels, dstRowBytes);
136     SkCanvas canvas(bm);
137 
138     SkPaint paint;
139     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
140     canvas.drawImage(this, -SkIntToScalar(srcX), -SkIntToScalar(srcY), &paint);
141 
142     return true;
143 }
144 
onNewImage(int newWidth,int newHeight,const SkIRect * subset,SkFilterQuality quality) const145 SkImage* SkImage_Base::onNewImage(int newWidth, int newHeight, const SkIRect* subset,
146                                   SkFilterQuality quality) const {
147     const bool opaque = this->isOpaque();
148     const SkImageInfo info = SkImageInfo::Make(newWidth, newHeight, kN32_SkColorType,
149                                                opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
150     SkAutoTUnref<SkSurface> surface(this->newSurface(info, NULL));
151     if (!surface.get()) {
152         return NULL;
153     }
154 
155     SkRect src;
156     if (subset) {
157         src.set(*subset);
158     } else {
159         src = SkRect::MakeIWH(this->width(), this->height());
160     }
161 
162     surface->getCanvas()->scale(newWidth / src.width(), newHeight / src.height());
163     surface->getCanvas()->translate(-src.x(), -src.y());
164 
165     SkPaint paint;
166     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
167     paint.setFilterQuality(quality);
168     surface->getCanvas()->drawImage(this, 0, 0, &paint);
169     return surface->newImageSnapshot();
170 }
171 
172 //////////////////////////////////////////////////////////////////////////////////////
173 
174 #if !SK_SUPPORT_GPU
175 
NewFromTexture(GrContext *,const GrBackendTextureDesc &,SkAlphaType)176 SkImage* SkImage::NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType) {
177     return NULL;
178 }
179 
NewFromTextureCopy(GrContext *,const GrBackendTextureDesc &,SkAlphaType)180 SkImage* SkImage::NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&, SkAlphaType) {
181     return NULL;
182 }
183 
184 #endif
185