1 /* Copyright (C) 2001-2012 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,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
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.
14 */
15 
16 
17 /* Sun raster file driver */
18 #include "gdevprn.h"
19 
20 /*
21  * Currently, the only variety of this format supported in this file is
22  * Harlequin's 1-bit "SUN_RAS" with no colormap and odd "};\n" at tail.
23  */
24 
25 #define	RAS_MAGIC	0x59a66a95
26 #define RT_STANDARD	1	/* Raw pixrect image in 68000 byte order */
27 #define RMT_NONE	0	/* ras_maplength is expected to be 0 */
28 typedef struct sun_rasterfile_s {
29         int	ras_magic;		/* magic number */
30         int	ras_width;		/* width (pixels) of image */
31         int	ras_height;		/* height (pixels) of image */
32         int	ras_depth;		/* depth (1, 8, or 24 bits) of pixel */
33         int	ras_length;		/* length (bytes) of image */
34         int	ras_type;		/* type of file; see RT_* below */
35         int	ras_maptype;		/* type of colormap; see RMT_* below */
36         int	ras_maplength;		/* length (bytes) of following map */
37 } sun_rasterfile_t;
38 
39 #ifndef X_DPI
40 #  define X_DPI 72
41 #endif
42 #ifndef Y_DPI
43 #  define Y_DPI 72
44 #endif
45 
46 static dev_proc_print_page(sunhmono_print_page);
47 
48 const gx_device_printer gs_sunhmono_device =
49     prn_device(prn_std_procs, "sunhmono",
50                DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
51                X_DPI, Y_DPI,
52                0, 0, 0, 0,	/* margins */
53                1, sunhmono_print_page);
54 
55 static int
sunhmono_print_page(gx_device_printer * pdev,FILE * prn_stream)56 sunhmono_print_page(gx_device_printer * pdev, FILE * prn_stream)
57 {
58     int gsLineBytes = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
59     /* Output bytes have to be padded to 16 bits. */
60     int rasLineBytes = ROUND_UP(gsLineBytes, 2);
61     int lineCnt;
62     byte *lineStorage; /* Allocated for passing storage to gdev_prn_get_bits() */
63     byte *data;
64     sun_rasterfile_t ras;
65     int code = 0;
66 
67     /*
68       errprintf(pdev->memory, "pdev->width:%d (%d/%d) gsLineBytes:%d rasLineBytes:%d\n",
69       pdev->width, pdev->width/8, pdev->width%8,gsLineBytes,rasLineBytes);
70     */
71     lineStorage = gs_malloc(pdev->memory, gsLineBytes, 1, "rasterfile_print_page(in)");
72     if (lineStorage == 0) {
73         code = gs_note_error(gs_error_VMerror);
74         goto out;
75     }
76     /* Setup values in header */
77     ras.ras_magic = RAS_MAGIC;
78     ras.ras_width = pdev->width;
79     ras.ras_height = pdev->height;
80     ras.ras_depth = 1;
81     ras.ras_length = (rasLineBytes * pdev->height);
82     ras.ras_type = RT_STANDARD;
83     ras.ras_maptype = RMT_NONE;
84     ras.ras_maplength = 0;
85     /* Write header */
86     fwrite(&ras, 1, sizeof(ras), prn_stream);
87     /* For each raster line */
88     for (lineCnt = 0; lineCnt < pdev->height; ++lineCnt) {
89         gdev_prn_get_bits(pdev, lineCnt, lineStorage, &data);
90         fwrite(data, 1, gsLineBytes, prn_stream);
91         if (gsLineBytes % 2)
92             fputc(0, prn_stream); /* pad to even # of bytes with a 0 */
93     }
94     /* The weird file terminator */
95     fwrite("};\n", 1, 3, prn_stream);
96 out:
97     /* Clean up... */
98     gs_free(pdev->memory, lineStorage, gsLineBytes, 1, "rasterfile_print_page(in)");
99     return code;
100 }
101