/* Copyright (C) 2009-2021 Artifex Software Inc. All rights reserved. This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of the license contained in the file LICENSE in this distribution. For more information about licensing, please refer to http://www.ghostscript.com/licensing/. For information on commercial licensing, go to http://www.artifex.com/licensing/ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, CA 94945, U.S.A., +1(415)492-9861. */ /* $Id: $ */ /* thresh_remap [-c] [-p] [-q] [-o outputfile] threshold.tos [transfer.dat][> threshold.bin] threshold.tos is the file produced by either gen_stochastic or gen_ordered consisting of a header line that has the width and height (format "# W=%d H=%d" followed by a list of pixels in order of painting, one line per pixel format: %d %d transfer.dat is optional. If missing, the thresold array will have 1/256 of the total at each level. The format of the transfer.dat file is: %d %f where the first integer is the level and the second float is the brightness (0 == dark, similar to L* value). The 'level' is in the range 0 to 256. The final entry should be 256 WHITEVALUE. If the final measurement is not level 256, then the assumed WHITEVALUE will be 1.0000 -c outputs the count of pixels at each of 256 levels -p generates output in PostScript HalftoneType 3 format -q suppresses output (except -c) -o specifies the file for the binary or PostScript remapped threshold array */ #include #include #define MAX_WIDTH 256 #define MAX_HEIGHT 256 int main( int argc, char *argv[]) { FILE *tfile, *ofile = stdout, *lfile = NULL; int code, optargc, i, level, width, height, num_pix, num_lin, cur_pix; int counts=0, quiet=0; int thresh_order [MAX_WIDTH*MAX_HEIGHT][2], cur_level, lin_levels[257]; double cur_value, lin_values[257], delta_value; unsigned char thresh[MAX_WIDTH*MAX_HEIGHT]; char *ofilename, format = 'b'; int pixcounts[256]; if (argc < 2) goto usage; /* process options */ optargc = 1; while (argv[optargc][0] == '-') { switch (argv[optargc][1]) { case 'c': counts = 1; break; case 'o': if (argv[optargc][2] == 0) ofilename = argv[++optargc]; else ofilename = &argv[optargc][2]; ofile = fopen(ofilename, "w"); if (ofile == NULL) { fprintf(stderr, "\nUnable to open outputfile: '%s'\n", ofilename); exit(1); } break; case 'p': format = 'p'; break; case 'q': quiet = 1; default: break; } optargc++; } if (argc-optargc < 1) goto usage; /* read the threshold array */ tfile = fopen(argv[optargc],"r"); if (tfile == NULL) { fprintf(stderr, "\n Threshold data file not found: '%s'\n", argv[optargc]); exit(1); } /* Read the header to get the width and height */ i = fscanf(tfile, "# W=%d H=%d", &width, &height); if (i < 2) { printf("Missing header line. Should be: # W=### H=###\n"); exit(1); } for (i=0; i next_value) end_value = next_value; /* clamp in case of rounding errors */ while (end_value - cur_value > 0.00001) { thresh[thresh_order[cur_pix][0] + (width*thresh_order[cur_pix][1])] = level; pixcounts[level]++; cur_pix++; if (cur_pix >= num_pix) break; cur_value += delta_value; } if (cur_pix >= num_pix) break; } cur_level = next_level; } /* now fill any remaining cells */ for (; cur_pix < num_pix; cur_pix++) { thresh[thresh_order[cur_pix][0] + (width*thresh_order[cur_pix][1])] = 255; pixcounts[255]++; } /* Now put out the mapped threshold order */ if (format == 'p') { /* PostScript HalftoneType 3 Threshold Array for testing */ if (num_pix >= 65536) { fprintf(stderr, "\nThreshold array too large for PostScript format HalftoneType 3.\n"); exit(1); } fprintf(ofile,"%%!PS\n%% Created from '%s'\n",argv[optargc]); fprintf(ofile, "<< /HalftoneType 3\n /Width %d\n /Height %d\n /Thresholds <", width, height); for (i=0; i\n>>\n"); fprintf(ofile,"/Default exch /Halftone defineresource sethalftone\n{ } settransfer\n"); fprintf(ofile,"%%%%EOF\n"); } else { /* Just dump the binary data (suitable for Scanvec */ fprintf(ofile, "%c%c", width/256, width % 256); for (i=0; i threshold.bin]\n" "\n" "\t-c outputs the count of pixels at each of 256 levels\n" "\t-p generates output in PostScript HalftoneType 3 format\n" "\t-q suppresses output (except -c)\n" "\t-o specifies the file for the binary or PostScript remapped threshold array\n" "\n" "\tthreshold.tos is the file produced by either gen_stochastic or\n" "\tgen_ordered consisting of a header line that has the width and\n" "\theight (format '# W=%%d H=%%d' followed by a list of pixels in\n" "\torder of painting, one line per pixel format: %%d %%d\n" "\ttransfer.dat is optional. If missing, the thresold array will have\n" "\t1/256 of the total at each level. The format of the transfer.dat\n" "\tfile is: %%d %%f where the first integer is the level and the\n" "\tsecond float is the brightness (0 == dark, similar to L* value).\n" "\tThe 'level' is in the range 0 to 256. The final entry should be\n" "\t256 WHITEVALUE. If the final measurement is not level 256, then\n" "\tthe assumed WHITEVALUE will be 1.0000\n" "\n" ); return(1); }