SkImagePriv.cpp revision 6997ebbe5cf06c938cc893e1d0217dc4048edf82
16997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com/*
26997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Copyright 2012 Google Inc.
36997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com *
46997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Use of this source code is governed by a BSD-style license that can be
56997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * found in the LICENSE file.
66997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com */
76997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com
8889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImagePriv.h"
970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkCanvas.h"
1070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkPicture.h"
11889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
12889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info,
13889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                                           bool* isOpaque) {
14889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    switch (info.fColorType) {
15889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkImage::kAlpha_8_ColorType:
16889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            switch (info.fAlphaType) {
17889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kIgnore_AlphaType:
18889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    // makes no sense
19889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kNo_Config;
20889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
21889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kOpaque_AlphaType:
22889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    *isOpaque = true;
23889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kA8_Config;
24889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
25889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kPremul_AlphaType:
26889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kUnpremul_AlphaType:
27889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    *isOpaque = false;
28889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kA8_Config;
29889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            }
30889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            break;
31889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
32889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkImage::kRGB_565_ColorType:
33889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            // we ignore fAlpahType, though some would not make sense
34889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            *isOpaque = true;
35889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            return SkBitmap::kRGB_565_Config;
36889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
37889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkImage::kRGBA_8888_ColorType:
38889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkImage::kBGRA_8888_ColorType:
39889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            // not supported yet
40889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            return SkBitmap::kNo_Config;
41889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
42889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkImage::kPMColor_ColorType:
43889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            switch (info.fAlphaType) {
44889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kIgnore_AlphaType:
45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kUnpremul_AlphaType:
46889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    // not supported yet
47889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kNo_Config;
48889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kOpaque_AlphaType:
49889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    *isOpaque = true;
50889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kARGB_8888_Config;
51889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                case SkImage::kPremul_AlphaType:
52889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    *isOpaque = false;
53889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                    return SkBitmap::kARGB_8888_Config;
54889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            }
55889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            break;
56889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
57889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkASSERT(!"how did we get here");
58889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return SkBitmap::kNo_Config;
59889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
60889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
61889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comint SkImageBytesPerPixel(SkImage::ColorType ct) {
62889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    static const uint8_t gColorTypeBytesPerPixel[] = {
63889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        1,  // kAlpha_8_ColorType
64889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        2,  // kRGB_565_ColorType
65889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        4,  // kRGBA_8888_ColorType
66889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        4,  // kBGRA_8888_ColorType
67889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        4,  // kPMColor_ColorType
68889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    };
69889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
70889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel));
71889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return gColorTypeBytesPerPixel[ct];
72889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
73889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
74889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.combool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) {
75889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    switch (bm.config()) {
76889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkBitmap::kA8_Config:
77889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            info->fColorType = SkImage::kAlpha_8_ColorType;
78889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            break;
79889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
80889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkBitmap::kRGB_565_Config:
81889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            info->fColorType = SkImage::kRGB_565_ColorType;
82889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            break;
83889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
84889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        case SkBitmap::kARGB_8888_Config:
85889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            info->fColorType = SkImage::kPMColor_ColorType;
86889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            break;
87889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
88889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        default:
89889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            return false;
90889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
91889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
92889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    info->fWidth = bm.width();
93889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    info->fHeight = bm.height();
94889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType :
95889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                                       SkImage::kPremul_AlphaType;
96889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return true;
97889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
98889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
99889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkImage* SkNewImageFromBitmap(const SkBitmap& bm) {
100889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkImage::Info info;
101889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    if (!SkBitmapToImageInfo(bm, &info)) {
102889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        return NULL;
103889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
104889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
105889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    SkImage* image = NULL;
106889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    if (bm.isImmutable()) {
107889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes());
108889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    } else {
109889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        bm.lockPixels();
11070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        if (bm.getPixels()) {
111889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com            image = SkImage::NewRasterCopy(info, NULL, bm.getPixels(),
112889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com                                           bm.rowBytes());
113889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        }
114889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com        bm.unlockPixels();
115889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    }
116889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com    return image;
117889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com}
118889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com
11970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgstatic bool needs_layer(const SkPaint& paint) {
12070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    return  0xFF != paint.getAlpha() ||
12170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    paint.getColorFilter() ||
12270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    paint.getImageFilter() ||
12370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode);
12470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
12570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
12670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture,
12770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                            SkScalar x, SkScalar y, const SkPaint* paint) {
12870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    int saveCount = canvas->getSaveCount();
12970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
13070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    if (paint && needs_layer(*paint)) {
13170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        SkRect bounds;
13270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        bounds.set(x, y,
13370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                   x + SkIntToScalar(picture->width()),
13470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org                   y + SkIntToScalar(picture->height()));
13570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        canvas->saveLayer(&bounds, paint);
13670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    } else if (x || y) {
13770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org        canvas->save();
13870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    }
13970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
14070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    canvas->drawPicture(*picture);
14170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org    canvas->restoreToCount(saveCount);
14270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org}
14370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org
144