diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2021-03-30 10:59:39 +0200 |
---|---|---|
committer | Thomas Deutschmann <whissi@gentoo.org> | 2021-04-01 00:04:14 +0200 |
commit | 5ff1d6955496b3cf9a35042c9ac35db43bc336b1 (patch) | |
tree | 6d470f7eb448f59f53e8df1010aec9dad8ce1f72 /base/gen_ordered.c | |
parent | Import Ghostscript 9.53.1 (diff) | |
download | ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.gz ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.tar.bz2 ghostscript-gpl-patches-5ff1d6955496b3cf9a35042c9ac35db43bc336b1.zip |
Import Ghostscript 9.54ghostscript-9.54
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'base/gen_ordered.c')
-rw-r--r-- | base/gen_ordered.c | 297 |
1 files changed, 250 insertions, 47 deletions
diff --git a/base/gen_ordered.c b/base/gen_ordered.c index e34e6202..e1cccb4e 100644 --- a/base/gen_ordered.c +++ b/base/gen_ordered.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2020 Artifex Software, Inc. +/* Copyright (C) 2001-2021 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -23,6 +23,7 @@ #include "string_.h" #include "gsmemory.h" #include "math_.h" +#include "gp.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") @@ -34,6 +35,15 @@ # define EPRINTF(mem, str) errprintf((gs_memory_t *)mem, str) # define EPRINTF1(mem, str, v1) errprintf((gs_memory_t *)mem, str, v1) # define EPRINTF3(mem, str, v1, v2, v3) errprintf((gs_memory_t *)mem, str, v1, v2, v3) +# define _FILE gp_file +# define FOPEN(mem, v1, v2) gp_fopen(mem, v1, v2) +# define FCLOSE(fid) gp_fclose(fid) +# define FPRINTF(fid, str) gp_fprintf(fid, str) +# define FPRINTF1(fid, str, v1) gp_fprintf(fid, str, v1) +# define FPRINTF2(fid, str, v1, v2) gp_fprintf(fid, str, v1, v2) +# define FPRINTF6(fid, str, v1, v2, v3, v4, v5, v6) gp_fprintf(fid, str, v1, v2, v3, v4, v5, v6) +# define FWRITE(v1, v2, v3, fid) gp_fwrite(v1, v2, v3, fid) + #endif /* defined GS_LIB_BUILD */ @@ -64,6 +74,14 @@ typedef unsigned char byte; # define EPRINTF(mem, str) fprintf(stderr, str) # define EPRINTF1(mem, str, v1) fprintf(stderr, str, v1) # define EPRINTF3(mem, str, v1, v2, v3) fprintf(stderr, str, v1, v2, v3) +# define _FILE FILE +# define FOPEN(mem, v1, v2) fopen(v1, v2) +# define FCLOSE(fid) fclose(fid) +# define FPRINTF(fid, str) fprintf(fid, str) +# define FPRINTF1(fid, str, v1) fprintf(fid, str, v1) +# define FPRINTF2(fid, str, v1, v2) fprintf(fid, str, v1, v2) +# define FPRINTF6(fid, str, v1, v2, v3, v4, v5, v6) fprintf(fid, str, v1, v2, v3, v4, v5, v6) +# define FWRITE(v1, v2, v3, fid) fwrite(v1, v2, v3, fid) #endif /* ndef LIB_BUILD */ @@ -124,15 +142,16 @@ static int htsc_allocate_supercell(htsc_dig_grid_t *super_cell, int x, int y, in htsc_dig_grid_t dot_grid, int N, int *S, int *H, int *L); static void htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, int x, int y, int u, int v, int N); -void create_2d_gauss_filter(double *filter, int x_size, int y_size, - double stdvalx, double stdvaly); +int create_2d_gauss_filter(double *filter, int x_size, int y_size, + double stdvalx, double stdvaly, gs_memory_t *mem); static int htsc_create_holladay_mask(htsc_dig_grid_t super_cell, int H, int L, double gamma, htsc_dig_grid_t *final_mask); static int htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, int verbose, int num_levels, int y, int x, double vert_dpi, double horiz_dpi, int N, double gamma, - htsc_dig_grid_t dot_grid, htsc_point_t one_index); + htsc_dig_grid_t dot_grid, htsc_point_t one_index, + gs_memory_t *mem); static int htsc_create_nondithered_mask(htsc_dig_grid_t super_cell, int H, int L, double gamma, htsc_dig_grid_t *final_mask); static int htsc_gcd(int a, int b); @@ -142,11 +161,11 @@ static void htsc_matrix_vector_mult(htsc_matrix_t matrix_in, htsc_vector_t vecto htsc_vector_t *vector_out); static int htsc_mask_to_tos(htsc_dig_grid_t *final_mask); #if RAW_SCREEN_DUMP -static void htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]); -static void htsc_dump_float_image(double *image, int height, int width, double max_val, - char filename[]); -static void htsc_dump_byte_image(byte *image, int height, int width, double max_val, - char filename[]); +static int htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[], gs_memory_t *mem); +static int htsc_dump_float_image(double *image, int height, int width, double max_val, + char filename[], gs_memory_t *mem); +static int htsc_dump_byte_image(byte *image, int height, int width, double max_val, + char filename[], gs_memory_t *mem); #endif /* Initialize default values */ @@ -169,7 +188,7 @@ void htsc_set_default_params(htsc_param_t *params) } int -htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) +htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask, gs_memory_t *mem) { int num_levels; int x=0, y=0, v=0, u=0, N=0; @@ -231,10 +250,12 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) on sequence or dot profile */ code = htsc_create_dot_mask(&dot_grid, x, y, u, v, params.scr_ang, vertices); if (code < 0) { - return -1; + return code; } #if RAW_SCREEN_DUMP - htsc_dump_screen(&dot_grid, "mask"); + code = htsc_dump_screen(&dot_grid, "mask", mem); + if (code < 0) + return code; #endif /* A sanity check */ if (htsc_sumsum(dot_grid) != -N) { @@ -255,7 +276,9 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) params.spot_type, trans_matrix_inv); #if RAW_SCREEN_DUMP - htsc_dump_screen(&dot_grid, "dot_profile"); + code = htsc_dump_screen(&dot_grid, "dot_profile", mem); + if (code < 0) + return code; #endif /* Allocate super cell */ code = htsc_allocate_supercell(&super_cell, x, y, u, v, params.targ_size, @@ -279,7 +302,9 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) /* Go ahead and fill up the super cell grid with our growth dot values */ htsc_tile_supercell(&super_cell, &dot_grid, x, y, u, v, N); #if RAW_SCREEN_DUMP - htsc_dump_screen(&super_cell, "super_cell_tiled"); + code = htsc_dump_screen(&super_cell, "super_cell_tiled", mem); + if (code < 0) + return code; #endif /* If we are using the Holladay grid (non dithered) then we are done. */ if (params.holladay) { @@ -302,7 +327,7 @@ htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) } code = htsc_create_dither_mask(super_cell, final_mask, params.verbose, num_levels, y, x, params.vert_dpi, params.horiz_dpi, N, - params.gamma, dot_grid, one_index); + params.gamma, dot_grid, one_index, mem); } } final_mask->bin_center = bin_center; @@ -1136,9 +1161,9 @@ htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, /* Create 2d gaussian filter that varies with respect to coordinate spatial resolution */ -void +int create_2d_gauss_filter(double *filter, int x_size, int y_size, - double stdvalx, double stdvaly) + double stdvalx, double stdvaly, gs_memory_t *mem) { int x_half_size = (x_size-1)/2; int y_half_size = (y_size-1)/2; @@ -1148,6 +1173,7 @@ create_2d_gauss_filter(double *filter, int x_size, int y_size, double max_val = 0; int total_size = x_size * y_size; int index_x, index_y; + int code = 0; for (j = -y_half_size; j < y_half_size+1; j++) { index_y = j + y_half_size; @@ -1165,8 +1191,9 @@ create_2d_gauss_filter(double *filter, int x_size, int y_size, filter[j]/=sum; } #if RAW_SCREEN_DUMP - htsc_dump_float_image(filter, y_size, x_size, max_val/sum, "guass_filt"); + code = htsc_dump_float_image(filter, y_size, x_size, max_val/sum, "guass_filt", mem); #endif + return code; } /* 2-D convolution (or correlation) with periodic boundary condition */ @@ -1256,6 +1283,7 @@ htsc_add_dots(byte *screen_matrix, int num_cols, int num_rows, int k,j; int dist, curr_dist; htsc_dither_pos_t curr_position; + int code; sizefiltx = ROUND(sigma_x * 4); sizefilty = ROUND(sigma_y * 4); @@ -1268,7 +1296,10 @@ htsc_add_dots(byte *screen_matrix, int num_cols, int num_rows, filter = (double*) ALLOC(mem, sizeof(double) * sizefilty * sizefiltx); if (filter == NULL) return -1; - create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty); + code = create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty, mem); + if (code < 0) + return code; + screen_blur = (double*)ALLOC(mem, sizeof(double) * num_cols * num_rows); if (screen_blur == NULL) { FREE(mem, filter); @@ -1327,6 +1358,7 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, int k; int dist, curr_dist; bool found_it; + int code = 0; sizefiltx = ROUND(sigma_x * 4); sizefilty = ROUND(sigma_y * 4); @@ -1339,7 +1371,10 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, filter = (double*) ALLOC(mem, sizeof(double) * sizefilty * sizefiltx); if (filter == NULL) return -1; - create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty); + code = create_2d_gauss_filter(filter, sizefiltx, sizefilty, (double)sizefiltx, (double)sizefilty, mem); + if (code < 0) + return code; + screen_blur = (double*) ALLOC(mem, sizeof(double) * num_cols * num_rows); if (screen_blur == NULL) { FREE(mem, filter); @@ -1351,7 +1386,9 @@ htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, htsc_apply_filter(screen_matrix, num_cols, num_rows, filter, sizefiltx, sizefilty, screen_blur, &max_val, &max_pos, &min_val, &min_pos); #if RAW_SCREEN_DUMP - htsc_dump_float_image(screen_blur, num_cols, num_rows, max_val, "blur_one"); + code = htsc_dump_float_image(screen_blur, num_cols, num_rows, max_val, "blur_one", mem); + if (code < 0) + return code; #endif /* Find the closest on dot to the max position */ black_pos = 0; @@ -1425,7 +1462,8 @@ static int htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, int verbose, int num_levels, int y, int x, double vert_dpi, double horiz_dpi, int N, double gamma, - htsc_dig_grid_t dot_grid, htsc_point_t dot_grid_one_index) + htsc_dig_grid_t dot_grid, htsc_point_t dot_grid_one_index, + gs_memory_t *mem) { int *dot_levels = NULL; int *locate = NULL; @@ -1562,8 +1600,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, } } #if RAW_SCREEN_DUMP - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, "screen0_init"); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_init", mem); + if (code < 0) + goto out; #endif /* Rearrange these dots into a pleasing pattern, but only if there is * more than 1. Otherwise there are none to move */ @@ -1574,8 +1614,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, if (code < 0) goto out; #if RAW_SCREEN_DUMP - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, "screen0_arrange"); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_arrange", mem); + if (code < 0) + goto out; #endif /* Now we want to introduce more dots at each level */ for (k = 1; k < num_levels; k++) { @@ -1589,8 +1631,10 @@ htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, { char str_name[30]; snprintf(str_name, 30, "screen%d_arrange",k); - htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, - 1, str_name); + code = htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, str_name, mem); + if (code < 0) + goto out; } #endif } @@ -1926,13 +1970,161 @@ htsc_spot_value(spottype_t spot_type, double x, double y) } } +#if FINAL_SCREEN_DUMP + +/* 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, gs_memory_t *mem) +{ + int width = final_mask->width; + int height = final_mask->height; + int *buff_ptr; + _FILE *fid; + int k = 0; + int count = height * width; + + fid = FOPEN(mem, "turn_on_seq.out", "w"); + if (fid == NULL) + return -1; + + FPRINTF2(fid, "# W=%d H=%d\n", width, height); + + /* Write out */ + buff_ptr = final_mask->data; + for (k = 0; k < count; k++) { + FPRINTF2(fid, "%d\t%d\n", *buff_ptr++, *buff_ptr++); + } + FCLOSE(fid); + return 0; +} + +int +htsc_save_screen(htsc_dig_grid_t *final_mask, bool use_holladay_grid, int S, + htsc_param_t params, gs_memory_t *mem) +{ + 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, mem); + } 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(mem, full_file_name, "wb"); + if (fid == NULL) + return -1; + + if (output_format == OUTPUT_PPM) + FPRINTF6(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 */ + FPRINTF2(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); + FPRINTF1(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); + FPRINTF1(fid, "%04x", data_short); + buff_ptr++; + if ((x & 0x1f) == 0x1f && (x != (width - 1))) + FPRINTF(fid, "\n"); + } + FPRINTF(fid, "\n"); /* end of one row */ + } + FPRINTF(fid, ">\n"); /* ASCIIHexDecode EOF */ + FPRINTF2(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 + #if RAW_SCREEN_DUMP -void -static -htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) +static int +htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int *buff_ptr = dig_grid->data; int width = dig_grid->width; @@ -1940,7 +2132,9 @@ htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) byte data[3]; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_%s_%dx%dx3.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { @@ -1957,58 +2151,67 @@ htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) data[1] = *buff_ptr; data[2] = *buff_ptr; } - fwrite(data,sizeof(unsigned char),3,fid); + FWRITE(data,sizeof(unsigned char),3,fid); buff_ptr++; } } - fclose(fid); + FCLOSE(fid); + return 0; } -static void +static int htsc_dump_float_image(double *image, int height, int width, double max_val, - char filename[]) + char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int data; byte data_byte; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Float_%s_%dx%d.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; + for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { data = (255.0 * image[x + y * width] / max_val); if (data > 255) data = 255; if (data < 0) data = 0; data_byte = data; - fwrite(&data_byte,sizeof(byte),1,fid); + FWRITE(&data_byte,sizeof(byte),1,fid); } } - fclose(fid); + FCLOSE(fid); + return 0; } -static void +static int htsc_dump_byte_image(byte *image, int height, int width, double max_val, - char filename[]) + char filename[], gs_memory_t *mem) { char full_file_name[FULL_FILE_NAME_LENGTH]; - FILE *fid; + _FILE *fid; int x,y; int data; byte data_byte; snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "ByteScaled_%s_%dx%d.raw",filename,width,height); - fid = fopen(full_file_name,"wb"); + fid = FOPEN(mem, full_file_name,"wb"); + if (fid == NULL) + return -1; + for (y = 0; y < height; y++) { for ( x = 0; x < width; x++ ) { data = (255.0 * image[x + y * width] / max_val); if (data > 255) data = 255; if (data < 0) data = 0; data_byte = data; - fwrite(&data_byte,sizeof(byte),1,fid); + FWRITE(&data_byte,sizeof(byte),1,fid); } } - fclose(fid); + FCLOSE(fid); + return 0; } #endif |