Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1992, 1993, 1997, 1998, 1999, 2000 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: gdevbmp.c,v 1.12 2005/10/20 19:42:18 ray Exp $ */
18
/* .BMP file format output drivers */
19
#include "gdevprn.h"
20
#include "gdevpccm.h"
21
#include "gdevbmp.h"
22
 
23
/* ------ The device descriptors ------ */
24
 
25
private dev_proc_print_page(bmp_print_page);
26
private dev_proc_print_page(bmp_cmyk_print_page);
27
 
28
/* Monochrome. */
29
 
30
const gx_device_printer gs_bmpmono_device =
31
prn_device(prn_std_procs, "bmpmono",
32
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
33
	   X_DPI, Y_DPI,
34
	   0, 0, 0, 0,		/* margins */
35
	   1, bmp_print_page);
36
 
37
/* 8-bit (SuperVGA-style) grayscale . */
38
/* (Uses a fixed palette of 256 gray levels.) */
39
 
40
private const gx_device_procs bmpgray_procs =
41
prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
42
		gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb);
43
const gx_device_printer gs_bmpgray_device = {
44
  prn_device_body(gx_device_printer, bmpgray_procs, "bmpgray",
45
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
46
	   X_DPI, Y_DPI,
47
	   0, 0, 0, 0,		/* margins */
48
	   1, 8, 255, 0, 256, 0, bmp_print_page)
49
};
50
 
51
/* 1-bit-per-plane separated CMYK color. */
52
 
53
#define bmp_cmyk_procs(p_map_color_rgb, p_map_cmyk_color)\
54
    gdev_prn_open, NULL, NULL, gdev_prn_output_page, gdev_prn_close,\
55
    NULL, p_map_color_rgb, NULL, NULL, NULL, NULL, NULL, NULL,\
56
    gdev_prn_get_params, gdev_prn_put_params,\
57
    p_map_cmyk_color, NULL, NULL, NULL, gx_page_device_get_page_device
58
 
59
private const gx_device_procs bmpsep1_procs = {
60
    bmp_cmyk_procs(cmyk_1bit_map_color_rgb, cmyk_1bit_map_cmyk_color)
61
};
62
const gx_device_printer gs_bmpsep1_device = {
63
  prn_device_body(gx_device_printer, bmpsep1_procs, "bmpsep1",
64
	DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
65
	X_DPI, Y_DPI,
66
	0,0,0,0,			/* margins */
67
	4, 4, 1, 1, 2, 2, bmp_cmyk_print_page)
68
};
69
 
70
/* 8-bit-per-plane separated CMYK color. */
71
 
72
private const gx_device_procs bmpsep8_procs = {
73
    bmp_cmyk_procs(cmyk_8bit_map_color_rgb, cmyk_8bit_map_cmyk_color)
74
};
75
const gx_device_printer gs_bmpsep8_device = {
76
  prn_device_body(gx_device_printer, bmpsep8_procs, "bmpsep8",
77
	DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
78
	X_DPI, Y_DPI,
79
	0,0,0,0,			/* margins */
80
	4, 32, 255, 255, 256, 256, bmp_cmyk_print_page)
81
};
82
 
83
/* 4-bit planar (EGA/VGA-style) color. */
84
 
85
private const gx_device_procs bmp16_procs =
86
prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
87
		pc_4bit_map_rgb_color, pc_4bit_map_color_rgb);
88
const gx_device_printer gs_bmp16_device = {
89
  prn_device_body(gx_device_printer, bmp16_procs, "bmp16",
90
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
91
	   X_DPI, Y_DPI,
92
	   0, 0, 0, 0,		/* margins */
93
	   3, 4, 1, 1, 2, 2, bmp_print_page)
94
};
95
 
96
/* 8-bit (SuperVGA-style) color. */
97
/* (Uses a fixed palette of 3,3,2 bits.) */
98
 
99
private const gx_device_procs bmp256_procs =
100
prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
101
		pc_8bit_map_rgb_color, pc_8bit_map_color_rgb);
102
const gx_device_printer gs_bmp256_device = {
103
  prn_device_body(gx_device_printer, bmp256_procs, "bmp256", 
104
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
105
	   X_DPI, Y_DPI,
106
	   0, 0, 0, 0,		/* margins */
107
	   3, 8, 5, 5, 6, 6, bmp_print_page)
108
};
109
 
