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