Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / image / SkImage.cpp
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 "SkImagePriv.h"
11 #include "SkImage_Base.h"
12
13 static SkImage_Base* as_IB(SkImage* image) {
14     return static_cast<SkImage_Base*>(image);
15 }
16
17 static const SkImage_Base* as_IB(const SkImage* image) {
18     return static_cast<const SkImage_Base*>(image);
19 }
20
21 uint32_t SkImage::NextUniqueID() {
22     static int32_t gUniqueID;
23
24     // never return 0;
25     uint32_t id;
26     do {
27         id = sk_atomic_inc(&gUniqueID) + 1;
28     } while (0 == id);
29     return id;
30 }
31
32 void SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const {
33     as_IB(this)->onDraw(canvas, x, y, paint);
34 }
35
36 void SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst,
37                    const SkPaint* paint) const {
38     as_IB(this)->onDrawRectToRect(canvas, src, dst, paint);
39 }
40
41 const void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const {
42     SkImageInfo infoStorage;
43     size_t rowBytesStorage;
44     if (NULL == info) {
45         info = &infoStorage;
46     }
47     if (NULL == rowBytes) {
48         rowBytes = &rowBytesStorage;
49     }
50     return as_IB(this)->onPeekPixels(info, rowBytes);
51 }
52
53 bool SkImage::readPixels(SkBitmap* bitmap, const SkIRect* subset) const {
54     if (NULL == bitmap) {
55         return false;
56     }
57
58     SkIRect bounds = SkIRect::MakeWH(this->width(), this->height());
59
60     // trim against the bitmap, if its already been allocated
61     if (bitmap->pixelRef()) {
62         bounds.fRight = SkMin32(bounds.fRight, bitmap->width());
63         bounds.fBottom = SkMin32(bounds.fBottom, bitmap->height());
64         if (bounds.isEmpty()) {
65             return false;
66         }
67     }
68
69     if (subset && !bounds.intersect(*subset)) {
70         // perhaps we could return true + empty-bitmap?
71         return false;
72     }
73     return as_IB(this)->onReadPixels(bitmap, bounds);
74 }
75
76 GrTexture* SkImage::getTexture() {
77     return as_IB(this)->onGetTexture();
78 }
79
80 SkShader* SkImage::newShader(SkShader::TileMode tileX,
81                              SkShader::TileMode tileY,
82                              const SkMatrix* localMatrix) const {
83     return as_IB(this)->onNewShader(tileX, tileY, localMatrix);
84 }
85
86 SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const {
87     SkBitmap bm;
88     if (as_IB(this)->getROPixels(&bm)) {
89         return SkImageEncoder::EncodeData(bm, type, quality);
90     }
91     return NULL;
92 }
93
94 ///////////////////////////////////////////////////////////////////////////////
95
96 static bool raster_canvas_supports(const SkImageInfo& info) {
97     switch (info.colorType()) {
98         case kN32_SkColorType:
99             return kUnpremul_SkAlphaType != info.alphaType();
100         case kRGB_565_SkColorType:
101             return true;
102         case kAlpha_8_SkColorType:
103             return true;
104         default:
105             break;
106     }
107     return false;
108 }
109
110 bool SkImage_Base::onReadPixels(SkBitmap* bitmap, const SkIRect& subset) const {
111     if (bitmap->pixelRef()) {
112         const SkImageInfo info = bitmap->info();
113         if (kUnknown_SkColorType == info.colorType()) {
114             return false;
115         }
116         if (!raster_canvas_supports(info)) {
117             return false;
118         }
119     } else {
120         SkBitmap tmp;
121         if (!tmp.tryAllocN32Pixels(subset.width(), subset.height())) {
122             return false;
123         }
124         *bitmap = tmp;
125     }
126
127     SkRect srcR, dstR;
128     srcR.set(subset);
129     dstR = srcR;
130     dstR.offset(-dstR.left(), -dstR.top());
131
132     SkCanvas canvas(*bitmap);
133
134     SkPaint paint;
135     paint.setXfermodeMode(SkXfermode::kClear_Mode);
136     canvas.drawRect(dstR, paint);
137
138     const_cast<SkImage_Base*>(this)->onDrawRectToRect(&canvas, &srcR, dstR, NULL);
139     return true;
140 }