1 /*
2 FLIF - Free Lossless Image Format
3
4 Copyright 2010-2016, Jon Sneyers & Pieter Wuille
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 #pragma once
20 #include "flif-interface-private_common.hpp"
21
FLIF_IMAGE()22 FLIF_IMAGE::FLIF_IMAGE() { }
23
24 #pragma pack(push,1)
25 struct FLIF_RGB {
26 uint8_t r, g, b;
27 };
28 struct FLIF_RGBA {
29 uint8_t r,g,b,a;
30 };
31 struct FLIF_RGBA16 {
32 uint16_t r,g,b,a;
33 };
34 #pragma pack(pop)
35
write_row_RGBA8(uint32_t row,const void * buffer,size_t buffer_size_bytes)36 void FLIF_IMAGE::write_row_RGBA8(uint32_t row, const void* buffer, size_t buffer_size_bytes) {
37 if(buffer_size_bytes < image.cols() * sizeof(FLIF_RGBA))
38 return;
39
40 const FLIF_RGBA* buffer_rgba = reinterpret_cast<const FLIF_RGBA*>(buffer);
41
42 if(image.numPlanes() >= 3) {
43 for (size_t c = 0; c < (size_t) image.cols(); c++) {
44 image.set(0, row, c, buffer_rgba[c].r);
45 image.set(1, row, c, buffer_rgba[c].g);
46 image.set(2, row, c, buffer_rgba[c].b);
47 }
48 }
49 if(image.numPlanes() >= 4) {
50 for (size_t c = 0; c < (size_t) image.cols(); c++) {
51 image.set(3, row, c, buffer_rgba[c].a);
52 }
53 }
54 }
55
write_row_RGB8(uint32_t row,const void * buffer,size_t buffer_size_bytes)56 void FLIF_IMAGE::write_row_RGB8(uint32_t row, const void * buffer, size_t buffer_size_bytes)
57 {
58 if (buffer_size_bytes < image.cols() * sizeof(FLIF_RGB))
59 return;
60
61 const FLIF_RGB* buffer_rgb = reinterpret_cast<const FLIF_RGB*>(buffer);
62
63 if (image.numPlanes() >= 3) {
64 for (size_t c = 0; c < (size_t)image.cols(); c++) {
65 image.set(0, row, c, buffer_rgb[c].r);
66 image.set(1, row, c, buffer_rgb[c].g);
67 image.set(2, row, c, buffer_rgb[c].b);
68 }
69 }
70 if (image.numPlanes() >= 4) {
71 for (size_t c = 0; c < (size_t)image.cols(); c++) {
72 image.set(3, row, c, 0xFF); // fully opaque
73 }
74 }
75 }
76
write_row_GRAY8(uint32_t row,const void * buffer,size_t buffer_size_bytes)77 void FLIF_IMAGE::write_row_GRAY8(uint32_t row, const void * buffer, size_t buffer_size_bytes)
78 {
79 if (buffer_size_bytes < image.cols() * sizeof(uint8_t))
80 return;
81
82 const uint8_t* buffer_gray = reinterpret_cast<const uint8_t*>(buffer);
83
84 if (image.numPlanes() >= 1) {
85 for (size_t c = 0; c < (size_t)image.cols(); c++) {
86 image.set(0, row, c, buffer_gray[c]);
87 }
88 }
89 if (image.numPlanes() >= 3) {
90 for (size_t c = 0; c < (size_t)image.cols(); c++) {
91 image.set(1, row, c, buffer_gray[c]);
92 image.set(2, row, c, buffer_gray[c]);
93 }
94 }
95 if (image.numPlanes() >= 4) {
96 for (size_t c = 0; c < (size_t)image.cols(); c++) {
97 image.set(3, row, c, 0xFF); // fully opaque
98 }
99 }
100 }
101
write_row_GRAY16(uint32_t row,const void * buffer,size_t buffer_size_bytes)102 void FLIF_IMAGE::write_row_GRAY16(uint32_t row, const void * buffer, size_t buffer_size_bytes)
103 {
104 if (buffer_size_bytes < image.cols() * sizeof(uint16_t))
105 return;
106
107 const uint16_t* buffer_gray = reinterpret_cast<const uint16_t*>(buffer);
108
109 if (image.numPlanes() >= 1) {
110 for (size_t c = 0; c < (size_t)image.cols(); c++) {
111 image.set(0, row, c, buffer_gray[c]);
112 }
113 }
114 if (image.numPlanes() >= 3) {
115 for (size_t c = 0; c < (size_t)image.cols(); c++) {
116 image.set(1, row, c, buffer_gray[c]);
117 image.set(2, row, c, buffer_gray[c]);
118 }
119 }
120 if (image.numPlanes() >= 4) {
121 for (size_t c = 0; c < (size_t)image.cols(); c++) {
122 image.set(3, row, c, 0xFF); // fully opaque
123 }
124 }
125 }
126
write_row_PALETTE8(uint32_t row,const void * buffer,size_t buffer_size_bytes)127 void FLIF_IMAGE::write_row_PALETTE8(uint32_t row, const void * buffer, size_t buffer_size_bytes)
128 {
129 if (buffer_size_bytes < image.cols() * sizeof(uint8_t))
130 return;
131
132 const uint8_t* buffer_gray = reinterpret_cast<const uint8_t*>(buffer);
133
134 if (image.numPlanes() >= 4) {
135 for (size_t c = 0; c < (size_t)image.cols(); c++) {
136 image.set(0, row, c, 0);
137 image.set(1, row, c, buffer_gray[c]);
138 image.set(2, row, c, 0);
139 image.set(3, row, c, 1);
140 }
141 }
142 }
143
read_row_RGBA8(uint32_t row,void * buffer,size_t buffer_size_bytes)144 void FLIF_IMAGE::read_row_RGBA8(uint32_t row, void* buffer, size_t buffer_size_bytes) {
145 if(buffer_size_bytes < image.cols() * sizeof(FLIF_RGBA))
146 return;
147
148 FLIF_RGBA* buffer_rgba = reinterpret_cast<FLIF_RGBA*>(buffer);
149 int rshift = 0;
150 int mult = 1;
151 ColorVal m=image.max(0);
152 while (m > 0xFF) { rshift++; m = m >> 1; } // in case the image has bit depth higher than 8
153 if ((m != 0) && m < 0xFF) mult = 0xFF / m;
154 if (image.palette) {
155 assert(image.numPlanes() >= 3);
156 // always color
157 for (size_t c = 0; c < (size_t) image.cols(); c++) {
158 buffer_rgba[c].r = ((image.palette_image->operator()(0, 0, image(1, row, c)) >> rshift) * mult) & 0xFF;
159 buffer_rgba[c].g = ((image.palette_image->operator()(1, 0, image(1, row, c)) >> rshift) * mult) & 0xFF;
160 buffer_rgba[c].b = ((image.palette_image->operator()(2, 0, image(1, row, c)) >> rshift) * mult) & 0xFF;
161 }
162 if (image.numPlanes() >= 4) {
163 for (size_t c = 0; c < (size_t) image.cols(); c++) {
164 buffer_rgba[c].a = ((image.palette_image->operator()(3, 0, image(1, row, c)) >> rshift) * mult) & 0xFF;
165 }
166 } else {
167 for (size_t c = 0; c < (size_t) image.cols(); c++) {
168 buffer_rgba[c].a = 0xFF; // fully opaque
169 }
170 }
171 } else {
172 if (image.numPlanes() >= 3) {
173 // color
174 for (size_t c = 0; c < (size_t) image.cols(); c++) {
175 buffer_rgba[c].r = ((image(0, row, c) >> rshift) * mult) & 0xFF;
176 buffer_rgba[c].g = ((image(1, row, c) >> rshift) * mult) & 0xFF;
177 buffer_rgba[c].b = ((image(2, row, c) >> rshift) * mult) & 0xFF;
178 }
179 } else {
180 // grayscale
181 for (size_t c = 0; c < (size_t) image.cols(); c++) {
182 buffer_rgba[c].r =
183 buffer_rgba[c].g =
184 buffer_rgba[c].b = ((image(0, row, c) >> rshift) * mult) & 0xFF;
185 }
186 }
187 if (image.numPlanes() >= 4) {
188 for (size_t c = 0; c < (size_t) image.cols(); c++) {
189 buffer_rgba[c].a = ((image(3, row, c) >> rshift) * mult) & 0xFF;
190 }
191 } else {
192 for (size_t c = 0; c < (size_t) image.cols(); c++) {
193 buffer_rgba[c].a = 0xFF; // fully opaque
194 }
195 }
196 }
197 }
198
read_row_GRAY8(uint32_t row,void * buffer,size_t buffer_size_bytes)199 void FLIF_IMAGE::read_row_GRAY8(uint32_t row, void* buffer, size_t buffer_size_bytes) {
200 if(buffer_size_bytes < image.cols()) return;
201
202 uint8_t* buffer_gray = reinterpret_cast<uint8_t*>(buffer);
203 int rshift = 0;
204 int mult = 1;
205 ColorVal m=image.max(0);
206 while (m > 0xFF) { rshift++; m = m >> 1; } // in case the image has bit depth higher than 8
207 if ((m != 0) && m < 0xFF) mult = 0xFF / m;
208
209 for (size_t c = 0; c < (size_t) image.cols(); c++) {
210 buffer_gray[c] = ((image(0, row, c) >> rshift) * mult) & 0xFF;
211 }
212 }
213
read_row_GRAY16(uint32_t row,void * buffer,size_t buffer_size_bytes)214 void FLIF_IMAGE::read_row_GRAY16(uint32_t row, void* buffer, size_t buffer_size_bytes) {
215 if(buffer_size_bytes < image.cols()) return;
216
217 uint16_t* buffer_gray = reinterpret_cast<uint16_t*>(buffer);
218 int rshift = 0;
219 int mult = 1;
220
221 for (size_t c = 0; c < (size_t) image.cols(); c++) {
222 buffer_gray[c] = ((image(0, row, c) >> rshift) * mult);
223 }
224 }
225
read_row_PALETTE8(uint32_t row,void * buffer,size_t buffer_size_bytes)226 void FLIF_IMAGE::read_row_PALETTE8(uint32_t row, void* buffer, size_t buffer_size_bytes) {
227 if(buffer_size_bytes < image.cols()) return;
228
229 assert(image.palette);
230
231 uint8_t* buffer_gray = reinterpret_cast<uint8_t*>(buffer);
232 for (size_t c = 0; c < (size_t) image.cols(); c++) {
233 buffer_gray[c] = image(1, row, c) & 0xFF;
234 }
235 }
236
237
write_row_RGBA16(uint32_t row,const void * buffer,size_t buffer_size_bytes)238 void FLIF_IMAGE::write_row_RGBA16(uint32_t row, const void* buffer, size_t buffer_size_bytes) {
239 if(buffer_size_bytes < image.cols() * sizeof(FLIF_RGBA16))
240 return;
241
242 const FLIF_RGBA16* buffer_rgba = reinterpret_cast<const FLIF_RGBA16*>(buffer);
243
244 if(image.numPlanes() >= 3) {
245 for (size_t c = 0; c < (size_t) image.cols(); c++) {
246 image.set(0, row, c, buffer_rgba[c].r);
247 image.set(1, row, c, buffer_rgba[c].g);
248 image.set(2, row, c, buffer_rgba[c].b);
249 }
250 }
251 if(image.numPlanes() >= 4) {
252 for (size_t c = 0; c < (size_t) image.cols(); c++) {
253 image.set(3, row, c, buffer_rgba[c].a);
254 }
255 }
256 }
257
read_row_RGBA16(uint32_t row,void * buffer,size_t buffer_size_bytes)258 void FLIF_IMAGE::read_row_RGBA16(uint32_t row, void* buffer, size_t buffer_size_bytes) {
259 if(buffer_size_bytes < image.cols() * sizeof(FLIF_RGBA16))
260 return;
261
262 FLIF_RGBA16* buffer_rgba = reinterpret_cast<FLIF_RGBA16*>(buffer);
263 int rshift = 0;
264 int mult = 1;
265 ColorVal m=image.max(0);
266 while (m > 0xFFFF) { rshift++; m = m >> 1; } // in the unlikely case that the image has bit depth higher than 16
267 if ((m != 0) && m < 0xFFFF) mult = 0xFFFF / m;
268
269 if(image.numPlanes() >= 3) {
270 // color
271 for (size_t c = 0; c < (size_t) image.cols(); c++) {
272 buffer_rgba[c].r = (image(0, row, c) >> rshift) * mult;
273 buffer_rgba[c].g = (image(1, row, c) >> rshift) * mult;
274 buffer_rgba[c].b = (image(2, row, c) >> rshift) * mult;
275 }
276 } else {
277 // grayscale
278 for (size_t c = 0; c < (size_t) image.cols(); c++) {
279 buffer_rgba[c].r =
280 buffer_rgba[c].g =
281 buffer_rgba[c].b = (image(0, row, c) >> rshift) * mult;
282 }
283 }
284 if(image.numPlanes() >= 4) {
285 for (size_t c = 0; c < (size_t) image.cols(); c++) {
286 buffer_rgba[c].a = (image(3, row, c) >> rshift) * mult;
287 }
288 } else {
289 for (size_t c = 0; c < (size_t) image.cols(); c++) {
290 buffer_rgba[c].a = 0xFFFF; // fully opaque
291 }
292 }
293 }
294
295 //=============================================================================
296
297 /*!
298 Notes about the C interface:
299
300 Only use types known to C.
301 Use types that are unambiguous across all compilers, like uint32_t.
302 Each function must have it's call convention set.
303 Exceptions must be caught no matter what.
304
305 */
306
307 //=============================================================================
308
309
310 extern "C" {
311
flif_create_image(uint32_t width,uint32_t height)312 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image(uint32_t width, uint32_t height) {
313 try
314 {
315 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
316 image->image.init(width, height, 0, 255, 4);
317 return image.release();
318 }
319 catch(...) {}
320 return 0;
321 }
322
flif_create_image_RGB(uint32_t width,uint32_t height)323 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image_RGB(uint32_t width, uint32_t height) {
324 try
325 {
326 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
327 image->image.init(width, height, 0, 255, 3);
328 return image.release();
329 }
330 catch(...) {}
331 return 0;
332 }
333
flif_create_image_GRAY(uint32_t width,uint32_t height)334 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image_GRAY(uint32_t width, uint32_t height) {
335 try
336 {
337 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
338 image->image.init(width, height, 0, 255, 1);
339 return image.release();
340 }
341 catch(...) {}
342 return 0;
343 }
344
flif_create_image_GRAY16(uint32_t width,uint32_t height)345 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image_GRAY16(uint32_t width, uint32_t height) {
346 try
347 {
348 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
349 image->image.init(width, height, 0, 65535, 1);
350 return image.release();
351 }
352 catch(...) {}
353 return 0;
354 }
355
flif_create_image_PALETTE(uint32_t width,uint32_t height)356 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image_PALETTE(uint32_t width, uint32_t height) {
357 try
358 {
359 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
360 image->image.semi_init(width, height, 0, 255, 4);
361 image->image.make_constant_plane(0,0);
362 image->image.make_constant_plane(2,0);
363 image->image.make_constant_plane(3,1);
364 image->image.real_init(true);
365 image->image.palette = true;
366 return image.release();
367 }
368 catch(...) {}
369 return 0;
370 }
371
flif_create_image_HDR(uint32_t width,uint32_t height)372 FLIF_DLLEXPORT FLIF_IMAGE* FLIF_API flif_create_image_HDR(uint32_t width, uint32_t height) {
373 try
374 {
375 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
376 #ifdef SUPPORT_HDR
377 image->image.init(width, height, 0, 65535, 4);
378 #else
379 image->image.init(width, height, 0, 255, 4);
380 #endif
381 return image.release();
382 }
383 catch(...) {}
384 return 0;
385 }
386
flif_import_image_RGBA(uint32_t width,uint32_t height,const void * rgba,uint32_t rgba_stride)387 FLIF_DLLIMPORT FLIF_IMAGE* FLIF_API flif_import_image_RGBA(uint32_t width, uint32_t height, const void* rgba, uint32_t rgba_stride) {
388 try
389 {
390 const int number_components = 4;
391 if (width == 0 || height == 0 || rgba_stride < width*number_components)
392 return 0;
393 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
394 image->image.init(width, height, 0, 255, number_components);
395 const uint8_t* buffer = static_cast<const uint8_t*>(rgba);
396 for (uint32_t row = 0; row < height; ++row) {
397 image->write_row_RGBA8(row, buffer, width*number_components);
398 buffer += rgba_stride;
399 }
400 return image.release();
401 }
402 catch (...) {}
403 return 0;
404 }
405
flif_import_image_RGB(uint32_t width,uint32_t height,const void * rgb,uint32_t rgb_stride)406 FLIF_DLLIMPORT FLIF_IMAGE* FLIF_API flif_import_image_RGB(uint32_t width, uint32_t height, const void* rgb, uint32_t rgb_stride) {
407 try
408 {
409 const int number_components = 3;
410 if (width == 0 || height == 0 || rgb_stride < width*number_components)
411 return 0;
412 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
413 image->image.init(width, height, 0, 255, number_components);
414 const uint8_t* buffer = static_cast<const uint8_t*>(rgb);
415 for (uint32_t row = 0; row < height; ++row) {
416 image->write_row_RGB8(row, buffer, width*number_components);
417 buffer += rgb_stride;
418 }
419 return image.release();
420 }
421 catch (...) {}
422 return 0;
423 }
424
flif_import_image_GRAY(uint32_t width,uint32_t height,const void * gray,uint32_t gray_stride)425 FLIF_DLLIMPORT FLIF_IMAGE* FLIF_API flif_import_image_GRAY(uint32_t width, uint32_t height, const void* gray, uint32_t gray_stride) {
426 try
427 {
428 const int number_components = 1;
429 if (width == 0 || height == 0 || gray_stride < width*number_components)
430 return 0;
431 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
432 image->image.init(width, height, 0, 255, number_components);
433 const uint8_t* buffer = static_cast<const uint8_t*>(gray);
434 for (uint32_t row = 0; row < height; ++row) {
435 image->write_row_GRAY8(row, buffer, width*number_components);
436 buffer += gray_stride;
437 }
438 return image.release();
439 }
440 catch (...) {}
441 return 0;
442 }
443
flif_import_image_GRAY16(uint32_t width,uint32_t height,const void * gray,uint32_t gray_stride)444 FLIF_DLLIMPORT FLIF_IMAGE* FLIF_API flif_import_image_GRAY16(uint32_t width, uint32_t height, const void* gray, uint32_t gray_stride) {
445 try
446 {
447 const int number_components = 1;
448 if (width == 0 || height == 0 || gray_stride < width*number_components)
449 return 0;
450 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
451 image->image.init(width, height, 0, 65535, number_components);
452 const uint16_t* buffer = static_cast<const uint16_t*>(gray);
453 for (uint32_t row = 0; row < height; ++row) {
454 image->write_row_GRAY16(row, buffer, (width * number_components * sizeof(uint16_t)));
455 buffer += gray_stride;
456 }
457 return image.release();
458 }
459 catch (...) {}
460 return 0;
461 }
462
flif_import_image_PALETTE(uint32_t width,uint32_t height,const void * gray,uint32_t gray_stride)463 FLIF_DLLIMPORT FLIF_IMAGE* FLIF_API flif_import_image_PALETTE(uint32_t width, uint32_t height, const void* gray, uint32_t gray_stride) {
464 try
465 {
466 const int number_components = 1;
467 if (width == 0 || height == 0 || gray_stride < width*number_components)
468 return 0;
469 std::unique_ptr<FLIF_IMAGE> image(new FLIF_IMAGE());
470 image->image.semi_init(width, height, 0, 255, 4);
471 image->image.make_constant_plane(0,0);
472 image->image.make_constant_plane(2,0);
473 image->image.make_constant_plane(3,1);
474 image->image.real_init(true);
475 image->image.palette = true;
476 const uint8_t* buffer = static_cast<const uint8_t*>(gray);
477 for (uint32_t row = 0; row < height; ++row) {
478 image->write_row_PALETTE8(row, buffer, width*number_components);
479 buffer += gray_stride;
480 }
481 return image.release();
482 }
483 catch (...) {}
484 return 0;
485 }
486
flif_destroy_image(FLIF_IMAGE * image)487 FLIF_DLLEXPORT void FLIF_API flif_destroy_image(FLIF_IMAGE* image) {
488 // delete should never let exceptions out
489 delete image;
490 }
491
flif_image_get_width(FLIF_IMAGE * image)492 FLIF_DLLEXPORT uint32_t FLIF_API flif_image_get_width(FLIF_IMAGE* image) {
493 try
494 {
495 return image->image.cols();
496 }
497 catch(...) {}
498 return 0;
499 }
500
flif_image_get_height(FLIF_IMAGE * image)501 FLIF_DLLEXPORT uint32_t FLIF_API flif_image_get_height(FLIF_IMAGE* image) {
502 try
503 {
504 return image->image.rows();
505 }
506 catch(...) {}
507 return 0;
508 }
509
flif_image_get_depth(FLIF_IMAGE * image)510 FLIF_DLLEXPORT uint8_t FLIF_API flif_image_get_depth(FLIF_IMAGE* image) {
511 try
512 {
513 return ( image->image.max(0) > 0xFF ? 16 : 8 );
514 }
515 catch(...) {}
516 return 0;
517 }
518
flif_image_get_nb_channels(FLIF_IMAGE * image)519 FLIF_DLLEXPORT uint8_t FLIF_API flif_image_get_nb_channels(FLIF_IMAGE* image) {
520 try
521 {
522 int nb = image->image.numPlanes();
523 if (nb > 4) nb = 4; // there could be an extra plane for FRA
524 return nb;
525 }
526 catch(...) {}
527 return 0;
528 }
529
flif_image_get_palette_size(FLIF_IMAGE * image)530 FLIF_DLLEXPORT uint32_t FLIF_API flif_image_get_palette_size(FLIF_IMAGE* image) {
531 try
532 {
533 uint32_t nb = 0;
534 if (image->image.palette && image->image.palette_image) nb = image->image.palette_image->cols();
535 return nb;
536 }
537 catch(...) {}
538 return 0;
539 }
540
flif_image_get_palette(FLIF_IMAGE * image,void * buffer)541 FLIF_DLLEXPORT void FLIF_API flif_image_get_palette(FLIF_IMAGE* image, void* buffer) {
542 try
543 {
544 int nb = 0;
545 if (image->image.palette && image->image.palette_image) nb = image->image.palette_image->cols();
546 FLIF_RGBA* buffer_rgba = reinterpret_cast<FLIF_RGBA*>(buffer);
547 for (int i=0; i<nb; i++) {
548 buffer_rgba[i].r = image->image.palette_image->operator()(0,0,i);
549 buffer_rgba[i].g = image->image.palette_image->operator()(1,0,i);
550 buffer_rgba[i].b = image->image.palette_image->operator()(2,0,i);
551 if(image->image.numPlanes() >= 4) {
552 buffer_rgba[i].a = image->image.palette_image->operator()(3,0,i);
553 } else {
554 buffer_rgba[i].a = 255;
555 }
556 }
557 }
558 catch(...) {}
559 }
560
flif_image_set_palette(FLIF_IMAGE * image,const void * buffer,uint32_t palette_size)561 FLIF_DLLEXPORT void FLIF_API flif_image_set_palette(FLIF_IMAGE* image, const void* buffer, uint32_t palette_size) {
562 try
563 {
564 int nb = palette_size;
565 image->image.palette = true;
566 image->image.palette_image = std::make_shared<Image>(nb,1,0,255,4);
567 const FLIF_RGBA* buffer_rgba = reinterpret_cast<const FLIF_RGBA*>(buffer);
568 for (int i=0; i<nb; i++) {
569 image->image.palette_image->set(0,0,i,buffer_rgba[i].r);
570 image->image.palette_image->set(1,0,i,buffer_rgba[i].g);
571 image->image.palette_image->set(2,0,i,buffer_rgba[i].b);
572 image->image.palette_image->set(3,0,i,buffer_rgba[i].a);
573 }
574 }
575 catch(...) {}
576 }
577
flif_image_get_frame_delay(FLIF_IMAGE * image)578 FLIF_DLLEXPORT uint32_t FLIF_API flif_image_get_frame_delay(FLIF_IMAGE* image) {
579 try
580 {
581 return image->image.frame_delay;
582 }
583 catch(...) {}
584 return 0;
585 }
586
flif_image_set_frame_delay(FLIF_IMAGE * image,uint32_t delay)587 FLIF_DLLEXPORT void FLIF_API flif_image_set_frame_delay(FLIF_IMAGE* image, uint32_t delay) {
588 try
589 {
590 image->image.frame_delay = delay;
591 }
592 catch(...) {}
593 }
594
flif_image_set_metadata(FLIF_IMAGE * image,const char * chunkname,const unsigned char * data,size_t length)595 FLIF_DLLEXPORT void FLIF_API flif_image_set_metadata(FLIF_IMAGE* image, const char* chunkname, const unsigned char* data, size_t length) {
596 try
597 {
598 image->image.set_metadata(chunkname, data, length);
599 }
600 catch(...) {}
601 }
602
flif_image_get_metadata(FLIF_IMAGE * image,const char * chunkname,unsigned char ** data,size_t * length)603 FLIF_DLLIMPORT uint8_t FLIF_API flif_image_get_metadata(FLIF_IMAGE* image, const char* chunkname, unsigned char** data, size_t* length){
604 uint8_t ret = 0;
605 try
606 {
607 ret = image->image.get_metadata(chunkname, data, length);
608 }
609 catch(...) {}
610
611 return ret;
612 }
613
flif_image_free_metadata(FLIF_IMAGE * image,unsigned char * data)614 FLIF_DLLIMPORT void FLIF_API flif_image_free_metadata(FLIF_IMAGE* image, unsigned char* data){
615 try
616 {
617 image->image.free_metadata(data);
618 }
619 catch(...) {}
620 }
621
flif_image_write_row_RGBA8(FLIF_IMAGE * image,uint32_t row,const void * buffer,size_t buffer_size_bytes)622 FLIF_DLLEXPORT void FLIF_API flif_image_write_row_RGBA8(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes) {
623 try
624 {
625 image->write_row_RGBA8(row, buffer, buffer_size_bytes);
626 }
627 catch(...) {}
628 }
629
flif_image_read_row_RGBA8(FLIF_IMAGE * image,uint32_t row,void * buffer,size_t buffer_size_bytes)630 FLIF_DLLEXPORT void FLIF_API flif_image_read_row_RGBA8(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes) {
631 try
632 {
633 image->read_row_RGBA8(row, buffer, buffer_size_bytes);
634 }
635 catch(...) {}
636 }
637
flif_image_write_row_GRAY8(FLIF_IMAGE * image,uint32_t row,const void * buffer,size_t buffer_size_bytes)638 FLIF_DLLEXPORT void FLIF_API flif_image_write_row_GRAY8(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes) {
639 try
640 {
641 image->write_row_GRAY8(row, buffer, buffer_size_bytes);
642 }
643 catch(...) {}
644 }
645
flif_image_write_row_GRAY16(FLIF_IMAGE * image,uint32_t row,const void * buffer,size_t buffer_size_bytes)646 FLIF_DLLEXPORT void FLIF_API flif_image_write_row_GRAY16(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes) {
647 try
648 {
649 image->write_row_GRAY16(row, buffer, buffer_size_bytes);
650 }
651 catch(...) {}
652 }
653
flif_image_read_row_GRAY8(FLIF_IMAGE * image,uint32_t row,void * buffer,size_t buffer_size_bytes)654 FLIF_DLLEXPORT void FLIF_API flif_image_read_row_GRAY8(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes) {
655 try
656 {
657 image->read_row_GRAY8(row, buffer, buffer_size_bytes);
658 }
659 catch(...) {}
660 }
661
flif_image_read_row_GRAY16(FLIF_IMAGE * image,uint32_t row,void * buffer,size_t buffer_size_bytes)662 FLIF_DLLEXPORT void FLIF_API flif_image_read_row_GRAY16(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes) {
663 try
664 {
665 image->read_row_GRAY16(row, buffer, buffer_size_bytes);
666 }
667 catch(...) {}
668 }
669
flif_image_write_row_PALETTE8(FLIF_IMAGE * image,uint32_t row,const void * buffer,size_t buffer_size_bytes)670 FLIF_DLLEXPORT void FLIF_API flif_image_write_row_PALETTE8(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes) {
671 try
672 {
673 image->write_row_PALETTE8(row, buffer, buffer_size_bytes);
674 }
675 catch(...) {}
676 }
677
flif_image_read_row_PALETTE8(FLIF_IMAGE * image,uint32_t row,void * buffer,size_t buffer_size_bytes)678 FLIF_DLLEXPORT void FLIF_API flif_image_read_row_PALETTE8(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes) {
679 try
680 {
681 image->read_row_PALETTE8(row, buffer, buffer_size_bytes);
682 }
683 catch(...) {}
684 }
685
flif_image_write_row_RGBA16(FLIF_IMAGE * image,uint32_t row,const void * buffer,size_t buffer_size_bytes)686 FLIF_DLLEXPORT void FLIF_API flif_image_write_row_RGBA16(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes) {
687 try
688 {
689 image->write_row_RGBA16(row, buffer, buffer_size_bytes);
690 }
691 catch(...) {}
692 }
693
flif_image_read_row_RGBA16(FLIF_IMAGE * image,uint32_t row,void * buffer,size_t buffer_size_bytes)694 FLIF_DLLEXPORT void FLIF_API flif_image_read_row_RGBA16(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes) {
695 try
696 {
697 image->read_row_RGBA16(row, buffer, buffer_size_bytes);
698 }
699 catch(...) {}
700 }
701
flif_free_memory(void * buffer)702 FLIF_DLLEXPORT void FLIF_API flif_free_memory(void* buffer) {
703 delete [] reinterpret_cast<uint8_t*>(buffer);
704 }
705
706 } // extern "C"
707