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