diff options
author | Ray Johnston <ray.johnston@artifex.com> | 2017-08-22 11:27:38 -0700 |
---|---|---|
committer | Ray Johnston <ray.johnston@artifex.com> | 2017-08-23 08:49:17 -0700 |
commit | 1a9c68e70e338c31a1fbfce6c3750123c6dda319 (patch) | |
tree | a91eb958490c1935e83bc51eb17268ed153acd44 | |
parent | 37c454cb7f70fd27f14dd2c1b9c63528b3a237ab (diff) | |
download | ghostpdl-1a9c68e70e338c31a1fbfce6c3750123c6dda319.tar.gz |
Move gen_ordered.c from toolbin to base.
Modify to strip non LIB_BUILD functions from gen_ordered.c and
move gen_ordered.[ch] to base. Main now in gen_ordered_main.c with
project file referencing ../../../base/ for gen_ordered.[ch].
Modify the project file appropriately and add a simple Makefile for
unix.
-rw-r--r-- | base/gen_ordered.c (renamed from toolbin/halftone/gen_ordered/gen_ordered.c) | 387 | ||||
-rw-r--r-- | base/gen_ordered.h (renamed from toolbin/halftone/gen_ordered/gen_ordered.h) | 6 | ||||
-rw-r--r-- | base/lib.mak | 7 | ||||
-rw-r--r-- | base/msvclib.mak | 5 | ||||
-rw-r--r-- | base/openvms.mak | 3 | ||||
-rw-r--r-- | base/ugcclib.mak | 3 | ||||
-rw-r--r-- | base/unix-gcc.mak | 3 | ||||
-rw-r--r-- | base/unixansi.mak | 3 | ||||
-rw-r--r-- | psi/int.mak | 2 | ||||
-rw-r--r-- | psi/msvc.mak | 5 | ||||
-rw-r--r-- | psi/os2.mak | 3 | ||||
-rw-r--r-- | toolbin/halftone/gen_ordered/Makefile | 14 | ||||
-rw-r--r-- | toolbin/halftone/gen_ordered/README | 2 | ||||
-rw-r--r-- | toolbin/halftone/gen_ordered/gen_ordered.vcproj | 8 | ||||
-rw-r--r-- | toolbin/halftone/gen_ordered/gen_ordered_main.c | 363 |
15 files changed, 420 insertions, 394 deletions
diff --git a/toolbin/halftone/gen_ordered/gen_ordered.c b/base/gen_ordered.c index 79cb2bff9..d2667c263 100644 --- a/toolbin/halftone/gen_ordered/gen_ordered.c +++ b/base/gen_ordered.c @@ -14,18 +14,15 @@ */ /* Ordered Dither Screen Creation Tool. */ -#include <stdio.h> #include <stdlib.h> -#include <string.h> -#include <memory.h> -#include <sys/stat.h> -#include <math.h> #ifdef GS_LIB_BUILD #define LIB_BUILD #include "std.h" +#include "string_.h" #include "gsmemory.h" +#include "math_.h" # define ALLOC(mem, size) (gs_alloc_bytes((gs_memory_t *)mem, size, "gen_ordered")) # define FREE(mem, ptr) gs_free_object((gs_memory_t *)mem, ptr, "gen_ordered") @@ -37,22 +34,32 @@ #endif /* defined GS_LIB_BUILD */ -#define RAW_SCREEN_DUMP 0 /* Noisy output for .raw files for detailed debugging */ -#define MAXVAL 65535.0 -#define MIN(x,y) ((x)>(y)?(y):(x)) -#define MAX(x,y) ((x)>(y)?(x):(y)) -#define ROUND( a ) ( ( (a) < 0 ) ? (int) ( (a) - 0.5 ) : \ - (int) ( (a) + 0.5 ) ) -#define FULL_FILE_NAME_LENGTH 50 +#ifndef LIB_BUILD + +#include <stdio.h> +#include <string.h> +#include <memory.h> +#include <sys/stat.h> +#include <math.h> -#ifndef stdpre_INCLUDED typedef unsigned char byte; #define false 0 #define true 1 -# ifndef __cplusplus - typedef int bool; -# endif /* __cpluplus */ -#endif /* stdpre_INCLUDED */ +#ifndef __cplusplus + typedef int bool; +#endif /* __cpluplus */ + +/* Needed if standalone (main) */ + +# define ALLOC(mem, size) (malloc(size)) +# define FREE(mem, ptr) (free(ptr)) + +# define PRINTF(mem, str) printf(str) +# define PRINTF7(mem, str, v1, v2, v3, v4, v5, v6, v7) printf(str, v1, v2, v3, v4, v5, v6, v7) +# define EPRINTF(mem, str) fprintf(stderr, str) +# define EPRINTF1(mem, str, v1) fprintf(stderr, str, v1) + +#endif /* ndef LIB_BUILD */ #include "gen_ordered.h" @@ -136,348 +143,6 @@ static void htsc_dump_byte_image(byte *image, int height, int width, float max_v char filename[]); #endif -#ifndef LIB_BUILD - -/* Needed if standalone (main) */ - -# define ALLOC(mem, size) (malloc(size)) -# define FREE(mem, ptr) (free(ptr)) - -# define PRINTF(mem, str) printf(str) -# define PRINTF7(mem, str, v1, v2, v3, v4, v5, v6, v7) printf(str, v1, v2, v3, v4, v5, v6, v7) -# define EPRINTF(mem, str) fprintf(stderr, str) -# define EPRINTF1(mem, str, v1) fprintf(stderr, str, v1) - -static int htsc_save_tos(htsc_dig_grid_t *final_mask); -static int htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, - htsc_param_t params); - -/* ------------------------- _snprintf -----------------------------*/ - -#if defined(_MSC_VER) -# if _MSC_VER>=1900 /* VS 2014 and later have (finally) snprintf */ -# define STDC99 -# else /* _MSC_VER >= 1900 */ - /* Microsoft Visual C++ 2005 doesn't properly define snprintf, - which is defined in the C standard ISO/IEC 9899:1999 (E) */ - - #include <stdarg.h> - - int snprintf(char *buffer, size_t count, const char *format, ...) - { - if (count > 0) { - va_list args; - int n; - - va_start(args, format); - n = _vsnprintf(buffer, count, format, args); - buffer[count - 1] = 0; - va_end(args); - return n; - } else - return 0; - } -# endif /* _MSC_VER >= 1900 */ -#endif /* defined _MSC_VER */ - -static int -usage (void) -{ - printf ("Usage: gen_ordered [-a target_angle] [-l target_lpi] [-q target_quantization_levels] \n"); - printf (" [-r WxH] [-s size_of_supercell] [-d dot_shape_code] -v verbosity\n"); - printf (" [ -f [ps | ppm | raw | raw16 | tos] ]\n"); - printf ("a is the desired angle in degrees for the screen\n"); - printf ("b is the desired bit depth of the output threshold\n"); - printf (" valid only with -ps or the default raw output\n"); - printf ("dot shape codes are as follows: \n"); - printf ("0 CIRCLE \n"); - printf ("1 REDBOOK CIRCLE \n"); - printf ("2 INVERTED \n"); - printf ("3 RHOMBOID \n"); - printf ("4 LINE_X \n"); - printf ("5 LINE_Y \n"); - printf ("6 DIAMOND1 \n"); - printf ("7 DIAMOND2 \n"); - printf ("8 ROUNDSPOT \n"); - printf ("f [tos | ppm | ps | raw] is the output format\n"); - printf (" If no output format is indicate a turn on sequence output will be created\n"); - printf (" ppm is an Portable Pixmap image file\n"); - printf (" ps indicates postscript style output file\n"); - printf (" raw is a raw 8-bit binary, row major file\n"); - printf (" tos indicates to output a turn on sequence which can\n"); - printf (" be fed into thresh_remap to apply a linearization curve.\n"); - printf ("l is the desired lines per inch (lpi)\n"); - printf ("q is the desired number of quantization (gray) levels\n"); - printf ("r is the device resolution in dots per inch (dpi)\n"); - printf (" use a single number for r if the resolution is symmetric\n"); - printf ("s is the desired size of the super cell\n"); - printf ("v is the verbosity level. Default is 0 which is error messages only.\n"); - return 1; -} - -/* Return the pointer to the value for an argument, either at 'arg' or the next argv */ -/* Allows for either -ovalue or -o value option syntax */ -/* Returns NULL if there is no value (at end of argc arguments) */ -static const char * -get_arg (int argc, char **argv, int *pi, const char *arg) -{ - if (arg[0] != 0) { - return arg; - } else { - (*pi)++; - if (*pi == argc) { - return NULL; - } else { - return argv[*pi]; - } - } -} - -int -main (int argc, char **argv) -{ - int code, i, j, k, m, S; - htsc_param_t params; - htsc_dig_grid_t final_mask; - - htsc_set_default_params(¶ms); - - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - const char *arg_value; - - if (arg[0] == '-') { - switch (arg[1]) { - case 'a': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - params.targ_scr_ang = atoi(arg_value); - break; - case 'f': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - switch (arg_value[0]) { - case 'p': - params.output_format = (arg_value[1] == 's') ? - OUTPUT_PS : OUTPUT_PPM; - break; - case 'r': - j = sscanf(arg_value, "raw%d", &k); - if (j == 0 || k == 8) - params.output_format = OUTPUT_RAW; - else - params.output_format = OUTPUT_RAW16; - break; - case 't': - params.output_format = OUTPUT_TOS; - break; - default: - goto usage_exit; - } - break; - case 'd': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - j = atoi(arg_value); - if (j < 0 || j > CUSTOM) - params.spot_type = CIRCLE; - else - params.spot_type = j; - break; - case 'l': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - params.targ_lpi = atoi(arg_value); - break; - case 'q': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - params.targ_quant = atoi(arg_value); - params.targ_quant_spec = true; - break; - case 'r': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - j = sscanf(arg_value, "%dx%d", &k, &m); - if (j < 1) - goto usage_exit; - params.horiz_dpi = k; - if (j > 1) { - params.vert_dpi = m; - } else { - params.vert_dpi = k; - } - break; - case 's': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - params.targ_size = atoi(arg_value); - params.targ_size_spec = true; - break; - case 'v': - if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) - goto usage_exit; - params.verbose = atoi(arg_value); - break; - default: -usage_exit: return usage(); - } - } - } - final_mask.memory = NULL; /* quiet compiler */ - code = htsc_gen_ordered(params, &S, &final_mask); - - if (code >= 0) - code = htsc_save_screen(&final_mask, params.holladay, S, params); - - if (final_mask.data != NULL) - FREE(final_mask->memory, final_mask.data); - - return code; -} - -/* Save turn on order list, Assume that htsc_gen_ordered has already converted to TOS */ -static int -htsc_save_tos(htsc_dig_grid_t *final_mask) -{ - int width = final_mask->width; - int height = final_mask->height; - int *buff_ptr; - FILE *fid; - int code, x, y, k = 0; - int count= height * width; - - fid = fopen("turn_on_seq.out","w"); - fprintf(fid,"# W=%d H=%d\n",width, height); - - /* Write out */ - buff_ptr = final_mask->data; - for (k = 0; k < count; k++) { - fprintf(fid,"%d\t%d\n", *buff_ptr++, *buff_ptr++); - } - fclose(fid); - return 0; -} - -static int -htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, - htsc_param_t params) -{ - char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; - int x,y, code = 0; - int *buff_ptr = final_mask->data; - int width = final_mask->width; - int height = final_mask->height; - byte data; - unsigned short data_short; - output_format_type output_format = params.output_format; - char *output_extension = (output_format == OUTPUT_PS) ? "ps" : - ((output_format == OUTPUT_PPM) ? "ppm" : - ((output_format == OUTPUT_RAW16 ? "16.raw" : "raw"))); - - if (output_format == OUTPUT_TOS) { - /* We need to figure out the turn-on sequence from the threshold - array */ - code = htsc_save_tos(final_mask); - } else { - if (use_holladay_grid) { - snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Holladay_Shift%d_%dx%d.%s", S, width, - height, output_extension); - } else { - snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Dithered_%dx%d.%s",width,height, - output_extension); - } - fid = fopen(full_file_name,"wb"); - - if (output_format == OUTPUT_PPM) - fprintf(fid, "P5\n" - "# Halftone threshold array, %s, [%d, %d], S=%d\n" - "%d %d\n" - "255\n", - use_holladay_grid ? "Holladay_Shift" : "Dithered", width, height, - S, width, height); - if (output_format != OUTPUT_PS) { - /* Both BIN and PPM format write the same binary data */ - if (output_format == OUTPUT_RAW || output_format == OUTPUT_PPM) { - for (y = 0; y < height; y++) { - for ( x = 0; x < width; x++ ) { - data_short = (unsigned short) (*buff_ptr & 0xffff); - data_short = ROUND((double) data_short * 255.0 / MAXVAL); - if (data_short > 255) data_short = 255; - data = (byte) (data_short & 0xff); - fwrite(&data, sizeof(byte), 1, fid); - buff_ptr++; - } - } - } else { /* raw16 data */ - for (y = 0; y < height; y++) { - for ( x = 0; x < width; x++ ) { - data_short = (unsigned short) (*buff_ptr & 0xffff); - fwrite(&data_short, sizeof(short), 1, fid); - buff_ptr++; - } - } - } - } else { /* ps output format */ - if (params.targ_quant <= 256) { - /* Output PS HalftoneType 3 dictionary */ - fprintf(fid, "%%!PS\n" - "<< /HalftoneType 3\n" - " /Width %d\n" - " /Height %d\n" - " /Thresholds <\n", - width, height); - - for (y = 0; y < height; y++) { - for ( x = 0; x < width; x++ ) { - data_short = (unsigned short) (*buff_ptr & 0xffff); - data_short = ROUND((double) data_short * 255.0 / MAXVAL); - if (data_short > 255) data_short = 255; - data = (byte) (data_short & 0xff); - fprintf(fid, "%02x", data); - buff_ptr++; - if ((x & 0x1f) == 0x1f && (x != (width - 1))) - fprintf(fid, "\n"); - } - fprintf(fid, "\n"); - } - fprintf(fid, " >\n" - ">>\n" - ); - } else { - /* Output PS HalftoneType 16 dictionary. Single array. */ - fprintf(fid, "%%!PS\n" - "%% Create a 'filter' from local hex data\n" - "{ currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter } exec\n"); - /* hex data follows, 'file' object will be left on stack */ - for (y = 0; y < height; y++) { - for ( x = 0; x < width; x++ ) { - data_short = (unsigned short) (*buff_ptr & 0xffff); - fprintf(fid, "%04x", data_short); - buff_ptr++; - if ((x & 0xf) == 0x1f && (x != (width - 1))) - fprintf(fid, "\n"); - } - fprintf(fid, "\n"); /* end of one row */ - } - fprintf(fid, ">\n"); /* ASCIIHexDecode EOF */ - fprintf(fid, - "<< /Thresholds 2 index %% file object for the 16-bit data\n" - " /HalftoneType 16\n" - " /Width %d\n" - " /Height %d\n" - ">>\n" - "exch pop %% discard ResuableStreamDecode file leaving the Halftone dict.\n", - width, height); - } - } - fclose(fid); - } - return code; -} -#endif /* not defined LIB_BUILD */ - /* Initialize default values */ void htsc_set_default_params(htsc_param_t *params) { @@ -1501,7 +1166,7 @@ htsc_apply_filter(byte *screen_matrix, int num_cols_sc, int j_circ,k_circ; float fmax_val = -1; float fmin_val = 100000000; - htsc_point_t fmax_pos, fmin_pos; + htsc_point_t fmax_pos = { 0.0, 0.0 }, fmin_pos = { 0.0, 0.0 }; for (j = 0; j < num_rows_sc; j++) { for (k = 0; k < num_cols_sc; k++) { @@ -1745,7 +1410,7 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, int *dot_levels = NULL; int *locate = NULL; double percent, perc_val; - int code, k, j, h, jj, mm; + int code = 0, k, j, h, jj, mm; int width_supercell = super_cell.width; int height_supercell = super_cell.height; int number_points = width_supercell * height_supercell; diff --git a/toolbin/halftone/gen_ordered/gen_ordered.h b/base/gen_ordered.h index 36d0773a0..fa433a8d1 100644 --- a/toolbin/halftone/gen_ordered/gen_ordered.h +++ b/base/gen_ordered.h @@ -15,6 +15,12 @@ /* Defines and exports for library (e.g., Ghostscript) use of gen_ordered.c */ +#define RAW_SCREEN_DUMP 0 /* Noisy output for .raw files for detailed debugging */ +#define MAXVAL 65535.0 +#define MIN(x,y) ((x)>(y)?(y):(x)) +#define MAX(x,y) ((x)>(y)?(x):(y)) +#define ROUND( a ) ( ( (a) < 0 ) ? (int) ( (a) - 0.5 ) : \ + (int) ( (a) + 0.5 ) ) typedef enum { CIRCLE = 0, REDBOOK, diff --git a/base/lib.mak b/base/lib.mak index 7d30f9c56..ee0247f07 100644 --- a/base/lib.mak +++ b/base/lib.mak @@ -25,7 +25,6 @@ # ZSRCDIR - zlib source directory # ZGENDIR - zlib object code directory # LCMSGENDIR - Little CMS object code directory -# GENORDERED_SRCDIR - source for gen_ordered.[ch] # One of: # LCMSSRCDIR - Little CMS source directory # LCMS2SRCDIR - Little CMS verion 2 source directory @@ -3209,10 +3208,10 @@ $(GLD)shadelib.dev : $(LIB_MAK) $(ECHOGS_XE) $(shadelib_)\ $(ADDMOD) $(GLD)shadelib -obj $(shadelib_2) $(ADDMOD) $(GLD)shadelib -include $(GLD)funclib $(GLD)patlib -$(GLOBJ)gen_ordered.$(OBJ) : $(GENORDERED_SRCDIR)$(D)gen_ordered.c $(GENORDERED_SRCDIR)$(D)gen_ordered.h\ +$(GLOBJ)gen_ordered.$(OBJ) : $(GLSRC)gen_ordered.c $(GLSRC)gen_ordered.h\ $(std_h) $(gsmemory_h) $(LIB_MAK) $(MAKEDIRS) - $(GLCC) $(GLO_)gen_ordered.$(OBJ) $(C_) $(II)$(GENORDERED_SRCDIR) $(D_)GS_LIB_BUILD$(_D) \ - $(GENORDERED_SRCDIR)$(D)gen_ordered.c + $(GLCC) $(GLO_)gen_ordered.$(OBJ) $(C_) $(D_)GS_LIB_BUILD$(_D) \ + $(GLSRC)gen_ordered.c # ---------------- Support for %rom% IODevice ----------------- # # This is used to access compressed, compiled-in support files diff --git a/base/msvclib.mak b/base/msvclib.mak index 3ed949ba7..a9c5aa92e 100644 --- a/base/msvclib.mak +++ b/base/msvclib.mak @@ -199,11 +199,6 @@ LCMSSRCDIR=lcms LCMS2SRCDIR=lcms2 !endif -# Define the directory where the gen_ordered source is stored. -!ifndef GENORDERED_SRCDIR -GENORDERED_SRCDIR=toolbin\halftone\gen_ordered -!endif - # Define any other compilation flags. !ifndef CFLAGS diff --git a/base/openvms.mak b/base/openvms.mak index 8c3bb689b..c9b355e72 100644 --- a/base/openvms.mak +++ b/base/openvms.mak @@ -144,9 +144,6 @@ LCMS2SRCDIR=[.lcms2] WHICH_CMS=lcms2 -# Define the directory where the gen_ordered source is stored. -GENORDERED_SRCDIR=.toolbin.halftone.gen_ordered - # IJS has not been ported to OpenVMS. If you do the port, # you'll need to set these values. You'll also need to # include the ijs.mak makefile diff --git a/base/ugcclib.mak b/base/ugcclib.mak index a2dbb24e0..559409406 100644 --- a/base/ugcclib.mak +++ b/base/ugcclib.mak @@ -72,9 +72,6 @@ LCMSSRCDIR=lcms LCMS2SRCDIR=lcms2 -# Define the directory where the gen_ordered source is stored. -GENORDERED_SRCDIR=toolbin/halftone/gen_ordered - # Define the directory where the ijs source is stored, # and the process forking method to use for the server. # See ijs.mak for more information. diff --git a/base/unix-gcc.mak b/base/unix-gcc.mak index e6c6e0d4c..9de449d5a 100644 --- a/base/unix-gcc.mak +++ b/base/unix-gcc.mak @@ -305,9 +305,6 @@ LCMS2_CFLAGS=-DSHARE_LCMS=$(SHARE_LCMS) -DCMS_USE_BIG_ENDIAN=0 # Options are currently lcms or lcms2 WHICH_CMS=lcms2 -# Define the directory where the gen_ordered source is stored. -GENORDERED_SRCDIR=./toolbin/halftone/gen_ordered - EXPATSRCDIR=./expat EXPAT_CFLAGS=-DHAVE_MEMMOVE EXPATGENDIR=$(GLGENDIR) diff --git a/base/unixansi.mak b/base/unixansi.mak index 35410030a..19b077b98 100644 --- a/base/unixansi.mak +++ b/base/unixansi.mak @@ -190,9 +190,6 @@ LCMS2SRCDIR=lcms2 WHICH_CMS=lcms2 -# Define the directory where the gen_ordered source is stored. -GENORDERED_SRCDIR=toolbin/halftone/gen_ordered - # Define the directory where the ijs source is stored, # and the process forking method to use for the server. # See ijs.mak for more information. diff --git a/psi/int.mak b/psi/int.mak index e149dddf0..617f868a4 100644 --- a/psi/int.mak +++ b/psi/int.mak @@ -84,7 +84,7 @@ store_h=$(PSSRC)store.h $(ialloc_h) $(idosave_h) iplugin_h=$(PSSRC)iplugin.h ifapi_h=$(PSSRC)ifapi.h $(iplugin_h) $(gstypes_h) $(gsmatrix_h) $(gp_h) $(memory__h) zht2_h=$(PSSRC)zht2.h $(gscspace_h) -gen_ordered_h=$(GENORDERED_SRCDIR)$(D)gen_ordered.h +gen_ordered_h=$(GLSRC)gen_ordered.h zchar42_h=$(PSSRC)zchar42.h zfunc_h=$(PSSRC)zfunc.h diff --git a/psi/msvc.mak b/psi/msvc.mak index a6c3adf14..c77e35e99 100644 --- a/psi/msvc.mak +++ b/psi/msvc.mak @@ -672,11 +672,6 @@ LCMSSRCDIR=lcms LCMS2SRCDIR=lcms2 !endif -# Define the directory where the gen_ordered source is stored. -!ifndef GENORDERED_SRCDIR -GENORDERED_SRCDIR=toolbin\halftone\gen_ordered -!endif - # Define the directory where the ijs source is stored, # and the process forking method to use for the server. # See ijs.mak for more information. diff --git a/psi/os2.mak b/psi/os2.mak index 888966f59..712a9f36d 100644 --- a/psi/os2.mak +++ b/psi/os2.mak @@ -134,9 +134,6 @@ ZSRCDIR=zlib JBIG2_LIB=jbig2dec JBIG2SRCDIR=jbig2dec -# Define the directory where the gen_ordered source is stored. -GENORDERED_SRCDIR=toolbin/halftone/gen_ordered - # IJS has not been ported to OS/2. If you do the port, # you'll need to set these values. You'll also need to # include the ijs.mak makefile diff --git a/toolbin/halftone/gen_ordered/Makefile b/toolbin/halftone/gen_ordered/Makefile new file mode 100644 index 000000000..c50f6cb6f --- /dev/null +++ b/toolbin/halftone/gen_ordered/Makefile @@ -0,0 +1,14 @@ +# Makefile for gen_ordered standalone executable + +CFLAGS= + +GLSRC=../../../base/ + +gen_ordered: gen_ordered_main.o gen_ordered.o + $(CC) -o gen_ordered gen_ordered_main.o gen_ordered.o -lm + +gen_ordered_main.o: gen_ordered_main.c $(GLSRC)gen_ordered.h + $(CC) -o gen_ordered_main.o -I$(GLSRC) -c gen_ordered_main.c + +gen_ordered.o: $(GLSRC)gen_ordered.c $(GLSRC)gen_ordered.h + $(CC) -o gen_ordered.o -I$(GLSRC) -c $(GLSRC)gen_ordered.c diff --git a/toolbin/halftone/gen_ordered/README b/toolbin/halftone/gen_ordered/README index 5bf639cf6..191c20a14 100644 --- a/toolbin/halftone/gen_ordered/README +++ b/toolbin/halftone/gen_ordered/README @@ -22,7 +22,7 @@ where: target_angle: The desired screen angle in degrees. [default 0 degrees] dot_shape: The index number of the dot shape, CIRCLE, REDBOOK_CIRCLE, INVERTED, - RHOMBOID, LINE_X, LINE_Y, DIAMOND1, or DIAMOND2 values from 0 to 7, + RHOMBOID, LINE_X, LINE_Y, DIAMOND1, DIAMOND2 or ROUNDSPOT values from 0 to 8, respectively. target_lpi: The desired resolution of the screen in lines/inch. [default 300dpi] diff --git a/toolbin/halftone/gen_ordered/gen_ordered.vcproj b/toolbin/halftone/gen_ordered/gen_ordered.vcproj index 56ca0bd32..5812bb0a3 100644 --- a/toolbin/halftone/gen_ordered/gen_ordered.vcproj +++ b/toolbin/halftone/gen_ordered/gen_ordered.vcproj @@ -40,7 +40,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" - AdditionalIncludeDirectories="$(SolutionDir)" + AdditionalIncludeDirectories="$(SolutionDir)\..\..\..\base" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -163,7 +163,11 @@ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > <File - RelativePath=".\gen_ordered.c" + RelativePath="..\..\..\base\gen_ordered.c" + > + </File> + <File + RelativePath=".\gen_ordered_main.c" > </File> </Filter> diff --git a/toolbin/halftone/gen_ordered/gen_ordered_main.c b/toolbin/halftone/gen_ordered/gen_ordered_main.c new file mode 100644 index 000000000..5caeebe9c --- /dev/null +++ b/toolbin/halftone/gen_ordered/gen_ordered_main.c @@ -0,0 +1,363 @@ +/* Copyright (C) 2001-2013 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. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, + CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ +/* Ordered Dither Screen Creation Tool. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> +#include <sys/stat.h> +#include <math.h> + +#define FULL_FILE_NAME_LENGTH 50 + +typedef unsigned char byte; +#define false 0 +#define true 1 +#ifndef __cplusplus + typedef int bool; +#endif /* __cpluplus */ + +/* included from base/gen_ordered.h */ +#include "gen_ordered.h" + +static int htsc_save_tos(htsc_dig_grid_t *final_mask); +static int htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, + htsc_param_t params); + +/* ------------------------- _snprintf -----------------------------*/ + +#if defined(_MSC_VER) +# if _MSC_VER>=1900 /* VS 2014 and later have (finally) snprintf */ +# define STDC99 +# else /* _MSC_VER >= 1900 */ + /* Microsoft Visual C++ 2005 doesn't properly define snprintf, + which is defined in the C standard ISO/IEC 9899:1999 (E) */ + + #include <stdarg.h> + + int snprintf(char *buffer, size_t count, const char *format, ...) + { + if (count > 0) { + va_list args; + int n; + + va_start(args, format); + n = _vsnprintf(buffer, count, format, args); + buffer[count - 1] = 0; + va_end(args); + return n; + } else + return 0; + } +# endif /* _MSC_VER >= 1900 */ +#endif /* defined _MSC_VER */ + +static int +usage (void) +{ + printf ("Usage: gen_ordered [-a target_angle] [-l target_lpi] [-q target_quantization_levels] \n"); + printf (" [-r WxH] [-s size_of_supercell] [-d dot_shape_code] -v verbosity\n"); + printf (" [ -f [ps | ppm | raw | raw16 | tos] ]\n"); + printf ("a is the desired angle in degrees for the screen\n"); + printf ("b is the desired bit depth of the output threshold\n"); + printf (" valid only with -ps or the default raw output\n"); + printf ("dot shape codes are as follows: \n"); + printf ("0 CIRCLE \n"); + printf ("1 REDBOOK CIRCLE \n"); + printf ("2 INVERTED \n"); + printf ("3 RHOMBOID \n"); + printf ("4 LINE_X \n"); + printf ("5 LINE_Y \n"); + printf ("6 DIAMOND1 \n"); + printf ("7 DIAMOND2 \n"); + printf ("8 ROUNDSPOT \n"); + printf ("f [tos | ppm | ps | raw] is the output format\n"); + printf (" If no output format is indicate a turn on sequence output will be created\n"); + printf (" ppm is an Portable Pixmap image file\n"); + printf (" ps indicates postscript style output file\n"); + printf (" raw is a raw 8-bit binary, row major file\n"); + printf (" tos indicates to output a turn on sequence which can\n"); + printf (" be fed into thresh_remap to apply a linearization curve.\n"); + printf ("l is the desired lines per inch (lpi)\n"); + printf ("q is the desired number of quantization (gray) levels\n"); + printf ("r is the device resolution in dots per inch (dpi)\n"); + printf (" use a single number for r if the resolution is symmetric\n"); + printf ("s is the desired size of the super cell\n"); + printf ("v is the verbosity level. Default is 0 which is error messages only.\n"); + return 1; +} + +/* Return the pointer to the value for an argument, either at 'arg' or the next argv */ +/* Allows for either -ovalue or -o value option syntax */ +/* Returns NULL if there is no value (at end of argc arguments) */ +static const char * +get_arg (int argc, char **argv, int *pi, const char *arg) +{ + if (arg[0] != 0) { + return arg; + } else { + (*pi)++; + if (*pi == argc) { + return NULL; + } else { + return argv[*pi]; + } + } +} + +int +main (int argc, char **argv) +{ + int code, i, j, k, m, S; + htsc_param_t params; + htsc_dig_grid_t final_mask; + + htsc_set_default_params(¶ms); + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + const char *arg_value; + + if (arg[0] == '-') { + switch (arg[1]) { + case 'a': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + params.targ_scr_ang = atoi(arg_value); + break; + case 'f': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + switch (arg_value[0]) { + case 'p': + params.output_format = (arg_value[1] == 's') ? + OUTPUT_PS : OUTPUT_PPM; + break; + case 'r': + j = sscanf(arg_value, "raw%d", &k); + if (j == 0 || k == 8) + params.output_format = OUTPUT_RAW; + else + params.output_format = OUTPUT_RAW16; + break; + case 't': + params.output_format = OUTPUT_TOS; + break; + default: + goto usage_exit; + } + break; + case 'd': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + j = atoi(arg_value); + if (j < 0 || j > CUSTOM) + params.spot_type = CIRCLE; + else + params.spot_type = j; + break; + case 'l': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + params.targ_lpi = atoi(arg_value); + break; + case 'q': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + params.targ_quant = atoi(arg_value); + params.targ_quant_spec = true; + break; + case 'r': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + j = sscanf(arg_value, "%dx%d", &k, &m); + if (j < 1) + goto usage_exit; + params.horiz_dpi = k; + if (j > 1) { + params.vert_dpi = m; + } else { + params.vert_dpi = k; + } + break; + case 's': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + params.targ_size = atoi(arg_value); + params.targ_size_spec = true; + break; + case 'v': + if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL) + goto usage_exit; + params.verbose = atoi(arg_value); + break; + default: +usage_exit: return usage(); + } + } + } + final_mask.memory = NULL; /* quiet compiler */ + code = htsc_gen_ordered(params, &S, &final_mask); + + if (code >= 0) + code = htsc_save_screen(&final_mask, params.holladay, S, params); + + if (final_mask.data != NULL) + free(final_mask.data); + + return code; +} + +/* Save turn on order list, Assume that htsc_gen_ordered has already converted to TOS */ +static int +htsc_save_tos(htsc_dig_grid_t *final_mask) +{ + int width = final_mask->width; + int height = final_mask->height; + int *buff_ptr; + FILE *fid; + int code, x, y, k = 0; + int count= height * width; + + fid = fopen("turn_on_seq.out","w"); + fprintf(fid,"# W=%d H=%d\n",width, height); + + /* Write out */ + buff_ptr = final_mask->data; + for (k = 0; k < count; k++) { + fprintf(fid,"%d\t%d\n", *buff_ptr++, *buff_ptr++); + } + fclose(fid); + return 0; +} + +static int +htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, + htsc_param_t params) +{ + char full_file_name[FULL_FILE_NAME_LENGTH]; + FILE *fid; + int x,y, code = 0; + int *buff_ptr = final_mask->data; + int width = final_mask->width; + int height = final_mask->height; + byte data; + unsigned short data_short; + output_format_type output_format = params.output_format; + char *output_extension = (output_format == OUTPUT_PS) ? "ps" : + ((output_format == OUTPUT_PPM) ? "ppm" : + ((output_format == OUTPUT_RAW16 ? "16.raw" : "raw"))); + + if (output_format == OUTPUT_TOS) { + /* We need to figure out the turn-on sequence from the threshold + array */ + code = htsc_save_tos(final_mask); + } else { + if (use_holladay_grid) { + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Holladay_Shift%d_%dx%d.%s", S, width, + height, output_extension); + } else { + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_Dithered_%dx%d.%s",width,height, + output_extension); + } + fid = fopen(full_file_name,"wb"); + + if (output_format == OUTPUT_PPM) + fprintf(fid, "P5\n" + "# Halftone threshold array, %s, [%d, %d], S=%d\n" + "%d %d\n" + "255\n", + use_holladay_grid ? "Holladay_Shift" : "Dithered", width, height, + S, width, height); + if (output_format != OUTPUT_PS) { + /* Both BIN and PPM format write the same binary data */ + if (output_format == OUTPUT_RAW || output_format == OUTPUT_PPM) { + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data_short = (unsigned short) (*buff_ptr & 0xffff); + data_short = ROUND((double) data_short * 255.0 / MAXVAL); + if (data_short > 255) data_short = 255; + data = (byte) (data_short & 0xff); + fwrite(&data, sizeof(byte), 1, fid); + buff_ptr++; + } + } + } else { /* raw16 data */ + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data_short = (unsigned short) (*buff_ptr & 0xffff); + fwrite(&data_short, sizeof(short), 1, fid); + buff_ptr++; + } + } + } + } else { /* ps output format */ + if (params.targ_quant <= 256) { + /* Output PS HalftoneType 3 dictionary */ + fprintf(fid, "%%!PS\n" + "<< /HalftoneType 3\n" + " /Width %d\n" + " /Height %d\n" + " /Thresholds <\n", + width, height); + + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data_short = (unsigned short) (*buff_ptr & 0xffff); + data_short = ROUND((double) data_short * 255.0 / MAXVAL); + if (data_short > 255) data_short = 255; + data = (byte) (data_short & 0xff); + fprintf(fid, "%02x", data); + buff_ptr++; + if ((x & 0x1f) == 0x1f && (x != (width - 1))) + fprintf(fid, "\n"); + } + fprintf(fid, "\n"); + } + fprintf(fid, " >\n" + ">>\n" + ); + } else { + /* Output PS HalftoneType 16 dictionary. Single array. */ + fprintf(fid, "%%!PS\n" + "%% Create a 'filter' from local hex data\n" + "{ currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter } exec\n"); + /* hex data follows, 'file' object will be left on stack */ + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data_short = (unsigned short) (*buff_ptr & 0xffff); + fprintf(fid, "%04x", data_short); + buff_ptr++; + if ((x & 0xf) == 0x1f && (x != (width - 1))) + fprintf(fid, "\n"); + } + fprintf(fid, "\n"); /* end of one row */ + } + fprintf(fid, ">\n"); /* ASCIIHexDecode EOF */ + fprintf(fid, + "<< /Thresholds 2 index %% file object for the 16-bit data\n" + " /HalftoneType 16\n" + " /Width %d\n" + " /Height %d\n" + ">>\n" + "exch pop %% discard ResuableStreamDecode file leaving the Halftone dict.\n", + width, height); + } + } + fclose(fid); + } + return code; +} |