SkImagePriv.cpp revision e16efc1882ab34a0bb3ae361a2d37f840044cf87
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 "SkImagePriv.h"
9#include "SkCanvas.h"
10#include "SkPicture.h"
11
12SkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info,
13                                           bool* isOpaque) {
14    switch (info.fColorType) {
15        case SkImage::kAlpha_8_ColorType:
16            switch (info.fAlphaType) {
17                case SkImage::kIgnore_AlphaType:
18                    // makes no sense
19                    return SkBitmap::kNo_Config;
20
21                case SkImage::kOpaque_AlphaType:
22                    *isOpaque = true;
23                    return SkBitmap::kA8_Config;
24
25                case SkImage::kPremul_AlphaType:
26                case SkImage::kUnpremul_AlphaType:
27                    *isOpaque = false;
28                    return SkBitmap::kA8_Config;
29            }
30            break;
31
32        case SkImage::kRGB_565_ColorType:
33            // we ignore fAlpahType, though some would not make sense
34            *isOpaque = true;
35            return SkBitmap::kRGB_565_Config;
36
37        case SkImage::kRGBA_8888_ColorType:
38        case SkImage::kBGRA_8888_ColorType:
39            // not supported yet
40            return SkBitmap::kNo_Config;
41
42        case SkImage::kPMColor_ColorType:
43            switch (info.fAlphaType) {
44                case SkImage::kIgnore_AlphaType:
45                case SkImage::kUnpremul_AlphaType:
46                    // not supported yet
47                    return SkBitmap::kNo_Config;
48                case SkImage::kOpaque_AlphaType:
49                    *isOpaque = true;
50                    return SkBitmap::kARGB_8888_Config;
51                case SkImage::kPremul_AlphaType:
52                    *isOpaque = false;
53                    return SkBitmap::kARGB_8888_Config;
54            }
55            break;
56    }
57    SkASSERT(!"how did we get here");
58    return SkBitmap::kNo_Config;
59}
60
61int SkImageBytesPerPixel(SkImage::ColorType ct) {
62    static const uint8_t gColorTypeBytesPerPixel[] = {
63        1,  // kAlpha_8_ColorType
64        2,  // kRGB_565_ColorType
65        4,  // kRGBA_8888_ColorType
66        4,  // kBGRA_8888_ColorType
67        4,  // kPMColor_ColorType
68    };
69
70    SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
71    return gColorTypeBytesPerPixel[ct];
72}
73
74bool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) {
75    switch (bm.config()) {
76        case SkBitmap::kA8_Config:
77            info->fColorType = SkImage::kAlpha_8_ColorType;
78            break;
79
80        case SkBitmap::kRGB_565_Config:
81            info->fColorType = SkImage::kRGB_565_ColorType;
82            break;
83
84        case SkBitmap::kARGB_8888_Config:
85            info->fColorType = SkImage::kPMColor_ColorType;
86            break;
87
88        default:
89            return false;
90    }
91
92    info->fWidth = bm.width();
93    info->fHeight = bm.height();
94    info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType :
95                                       SkImage::kPremul_AlphaType;
96    return true;
97}
98
99SkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) {
100    SkImage::Info info;
101    if (!SkBitmapToImageInfo(bm, &info)) {
102        return NULL;
103    }
104
105    SkImage* image = NULL;
106    if (canSharePixelRef || bm.isImmutable()) {
107        image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
108    } else {
109        bm.lockPixels();
110        if (bm.getPixels()) {
111            image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes());
112        }
113        bm.unlockPixels();
114    }
115    return image;
116}
117
118static bool needs_layer(const SkPaint& paint) {
119    return  0xFF != paint.getAlpha() ||
120    paint.getColorFilter() ||
121    paint.getImageFilter() ||
122    SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
123}
124
125void SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
126                            SkScalar x, SkScalar y, const SkPaint* paint) {
127    int saveCount = canvas->getSaveCount();
128
129    if (paint && needs_layer(*paint)) {
130        SkRect bounds;
131        bounds.set(x, y,
132                   x + SkIntToScalar(picture->width()),
133                   y + SkIntToScalar(picture->height()));
134        canvas->saveLayer(&bounds, paint);
135        canvas->translate(x, y);
136    } else if (x || y) {
137        canvas->save();
138        canvas->translate(x, y);
139    }
140
141    canvas->drawPicture(*picture);
142    canvas->restoreToCount(saveCount);
143}
144