Fixes: - cdj850 and cdj1600 were broken, because of terminating *b command (by 'Y' or 'V' instead of 'y' or 'v'); now *b is terminated only for cdj880 - do_gcr replaced whole black component by CMY (so everything was printed using colour ink!); do_gcr with NOBLACK looks strange, like somebody didn't know what he's doing... (see the "XXX" comments); now old, actual DOGCR is used, but NOBLACK can be enabled by -dUseBlack=0 though Jakub Bogusz --- ghostscript-9.52/contrib/gdevcd8.c.orig 2020-03-19 09:21:42.000000000 +0100 +++ ghostscript-9.52/contrib/gdevcd8.c 2020-03-25 20:10:39.745178961 +0100 @@ -604,6 +604,7 @@ StartRasterMode start_raster_mode; /* output function to start raster mode */ PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */ TerminatePage terminate_page; /* page termination output function */ + int useblack; /* use K compound */ } gx_device_cdj850; typedef struct { @@ -659,7 +660,7 @@ blackcorrect,\ start_raster_mode,\ print_non_blank_line,\ - terminate_page\ + terminate_page, 1\ } #define cdj_1600_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, correction, quality, papertype, intensities,ptype,compression,mastergamma,gammavalc,gammavalm,gammavaly,gammavalk,blackcorrect,start_raster_mode,print_non_blank_line,terminate_page)\ @@ -678,7 +679,7 @@ blackcorrect,\ start_raster_mode,\ print_non_blank_line,\ - terminate_page\ + terminate_page, 1\ } /* HP2200 and DNJ500 is a RGB printer */ @@ -698,7 +699,7 @@ blackcorrect,\ start_raster_mode,\ print_non_blank_line,\ - terminate_page\ + terminate_page, 1\ } #define cmyk_colour_procs(proc_colour_open, proc_get_params, proc_put_params, \ @@ -1057,6 +1058,7 @@ if (code < 0 || (code = param_write_int(plist, "Quality", &cdj850->quality)) < 0 || (code = param_write_int(plist, "Papertype", &cdj850->papertype)) < 0 || + (code = param_write_int(plist, "UseBlack", &cdj850->useblack)) < 0 || (code = param_write_float(plist, "MasterGamma", &cdj850->gammavalc)) < 0 || (code = param_write_float(plist, "GammaValC", &cdj850->gammavalc)) < @@ -1080,6 +1082,7 @@ { int quality = cdj850->quality; int papertype = cdj850->papertype; + int useblack = cdj850->useblack; float mastergamma = cdj850->mastergamma; float gammavalc = cdj850->gammavalc; float gammavalm = cdj850->gammavalm; @@ -1092,6 +1095,7 @@ code = cdj_put_param_int(plist, "BitsPerPixel", &bpp, 1, 32, code); code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code); code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code); + code = cdj_put_param_int(plist, "UseBlack", &useblack, 0, 1, code); code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1f, 9.0f, code); code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0f, 9.0f, code); code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0f, 9.0f, code); @@ -1108,6 +1112,7 @@ cdj850->quality = quality; cdj850->papertype = papertype; + cdj850->useblack = useblack; cdj850->mastergamma = mastergamma; cdj850->gammavalc = gammavalc; cdj850->gammavalm = gammavalm; @@ -1160,7 +1165,13 @@ gx_device_printer * pdev, struct error_val_field *error_values); static int - do_gcr(int bytecount, byte * inbyte, const byte * kvalues, + do_gcr_noblack(int bytecount, byte * inbyte, const byte * kvalues, + const byte * cvalues, const byte * mvalues, + const byte * yvalues, const int *kcorrect, + word * inword); + +static int + do_gcr_gcr(int bytecount, byte * inbyte, const byte * kvalues, const byte * cvalues, const byte * mvalues, const byte * yvalues, const int *kcorrect, word * inword); @@ -2025,7 +2036,10 @@ } /* Skip blank lines if any */ if (num_blank_lines > 0) { + if(cdj850->ptype == DJ880C) gp_fprintf(prn_stream, "\033*b%dY", num_blank_lines / (cdj850->yscal + 1)); + else /* still in *b if not dj880 */ + fprintf(prn_stream, "%dy", num_blank_lines / (cdj850->yscal + 1)); memset(data_ptrs->plane_data[0][0], 0, (misc_vars->plane_size * 2 * misc_vars->num_comps)); memset(data_ptrs->plane_data_c[0][0], 0, @@ -2035,7 +2049,10 @@ /* all blank lines printed, now for the non-blank lines */ if (cdj850->yscal && odd(lnum)) { /* output a blank black plane for odd lines */ + if(cdj850->ptype == DJ880C) gp_fprintf(prn_stream, "\033*b0V"); + else /* still in *b if not dj880 */ + putc('v', prn_stream); } /* now output all non blank lines */ while (lnum < lend && llen != 0) { @@ -2061,9 +2078,11 @@ int out_count = gdev_pcl_mode9compress(plane_size, curr, prev, out_data); /* and output the data */ - gp_fprintf(prn_stream, "%d%c", out_count, plane_code); if (out_count > 0) { + gp_fprintf(prn_stream, "%d%c", out_count, plane_code); gp_fwrite(out_data, sizeof(byte), out_count, prn_stream); + } else { /* single plane_code is sufficient for cdj850 */ + putc(plane_code, prn_stream); } } @@ -2122,15 +2141,22 @@ byte *dp = data_ptrs->data[misc_vars->scan + 2]; int *ep = data_ptrs->errors[misc_vars->scan]; - /* we need cmyk color separation befor all the rest, since + /* we need cmyk color separation before all the rest, since black may be contained in the color fields. This needs to be done on all pixel-rows, since even unused color-bytes might generate black */ + if(cdj850->useblack) { misc_vars->is_color_data = - do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], + do_gcr_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct, (word *) data_ptrs->data[misc_vars->scan]); + } else { + misc_vars->is_color_data = + do_gcr_noblack(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], + gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct, + (word *) data_ptrs->data[misc_vars->scan]); + } /* dithering the black-plane */ FSDlinebw(misc_vars->scan, misc_vars->plane_size, @@ -2200,15 +2226,22 @@ byte *dp = data_ptrs->data[misc_vars->scan + 2]; int *ep = data_ptrs->errors[misc_vars->scan]; - /* we need cmyk color separation befor all the rest, since + /* we need cmyk color separation before all the rest, since black may be contained in the color fields. This needs to be done on all pixel-rows, since even unused color-bytes might generate black */ + if(cdj850->useblack) { + misc_vars->is_color_data = + do_gcr_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], + gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct, + (word *) data_ptrs->data[misc_vars->scan]); + } else { misc_vars->is_color_data = - do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], + do_gcr_noblack(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct, (word *) data_ptrs->data[misc_vars->scan]); + } /* dithering the black-plane */ FSDlinebw(misc_vars->scan, misc_vars->plane_size, @@ -2411,7 +2444,7 @@ do real color separation, here we try a real grey component replacement */ static int -do_gcr(int bytecount, byte * inbyte, const byte kvalues[256], +do_gcr_noblack(int bytecount, byte * inbyte, const byte kvalues[256], const byte cvalues[256], const byte mvalues[256], const byte yvalues[256], const int kcorrect[256], word * inword) @@ -2421,7 +2454,7 @@ word last_color_value = 0; word *last_color; - /* initialise *last_color with a dummmy value */ + /* initialise *last_color with a dummy value */ last_color = &last_color_value; /* Grey component replacement */ for (i = 0; i < bytecount; i += 4) { @@ -2451,11 +2484,12 @@ /* Test whether we 've already computet the value */ if (*inword == last_color_value) { /* save a copy of the current color before it will be modified */ - last_color_value = *inword; + last_color_value = *inword; /* NOP --q */ /* debug_print_string("\n", 1);*/ /* copy the result of the old value onto the new position */ *inword = *last_color; } else { + /* ??? ALL these NOBLACKs will be NOPs after the first NOBLACK! what are they for??? --q */ /* save a copy of the current color before it will be modified */ last_color_value = *inword; NOBLACK(cyan, magenta, yellow, black); @@ -2493,6 +2527,7 @@ debug_print_string(output, strlen(output)); } #endif /* 0 */ + /* XXX: how byte could be >255??? --q */ if ( *cyan > 255) *cyan = 255; if (*magenta > 255) *magenta = 255; if ( *yellow > 255) *yellow = 255; @@ -2500,6 +2535,96 @@ *cyan = *(cvalues + *cyan); *magenta = *(mvalues + *magenta); *yellow = *(yvalues + *yellow); + last_color = inword; /* save pointer */ + }/* end current_color */ + } /* end of if c+m+y > 0 */ + *black = *(kvalues + *black); + inword = inword + 1; + } /* end of for bytecount */ + return is_color; +} + +static int +do_gcr_gcr(int bytecount, byte * inbyte, const byte kvalues[256], + const byte cvalues[256], const byte mvalues[256], + const byte yvalues[256], const int kcorrect[256], + word * inword) +{ + int i, ucr, kadd, is_color = 0; + float uca_fac; + byte *black, *cyan, *magenta, *yellow; + word last_color_value = 0; + word *last_color; + + /* initialise *last_color with a dummy value */ + last_color = &last_color_value; + /* Grey component replacement */ + for (i = 0; i < bytecount; i += 4) { + + /* Assign to black the current address of inbyte */ + black = inbyte++; + cyan = inbyte++; + magenta = inbyte++; + yellow = inbyte++; + + if (*magenta + *yellow + *cyan > 0) { /* if any color at all */ + +#if 0 + if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0)) + { + char output[255]; + gs_sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black); + debug_print_string(output, strlen(output)); + } +#endif /* 0 */ + + is_color = 1; + + /* Test whether we 've already computet the value */ + if (*inword == last_color_value) { +/* debug_print_string("\n", 1);*/ + /* copy the result of the old value onto the new position */ + *inword = *last_color; + } else { + /* save a copy of the current color before it will be modified */ + last_color_value = *inword; + if ((*cyan >= *magenta) + && (*magenta >= *yellow) + && (*yellow > 0)) { /* if any grey component */ + DOGCR(cyan, magenta, yellow, black); + } else if ((*cyan >= *yellow) + && (*yellow >= *magenta) + && (*magenta > 0)) { + DOGCR(cyan, yellow, magenta, black); + } else if ((*yellow >= *magenta) + && (*magenta >= *cyan) + && (*cyan > 0)) { + DOGCR(yellow, magenta, cyan, black); + } else if ((*yellow >= *cyan) + && (*cyan >= *magenta) + && (*magenta > 0)) { + DOGCR(yellow, cyan, magenta, black); + } else if ((*magenta >= *yellow) + && (*yellow >= *cyan) + && (*cyan > 0)) { + DOGCR(magenta, yellow, cyan, black); + } else if ((*magenta >= *cyan) + && (*cyan >= *yellow) + && (*yellow > 0)) { + DOGCR(magenta, cyan, yellow, black); + } else { /* do gamma only if no black */ + } +#if 0 + if (ucr > 0) + { + char output[255]; + gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); + debug_print_string(output, strlen(output)); + } +#endif /* 0 */ + *cyan = *(cvalues + *cyan); + *magenta = *(mvalues + *magenta); + *yellow = *(yvalues + *yellow); last_color = inword; /* save pointer */ }/* end current_color */ } /* end of if c+m+y > 0 */