1
/* Copyright (C) 2001-2012 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied,
8
modified or distributed except as expressly authorized under the terms
9
of the license contained in the file LICENSE in this distribution.
11
Refer to licensing information at http://www.artifex.com or contact
12
Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael,
13
CA 94903, U.S.A., +1(415)492-9861, for further information.
17
/* 12-bit & 24-bit RGB uncompressed TIFF driver */
19
#include "stdint_.h" /* for tiff.h */
27
* Thanks to Alan Barclay <alan@escribe.co.uk> for donating the original
28
* version of this code to Ghostscript.
31
/* ------ The device descriptors ------ */
33
/* Default X and Y resolution */
37
static dev_proc_print_page(tiff12_print_page);
38
static dev_proc_print_page(tiff_rgb_print_page);
40
/* FIXME: From initial analysis this is NOT safe for bg_printing, but might be fixable */
42
static const gx_device_procs tiff12_procs =
43
prn_color_params_procs(tiff_open, gdev_prn_output_page_seekable, tiff_close,
44
gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
45
tiff_get_params, tiff_put_params);
46
static const gx_device_procs tiff24_procs =
47
prn_color_params_procs(tiff_open, gdev_prn_output_page_seekable, tiff_close,
48
gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb,
49
tiff_get_params, tiff_put_params);
51
const gx_device_tiff gs_tiff12nc_device = {
52
prn_device_std_body(gx_device_tiff, tiff12_procs, "tiff12nc",
53
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
56
24, tiff12_print_page),
57
arch_is_big_endian /* default to native endian (i.e. use big endian iff the platform is so*/,
58
false, /* default to not bigtiff */
60
TIFF_DEFAULT_STRIP_SIZE,
61
TIFF_DEFAULT_DOWNSCALE,
63
1 /* MinFeatureSize */
66
const gx_device_tiff gs_tiff24nc_device = {
67
prn_device_std_body(gx_device_tiff, tiff24_procs, "tiff24nc",
68
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
71
24, tiff_rgb_print_page),
72
arch_is_big_endian /* default to native endian (i.e. use big endian iff the platform is so*/,
73
false, /* default to not bigtiff */
75
TIFF_DEFAULT_STRIP_SIZE,
76
TIFF_DEFAULT_DOWNSCALE,
78
1 /* MinFeatureSize */
81
const gx_device_tiff gs_tiff48nc_device = {
82
prn_device_std_body(gx_device_tiff, tiff24_procs, "tiff48nc",
83
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
86
48, tiff_rgb_print_page),
87
arch_is_big_endian /* default to native endian (i.e. use big endian iff the platform is so*/,
88
false, /* default to not bigtiff */
90
TIFF_DEFAULT_STRIP_SIZE,
91
TIFF_DEFAULT_DOWNSCALE,
93
1 /* MinFeatureSize */
96
/* ------ Private functions ------ */
99
tiff_set_rgb_fields(gx_device_tiff *tfdev)
101
/* Put in a switch statement in case we want to have others */
102
switch (tfdev->icc_struct->device_profile[0]->data_cs) {
104
TIFFSetField(tfdev->tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
107
TIFFSetField(tfdev->tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_ICCLAB);
110
TIFFSetField(tfdev->tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
113
TIFFSetField(tfdev->tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
114
TIFFSetField(tfdev->tif, TIFFTAG_SAMPLESPERPIXEL, 3);
116
tiff_set_compression((gx_device_printer *)tfdev, tfdev->tif,
117
tfdev->Compression, tfdev->MaxStripSize);
121
tiff12_print_page(gx_device_printer * pdev, FILE * file)
123
gx_device_tiff *const tfdev = (gx_device_tiff *)pdev;
126
/* open the TIFF device */
127
if (gdev_prn_file_is_new(pdev)) {
128
tfdev->tif = tiff_from_filep(pdev, pdev->dname, file, tfdev->BigEndian, tfdev->UseBigTIFF);
130
return_error(gs_error_invalidfileaccess);
133
code = gdev_tiff_begin_page(tfdev, file);
137
TIFFSetField(tfdev->tif, TIFFTAG_BITSPERSAMPLE, 4);
138
tiff_set_rgb_fields(tfdev);
140
TIFFCheckpointDirectory(tfdev->tif);
142
/* Write the page data. */
145
int size = gdev_prn_raster(pdev);
146
byte *data = gs_alloc_bytes(pdev->memory, size, "tiff12_print_page");
149
return_error(gs_error_VMerror);
151
memset(data, 0, size);
153
for (y = 0; y < pdev->height; ++y) {
158
code = gdev_prn_copy_scan_lines(pdev, y, data, size);
162
for (src = data, dest = data, x = 0; x < size;
163
src += 6, dest += 3, x += 6
165
dest[0] = (src[0] & 0xf0) | (src[1] >> 4);
166
dest[1] = (src[2] & 0xf0) | (src[3] >> 4);
167
dest[2] = (src[4] & 0xf0) | (src[5] >> 4);
169
TIFFWriteScanline(tfdev->tif, data, y, 0);
171
gs_free_object(pdev->memory, data, "tiff12_print_page");
173
TIFFWriteDirectory(tfdev->tif);
180
tiff_rgb_print_page(gx_device_printer * pdev, FILE * file)
182
gx_device_tiff *const tfdev = (gx_device_tiff *)pdev;
185
/* open the TIFF device */
186
if (gdev_prn_file_is_new(pdev)) {
187
tfdev->tif = tiff_from_filep(pdev, pdev->dname, file, tfdev->BigEndian, tfdev->UseBigTIFF);
189
return_error(gs_error_invalidfileaccess);
192
code = gdev_tiff_begin_page(tfdev, file);
196
TIFFSetField(tfdev->tif, TIFFTAG_BITSPERSAMPLE,
197
pdev->color_info.depth / pdev->color_info.num_components);
198
tiff_set_rgb_fields(tfdev);
200
/* Write the page data. */
201
return tiff_print_page(pdev, tfdev->tif, 0);