110
/* 24-bit color. */
111
 
112
private const gx_device_procs bmp16m_procs =
113
prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
114
		bmp_map_16m_rgb_color, bmp_map_16m_color_rgb);
115
const gx_device_printer gs_bmp16m_device =
116
prn_device(bmp16m_procs, "bmp16m",
117
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
118
	   X_DPI, Y_DPI,
119
	   0, 0, 0, 0,		/* margins */
120
	   24, bmp_print_page);
121
 
122
/* 32-bit CMYK color (outside the BMP specification). */
123
 
124
private const gx_device_procs bmp32b_procs = {
125
    bmp_cmyk_procs(cmyk_8bit_map_color_rgb, gx_default_cmyk_map_cmyk_color)
126
};
127
const gx_device_printer gs_bmp32b_device =
128
prn_device(bmp32b_procs, "bmp32b",
129
	   DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
130
	   X_DPI, Y_DPI,
131
	   0, 0, 0, 0,		/* margins */
132
	   32, bmp_print_page);
133
 
134
/* ------ Private definitions ------ */
135
 
136
/* Write out a page in BMP format. */
137
/* This routine is used for all non-separated formats. */
138
private int
139
bmp_print_page(gx_device_printer * pdev, FILE * file)
140
{
141
    uint raster = gdev_prn_raster(pdev);
142
    /* BMP scan lines are padded to 32 bits. */
143
    uint bmp_raster = raster + (-(int)raster & 3);
144
    byte *row = gs_alloc_bytes(pdev->memory, bmp_raster, "bmp file buffer");
145
    int y;
146
    int code;		/* return code */
147
 
148
    if (row == 0)		/* can't allocate row buffer */
149
	return_error(gs_error_VMerror);
150
    memset(row+raster, 0, bmp_raster - raster); /* clear the padding bytes */
151
 
152
    /* Write the file header. */
153
 
154
    code = write_bmp_header(pdev, file);
155
    if (code < 0)
156
	goto done;
157
 
158
    /* Write the contents of the image. */
159
    /* BMP files want the image in bottom-to-top order! */
160
 
161
    for (y = pdev->height - 1; y >= 0; y--) {
162
	gdev_prn_copy_scan_lines(pdev, y, row, raster);
163
	fwrite((const char *)row, bmp_raster, 1, file);
164
    }
165
 
166
done:
167
    gs_free_object(pdev->memory, row, "bmp file buffer");
168
 
169
    return code;
170
}
171
 
172
/* Write out a page in separated CMYK format. */
173
/* This routine is used for all formats. */
174
private int
175
bmp_cmyk_print_page(gx_device_printer * pdev, FILE * file)
176
{
177
    int plane_depth = pdev->color_info.depth / 4;
178
    uint raster = (pdev->width * plane_depth + 7) >> 3;
179
    /* BMP scan lines are padded to 32 bits. */
180
    uint bmp_raster = raster + (-(int)raster & 3);
181
    byte *row = gs_alloc_bytes(pdev->memory, bmp_raster, "bmp file buffer");
182
    int y;
183
    int code = 0;		/* return code */
184
    int plane;
185
 
186
    if (row == 0)		/* can't allocate row buffer */
187
	return_error(gs_error_VMerror);
188
    memset(row+raster, 0, bmp_raster - raster); /* clear the padding bytes */
189
 
190
    for (plane = 0; plane <= 3; ++plane) {
191
	gx_render_plane_t render_plane;
192
 
193
	/* Write the page header. */
194
 
195
    	code = write_bmp_separated_header(pdev, file);
196
	if (code < 0)
197
	    break;
198
 
199
	/* Write the contents of the image. */
200
	/* BMP files want the image in bottom-to-top order! */
201
 
202
	gx_render_plane_init(&render_plane, (gx_device *)pdev, plane);
203
	for (y = pdev->height - 1; y >= 0; y--) {
204
	    byte *actual_data;
205
	    uint actual_raster;
206
 
207
	    code = gdev_prn_get_lines(pdev, y, 1, row, bmp_raster,
208
				      &actual_data, &actual_raster,
209
				      &render_plane);
210
	    if (code < 0)
211
		goto done;
212
	    fwrite((const char *)actual_data, bmp_raster, 1, file);
213
	}
214
    }
215
 
216
done:
217
    gs_free_object(pdev->memory, row, "bmp file buffer");
218
 
219
    return code;
220
}