FloatImg/funcs/fimg-png.c

226 lines
5.3 KiB
C
Raw Normal View History

2019-03-04 02:22:55 +11:00
/*
* Lecture des images PNG
2020-11-10 00:27:28 +11:00
* ----------------------
2019-03-04 02:22:55 +11:00
*/
#include <stdio.h>
#include <stdlib.h>
2021-05-20 18:31:28 +11:00
#include <stdint.h>
2019-03-04 02:22:55 +11:00
#include <string.h>
#include <pnglite.h>
#include "../floatimg.h"
2019-12-19 01:34:10 +11:00
extern int verbosity;
2019-03-04 02:22:55 +11:00
/* --------------------------------------------------------------------- */
/*
* warning : this func has been tested only with
* RGB (3x8bits) PNG files
2020-11-10 00:27:28 +11:00
*
* Attention : certains fichiers, tels que ceux
* produits par ImageMagick ne sont pas lisibles
* par cette fonction :(
2019-03-04 02:22:55 +11:00
*/
int fimg_create_from_png(char *filename, FloatImg *fimg)
{
png_t png;
int foo, idx;
unsigned char *datas, *ptr;
int datasize;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, filename, fimg);
#endif
2019-12-27 22:25:33 +11:00
/* We MUST clear the fimg destination header first */
2019-09-10 02:26:32 +11:00
memset(fimg, 0, sizeof(FloatImg));
2019-03-04 02:22:55 +11:00
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
foo = png_open_file_read(&png, filename);
if (PNG_NO_ERROR != foo) {
2019-09-10 02:26:32 +11:00
fprintf(stderr, "%s :\n\topen_file '%s' = %d %s\n", __func__,
2020-11-10 00:27:28 +11:00
filename, foo, png_error_string(foo));
png_close_file(&png);
2019-03-04 02:22:55 +11:00
return foo;
}
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s opened\n", filename);
#endif
2020-11-10 00:27:28 +11:00
if (verbosity) {
printf("----------- %s ---------\n", filename);
png_print_info(&png); puts("");
fflush(stdout);
}
2019-03-04 02:22:55 +11:00
if ( 3 != png.bpp ) {
2019-09-13 04:33:08 +11:00
fprintf(stderr, "bpp format %d of '%s' not supported\n",
2019-03-04 02:22:55 +11:00
png.color_type, filename);
return -21;
}
2020-11-10 00:27:28 +11:00
datasize = png.width * png.height * png.bpp;
2019-03-04 02:22:55 +11:00
datas = malloc(datasize);
if (NULL==datas) {
fprintf(stderr, "%s : fatal memory failure\n", __func__);
exit(1);
}
memset(fimg, 0, sizeof(FloatImg));
foo = fimg_create(fimg, png.width, png.height, 3);
if (foo) {
fprintf(stderr, "can't create fimg\n");
exit(1);
}
2020-11-10 00:27:28 +11:00
/* I GET AN 'Unknown file error' HERE, WHY ???*/
2019-03-04 02:22:55 +11:00
foo = png_get_data(&png, datas);
if (PNG_NO_ERROR != foo) {
2020-11-10 00:27:28 +11:00
fprintf(stderr, "err in '%s:%s' :\n\tpng_get_data -> %d = %s\n\n",
__FILE__, __func__, foo, png_error_string(foo));
png_close_file(&png);
2019-03-04 02:22:55 +11:00
return foo;
}
ptr = datas;
2022-02-05 09:39:52 +11:00
for (idx=0; idx<(int)(png.width*png.height); idx++) {
2019-03-04 02:22:55 +11:00
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
}
free(datas);
png_close_file(&png);
// fprintf(stderr, "png closed...\n");
return foo;
}
/* --------------------------------------------------------------------- */
/*
* warning : this func has been tested only with
* RGB (3x8bits) PNG files
*/
int fimg_load_from_png(char *filename, FloatImg *fimg)
{
png_t png;
int foo, idx, datasize;
unsigned char *datas, *ptr;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %-25s ( '%s' %p )\n", __func__, filename, fimg);
#endif
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
foo = png_open_file_read(&png, filename);
if (PNG_NO_ERROR != foo) {
#if DEBUG_LEVEL
fprintf(stderr, "open png -> %d\n", foo);
#endif
return foo;
}
// puts(""); png_print_info(&png); puts("");
if ( 3 != png.bpp ) { /* TO BE PATCHED */
fprintf(stderr, "format of '%s' not supported\n", filename);
return -21;
}
/* check if floatimg and PNG have the same size */
2022-02-05 09:39:52 +11:00
if ((fimg->width != (int)png.width) || (fimg->height != (int)png.height)) {
2019-03-04 02:22:55 +11:00
fprintf(stderr, "%s : fatal error on images sizes\n", __func__);
exit(1);
}
2022-02-05 09:39:52 +11:00
datasize = png.width * png.height * png.bpp;
2019-03-04 02:22:55 +11:00
datas = malloc(datasize);
if (NULL==datas) {
fprintf(stderr, "%s : fatal memory failure\n", __func__);
exit(1);
}
foo = png_get_data(&png, datas);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : read png -> %d\n",
__func__, foo);
return foo;
}
2019-09-10 02:26:32 +11:00
2019-03-04 02:22:55 +11:00
ptr = datas;
2022-02-05 09:39:52 +11:00
for (idx=0; idx<(int)(png.width*png.height); idx++) {
2019-03-04 02:22:55 +11:00
fimg->R[idx] = (float)*ptr++;
fimg->G[idx] = (float)*ptr++;
fimg->B[idx] = (float)*ptr++;
}
free(datas);
png_close_file(&png);
return 0;
}
/* --------------------------------------------------------------------- */
2019-12-14 04:18:07 +11:00
/* nouveau 13 decembre 2019 */
2019-03-04 02:22:55 +11:00
int fimg_save_as_png(FloatImg *src, char *outname, int flags)
{
2019-12-14 04:18:07 +11:00
png_t png;
int foo, sz, idx;
unsigned char *bytes, *bptr;
double maximum, fk;
#if DEBUG_LEVEL
2021-02-11 02:19:15 +11:00
fprintf(stderr, ">>> %-25s ( %p '%s' 0x%x )\n", __func__, src, outname, flags);
2019-12-14 04:18:07 +11:00
#endif
2019-03-04 02:22:55 +11:00
2022-02-05 09:39:52 +11:00
if (flags) {
fprintf(stderr, "*** in %s, flags are %08x\n", __func__, flags);
}
2019-12-14 04:18:07 +11:00
/* convert ou floating datas to a byte/rgb array */
/* first, alloc a buffer */
sz = src->width * src->height;
bytes = calloc(sz, 3);
if (NULL==bytes) {
fprintf(stderr, "%s : no mem ?\n", __func__);
exit(3);
}
/* compute max value */
maximum = (double)fimg_get_maxvalue(src);
fk = maximum / 255.0;
2020-02-20 01:59:46 +11:00
if (verbosity > 1)
fprintf(stderr, "%s: max val %g fk %g\n", __func__, maximum, fk);
2019-12-14 04:18:07 +11:00
/* massage des pixels */
bptr = bytes;
for (idx=0; idx<sz; idx++) {
*bptr++ = (unsigned char) (src->R[idx] / fk);
*bptr++ = (unsigned char) (src->G[idx] / fk);
*bptr++ = (unsigned char) (src->B[idx] / fk);
}
2019-03-04 02:22:55 +11:00
2019-12-14 04:18:07 +11:00
memset(&png, 0, sizeof(png_t));
png_init(NULL, NULL); /* this is VITAL ! */
2019-03-04 02:22:55 +11:00
2019-12-14 04:18:07 +11:00
foo = png_open_file_write(&png, outname);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : open_file_write -> %d\n",
__func__, foo);
return foo;
}
foo = png_set_data(&png, src->width, src->height, 8, PNG_TRUECOLOR, bytes);
if (PNG_NO_ERROR != foo) {
fprintf(stderr, "error in '%s' : set_data -> %d\n",
__func__, foo);
return foo;
}
png_close_file(&png);
free(bytes); /* yolo ? */
return 0;
2019-03-04 02:22:55 +11:00
}
/* --------------------------------------------------------------------- */