int tiff_set_fields_for_printer(gx_device_printer *pdev, TIFF *tif, int factor, int adjustWidth) { int width = gx_downscaler_scale(pdev->width, factor); int height = gx_downscaler_scale(pdev->height, factor); int xpi = gx_downscaler_scale(pdev->x_pixels_per_inch, factor); int ypi = gx_downscaler_scale(pdev->y_pixels_per_inch, factor); width = fax_adjusted_width(width, adjustWidth); TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)xpi); TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)ypi); { char revs[10]; #define maxSoftware 40 char softwareValue[maxSoftware]; strncpy(softwareValue, gs_product, maxSoftware); softwareValue[maxSoftware - 1] = 0; sprintf(revs, " %1.2f", gs_revision / 100.0); strncat(softwareValue, revs, maxSoftware - strlen(softwareValue) - 1); TIFFSetField(tif, TIFFTAG_SOFTWARE, softwareValue); } { struct tm tms; time_t t; char dateTimeValue[20]; time(&t); tms = *localtime(&t); sprintf(dateTimeValue, "%04d:%02d:%02d %02d:%02d:%02d", tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, tms.tm_hour, tms.tm_min, tms.tm_sec); TIFFSetField(tif, TIFFTAG_DATETIME, dateTimeValue); } TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); TIFFSetField(tif, TIFFTAG_PAGENUMBER, pdev->PageCount, 0); /* Set the ICC profile. Test to avoid issues with separations and also if the color space is set to LAB, we do that as an enumerated type */ if (pdev->icc_struct != NULL && pdev->icc_struct->device_profile[0] != NULL) { cmm_profile_t *icc_profile = pdev->icc_struct->device_profile[0]; if (icc_profile->num_comps == pdev->color_info.num_components && icc_profile->data_cs != gsCIELAB) { TIFFSetField(tif, TIFFTAG_ICCPROFILE, icc_profile->buffer_size, icc_profile->buffer); } } return 0; }
/* Special version, called with 8 bit grey input to be downsampled to 1bpp * output. */ int tiff_downscale_and_print_page(gx_device_printer *dev, TIFF *tif, int factor, int mfs, int aw) { int code = 0; byte *data = NULL; byte *mfs_data = NULL; int *errors = NULL; int size = gdev_mem_bytes_per_scan_line((gx_device *)dev); int max_size; int row; int n; int width = dev->width/factor; int awidth = width; int padWhite; if (aw > 0) awidth = fax_adjusted_width(awidth); padWhite = awidth - width; if (padWhite < 0) padWhite = 0; max_size = max(size + padWhite*factor, TIFFScanlineSize(tif)) + factor-1; data = gs_alloc_bytes(dev->memory, max_size * factor, "tiff_print_page(data)"); if (data == NULL) return_error(gs_error_VMerror); errors = (int *)gs_alloc_bytes(dev->memory, (awidth+3) * sizeof(int), "tiff_print_page(errors)"); if (errors == NULL) { code = gs_note_error(gs_error_VMerror); goto cleanup; } if (mfs > 1) { mfs_data = (byte *)gs_alloc_bytes(dev->memory, (awidth+1), "tiff_print_page(mfs)"); if (mfs_data == NULL) { code = gs_note_error(gs_error_VMerror); goto cleanup; } } code = TIFFCheckpointDirectory(tif); memset(data, 0xFF, max_size * factor); memset(errors, 0, (awidth+3) * sizeof(int)); if (mfs_data) memset(mfs_data, 0, awidth+1); n = 0; for (row = 0; row < dev->height && code >= 0; row++) { code = gdev_prn_copy_scan_lines(dev, row, data + max_size*n, size); if (code < 0) break; n++; if (n == factor) { /* Do the downsample */ n = 0; code = down_and_out(tif, data, max_size, factor, row/factor, awidth, errors, mfs_data, padWhite); } } #if DISABLED_AS_WE_DONT_ROUND_UP_ANY_MORE if (n != 0 && code >= 0) { row--; while (n != factor) { memset(data + max_size * n, 0xFF, max_size); n++; row++; } code = down_and_out(tif, data, max_size, factor, row/factor, awidth, errors, mfs_data, padWhite); } #endif if (code >= 0) code = TIFFWriteDirectory(tif); cleanup: gs_free_object(dev->memory, mfs_data, "tiff_print_page(mfs)"); gs_free_object(dev->memory, errors, "tiff_print_page(errors)"); gs_free_object(dev->memory, data, "tiff_print_page(data)"); return code; }