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