1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2 All Rights Reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied, modified
8 or distributed except as expressly authorized under the terms of that
9 license. Refer to licensing information at http://www.artifex.com/
10 or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11 San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 /* $Id: gdevlj56.c 8250 2007-09-25 13:31:24Z giles $ */
14 /* H-P LaserJet 5 & 6 drivers for Ghostscript */
15 #include "gdevprn.h"
16 #include "stream.h"
17 #include "gdevpcl.h"
18 #include "gdevpxat.h"
19 #include "gdevpxen.h"
20 #include "gdevpxop.h"
21 #include "gdevpxut.h"
22
23 /* Define the default resolution. */
24 #ifndef X_DPI
25 # define X_DPI 600
26 #endif
27 #ifndef Y_DPI
28 # define Y_DPI 600
29 #endif
30
31 /* Define the number of blank lines that make it worthwhile to */
32 /* start a new image. */
33 #define MIN_SKIP_LINES 2
34
35 /* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */
36 #define W sizeof(word)
37
38 static dev_proc_open_device(ljet5_open);
39 static dev_proc_close_device(ljet5_close);
40 static dev_proc_print_page(ljet5_print_page);
41
42 static const gx_device_procs ljet5_procs =
43 prn_procs(ljet5_open, gdev_prn_output_page, ljet5_close);
44
45 const gx_device_printer gs_lj5mono_device =
46 prn_device(ljet5_procs, "lj5mono",
47 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
48 X_DPI, Y_DPI,
49 0, 0, 0, 0,
50 1, ljet5_print_page);
51
52 static const gx_device_procs lj5gray_procs =
53 prn_color_procs(ljet5_open, gdev_prn_output_page, ljet5_close,
54 gx_default_gray_map_rgb_color,
55 gx_default_gray_map_color_rgb);
56
57 const gx_device_printer gs_lj5gray_device = {
58 prn_device_body(gx_device_printer, lj5gray_procs, "lj5gray",
59 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
60 X_DPI, Y_DPI,
61 0, 0, 0, 0,
62 1, 8, 255, 0, 256, 1, ljet5_print_page)
63 };
64
65 /* Open the printer, writing the stream header. */
66 static int
ljet5_open(gx_device * pdev)67 ljet5_open(gx_device * pdev)
68 {
69 int code = gdev_prn_open(pdev);
70
71 if (code < 0)
72 return code;
73 code = gdev_prn_open_printer(pdev, true);
74 if (code < 0)
75 return code;
76 {
77 gx_device_printer *const ppdev = (gx_device_printer *)pdev;
78 stream fs;
79 stream *const s = &fs;
80 byte buf[50]; /* arbitrary */
81
82 s_init(s, pdev->memory);
83 swrite_file(s, ppdev->file, buf, sizeof(buf));
84 px_write_file_header(s, pdev);
85 sflush(s); /* don't close */
86 }
87 return 0;
88 }
89
90 /* Close the printer, writing the stream trailer. */
91 static int
ljet5_close(gx_device * pdev)92 ljet5_close(gx_device * pdev)
93 {
94 gx_device_printer *const ppdev = (gx_device_printer *)pdev;
95 int code = gdev_prn_open_printer(pdev, true);
96
97 if (code < 0)
98 return code;
99 px_write_file_trailer(ppdev->file);
100 return gdev_prn_close(pdev);
101 }
102
103 /* Send the page to the printer. For now, just send the whole image. */
104 static int
ljet5_print_page(gx_device_printer * pdev,FILE * prn_stream)105 ljet5_print_page(gx_device_printer * pdev, FILE * prn_stream)
106 {
107 gs_memory_t *mem = pdev->memory;
108 uint line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
109 uint line_size_words = (line_size + W - 1) / W;
110 uint out_size = line_size + (line_size / 127) + 1;
111 word *line = (word *)gs_alloc_byte_array(mem, line_size_words, W, "ljet5(line)");
112 byte *out = gs_alloc_bytes(mem, out_size, "ljet5(out)");
113 int code = 0;
114 int lnum;
115 stream fs;
116 stream *const s = &fs;
117 byte buf[200]; /* arbitrary */
118
119 if (line == 0 || out == 0) {
120 code = gs_note_error(gs_error_VMerror);
121 goto done;
122 }
123 s_init(s, mem);
124 swrite_file(s, prn_stream, buf, sizeof(buf));
125
126 /* Write the page header. */
127 {
128 static const byte page_header[] = {
129 pxtBeginPage,
130 DUSP(0, 0), DA(pxaPoint),
131 pxtSetCursor
132 };
133 static const byte mono_header[] = {
134 DUB(eGray), DA(pxaColorSpace),
135 DUB(e8Bit), DA(pxaPaletteDepth),
136 pxt_ubyte_array, pxt_ubyte, 2, 0xff, 0x00, DA(pxaPaletteData),
137 pxtSetColorSpace
138 };
139 static const byte gray_header[] = {
140 DUB(eGray), DA(pxaColorSpace),
141 pxtSetColorSpace
142 };
143
144 px_write_page_header(s, (gx_device *)pdev);
145 px_write_select_media(s, (gx_device *)pdev, NULL, NULL, 0, false, false);
146 PX_PUT_LIT(s, page_header);
147 if (pdev->color_info.depth == 1)
148 PX_PUT_LIT(s, mono_header);
149 else
150 PX_PUT_LIT(s, gray_header);
151 }
152
153 /* Write the image header. */
154 {
155 static const byte mono_image_header[] = {
156 DA(pxaDestinationSize),
157 DUB(eIndexedPixel), DA(pxaColorMapping),
158 DUB(e1Bit), DA(pxaColorDepth),
159 pxtBeginImage
160 };
161 static const byte gray_image_header[] = {
162 DA(pxaDestinationSize),
163 DUB(eDirectPixel), DA(pxaColorMapping),
164 DUB(e8Bit), DA(pxaColorDepth),
165 pxtBeginImage
166 };
167
168 px_put_us(s, pdev->width);
169 px_put_a(s, pxaSourceWidth);
170 px_put_us(s, pdev->height);
171 px_put_a(s, pxaSourceHeight);
172 px_put_usp(s, pdev->width, pdev->height);
173 if (pdev->color_info.depth == 1)
174 PX_PUT_LIT(s, mono_image_header);
175 else
176 PX_PUT_LIT(s, gray_image_header);
177 }
178
179 /* Write the image data, compressing each line. */
180 for (lnum = 0; lnum < pdev->height; ++lnum) {
181 int ncompr;
182 static const byte line_header[] = {
183 DA(pxaStartLine),
184 DUS(1), DA(pxaBlockHeight),
185 DUB(eRLECompression), DA(pxaCompressMode),
186 pxtReadImage
187 };
188
189 code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) line, line_size);
190 if (code < 0)
191 goto fin;
192 px_put_us(s, lnum);
193 PX_PUT_LIT(s, line_header);
194 ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words,
195 out, true);
196 px_put_data_length(s, ncompr);
197 px_put_bytes(s, out, ncompr);
198 }
199
200 /* Finish up. */
201 fin:
202 spputc(s, pxtEndImage);
203 spputc(s, pxtEndPage);
204 sflush(s);
205 done:
206 gs_free_object(mem, out, "ljet5(out)");
207 gs_free_object(mem, line, "ljet5(line)");
208 return code;
209 }
210