/* * Lecture des images PNG * ---------------------- */ #include #include #include #include #include "../floatimg.h" extern int verbosity; /* --------------------------------------------------------------------- */ /* * warning : this func has been tested only with * RGB (3x8bits) PNG files * * Attention : certains fichiers, tels que ceux * produits par ImageMagick ne sont pas lisibles * par cette fonction :( */ 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 /* We MUST clear the fimg destination header first */ memset(fimg, 0, sizeof(FloatImg)); 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) { fprintf(stderr, "%s :\n\topen_file '%s' = %d %s\n", __func__, filename, foo, png_error_string(foo)); png_close_file(&png); return foo; } #if DEBUG_LEVEL > 1 fprintf(stderr, "%s opened\n", filename); #endif if (verbosity) { printf("----------- %s ---------\n", filename); png_print_info(&png); puts(""); fflush(stdout); } if ( 3 != png.bpp ) { fprintf(stderr, "bpp format %d of '%s' not supported\n", png.color_type, filename); return -21; } datasize = png.width * png.height * png.bpp; 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); } /* I GET AN 'Unknown file error' HERE, WHY ???*/ foo = png_get_data(&png, datas); if (PNG_NO_ERROR != foo) { 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); return foo; } ptr = datas; for (idx=0; idxR[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 */ if ((fimg->width != png.width) || (fimg->height != png.height)) { fprintf(stderr, "%s : fatal error on images sizes\n", __func__); exit(1); } datasize = png.width * png.height * png.bpp; 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; } ptr = datas; for (idx=0; idxR[idx] = (float)*ptr++; fimg->G[idx] = (float)*ptr++; fimg->B[idx] = (float)*ptr++; } free(datas); png_close_file(&png); return 0; } /* --------------------------------------------------------------------- */ /* nouveau 13 decembre 2019 */ int fimg_save_as_png(FloatImg *src, char *outname, int flags) { png_t png; int foo, sz, idx; unsigned char *bytes, *bptr; double maximum, fk; #if DEBUG_LEVEL fprintf(stderr, ">>> %-25s ( %p '%s' %x )\n", __func__, src, outname, flags); #endif /* 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; if (verbosity > 1) fprintf(stderr, "%s: max val %g fk %g\n", __func__, maximum, fk); /* massage des pixels */ bptr = bytes; for (idx=0; idxR[idx] / fk); *bptr++ = (unsigned char) (src->G[idx] / fk); *bptr++ = (unsigned char) (src->B[idx] / fk); } memset(&png, 0, sizeof(png_t)); png_init(NULL, NULL); /* this is VITAL ! */ 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; } /* --------------------------------------------------------------------- */