1 /******************************************************************************
2   File:     $Id: pclgen.h,v 1.25 2001/08/18 17:41:29 Martin Rel $
3   Contents: Header for PCL-generating routines
4   Author:   Martin Lottermoser, Greifswaldstrasse 28, 38124 Braunschweig,
5             Germany. E-mail: Martin.Lottermoser@t-online.de.
6 
7 *******************************************************************************
8 *									      *
9 *	Copyright (C) 1999, 2000, 2001 by Martin Lottermoser		      *
10 *	All rights reserved						      *
11 *									      *
12 *******************************************************************************
13 
14   The functions declared in this header file generate code for
15   Hewlett-Packard's Printer Command Language level 3+ ("PCL 3+", also called
16   "PCL 3 Plus").
17 
18   The routines support only raster graphics data.
19 
20 ******************************************************************************/
21 
22 #ifndef _pclgen_h	/* Inclusion protection */
23 #define _pclgen_h
24 
25 /* Configuration management identification */
26 #pragma ident "@(#)$Id: pclgen.h,v 1.25 2001/08/18 17:41:29 Martin Rel $"
27 
28 /*****************************************************************************/
29 
30 /* Standard headers */
31 #include <stdio.h>
32 
33 /*****************************************************************************/
34 
35 /* PCL dialects */
36 typedef enum {
37   pcl_level_3plus_DJ500,
38    /* End Raster Graphics is still ESC * r B, no Shingling */
39   pcl_level_3plus_ERG_both,
40    /* ESC*rbC, otherwise identical with 'pcl_level_3plus_S5' */
41   pcl_level_3plus_S5,
42    /* DeskJet 500 series except 540: old quality commands, no
43       Configure Raster Data, ESC*rC */
44   pcl_level_3plus_S68,
45    /* DeskJet 540, DeskJet 600 and 800 series */
46   pcl_level_3plus_CRD_only
47    /* printers always and only using Configure Raster Data instead of
48       Set Number of Planes per Row and Set Raster Graphics Resolution */
49 } pcl_Level;
50 
51 /* Test macros */
52 #define pcl_use_oldERG(level)		(level <= pcl_level_3plus_DJ500)
53 #define pcl_use_oldquality(level)	(level <= pcl_level_3plus_S5)
54 #define pcl_has_CRD(level)		(level >= pcl_level_3plus_S68)
55 
56 /*****************************************************************************/
57 
58 /*  Page Size codes (permitted arguments for the PCL command "Page Size")
59 
60     There exists an area of confusion around this command in connection with
61     "orientation" in various senses. Unfortunately, the documentation made
62     externally available by Hewlett-Packard is not only incomplete but also
63     inconsistent in this respect. (Well, not only in this respect, but don't
64     get me started on this topic or I'll run out of screen space.) In
65     particular, HP does not distinguish between "input orientation"
66     (orientation of a sheet with respect to the feeding direction: short edge
67     first or long edge first) and "page orientation" (orientation of a sheet
68     with respect to the "up" direction of the page contents: portrait or
69     landscape). This is further complicated by the fact that PCL permits
70     several relative orientations between text and graphics data.
71 
72     The following information is therefore partially in disagreement with
73     HP documentation but does agree with the actual behaviour of the DJ 850C.
74 
75     (1) The Page Orientation command has no influence on the orientation of
76         raster graphics data.
77     (2) Therefore it is possible to define, independent of the Page Orientation
78         setting, a coordinate system on the medium by reference to the printing
79         of raster lines ("rows"): the order of pixels within a row defines what
80         is left and right, and the order in which successive rows are printed
81         distinguishes between up and down. I call this the "raster space"
82         coordinate system. (Its units are irrelevant, but we need the
83         directions.)
84     (3) Because of the way DeskJet printers are constructed (limited memory!),
85         raster space is fixed with respect to the feeding direction: the "up"
86         edge of a sheet in raster space is the one entering the printer first
87         (the leading edge).
88     (4) Hence the media orientation in raster space depends only on the
89         input orientation: short edge first leads to portrait and long edge
90         first to landscape orientation in raster space.
91     (5) Among other effects, the Page Size command sets in particular the
92         printable region for the media size requested.
93     (6) For raster graphics data, clipping occurs at the edge of the printable
94         region. This happens at the right edge in raster space.
95     (7) It is not possible in PCL to specify the input orientation one has
96         chosen. In particular, the sign of a Page Size code has no influence on
97         the printable region as seen in raster space.
98     (8) Some Page Size codes do modify the orientation for text printing on
99         some printers, but this can be overridden with a subsequent Page
100         Orientation command.
101     (9) The Page Size command usually sets up the printable region under the
102         assumption of portrait orientation in raster space (i.e., the input
103         orientation is short edge first). Exceptions occur with envelope sizes
104         (Env10 and EnvDL) on older DeskJet printers (500 and 500C, possibly
105         also 400) where envelopes have to be fed long edge first.
106 
107     The key conclusion to be drawn from this is that the layer represented by
108     the functions in this interface does not have any information on the media
109     orientation in raster space nor can this information be formulated in PCL
110     and passed through this layer. It is information shared between the printer
111     and the client code calling this interface, and the caller must therefore
112     obtain it from an external source.
113 
114     In introducing the concept of a "raster space" I have deliberately avoided
115     the term "physical page" used in the PCL documentation. The latter is not
116     made sufficiently precise, and for printing raster data as done here the
117     first concept is the one required.
118 
119     Two Page Size codes are marked "PS3". These are from Adobe's "LanguageLevel
120     3 Specification and Adobe PostScript 3 Version 3010 Product Supplement"
121     (dated 1997-10-10), page 352, where eight PCL-5 page size codes are listed.
122     Six of these agree with PCL-3 page size codes, and the remaining two are
123     those inserted here and marked "PS3". I have not heard of any PCL-3 printer
124     supporting these two sizes as discrete sizes.
125 
126     The identifiers are usually named after the corresponding 'mediaOption'
127     keyword from Adobe's PPD 4.3 specification.
128 */
129 typedef enum {
130   pcl_ps_default = 0,	/* default size for the printer (e.g., BPD03004 or
131     BPD02926; but note that in some versions of these documents the text
132     representation is wrong, you should look at the hex codes) */
133   pcl_ps_Executive = 1,	/* US Executive (7.25 x 10.5 in).
134     According to Adobe's PPD 4.3 specification, media sizes called by this name
135     vary by up to 1/2 in. */
136   pcl_ps_Letter = 2,	/* US Letter (8.5 x 11 in) */
137   pcl_ps_Legal = 3,	/* US Legal (8.5 x 14 in) */
138   pcl_ps_Tabloid = 6,	/* US Tabloid (11 x 17 in) or Ledger (17 x 11 in)
139                            (DJ1120C). The designation as Tabloid versus Ledger
140                            is not always consistent. I'm following PPD 4.3. */
141   pcl_ps_Statement = 15, /* US Statement (5.5 x 8.5 in) (DJ1120C) */
142   pcl_ps_HPSuperB = 16,	/* Super B (13 x 19 in (330 x 483 mm) according to
143                            DJ1120C, while 305 x 487 mm according to PPD 4.3).
144                            Not supported in PCL 3 according to BPD07645
145                            (HP 2500C). */
146   pcl_ps_A6 = 24,	/* ISO/JIS A6 (105 x 148 mm) */
147   pcl_ps_A5 = 25,	/* ISO/JIS A5 (148 x 210 mm) */
148   pcl_ps_A4 = 26,	/* ISO/JIS A4 (210 x 297 mm) */
149   pcl_ps_A3 = 27,	/* ISO/JIS A3 (297 x 420 mm) (DJ1120C, BPL02327) */
150   pcl_ps_JISB5 = 45,	/* JIS B5 (182 x 257 mm) */
151   pcl_ps_JISB4 = 46,	/* JIS B4 (257 x 364 mm) (DJ1120C, BPL02327) */
152   pcl_ps_Postcard = 71,	/* Japanese Hagaki postcard (100 x 148 mm) */
153   pcl_ps_DoublePostcard = 72,	/* Japanese Oufuko-Hagaki postcard
154                            (148 x 200 mm) (DJ6/8) */
155   pcl_ps_A6Card = 73,	/* "ISO and JIS A6 card" (DJ6/8, DJ1120C). This is the
156                            value given for most DeskJets supporting A6. I do
157                            not know what the difference between this value and
158                            pcl_ps_A6 (24) is. */
159   pcl_ps_Index4x6in = 74,  /* US Index card (4 x 6 in) */
160   pcl_ps_Index5x8in = 75,  /* US Index card (5 x 8 in) */
161   pcl_ps_Index3x5in = 78,  /* US Index card (3 x 5 in) */
162   pcl_ps_EnvMonarch = 80,  /* US Monarch (3.875 x 7.5 in) (PS3, BPL02327) */
163   pcl_ps_Env10 = 81,	/* US No. 10 envelope (4.125 x 9.5 in) */
164   pcl_ps_Env10_Negative = -81,  /* also US No. 10 envelope */
165   /* According to Lexmark-PTR, 89 is US No. 9 envelope (3.875 x 8.875 in). */
166   pcl_ps_EnvDL = 90,	/* ISO DL (110 x 220 mm) */
167   pcl_ps_EnvDL_Negative = -90,  /* also ISO DL. This value is hinted at in
168     TRG500 p. 3-2 in the "Range" line at the bottom of the table and it is
169     explicitly listed in DJ3/4 on p. 36. On a DJ 850C, I found no difference in
170     text orientation with respect to the value 90. */
171   pcl_ps_EnvC5 = 91,	/* ISO C5 (162 x 229 mm) in PCL 5 (PS3, BPL02327) */
172   pcl_ps_EnvC6 = 92,	/* ISO C6 (114 x 162 mm) */
173   pcl_ps_ISOB5 = 100,	/* ISO B5 (176 x 250 mm, BPL02327; the dimensions in
174     millimetres in BPL02327 are wrong, those in inches are right) */
175   pcl_ps_CustomPageSize = 101,  /* Custom page size */
176   pcl_ps_EnvUS_A2 = 109,  /* US A2 envelope (4.375 x 5.75 in) */
177   pcl_ps_EnvChou3 = 110, /* Japanese long Envelope #3 (120 mm x 235 mm)
178                             (DJ1120C) */
179   pcl_ps_EnvChou4 = 111, /* Japanese long envelope #4 (90 mm x 205 mm)
180                             (DJ1120C) */
181   pcl_ps_EnvKaku2 = 113	/* Kaku envelope (240 x 332 mm) (DJ1120C) */
182 } pcl_PageSize;
183 
184 /*****************************************************************************/
185 
186 /* Raster graphics compression methods */
187 typedef enum {
188   pcl_cm_none = 0,	/* Unencoded, non-compressed method */
189   pcl_cm_rl = 1,	/* Run-Length Encoding */
190   pcl_cm_tiff = 2,	/* Tagged Image File Format (TIFF) revision 4.0
191                            "packbits" encoding */
192   pcl_cm_delta = 3,	/* Delta Row Compression */
193   pcl_cm_adaptive = 5,	/* Adaptive Compression */
194   pcl_cm_crdr = 9	/* Compressed Replacement Delta Row Encoding */
195 } pcl_Compression;
196 
197 /* Macro to test for differential compression methods */
198 #define pcl_cm_is_differential(cm)		\
199   ((cm) == pcl_cm_delta || (cm) == pcl_cm_adaptive || (cm) == pcl_cm_crdr)
200 
201 /*****************************************************************************/
202 
203 /* Type and constants for boolean variables */
204 typedef int pcl_bool;
205 #ifndef FALSE
206 #define FALSE	0
207 #else
208 #if FALSE != 0
209 #error "FALSE is defined as non-zero."
210 #endif	/* FALSE != 0 */
211 #endif	/* FALSE */
212 #ifndef TRUE
213 #define TRUE	1
214 #else
215 #if TRUE == 0
216 #error "TRUE is defined as zero."
217 #endif	/* TRUE == 0 */
218 #endif	/* TRUE */
219 
220 /* Palette (process colour model) */
221 typedef enum {
222   pcl_no_palette,	/* Don't send Number of Planes per Row */
223   pcl_black,
224   pcl_CMY,
225   pcl_CMYK,
226   pcl_RGB,		/* Using the RGB palette is discouraged by HP. */
227   pcl_any_palette	/* Don't use this value unless you know what you are
228                            doing. */
229 } pcl_Palette;
230 
231 /* Information per colorant for raster images */
232 typedef struct {
233   unsigned int hres, vres;	/* Resolution in ppi. The orientation refers to
234     raster space. Both values must be non-zero. */
235   unsigned int levels;	/* Number of intensity levels. 2 or larger. */
236 } pcl_ColorantState;
237 
238 /*****************************************************************************/
239 
240 /* 'pcl_Octet' is used to store 8-bit bytes as unsigned numbers. */
241 #ifndef _pcl_Octet_defined
242 #define _pcl_Octet_defined
243 typedef unsigned char pcl_Octet;
244 #endif
245 
246 /* Octet strings */
247 typedef struct {
248   pcl_Octet *str;	/* Data area for storing the octet string. */
249   int length;		/* Length of 'str' in octets (non-negative). */
250 } pcl_OctetString;
251 /*  A "valid" pcl_OctetString is one where either 'length' is zero, or
252     'length' is positive and 'str' is non-NULL and points to a storage
253     area of at least 'length' octets.
254     A "zero" pcl_OctetString is one where 'length' is zero.
255 */
256 
257 /*****************************************************************************/
258 
259 /* File-global data */
260 typedef struct {
261   pcl_Level level;
262 
263   /* Printer initialization */
264   int NULs_to_send;
265   char
266     *PJL_job,		/* PJL job name. Ignored if NULL. */
267     *PJL_language;	/* PJL personality. Ignored if NULL. */
268 
269   /* Additional initialization commands (ignored if zero) */
270   pcl_OctetString
271     init1,		/* send immediately after resetting the printer */
272     init2;		/* send after all other initialization commands */
273 
274   /* Media */
275   pcl_PageSize size;
276   int
277     media_type,
278     media_source,	/* 0: don't request a particular media source */
279     media_destination,	/* 0: don't request a particular media destination.
280                            Not based on HP documentation. */
281     duplex;		/* -1: don't request anything in this respect,
282       0: simplex, 1: duplex long-edge binding, 2: duplex short-edge binding
283       (BPL02705). I assume the correct interpretation of the duplex values to
284       be:
285         1: duplex, print back side with the same top edge in raster space
286         2: duplex, print back side with top and bottom edges exchanged in
287            raster space
288       */
289   pcl_bool manual_feed;
290 
291   /* Print quality selection. Which of these variables are used depends on the
292      PCL level chosen. */
293   int
294     print_quality,
295     depletion,		/* 0: no depletion command */
296     shingling,
297     raster_graphics_quality;
298 
299   /* Colour information */
300   pcl_Palette palette;
301   unsigned int number_of_colorants;
302   pcl_ColorantState *colorant;
303    /* This variable must either be NULL or point to an array of at least
304       'number_of_colorants' elements. The order of colorants is (K)(CMY) except
305       for 'pcl_any_palette'. If the pointer is NULL, 'colorant_array' is used
306       instead. */
307   pcl_ColorantState colorant_array[4];
308     /* Used if 'colorant' is NULL and with the same meaning. This is only
309        possible if 'number_of_colorants' is at most 4. */
310   pcl_bool order_CMYK;
311    /* For pcl_CMYK, should the order of bit planes when sent to the printer be
312       reversed to CMYK instead of KCMY? This is not standard PCL but is needed
313       by at least one Olivetti printer (Olivetti JP792). */
314 
315   int dry_time;	/* negative for "don't send this command" */
316   pcl_Compression compression;
317 
318   /* Derived information managed by the routines declared here. These fields
319      have reliable values only after a call to plc3_init_file(). */
320   unsigned short number_of_bitplanes;
321   unsigned short black_planes;
322   unsigned int minvres;	/* minimal vertical resolution */
323 } pcl_FileData;
324 
325 /*****************************************************************************/
326 
327 /* Types for raster data */
328 
329 typedef struct {
330   /* Data to be provided by the caller */
331   unsigned int width;	/* maximal length of raster lines in pixels at the
332     lowest horizontal resolution. This may be zero to indicate "as large as
333     possible", but this could waste printer memory. Always set this when
334     using an RGB palette unless you have reliable data on the clipping
335     boundary. The value should probably always be a multiple of 8. */
336   pcl_FileData *global;		/* must point to the data used in the last call
337                                    to pcl3_init_file() */
338   pcl_OctetString
339     *previous, *next;
340     /*  These variables point to the sequences of bit planes for the old and
341         the new strip group. The total number of bit planes per group can be
342         obtained in the 'number_of_bitplanes' parameter in '*global'.
343 
344         The order of bit planes within a strip group is as follows:
345         - Each strip group consists of a number of "colorant strips", one for
346           each colorant. All strips in such a group cover the same region on
347           the page. Except for 'pcl_RGB', colorant strips are ordered in the
348           sequence (K)(CMY), independent of 'order_CMYK'. For an RGB palette,
349           the order is (of course) RGB.
350         - Each colorant strip contains a number of pixel lines for this
351           colorant. If there is more than one line, the lines are ordered from
352           top to bottom as seen from raster space. The number of lines is
353           the ratio of that colorant's vertical resolution to the smallest
354           vertical resolution.
355         - Within each pixel line for a colorant, bit planes are ordered from
356           least to most significant. The number of bit planes within a line is
357           pcl3_levels_to_planes(levels) for this colorant.
358           When bit planes are again combined into lines for a particular
359           colorant, the resulting value per pixel denotes the intensity for
360           that colorant. A value of zero denotes absence of that colorant.
361         'previous' will be ignored (and may then be NULL) unless a differential
362         compression method is requested (pcl_cm_is_differential()).
363 
364         When using an RGB palette you should always send bit planes extending
365         over the whole 'width' because shorter bit planes are implicitly
366         extended with null octets and a pixel value of zero denotes black in an
367         RGB palette which is not usually desired.
368     */
369   pcl_Octet *workspace[2];
370     /* Storage for the use of these routines. workspace[0] must be non-NULL,
371        workspace[1] will be ignored except for Delta Row Compression. */
372   size_t workspace_allocated;
373     /* Length allocated for each non-NULL 'workspace[]'. This should be at
374        least 2 larger than the longest possible bit plane, otherwise raster
375        data might have to be sent in uncompressed form even if that would take
376        more space. */
377 
378   /* Internal data for these routines */
379   pcl_Compression current_compression;	/* last compression method used */
380   pcl_OctetString **seed_plane;	/* seed plane indexed by plane index */
381 } pcl_RasterData;
382 
383 /******************************************************************************
384 
385   The routines assume a simple state machine:
386 
387   - You are either on a page or between pages.
388   - If you are on a page, you are either in raster mode or not.
389 
390   You should call pcl3_init_file() before the first page and between pages
391   whenever you change the file-global data (like the resolution). Otherwise,
392   use the ..._begin() and ..._end() functions to navigate between the states.
393 
394   Look into the implementation file for detailed interface descriptions for
395   these routines.
396 
397   The error conventions are the same for all file, page and raster functions:
398   - A return code of zero indicates success.
399   - A positive return code indicates an argument error. This should be
400     avoidable by careful programming.
401   - A negative return code indicates an environment error (e.g., disk overflow).
402   If a function returns with a non-zero code, an error message will have been
403   issued on standard error.
404 
405 ******************************************************************************/
406 
407 /* Auxiliary functions */
408 extern unsigned int pcl3_levels_to_planes(unsigned int levels);
409 extern int pcl3_set_printquality(pcl_FileData *data, int quality);
410 extern int pcl3_set_mediatype(pcl_FileData *data, int mediatype);
411 extern int pcl3_set_oldquality(pcl_FileData *data);
412 extern int pcl_compress(pcl_Compression method, const pcl_OctetString *in,
413   const pcl_OctetString *prev, pcl_OctetString *out);
414 
415 /* File and page functions */
416 extern int pcl3_init_file(FILE *out, pcl_FileData *global);
417 extern int pcl3_begin_page(FILE *out, pcl_FileData *global);
418 extern int pcl3_end_page(FILE *out, pcl_FileData *global);
419 extern int pcl3_end_file(FILE *out, pcl_FileData *global);
420 
421 /* Raster functions */
422 extern int pcl3_begin_raster(FILE *out, pcl_RasterData *data);
423 extern int pcl3_skip_groups(FILE *out, pcl_RasterData *data,
424   unsigned int count);
425 extern int pcl3_transfer_group(FILE *out, pcl_RasterData *data);
426 extern int pcl3_end_raster(FILE *out, pcl_RasterData *data);
427 
428 /*****************************************************************************/
429 
430 #endif	/* Inclusion protection */
431