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) 1996, 1997 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: gdevccr.c,v 1.6 2005/01/19 00:24:07 dan Exp $*/
18
/* CalComp Raster Format driver */
19
#include "gdevprn.h"
20
 
21
/*
22
 * Please contact the author, Ernst Muellner (ernst.muellner@oenzl.siemens.de),
23
 * if you have any questions about this driver.
24
 */
25
 
26
#define CCFILESTART(p) putc(0x02, p)
27
#define CCFILEEND(p) putc(0x04, p)
28
#define CCNEWPASS(p) putc(0x0c, p)
29
#define CCEMPTYLINE(p) putc(0x0a, p)
30
#define CCLINESTART(len,p) do{ putc(0x1b,p);putc(0x4b,p);putc(len>>8,p); \
31
			       putc(len&0xff,p);} while(0)
32
 
33
#define CPASS (0)
34
#define MPASS (1)
35
#define YPASS (2)
36
#define NPASS (3)
37
 
38
 
39
typedef struct cmyrow_s
40
	  {
41
	    int current;
42
            int _cmylen[NPASS];
43
	    int is_used;
44
	    char cname[4];
45
	    char mname[4];
46
	    char yname[4];
47
            unsigned char *_cmybuf[NPASS];
48
	  } cmyrow;
49
 
50
#define clen _cmylen[CPASS]
51
#define mlen _cmylen[MPASS]
52
#define ylen _cmylen[YPASS]
53
#define cmylen _cmylen
54
 
55
#define cbuf _cmybuf[CPASS]
56
#define mbuf _cmybuf[MPASS]
57
#define ybuf _cmybuf[YPASS]
58
#define cmybuf _cmybuf
59
 
60
private int alloc_rb( gs_memory_t *mem, cmyrow **rb, int rows);
61
private int alloc_line( gs_memory_t *mem, cmyrow *row, int cols);
62
private void add_cmy8(cmyrow *rb, char c, char m, char y);
63
private void write_cpass(cmyrow *buf, int rows, int pass, FILE * pstream);
64
private void free_rb_line( gs_memory_t *mem, cmyrow *rbuf, int rows, int cols);
65
 
66
struct gx_device_ccr_s {
67
	gx_device_common;
68
	gx_prn_device_common;
69
        /* optional parameters */
70
};
71
typedef struct gx_device_ccr_s gx_device_ccr;
72
 
73
#define bdev ((gx_device_ccr *)pdev)
74
 
75
/* ------ The device descriptors ------ */
76
 
77
/*
78
 * Default X and Y resolution.
79
 */
80
#define X_DPI 300
81
#define Y_DPI 300
82
#define DEFAULT_WIDTH_10THS_A3 117
83
#define DEFAULT_HEIGHT_10THS_A3 165
84
 
85
/* Macro for generating ccr device descriptors. */
86
#define ccr_prn_device(procs, dev_name, margin, num_comp, depth, max_gray, max_rgb, print_page)\
87
{	prn_device_body(gx_device_ccr, procs, dev_name,\
88
	  DEFAULT_WIDTH_10THS_A3, DEFAULT_HEIGHT_10THS_A3, X_DPI, Y_DPI,\
89
	  margin, margin, margin, margin,\
90
	  num_comp, depth, max_gray, max_rgb, max_gray + 1, max_rgb + 1,\
91
	  print_page)\
92
}
93
 
94
/* For CCR, we need our own color mapping procedures. */
95
private dev_proc_map_rgb_color(ccr_map_rgb_color);
96
private dev_proc_map_color_rgb(ccr_map_color_rgb);
97
 
98
 
99
/* And of course we need our own print-page routine. */
100
private dev_proc_print_page(ccr_print_page);
101
 
102
/* The device procedures */
103
private gx_device_procs ccr_procs =
104
    prn_color_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
105
		    ccr_map_rgb_color, ccr_map_color_rgb);
106
 
107
/* The device descriptors themselves */
108
gx_device_ccr far_data gs_ccr_device =
109
  ccr_prn_device(ccr_procs, "ccr", 0.2, 3, 8, 1, 1,
110
		 ccr_print_page);
111
 
112
/* ------ Color mapping routines ------ */
113
/* map an rgb color to a ccr cmy bitmap */
114
private gx_color_index
115
ccr_map_rgb_color(gx_device *pdev, const ushort cv[])
116
{
117
  ushort r, g, b;
118
  register int shift = gx_color_value_bits - 1;
119
 
120
  r = cv[0]; g = cv[1]; b = cv[2];
121
  r>>=shift;
122
  g>>=shift;
123
  b>>=shift;
124
 
125
  r=1-r; g=1-g; b=1-b; /* rgb -> cmy */
126
  return r<<2 | g<<1 | b;
127
}
128
 
129
/* map an ccr cmy bitmap to a rgb color */ 
130
private int
131
ccr_map_color_rgb(gx_device *pdev, gx_color_index color, ushort rgb[3])
132
{
133
  rgb[2]=(1-(color >>2))*gx_max_color_value; /* r */
134
  rgb[1]=(1-( (color & 0x2) >> 1))*gx_max_color_value; /* g */
135
  rgb[0]=(1-(color & 0x1))*gx_max_color_value; /* b */
136
  return 0;
137
}
138
/* ------ print page routine ------ */
139
 
140
 
