SkImage.cpp revision f6627b78f933b77b358ac0791c520f99b0e79fca
1f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkImage.h"
2f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
3f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkBitmap.h"
4f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
5f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
6f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
7f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comclass SkImage_Base : public SkImage {
8f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.compublic:
9f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Base(int width, int height) : INHERITED(width, height) {}
10f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
11f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    virtual const SkBitmap* asABitmap() { return NULL; }
12f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
13f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comprivate:
14f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    typedef SkImage INHERITED;
15f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com};
16f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
17f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comstatic SkImage_Base* asIB(SkImage* image) {
18f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return static_cast<SkImage_Base*>(image);
19f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
20f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
21f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
22f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
23f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comstatic SkBitmap::Config InfoToConfig(const SkImage::Info& info, bool* isOpaque) {
24f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    switch (info.fColorType) {
25f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        case SkImage::kAlpha_8_ColorType:
26f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            switch (info.fAlphaType) {
27f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kIgnore_AlphaType:
28f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    // makes no sense
29f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kNo_Config;
30f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
31f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kOpaque_AlphaType:
32f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    *isOpaque = true;
33f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kA8_Config;
34f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
35f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kPremul_AlphaType:
36f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kUnpremul_AlphaType:
37f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    *isOpaque = false;
38f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kA8_Config;
39f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            }
40f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            break;
41f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
42f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        case SkImage::kRGB_565_ColorType:
43f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            // we ignore fAlpahType, though some would not make sense
44f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            *isOpaque = true;
45f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return SkBitmap::kRGB_565_Config;
46f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
47f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        case SkImage::kRGBA_8888_ColorType:
48f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        case SkImage::kBGRA_8888_ColorType:
49f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            // not supported yet
50f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return SkBitmap::kNo_Config;
51f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
52f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        case SkImage::kPMColor_ColorType:
53f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            switch (info.fAlphaType) {
54f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kIgnore_AlphaType:
55f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kUnpremul_AlphaType:
56f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    // not supported yet
57f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kNo_Config;
58f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kOpaque_AlphaType:
59f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    *isOpaque = true;
60f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kARGB_8888_Config;
61f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                case SkImage::kPremul_AlphaType:
62f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    *isOpaque = false;
63f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                    return SkBitmap::kARGB_8888_Config;
64f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            }
65f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            break;
66f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
67f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkASSERT(!"how did we get here");
68f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return SkBitmap::kNo_Config;
69f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
70f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
71f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comstatic int BytesPerPixel(SkImage::ColorType ct) {
72f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static const uint8_t gColorTypeBytesPerPixel[] = {
73f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        1,  // kAlpha_8_ColorType
74f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        2,  // kRGB_565_ColorType
75f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        4,  // kRGBA_8888_ColorType
76f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        4,  // kBGRA_8888_ColorType
77f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        4,  // kPMColor_ColorType
78f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    };
79f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
80f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
81f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return gColorTypeBytesPerPixel[ct];
82f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
83f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
84f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comstatic size_t ComputeMinRowBytes(const SkImage::Info& info) {
85f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return info.fWidth * BytesPerPixel(info.fColorType);
86f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
87f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
88f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comclass SkImage_Raster : public SkImage_Base {
89f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.compublic:
90f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static bool ValidArgs(const Info& info, SkColorSpace* cs, size_t rowBytes) {
91f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        const int maxDimension = SK_MaxS32 >> 2;
92f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        const size_t kMaxPixelByteSize = SK_MaxS32;
93f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
94f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (info.fWidth < 0 || info.fHeight < 0) {
95f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
96f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
97f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (info.fWidth > maxDimension || info.fHeight > maxDimension) {
98f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
99f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
100f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if ((unsigned)info.fColorType > (unsigned)kLastEnum_ColorType) {
101f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
102f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
103f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if ((unsigned)info.fAlphaType > (unsigned)kLastEnum_AlphaType) {
104f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
105f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
106f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
107f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        bool isOpaque;
108f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (InfoToConfig(info, &isOpaque) == SkBitmap::kNo_Config) {
109f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
110f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
111f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
112f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        // TODO: check colorspace
113f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
114f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (rowBytes < ComputeMinRowBytes(info)) {
115f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
116f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
117f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
118f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        int64_t size = (int64_t)info.fHeight * rowBytes;
119f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        if (size > kMaxPixelByteSize) {
120f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com            return false;
121f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        }
122f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return true;
123f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
124f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
125f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static SkImage* NewEmpty();
126f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
127f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Raster(const SkImage::Info&, SkColorSpace*, SkData*, size_t rb);
128f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    virtual ~SkImage_Raster();
129f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
130f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    virtual const SkBitmap* asABitmap() SK_OVERRIDE;
131f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
132f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comprivate:
133f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkImage_Raster() : INHERITED(0, 0) {}
134f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
135f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkBitmap    fBitmap;
136f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
137f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    typedef SkImage_Base INHERITED;
138f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com};
139f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
140f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
141f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
142f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkData.h"
143f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkDataPixelRef.h"
144f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
145f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage_Raster::NewEmpty() {
146f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // Returns lazily created singleton
147f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static SkImage* gEmpty;
148f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == gEmpty) {
149f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        gEmpty = SkNEW(SkImage_Raster);
150f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
151f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    gEmpty->ref();
152f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return gEmpty;
153f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
154f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
155f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage_Raster::SkImage_Raster(const Info& info, SkColorSpace* cs,
156f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                               SkData* data, size_t rowBytes)
157f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        : INHERITED(info.fWidth, info.fHeight) {
158f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    bool isOpaque;
159f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkBitmap::Config config = InfoToConfig(info, &isOpaque);
160f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
161f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setConfig(config, info.fWidth, info.fHeight, rowBytes);
162f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setPixelRef(SkNEW_ARGS(SkDataPixelRef, (data)))->unref();
163f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setIsOpaque(isOpaque);
164f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    fBitmap.setImmutable();   // Yea baby!
165f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
166f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
167f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage_Raster::~SkImage_Raster() {}
168f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
169f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comconst SkBitmap* SkImage_Raster::asABitmap() {
170f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return &fBitmap;
171f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
172f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
173f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
174f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
175f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage::NewRasterCopy(const SkImage::Info& info, SkColorSpace* cs,
176f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                                const void* pixels, size_t rowBytes) {
177f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (!SkImage_Raster::ValidArgs(info, cs, rowBytes)) {
178f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
179f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
180f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (0 == info.fWidth && 0 == info.fHeight) {
181f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return SkImage_Raster::NewEmpty();
182f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
183f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // check this after empty-check
184f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == pixels) {
185f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
186f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
187f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
188f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // Here we actually make a copy of the caller's pixel data
189f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkAutoDataUnref data(SkData::NewWithCopy(pixels, info.fHeight * rowBytes));
190f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return SkNEW_ARGS(SkImage_Raster, (info, cs, data, rowBytes));
191f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
192f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
193f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
194f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comSkImage* SkImage::NewRasterData(const SkImage::Info& info, SkColorSpace* cs,
195f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                                SkData* pixelData, size_t rowBytes) {
196f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (!SkImage_Raster::ValidArgs(info, cs, rowBytes)) {
197f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
198f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
199f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (0 == info.fWidth && 0 == info.fHeight) {
200f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return SkImage_Raster::NewEmpty();
201f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
202f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // check this after empty-check
203f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (NULL == pixelData) {
204f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
205f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
206f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
207f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // did they give us enough data?
208f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    size_t size = info.fHeight * rowBytes;
209f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (pixelData->size() < size) {
210f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        return NULL;
211f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
212f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
213f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    SkAutoDataUnref data(pixelData);
214f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return SkNEW_ARGS(SkImage_Raster, (info, cs, data, rowBytes));
215f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
216f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
217f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com///////////////////////////////////////////////////////////////////////////////
218f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
219f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkCanvas.h"
220f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
221f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comuint32_t SkImage::NextUniqueID() {
222f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    static int32_t gUniqueID;
223f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
224f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    // never return 0;
225f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    uint32_t id;
226f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    do {
227f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        id = sk_atomic_inc(&gUniqueID) + 1;
228f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    } while (0 == id);
229f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    return id;
230f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
231f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
232f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comvoid SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y,
233f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com                   const SkPaint* paint) {
234f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    const SkBitmap* bitmap = asIB(this)->asABitmap();
235f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    if (bitmap) {
236f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com        canvas->drawBitmap(*bitmap, x, y, paint);
237f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com    }
238f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com}
239f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com
240