summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gs/base/gdevtsep.c266
1 files changed, 189 insertions, 77 deletions
diff --git a/gs/base/gdevtsep.c b/gs/base/gdevtsep.c
index 15e276a22..a50557a41 100644
--- a/gs/base/gdevtsep.c
+++ b/gs/base/gdevtsep.c
@@ -406,6 +406,10 @@ static dev_proc_put_params(tiffsep1_put_params);
static dev_proc_print_page(tiffsep1_print_page);
static dev_proc_fill_path(sep1_fill_path);
+/* common to tiffsep and tiffsepo1 */
+static dev_proc_print_page_copies(tiffseps_print_page_copies);
+static dev_proc_output_page(tiffseps_output_page);
+
#define tiffsep_devices_common\
gx_device_common;\
gx_prn_device_common;\
@@ -415,6 +419,7 @@ static dev_proc_fill_path(sep1_fill_path);
bool BigEndian; /* true = big endian; false = little endian */\
uint16 Compression; /* for the separation files, same values as
TIFFTAG_COMPRESSION */\
+ bool close_files; \
long MaxStripSize;\
gs_devn_params devn_params; /* DeviceN generated parameters */\
equivalent_cmyk_color_params equiv_cmyk_colors\
@@ -424,6 +429,7 @@ static dev_proc_fill_path(sep1_fill_path);
*/
typedef struct tiffsep_device_s {
tiffsep_devices_common;
+ FILE *comp_file; /* Underlying file for tiff_comp */
TIFF *tiff_comp; /* tiff file for comp file */
bool warning_given;
} tiffsep_device;
@@ -479,6 +485,11 @@ RELOC_PTRS_END
static void
tiffsep_device_finalize(const gs_memory_t *cmem, void *vpdev)
{
+ tiffsep_device * const pdevn = (tiffsep_device *) vpdev;
+
+ /* for safety */
+ pdevn->close_files = true;
+
/* We need to deallocate the compressed_color_list.
and the names. */
devn_free_params((gx_device*) vpdev);
@@ -496,7 +507,7 @@ gs_private_st_composite_final(st_tiffsep_device, tiffsep_device,
{ open,\
gx_default_get_initial_matrix,\
NULL, /* sync_output */\
- tiff_output_page, /* output_page */\
+ tiffseps_output_page, /* output_page */\
close, /* close */\
NULL, /* map_rgb_color - not used */\
tiffsep_decode_color, /* map_color_rgb */\
@@ -557,7 +568,7 @@ gs_private_st_composite_final(st_tiffsep_device, tiffsep_device,
}
-#define tiffsep_devices_body(dtype, procs, dname, ncomp, pol, depth, mg, mc, sl, cn, print_page, compr)\
+#define tiffsep_devices_body(dtype, procs, dname, ncomp, pol, depth, mg, mc, sl, cn, print_page, print_page_copies, compr)\
std_device_full_body_type_extended(dtype, &procs, dname,\
&st_tiffsep_device,\
(int)((long)(DEFAULT_WIDTH_10THS) * (X_DPI) / 10),\
@@ -574,11 +585,12 @@ gs_private_st_composite_final(st_tiffsep_device, tiffsep_device,
0, 0, /* offsets */\
0, 0, 0, 0 /* margins */\
),\
- prn_device_body_rest_(print_page),\
+ prn_device_body_rest2_(print_page, print_page_copies, -1),\
{ 0 }, /* tiff state for separation files */\
{ 0 }, /* separation files */\
arch_is_big_endian /* true = big endian; false = little endian */,\
compr /* COMPRESSION_* */,\
+ true, /* close_files */ \
TIFF_DEFAULT_STRIP_SIZE /* MaxStripSize */
/*
@@ -614,7 +626,7 @@ static const gx_device_procs spot1_cmyk_procs =
const tiffsep_device gs_tiffsep_device =
{
- tiffsep_devices_body(tiffsep_device, spot_cmyk_procs, "tiffsep", NC, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, SL, "DeviceCMYK", tiffsep_print_page, COMPRESSION_LZW),
+ tiffsep_devices_body(tiffsep_device, spot_cmyk_procs, "tiffsep", NC, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, SL, "DeviceCMYK", tiffsep_print_page, tiffseps_print_page_copies, COMPRESSION_LZW),
/* devn_params specific parameters */
{ 8, /* Not used - Bits per color */
DeviceCMYKComponents, /* Names of color model colorants */
@@ -630,7 +642,7 @@ const tiffsep_device gs_tiffsep_device =
const tiffsep1_device gs_tiffsep1_device =
{
- tiffsep_devices_body(tiffsep1_device, spot1_cmyk_procs, "tiffsep1", NC, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, SL, "DeviceCMYK", tiffsep1_print_page, COMPRESSION_CCITTFAX4),
+ tiffsep_devices_body(tiffsep1_device, spot1_cmyk_procs, "tiffsep1", NC, GX_CINFO_POLARITY_SUBTRACTIVE, GCIB, MAX_COLOR_VALUE, MAX_COLOR_VALUE, SL, "DeviceCMYK", tiffsep1_print_page, tiffseps_print_page_copies, COMPRESSION_CCITTFAX4),
/* devn_params specific parameters */
{ 1, /* Not used - Bits per color */
DeviceCMYKComponents, /* Names of color model colorants */
@@ -838,6 +850,7 @@ tiffsep_put_params(gx_device * pdev, gs_param_list * plist)
int code;
const char *param_name;
gs_param_string comprstr;
+ bool save_close_files = pdevn->close_files;
/* Read BigEndian option as bool */
switch (code = param_read_bool(plist, (param_name = "BigEndian"), &pdevn->BigEndian)) {
@@ -882,8 +895,14 @@ tiffsep_put_params(gx_device * pdev, gs_param_list * plist)
break;
}
- return devn_printer_put_params(pdev, plist,
+ pdevn->close_files = false;
+
+ code = devn_printer_put_params(pdev, plist,
&(pdevn->devn_params), &(pdevn->equiv_cmyk_colors));
+
+ pdevn->close_files = save_close_files;
+
+ return(code);
}
static int
@@ -903,6 +922,52 @@ tiffsep1_put_params(gx_device * pdev, gs_param_list * plist)
return code;
}
+
+/* common print_page_copies method for both tiff separation devices */
+static int
+tiffseps_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
+{
+ int i = 1;
+ int code = 0;
+ (void) prn_stream;
+
+ for (; i < num_copies; ++i) {
+ code = (*pdev->printer_procs.print_page) (pdev, NULL);
+ if (code < 0)
+ return code;
+
+ pdev->PageCount++;
+
+ }
+ /* Print the last (or only) page. */
+ pdev->PageCount -= num_copies - 1;
+ return (*pdev->printer_procs.print_page) (pdev, NULL);
+}
+
+int
+tiffseps_output_page(gx_device *pdev, int num_copies, int flush)
+{
+ gx_device_printer * const ppdev = (gx_device_printer *)pdev;
+ int outcode = 0, closecode = 0, endcode;
+
+ if (num_copies > 0 || !flush) {
+ /* Print the accumulated page description. */
+ outcode = (*ppdev->printer_procs.print_page_copies)(ppdev, ppdev->file, num_copies);
+ }
+ endcode = (ppdev->buffer_space && !ppdev->is_async_renderer ?
+ clist_finish_page(pdev, flush) : 0);
+
+ if (outcode < 0)
+ return (outcode);
+ if (closecode < 0)
+ return (closecode);
+ if (endcode < 0)
+ return (endcode);
+
+ endcode = gx_finish_output_page(pdev, num_copies, flush);
+ return (endcode);
+}
+
static void build_comp_to_sep_map(tiffsep_device *, short *);
static int number_output_separations(int, int, int, int);
static int create_separation_file_name(tiffsep_device *, char *, uint, int, bool);
@@ -932,6 +997,7 @@ tiffsep1_prn_open(gx_device * pdev)
tfdev->fill_path = pdev->procs.fill_path;
pdev->procs.fill_path = sep1_fill_path;
}
+
return code;
}
@@ -979,26 +1045,28 @@ tiffsep1_prn_close(gx_device * pdev)
}
- build_comp_to_sep_map((tiffsep_device *)tfdev, map_comp_to_sep);
- /* Close the separation files */
- for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
- if (tfdev->sep_file[comp_num] != NULL) {
- int sep_num = map_comp_to_sep[comp_num];
-
- code = create_separation_file_name((tiffsep_device *)tfdev, name,
- MAX_FILE_NAME_SIZE, sep_num, true);
- if (code < 0)
- return code;
- code = gx_device_close_output_file(pdev, name, tfdev->sep_file[comp_num]);
- if (code < 0)
- return code;
- tfdev->sep_file[comp_num] = NULL;
+ if (tfdev->close_files) {
+ build_comp_to_sep_map((tiffsep_device *)tfdev, map_comp_to_sep);
+ /* Close the separation files */
+ for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
+ if (tfdev->sep_file[comp_num] != NULL) {
+ int sep_num = map_comp_to_sep[comp_num];
+
+ code = create_separation_file_name((tiffsep_device *)tfdev, name,
+ MAX_FILE_NAME_SIZE, sep_num, true);
+ if (code < 0)
+ return code;
+ code = gx_device_close_output_file(pdev, name, tfdev->sep_file[comp_num]);
+ if (code < 0)
+ return code;
+ tfdev->sep_file[comp_num] = NULL;
+ }
+ if (tfdev->tiff[comp_num]) {
+ TIFFCleanup(tfdev->tiff[comp_num]);
+ tfdev->tiff[comp_num] = NULL;
+ }
}
- if (tfdev->tiff[comp_num]) {
- TIFFCleanup(tfdev->tiff[comp_num]);
- tfdev->tiff[comp_num] = NULL;
}
- }
/* If we have thresholds, free them and clear the pointers */
if( tfdev->thresholds[0].dstart != NULL) {
sep1_free_thresholds(tfdev);
@@ -1238,11 +1306,11 @@ build_comp_to_sep_map(tiffsep_device * pdev, short * map_comp_to_sep)
int
tiffsep_prn_open(gx_device * pdev)
{
-
-#if TIFFSEP_PLANAR
gx_device_printer * const ppdev = (gx_device_printer *)pdev;
tiffsep_device *pdev_sep = (tiffsep_device *) pdev;
int code;
+
+#if TIFFSEP_PLANAR
/* With planar the depth can be more than 64. Update the color
info to reflect the proper depth and number of planes */
@@ -1268,15 +1336,11 @@ tiffsep_prn_open(gx_device * pdev)
pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
code = gdev_prn_open_planar(pdev, true);
ppdev->file = NULL;
- if (ppdev->OpenOutputFile)
- code = gdev_prn_open_printer_seekable(pdev, 1, true);
+
pdev->icc_struct->supports_devn = true;
- return code;
#else
- int code = tiff_open(pdev);
- tiffsep_device *pdev_sep = (tiffsep_device *) pdev;
+ code = tiff_open(pdev);
pdev_sep->warning_given = false;
-#endif
#if !USE_COMPRESSED_ENCODING
/*
@@ -1286,6 +1350,8 @@ tiffsep_prn_open(gx_device * pdev)
set_linear_color_bits_mask_shift(pdev);
pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
#endif
+#endif
+
return code;
}
@@ -1308,6 +1374,24 @@ tiffsep_close_sep_file(tiffsep_device *tfdev, const char *fn, int comp_num)
return code;
}
+static int
+tiffsep_close_comp_file(tiffsep_device *tfdev, const char *fn)
+{
+ int code;
+
+ if (tfdev->tiff_comp) {
+ TIFFCleanup(tfdev->tiff_comp);
+ tfdev->tiff_comp = NULL;
+ }
+
+ code = gx_device_close_output_file((gx_device *)tfdev,
+ fn,
+ tfdev->comp_file);
+ tfdev->comp_file = NULL;
+
+ return code;
+}
+
/* Close the tiffsep device */
int
tiffsep_prn_close(gx_device * pdev)
@@ -1324,7 +1408,7 @@ tiffsep_prn_close(gx_device * pdev)
int num_comp = number_output_separations(num_dev_comp, num_std_colorants,
num_order, num_spot);
- if (pdevn->tiff_comp) {
+ if (pdevn->tiff_comp && pdevn->close_files) {
TIFFCleanup(pdevn->tiff_comp);
pdevn->tiff_comp = NULL;
}
@@ -1332,19 +1416,21 @@ tiffsep_prn_close(gx_device * pdev)
if (code < 0)
return code;
- build_comp_to_sep_map(pdevn, map_comp_to_sep);
- /* Close the separation files */
- for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
- if (pdevn->sep_file[comp_num] != NULL) {
- int sep_num = map_comp_to_sep[comp_num];
-
- code = create_separation_file_name(pdevn, name,
- MAX_FILE_NAME_SIZE, sep_num, false);
- if (code < 0)
- return code;
- code = tiffsep_close_sep_file(pdevn, name, comp_num);
- if (code < 0)
- return code;
+ if (pdevn->close_files) {
+ build_comp_to_sep_map(pdevn, map_comp_to_sep);
+ /* Close the separation files */
+ for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
+ if (pdevn->sep_file[comp_num] != NULL) {
+ int sep_num = map_comp_to_sep[comp_num];
+
+ code = create_separation_file_name(pdevn, name,
+ MAX_FILE_NAME_SIZE, sep_num, false);
+ if (code < 0)
+ return code;
+ code = tiffsep_close_sep_file(pdevn, name, comp_num);
+ if (code < 0)
+ return code;
+ }
}
}
@@ -1655,7 +1741,7 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file)
int num_std_colorants = tfdev->devn_params.num_std_colorant_names;
int num_order = tfdev->devn_params.num_separation_order_names;
int num_spot = tfdev->devn_params.separations.num_separations;
- int num_comp, comp_num, sep_num, code = 0;
+ int num_comp, comp_num, sep_num, code = 0, code1 = 0;
short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS];
cmyk_composite_map cmyk_map[GX_DEVICE_COLOR_MAX_COMPONENTS];
char name[MAX_FILE_NAME_SIZE];
@@ -1689,12 +1775,18 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file)
dprintf("CMYK composite file would be too large! Reduce resolution or enable compression.\n");
return_error(gs_error_rangecheck); /* this will overflow 32 bits */
}
-
- if (gdev_prn_file_is_new(pdev)) {
- tfdev->tiff_comp = tiff_from_filep(pdev->dname, file, tfdev->BigEndian);
+
+ if (!tfdev->comp_file) {
+ code = gx_device_open_output_file((gx_device *)pdev, pdev->fname, true, true, &(tfdev->comp_file));
+ if (code < 0)
+ return code;
+
+ tfdev->tiff_comp = tiff_from_filep(pdev->dname, tfdev->comp_file, tfdev->BigEndian);
if (!tfdev->tiff_comp)
return_error(gs_error_invalidfileaccess);
+
}
+
code = tiff_set_fields_for_printer(pdev, tfdev->tiff_comp, 1, 0);
if (tfdev->Compression==COMPRESSION_NONE || tfdev->Compression==COMPRESSION_LZW || tfdev->Compression==COMPRESSION_PACKBITS)
tiff_set_cmyk_fields(pdev, tfdev->tiff_comp, 8, tfdev->Compression, tfdev->MaxStripSize);
@@ -1719,15 +1811,7 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file)
sep_num, false);
if (code < 0)
return code;
- /*
- * Close the old separation file if we are creating individual files
- * for each page.
- */
- if (tfdev->sep_file[comp_num] != NULL && fmt != NULL) {
- code = tiffsep_close_sep_file(tfdev, name, comp_num);
- if (code < 0)
- return code;
- }
+
/* Open the separation file, if not already open */
if (tfdev->sep_file[comp_num] == NULL) {
code = gx_device_open_output_file((gx_device *)pdev, name,
@@ -1867,9 +1951,32 @@ tiffsep_print_page(gx_device_printer * pdev, FILE * file)
gs_free_object(pdev->memory, line, "tiffsep_print_page");
gs_free_object(pdev->memory, sep_line, "tiffsep_print_page");
#endif
- for (comp_num = 0; comp_num < num_comp; comp_num++ )
+
+ code1 = 0;
+ for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
TIFFWriteDirectory(tfdev->tiff[comp_num]);
+ if (fmt) {
+ int sep_num = map_comp_to_sep[comp_num];
+
+ code = create_separation_file_name(tfdev, name, MAX_FILE_NAME_SIZE, sep_num, false);
+ if (code < 0) {
+ code1 = code;
+ continue;
+ }
+ code = tiffsep_close_sep_file(tfdev, name, comp_num);
+ if (code < 0) {
+ code1 = code;
+ }
+ }
+ }
+
TIFFWriteDirectory(tfdev->tiff_comp);
+ if (fmt) {
+ code = tiffsep_close_comp_file(tfdev, pdev->fname);
+ }
+ if (code1 < 0) {
+ code = code1;
+ }
}
#if defined(DEBUG) && 0
@@ -1905,7 +2012,7 @@ tiffsep1_print_page(gx_device_printer * pdev, FILE * file)
int num_std_colorants = tfdev->devn_params.num_std_colorant_names;
int num_order = tfdev->devn_params.num_separation_order_names;
int num_spot = tfdev->devn_params.separations.num_separations;
- int num_comp, comp_num, code = 0;
+ int num_comp, comp_num, code = 0, code1 = 0;
short map_comp_to_sep[GX_DEVICE_COLOR_MAX_COMPONENTS];
char name[MAX_FILE_NAME_SIZE];
int save_depth = pdev->color_info.depth;
@@ -1957,21 +2064,7 @@ tiffsep1_print_page(gx_device_printer * pdev, FILE * file)
MAX_FILE_NAME_SIZE, sep_num, true);
if (code < 0)
return code;
- /*
- * Close the old separation file if we are creating individual files
- * for each page.
- */
- if (tfdev->sep_file[comp_num] != NULL && fmt != NULL) {
- code = gx_device_close_output_file((const gx_device *)tfdev, name,
- tfdev->sep_file[comp_num]);
- if (code < 0)
- return code;
- tfdev->sep_file[comp_num] = NULL;
- if (tfdev->tiff[comp_num]) {
- TIFFCleanup(tfdev->tiff[comp_num]);
- tfdev->tiff[comp_num] = NULL;
- }
- }
+
/* Open the separation file, if not already open */
if (tfdev->sep_file[comp_num] == NULL) {
code = gx_device_open_output_file((gx_device *)pdev, name,
@@ -2096,9 +2189,28 @@ tiffsep1_print_page(gx_device_printer * pdev, FILE * file)
TIFFWriteScanline(tfdev->tiff[comp_num], (tdata_t)dithered_line, y, 0);
} /* end component loop */
}
+
/* Update the strip data */
- for (comp_num = 0; comp_num < num_comp; comp_num++ )
+ code1 = 0;
+ for (comp_num = 0; comp_num < num_comp; comp_num++ ) {
TIFFWriteDirectory(tfdev->tiff[comp_num]);
+
+ if (fmt) {
+ int sep_num = map_comp_to_sep[comp_num];
+
+ code = create_separation_file_name((tiffsep_device *)tfdev, name, MAX_FILE_NAME_SIZE, sep_num, false);
+ if (code < 0) {
+ code1 = code;
+ continue;
+ }
+ code = tiffsep_close_sep_file((tiffsep_device *)tfdev, name, comp_num);
+ if (code < 0) {
+ code1 = code;
+ }
+ }
+ }
+ code = code1;
+
gs_free_object(pdev->memory, line, "tiffsep1_print_page");
gs_free_object(pdev->memory, dithered_line, "tiffsep1_print_page");
}