Skip to content

Commit

Permalink
Input/output files
Browse files Browse the repository at this point in the history
  • Loading branch information
kornelski committed Jul 24, 2013
1 parent 61646e5 commit f49c0e5
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ The goal of this tool is to make RGB/RGBA PNG images more compressible, assuming

##Usage

posterize [ -v ] [ -d ] [ -q <quality> ] [ levels ] < input.png > output.png
posterize [ -v ] [ -d ] [ -Q <quality> ] [ levels ] -- [ input.png ] [ output.png ]

* `levels` — Number of levels to use (2-255). Lower number gives worse quality, but smaller file.
* `-q num` — Picks minimum number of levels needed to achieve given quality. `num` is quality 0-100 (100 is best, similar to JPEG). Number of levels is optional if quality is specified.
* `-Q num` — Picks minimum number of levels needed to achieve given quality. `num` is quality 0-100 (100 is best, similar to JPEG). Number of levels is optional if quality is specified.
* `-d` — Enables simple ordered dithering.
* `-v` — Verbose output. Prints mean square error (MSE) caused by posterization.

Only stdin/stdout is supported.
If input/output files are not specified then stdin/stdout is used respectively.

Posterized images can be further compressed using [PNGOUT](http:https://www.jonof.id.au/kenutils) or similar. Try [ImageOptim](http:https://imageoptim.com).

Expand Down
38 changes: 30 additions & 8 deletions posterize.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,12 @@ static void usage(const char *exepath)
const char *name = strrchr(exepath, '/');
if (name) name++; else name = exepath;
fprintf(stderr, "Median Cut PNG Posterizer 1.6 (2013).\n" \
"Usage: %s [-vd] [-Q <quality>] [levels]\n\n" \
"Usage: %s [-vd] [-Q <quality>] [levels] [input file] [output file]\n\n" \
"Specify number of levels (2-255) or quality (10-100).\n" \
"-d enables dithering\n" \
"-v verbose output (to stderr)\n\n" \
"Image is always read from stdin and written to stdout.\n"
"%s -d 16 < in.png > out.png\n", name, name);
"If files are not specified stdin and stdout is used.\n"
"%s -Q 95 in.png out.png\n", name, name);
}

// performs voronoi iteration (mapping histogram to palette and creating new palette from remapped values)
Expand Down Expand Up @@ -457,7 +457,26 @@ int main(int argc, char *argv[])
}
}

if (argc != argn || maxlevels < 2 || maxlevels > 255) {
if (maxlevels < 2 || maxlevels > 255) {
usage(argv[0]);
return 1;
}

FILE *input = stdin;
const char *input_name = "stdin";
if (argn < argc && 0 != strcmp("-",argv[argn])) {
input_name = argv[argn++];
input = fopen(input_name, "rb");
}

FILE *output = stdout;
const char *output_name = "stdout";
if (argn < argc && 0 != strcmp("-",argv[argn])) {
output_name = argv[argn++];
output = fopen(output_name, "wb");
}

if (argn != argc) {
usage(argv[0]);
return 1;
}
Expand All @@ -468,18 +487,21 @@ int main(int argc, char *argv[])
png24_image img;
pngquant_error retval;

if ((retval = rwpng_read_image24(stdin, &img))) {
fprintf(stderr, "Error: cannot read PNG from stdin\n");
if ((retval = rwpng_read_image24(input, &img))) {
fprintf(stderr, "Error: cannot read PNG from %s\n", input_name);
return retval;
}
if (input != stdin) fclose(input);

image_gamma = 1.0/img.gamma;

posterize(&img, maxlevels, maxerror, dither, verbose);

if ((retval = rwpng_write_image24(stdout, &img))) {
fprintf(stderr, "Error: cannot write PNG to stdout\n");
if ((retval = rwpng_write_image24(output, &img))) {
fprintf(stderr, "Error: cannot write PNG to %s\n", output_name);
return retval;
}
if (output != stdout) fclose(output);

return 0;
}
Expand Down
5 changes: 4 additions & 1 deletion rwpng.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ pngquant_error rwpng_read_image24_libpng(FILE *infile, png24_image *mainprog_ptr

pngquant_error rwpng_read_image24(FILE *infile, png24_image *input_image_p)
{
if (!infile) return READ_ERROR;

#if USE_COCOA
return rwpng_read_image24_cocoa(infile, input_image_p);
#else
Expand All @@ -219,8 +221,9 @@ pngquant_error rwpng_read_image24(FILE *infile, png24_image *input_image_p)

static pngquant_error rwpng_write_image_init(rwpng_png_image *mainprog_ptr, png_structpp png_ptr_p, png_infopp info_ptr_p, FILE *outfile, int fast_compression)
{
/* could also replace libpng warning-handler (final NULL), but no need: */
if (!outfile) return CANT_WRITE_ERROR;

/* could also replace libpng warning-handler (final NULL), but no need: */
*png_ptr_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr, rwpng_error_handler, NULL);

if (!(*png_ptr_p)) {
Expand Down

0 comments on commit f49c0e5

Please sign in to comment.