Exposing the SkBitmap::swap method as this is used.
[platform/upstream/libSkiaSharp.git] / src / c / sk_bitmap.cpp
1 /*
2  * Copyright 2016 Xamarin 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 "SkColor.h"
10 #include "SkColorPriv.h"
11 #include "SkDither.h"
12 #include "SkImageInfo.h"
13 #include "SkMath.h"
14 #include "SkUnPreMultiply.h"
15
16 #include "sk_bitmap.h"
17
18 #include "sk_types_priv.h"
19
20 static inline void copyAlpha8ToColor(size_t size, const uint8_t* pixels, sk_color_t* colors)
21 {
22     while (size-- != 0) {
23         const uint8_t* addr = pixels++;
24         *colors++ = SkColorSetA(0, *addr);
25     }
26 }
27
28 static inline void copyIndex8ToColor(sk_bitmap_t* cbitmap, size_t size, const uint8_t* pixels, sk_color_t* colors)
29 {
30     SkBitmap* bmp = AsBitmap(cbitmap);
31     SkColorTable* ctable = bmp->getColorTable();
32     while (size-- != 0) {
33         const uint8_t* addr = pixels++;
34         const SkPMColor c = (*ctable)[*addr];
35         *colors++ = SkUnPreMultiply::PMColorToColor(c);
36     }
37 }
38
39 static inline void copyGray8ToColor(size_t size, const uint8_t* pixels, sk_color_t* colors)
40 {
41     while (size-- != 0) {
42         const uint8_t* addr = pixels++;
43         *colors++ = SkColorSetRGB(*addr, *addr, *addr);
44     }
45 }
46
47 static inline void copyRgb565ToColor(size_t size, const uint16_t* pixels, sk_color_t* colors)
48 {
49     while (size-- != 0) {
50         const uint16_t* addr = pixels++;
51         *colors++ = SkPixel16ToColor(*addr);
52     }
53 }
54 static inline void copy8888ToColor(size_t size, const uint32_t* pixels, sk_color_t* colors)
55 {
56     while (size-- != 0) {
57         const uint32_t* addr = pixels++;
58         *colors++ = SkUnPreMultiply::PMColorToColor(*addr);
59     }
60 }
61
62 static inline void copyAlpha8FromColor(size_t size, const sk_color_t* colors, uint8_t* pixels)
63 {
64     while (size-- != 0) {
65         *pixels++ = SkColorGetA(*colors++);
66     }
67 }
68
69 static inline void copyGray8FromColor(size_t size, const sk_color_t* colors, uint8_t* pixels)
70 {
71     while (size-- != 0) {
72         SkColor c = *colors++;
73
74         uint8_t r = SkColorGetR(c);
75         uint8_t g = SkColorGetG(c);
76         uint8_t b = SkColorGetB(c);
77         uint8_t a = SkColorGetA(c);
78         if (255 != a) {
79             r = SkMulDiv255Round(r, a);
80             g = SkMulDiv255Round(g, a);
81             b = SkMulDiv255Round(b, a);
82         }
83         *pixels++ = SkComputeLuminance(r, g, b);
84     }
85 }
86
87 static inline void copyRgb565FromColor(size_t width, size_t height, const sk_color_t* colors, uint16_t* pixels)
88 {
89     for (size_t y = 0; y < height; y++) {
90         DITHER_565_SCAN(y);
91         for (size_t x = 0; x < width; x++) {
92             SkColor c = *colors++;
93             *pixels++ = SkDitherRGBTo565(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), DITHER_VALUE(x));
94         }
95     }
96 }
97 static inline void copy8888FromColor(size_t size, const sk_color_t* colors, uint32_t* pixels)
98 {
99     while (size-- != 0) {
100         *pixels++ = SkPreMultiplyColor(*colors++);
101     }
102 }
103
104
105 void sk_bitmap_destructor(sk_bitmap_t* cbitmap)
106 {
107     delete AsBitmap(cbitmap);
108 }
109
110 sk_bitmap_t* sk_bitmap_new()
111 {
112     return (sk_bitmap_t*) new SkBitmap();
113 }
114
115 void sk_bitmap_get_info(sk_bitmap_t* cbitmap, sk_imageinfo_t* info)
116 {
117     from_sk(AsBitmap(cbitmap)->info(), info);
118 }
119
120 void* sk_bitmap_get_pixels(sk_bitmap_t* cbitmap, size_t* length)
121 {
122     SkBitmap* bmp = AsBitmap(cbitmap);
123     *length = bmp->getSize();
124     return bmp->getPixels();
125 }
126
127 size_t sk_bitmap_get_row_bytes(sk_bitmap_t* cbitmap)
128 {
129     return AsBitmap(cbitmap)->rowBytes();
130 }
131
132 size_t sk_bitmap_get_byte_count(sk_bitmap_t* cbitmap)
133 {
134     return AsBitmap(cbitmap)->getSize();
135 }
136
137 void sk_bitmap_reset(sk_bitmap_t* cbitmap)
138 {
139     AsBitmap(cbitmap)->reset();
140 }
141
142 bool sk_bitmap_is_null(sk_bitmap_t* cbitmap)
143 {
144     return AsBitmap(cbitmap)->isNull();
145 }
146
147 bool sk_bitmap_is_immutable(sk_bitmap_t* cbitmap)
148 {
149     return AsBitmap(cbitmap)->isImmutable();
150 }
151
152 void sk_bitmap_set_immutable(sk_bitmap_t* cbitmap)
153 {
154     AsBitmap(cbitmap)->setImmutable();
155 }
156
157 bool sk_bitmap_is_volatile(sk_bitmap_t* cbitmap)
158 {
159     return AsBitmap(cbitmap)->isVolatile();
160 }
161
162 void sk_bitmap_set_volatile(sk_bitmap_t* cbitmap, bool value)
163 {
164     AsBitmap(cbitmap)->setIsVolatile(value);
165 }
166
167 void sk_bitmap_erase(sk_bitmap_t* cbitmap, sk_color_t color)
168 {
169     AsBitmap(cbitmap)->eraseColor(color);
170 }
171
172 void sk_bitmap_erase_rect(sk_bitmap_t* cbitmap, sk_color_t color, sk_irect_t* rect)
173 {
174     AsBitmap(cbitmap)->erase(color, AsIRect(*rect));
175 }
176
177 uint8_t sk_bitmap_get_addr_8(sk_bitmap_t* cbitmap, int x, int y)
178 {
179     return *(AsBitmap(cbitmap)->getAddr8(x, y));
180 }
181
182 uint16_t sk_bitmap_get_addr_16(sk_bitmap_t* cbitmap, int x, int y)
183 {
184     return *(AsBitmap(cbitmap)->getAddr16(x, y));
185 }
186
187 uint32_t sk_bitmap_get_addr_32(sk_bitmap_t* cbitmap, int x, int y)
188 {
189     return *(AsBitmap(cbitmap)->getAddr32(x, y));
190 }
191
192 void* sk_bitmap_get_addr(sk_bitmap_t* cbitmap, int x, int y)
193 {
194     return AsBitmap(cbitmap)->getAddr(x, y);
195 }
196
197 sk_color_t sk_bitmap_get_pixel_color(sk_bitmap_t* cbitmap, int x, int y)
198 {
199     return AsBitmap(cbitmap)->getColor(x, y);
200 }
201
202 sk_pmcolor_t sk_bitmap_get_index8_color(sk_bitmap_t* cbitmap, int x, int y)
203 {
204     return AsBitmap(cbitmap)->getIndex8Color(x, y);
205 }
206
207 void sk_bitmap_set_pixel_color(sk_bitmap_t* cbitmap, int x, int y, sk_color_t color)
208 {
209     SkBitmap* bmp = AsBitmap(cbitmap);
210
211     switch (bmp->colorType()) {
212     case kAlpha_8_SkColorType:
213         copyAlpha8FromColor(1, &color, (uint8_t*)bmp->getAddr8(x, y));
214         break;
215     case kGray_8_SkColorType:
216         copyGray8FromColor(1, &color, (uint8_t*)bmp->getAddr8(x, y));
217         break;
218     case kRGB_565_SkColorType:
219         copyRgb565FromColor(1, 1, &color, (uint16_t*)bmp->getAddr16(x, y));
220         break;
221     case kBGRA_8888_SkColorType:
222     case kRGBA_8888_SkColorType:
223         copy8888FromColor(1, &color, (uint32_t*)bmp->getAddr32(x, y));
224         break;
225     default:
226         break;
227     }
228 }
229
230 bool sk_bitmap_ready_to_draw(sk_bitmap_t* cbitmap)
231 {
232     return AsBitmap(cbitmap)->readyToDraw();
233 }
234
235 void sk_bitmap_get_pixel_colors(sk_bitmap_t* cbitmap, sk_color_t* colors)
236 {
237     SkBitmap* bmp = AsBitmap(cbitmap);
238
239     size_t size = bmp->height() * bmp->width();
240     const void* pixels = bmp->getPixels();
241
242     switch (bmp->colorType()) {
243     case kAlpha_8_SkColorType:
244         copyAlpha8ToColor(size, (const uint8_t*)pixels, colors);
245         break;
246     case kIndex_8_SkColorType:
247         copyIndex8ToColor(cbitmap, size, (const uint8_t*)pixels, colors);
248         break;
249     case kGray_8_SkColorType:
250         copyGray8ToColor(size, (const uint8_t*)pixels, colors);
251         break;
252     case kRGB_565_SkColorType:
253         copyRgb565ToColor(size, (const uint16_t*)pixels, colors);
254         break;
255     case kBGRA_8888_SkColorType:
256     case kRGBA_8888_SkColorType:
257         copy8888ToColor(size, (const uint32_t*)pixels, colors);
258         break;
259     default:
260         break;
261     }
262 }
263
264 void sk_bitmap_set_pixel_colors(sk_bitmap_t* cbitmap, const sk_color_t* colors)
265 {
266     SkBitmap* bmp = AsBitmap(cbitmap);
267
268     size_t width = bmp->width();
269     size_t height = bmp->height();
270     size_t size = height * width;
271     void* pixels = bmp->getPixels();
272
273     switch (bmp->colorType()) {
274     case kAlpha_8_SkColorType:
275         copyAlpha8FromColor(size, colors, (uint8_t*)pixels);
276         break;
277     case kGray_8_SkColorType:
278         copyGray8FromColor(size, colors, (uint8_t*)pixels);
279         break;
280     case kRGB_565_SkColorType:
281         copyRgb565FromColor(width, height, colors, (uint16_t*)pixels);
282         break;
283     case kBGRA_8888_SkColorType:
284     case kRGBA_8888_SkColorType:
285         copy8888FromColor(size, colors, (uint32_t*)pixels);
286         break;
287     default:
288         break;
289     }
290 }
291
292 bool sk_bitmap_install_pixels(sk_bitmap_t* cbitmap, const sk_imageinfo_t* cinfo, void* pixels, size_t rowBytes, sk_colortable_t* ctable, const sk_bitmap_release_proc releaseProc, void* context)
293 {
294     SkBitmap* bmp = AsBitmap(cbitmap);
295
296     SkImageInfo info;
297     from_c(*cinfo, &info);
298
299     return bmp->installPixels(info, pixels, rowBytes, AsColorTable(ctable), releaseProc, context);
300 }
301
302 bool sk_bitmap_install_pixels_with_pixmap(sk_bitmap_t* cbitmap, const sk_pixmap_t* cpixmap)
303 {
304     SkBitmap* bmp = AsBitmap(cbitmap);
305     return bmp->installPixels(AsPixmap(*cpixmap));
306 }
307
308 SK_API bool sk_bitmap_install_mask_pixels(sk_bitmap_t* cbitmap, const sk_mask_t* cmask) {
309     SkBitmap* bmp = AsBitmap(cbitmap);
310     const SkMask* mask = AsMask(cmask);
311     return bmp->installMaskPixels(*mask);
312 }
313
314 bool sk_bitmap_try_alloc_pixels(sk_bitmap_t* cbitmap, const sk_imageinfo_t* requestedInfo, size_t rowBytes)
315 {
316     SkBitmap* bmp = AsBitmap(cbitmap);
317
318     SkImageInfo info;
319     from_c(*requestedInfo, &info);
320
321     return bmp->tryAllocPixels(info, rowBytes);
322 }
323
324 bool sk_bitmap_try_alloc_pixels_with_color_table(sk_bitmap_t* cbitmap, const sk_imageinfo_t* requestedInfo, sk_colortable_t* ctable, uint32_t flags)
325 {
326     SkBitmap* bmp = AsBitmap(cbitmap);
327
328     SkImageInfo info;
329     from_c(*requestedInfo, &info);
330
331     return bmp->tryAllocPixels(info, sk_ref_sp(AsColorTable(ctable)), flags);
332 }
333
334 sk_colortable_t* sk_bitmap_get_colortable(sk_bitmap_t* cbitmap)
335 {
336     return ToColorTable(AsBitmap(cbitmap)->getColorTable());
337 }
338
339 void sk_bitmap_set_pixels(sk_bitmap_t* cbitmap, void* pixels, sk_colortable_t* ctable)
340 {
341     SkBitmap* bmp = AsBitmap(cbitmap);
342     bmp->setPixels(pixels, AsColorTable(ctable));
343 }
344
345 bool sk_bitmap_peek_pixels(sk_bitmap_t* cbitmap, sk_pixmap_t* cpixmap)
346 {
347     SkBitmap* bmp = AsBitmap(cbitmap);
348     return bmp->peekPixels(AsPixmap(cpixmap));
349 }
350
351 bool sk_bitmap_extract_subset(sk_bitmap_t* cbitmap, sk_bitmap_t* cdst, sk_irect_t* subset)
352 {
353     SkBitmap* bmp = AsBitmap(cbitmap);
354     SkBitmap* dst = AsBitmap(cdst);
355     return bmp->extractSubset(dst, AsIRect(*subset));
356 }
357
358 bool sk_bitmap_extract_alpha(sk_bitmap_t* cbitmap, sk_bitmap_t* cdst, const sk_paint_t* paint, sk_ipoint_t* offset)
359 {
360     SkBitmap* bmp = AsBitmap(cbitmap);
361     SkBitmap* dst = AsBitmap(cdst);
362     return bmp->extractAlpha(dst, AsPaint(paint), AsIPoint(offset));
363 }
364
365 void sk_bitmap_notify_pixels_changed(sk_bitmap_t* cbitmap)
366 {
367     AsBitmap(cbitmap)->notifyPixelsChanged();
368 }
369
370 void sk_bitmap_swap(sk_bitmap_t* cbitmap, sk_bitmap_t* cother)
371 {
372     AsBitmap(cbitmap)->swap(AsBitmap(*cother));
373 }