From 7cc6746ff112ccd3fafef1be1a4843a5d972a49c Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Wed, 12 May 2021 09:34:06 +0300 Subject: [PATCH] improved shade-lut generation --- tools/pngdump/Makefile | 2 +- tools/pngdump/image.c | 21 ++++++---- tools/pngdump/image.h | 8 ++-- tools/pngdump/main.c | 107 ++++++++++++++++++++++++++++++++---------------- 4 files changed, 92 insertions(+), 46 deletions(-) diff --git a/tools/pngdump/Makefile b/tools/pngdump/Makefile index f6cbd9d..9e6fa6a 100644 --- a/tools/pngdump/Makefile +++ b/tools/pngdump/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -pedantic -Wall -g +CFLAGS = -pedantic -Wall -Wno-unused-function -g LDFLAGS = -lpng -lz pngdump: main.o image.o quant.o diff --git a/tools/pngdump/image.c b/tools/pngdump/image.c index 5602354..b3069f7 100644 --- a/tools/pngdump/image.c +++ b/tools/pngdump/image.c @@ -102,18 +102,26 @@ int load_image(struct image *img, const char *fname) int save_image(struct image *img, const char *fname) { - int i, chan_bits, coltype; FILE *fp; - png_struct *png; - png_info *info; - png_text txt; - unsigned char **scanline = 0; - unsigned char *pptr; + int res; if(!(fp = fopen(fname, "wb"))) { fprintf(stderr, "save_image: failed to open: %s: %s\n", fname, strerror(errno)); return -1; } + res = save_image_file(img, fp); + fclose(fp); + return res; +} + +int save_image_file(struct image *img, FILE *fp) +{ + int i, chan_bits, coltype; + png_struct *png; + png_info *info; + png_text txt; + unsigned char **scanline = 0; + unsigned char *pptr; if(!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) { fclose(fp); @@ -182,7 +190,6 @@ int save_image(struct image *img, const char *fname) png_write_png(png, info, 0, 0); png_destroy_write_struct(&png, &info); free(scanline); - fclose(fp); return 0; } diff --git a/tools/pngdump/image.h b/tools/pngdump/image.h index d5aaccf..f86de94 100644 --- a/tools/pngdump/image.h +++ b/tools/pngdump/image.h @@ -1,6 +1,8 @@ #ifndef IMAGE_H_ #define IMAGE_H_ +#include + struct cmapent { unsigned char r, g, b; }; @@ -19,6 +21,7 @@ struct image { int alloc_image(struct image *img, int x, int y, int bpp); int load_image(struct image *img, const char *fname); int save_image(struct image *img, const char *fname); +int save_image_file(struct image *img, FILE *fp); int cmp_image(struct image *a, struct image *b); @@ -29,8 +32,7 @@ unsigned int get_pixel(struct image *img, int x, int y); unsigned int get_pixel_rgb(struct image *img, int x, int y, unsigned int *rgb); void put_pixel(struct image *img, int x, int y, unsigned int pix); -void quantize_image(struct image *img, int maxcol); -int gen_shade_lut(struct image *img, int levels, int maxcol, struct cmapent *shade_cmap, - int *shade_lut); +int quantize_image(struct image *img, int maxcol); +int gen_shades(struct image *img, int levels, int maxcol, int *shade_lut); #endif /* IMAGE_H_ */ diff --git a/tools/pngdump/main.c b/tools/pngdump/main.c index 9f281cc..2d1922e 100644 --- a/tools/pngdump/main.c +++ b/tools/pngdump/main.c @@ -6,33 +6,39 @@ #include "image.h" enum { + MODE_PNG, MODE_PIXELS, MODE_CMAP, - MODE_INFO, - MODE_SHADE_CMAP, - MODE_SHADE_LUT + MODE_INFO }; void print_usage(const char *argv0); int main(int argc, char **argv) { - int i, mode = 0; + int i, j, mode = 0; int text = 0; int renibble = 0; char *outfname = 0; + char *slut_fname = 0; char *infiles[256]; int num_infiles = 0; struct image img, tmpimg; FILE *out = stdout; - struct cmapent shade_cmap[256] = {0}; + FILE *slut_out = 0; int *shade_lut = 0; + int *lutptr; int shade_levels = 8; + int maxcol = 0; for(i=1; i 256) { + fprintf(stderr, "-C must be followed by the number of colors to reduce down to\n"); + return 1; + } break; case 's': @@ -76,6 +81,14 @@ int main(int argc, char **argv) outfname = argv[i]; break; + case 'S': + if(!argv[++i]) { + fprintf(stderr, "-S must be followed by a filename\n"); + return 1; + } + slut_fname = argv[i]; + break; + case 'h': print_usage(argv[0]); return 0; @@ -123,6 +136,47 @@ int main(int argc, char **argv) overlay_key(&tmpimg, 0, &img); } + /* generate shading LUT and quantize image as necessary */ + if(slut_fname) { + if(img.bpp > 8) { + fprintf(stderr, "shading LUT generation is only supported for indexed color images\n"); + return 1; + } + if(!(slut_out = fopen(slut_fname, "wb"))) { + fprintf(stderr, "failed to open shading LUT output file: %s: %s\n", slut_fname, strerror(errno)); + return 1; + } + + if(!maxcol) maxcol = 256; + + if(!(shade_lut = malloc(maxcol * shade_levels * sizeof *shade_lut))) { + fprintf(stderr, "failed to allocate shading look-up table\n"); + return 1; + } + + gen_shades(&img, shade_levels, maxcol, shade_lut); + + lutptr = shade_lut; + for(i=0; i: specify output file (default: stdout)\n"); printf(" -p: dump pixels (default)\n"); + printf(" -P: output in PNG format\n"); printf(" -c: dump colormap (palette) entries\n"); - printf(" -C: generate shading colormap\n"); - printf(" -S: generate shading LUT\n"); + printf(" -C : reduce image down to specified number of colors\n"); + printf(" -S : generate and output shading LUT\n"); printf(" -s : used in conjunction with -C or -S (default: 8)\n"); printf(" -i: print image information\n"); - printf(" -t: dump as text\n"); + printf(" -t: output as text when possible\n"); printf(" -n: swap the order of nibbles (for 4bpp)\n"); printf(" -h: print usage and exit\n"); } -- 1.7.10.4