141
private int
142
ccr_print_page(gx_device_printer *pdev, FILE *pstream)
143
{
144
  cmyrow *linebuf;
145
  int line_size = gdev_prn_raster((gx_device *)pdev);
146
  int pixnum = pdev->width;
147
  int lnum = pdev->height;
148
  int l, p, b;
149
  int cmy, c, m, y;
150
  byte *in;
151
  byte *data;
152
 
153
  if((in = (byte *)gs_malloc(pdev->memory, line_size, 1, "gsline")) == NULL)
154
     return_error(gs_error_VMerror);
155
 
156
  if(alloc_rb( pdev->memory, &linebuf, lnum))
157
    {
158
      gs_free(pdev->memory, in, line_size, 1, "gsline");
159
      return_error(gs_error_VMerror);
160
    }
161
 
162
  for ( l = 0; l < lnum; l++ )
163
     {	gdev_prn_get_bits(pdev, l, in, &data);
164
        if(alloc_line(pdev->memory, &linebuf[l], pixnum))
165
	  {
166
	    gs_free(pdev->memory, in, line_size, 1, "gsline");
167
	    free_rb_line( pdev->memory, linebuf, lnum, pixnum );
168
	    return_error(gs_error_VMerror);
169
	  }
170
        for ( p=0; p< pixnum; p+=8)
171
	  {
172
	    c=m=y=0;
173
            for(b=0; b<8; b++)
174
	    {
175
              c <<= 1; m <<= 1; y <<= 1;
176
	      if(p+b < pixnum)
177
		cmy = *data;
178
	      else
179
		cmy = 0;
180
 
181
              c |= cmy>>2;
182
	      m |= (cmy>>1) & 0x1;
183
	      y |= cmy & 0x1;
184
	      data++;
185
	    }
186
	    add_cmy8(&linebuf[l], c, m, y);
187
	  }
188
      }
189
CCFILESTART(pstream);
190
write_cpass(linebuf, lnum, YPASS, pstream);
191
CCNEWPASS(pstream);
192
write_cpass(linebuf, lnum, MPASS, pstream);
193
CCNEWPASS(pstream);
194
write_cpass(linebuf, lnum, CPASS, pstream);
195
CCFILEEND(pstream);		 
196
 
197
/* clean up */	      
198
gs_free(pdev->memory, in, line_size, 1, "gsline");
199
free_rb_line( pdev->memory, linebuf, lnum, pixnum );
200
return 0;
201
}
202
 
203
 
204
/* ------ Internal routines ------ */
205
 
206
 
207
private int alloc_rb( gs_memory_t *mem, cmyrow **rb, int rows)
208
  {
209
  *rb = (cmyrow*) gs_malloc(mem, rows, sizeof(cmyrow), "rb");
210
  if( *rb == 0)
211
    return_error(gs_error_VMerror);
212
  else
213
    {
214
      int r;
215
      for(r=0; r<rows; r++)
216
	{
217
	  sprintf((*rb)[r].cname, "C%02x", r);
218
	  sprintf((*rb)[r].mname, "M%02x", r);
219
	  sprintf((*rb)[r].yname, "Y%02x", r);
220
	  (*rb)[r].is_used=0;
221
	}
222
      return 0;
223
    }
224
}
225
 
226
private int alloc_line( gs_memory_t *mem, cmyrow *row, int cols)
227
{
228
  int suc;
229
  suc=((row->cbuf = (unsigned char *) gs_malloc(mem, cols,1, row->cname)) &&
230
       (row->mbuf = (unsigned char *) gs_malloc(mem, cols,1, row->mname)) &&
231
       (row->ybuf = (unsigned char *) gs_malloc(mem, cols,1, row->yname)));
232
  if(suc == 0)
233
       {
234
       gs_free(mem, row->cbuf, cols,1, row->cname);
235
       gs_free(mem, row->mbuf, cols,1, row->mname);
236
       gs_free(mem, row->ybuf, cols,1, row->yname);
237
 
238
       return_error(gs_error_VMerror);
239
     }
240
  row->is_used = 1;
241
  row->current = row->clen = row->mlen = row->ylen = 0;
242
  return 0;
243
}
244
 
245
private void add_cmy8(cmyrow *rb, char c, char m, char y)
246
{
247
  int cur=rb->current;
248
  rb->cbuf[cur]=c;
249
  if(c)
250
    rb->clen=cur+1;
251
  rb->mbuf[cur]=m;
252
  if(m)
253
    rb->mlen=cur+1;
254
  rb->ybuf[cur]=y;
255
  if(y)
256
    rb->ylen=cur+1;
257
  rb->current++;
258
  return;
259
}
260
 
261
private void write_cpass(cmyrow *buf, int rows, int pass, FILE * pstream)
262
{
263
  int row, len;
264
    for(row=0; row<rows; row++)
265
      {
266
      len=buf[row].cmylen[pass];
267
      if(len == 0)
268
	CCEMPTYLINE(pstream);
269
      else
270
	{
271
	  CCLINESTART(len,pstream);
272
          fwrite( buf[row].cmybuf[pass], len, 1, pstream);
273
        }
274
    }
275
  return;
276
}
277
 
278
private void free_rb_line( gs_memory_t *mem, cmyrow *rbuf, int rows, int cols)
279
{
280
  int i;
281
  for(i=0; i<rows; i++)
282
    {
283
      if(rbuf[i].is_used)
284
	{
285
          gs_free(mem, rbuf[i].cbuf, cols, 1, rbuf[i].cname);
286
	  gs_free(mem, rbuf[i].mbuf, cols, 1, rbuf[i].mname);
287
	  gs_free(mem, rbuf[i].ybuf, cols, 1, rbuf[i].yname);
288
	  rbuf[i].is_used = 0;
289
	}
290
      else
291
	break;
292
    }
293
  gs_free( mem, rbuf, rows, sizeof(cmyrow),  "rb");
294
  return;
295
}