~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gdevstc2.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 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, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
 
 
14
/* $Id: gdevstc2.c 8022 2007-06-05 22:23:38Z giles $*/
 
15
/* Epson Stylus-Color Printer-Driver */
 
16
 
 
17
/***
 
18
     This file holds two implementations of the Floyd-Steinberg error
 
19
     diffusion-algorithm. This algorithms are intended for high quality
 
20
     printing in conjunction with the PostScript-Header stcolor.ps:
 
21
 
 
22
          gs -sDEVICE=stcolor <other options> stcolor.ps ...
 
23
 
 
24
     Most prominent option is -sDithering=xxx, to select the algorithm:
 
25
 
 
26
     fsmono - monochrome Floyd-Steinberg
 
27
     fsrgb  - 3-Component Floyd-Steinberg
 
28
     fsx4   - 4-Component Floyd-Steinberg (Bad results)
 
29
 
 
30
     fscmyk - Modified 4-Component Floyd-Steinberg
 
31
              (Algorithmically identical with hscmyk, but slower)
 
32
 
 
33
 ***/
 
34
 
 
35
#include "gdevstc.h"
 
36
 
 
37
#include <stdlib.h>     /* for rand */
 
38
 
 
39
/*
 
40
   Both algorithms require an error-buffer of 
 
41
 
 
42
       3 + 3*num_components +1*scan long-items.
 
43
 
 
44
   and must consequently set up to work with longs. 
 
45
   It is just a Floyd-Steinberg-algorithm applied to each component.
 
46
 
 
47
 */
 
48
 
 
49
/*
 
50
 * Due to the -selfdefined- ugly coding of the output-data, we need
 
51
 * some conversion. But since this includes the black-separation, I
 
52
 * did not change the definition.
 
53
 *
 
54
 * This algorithm stores the 1st component in the LSB, thus it
 
55
 * reverts the order used by the basic driver.
 
56
 */
 
57
 
 
58
static const byte grayvals[2]  = { 0, BLACK };
 
59
 
 
60
static const byte  rgbvals[8]  = {
 
61
   0, RED, GREEN, RED|GREEN, BLUE, BLUE|RED, BLUE|GREEN, BLUE|RED|GREEN};
 
62
 
 
63
static const byte cmykvals[16] = {
 
64
      0, CYAN,MAGENTA,CYAN|MAGENTA,YELLOW,YELLOW|CYAN,YELLOW|MAGENTA,BLACK,
 
65
  BLACK,BLACK,  BLACK,       BLACK, BLACK,      BLACK,         BLACK,BLACK};
 
66
 
 
67
static const byte  *const pixelconversion[5] = {
 
68
   NULL, grayvals, NULL, rgbvals, cmykvals};
 
69
 
 
70
 
 
71
int 
 
72
stc_fs(stcolor_device *sdev,int npixel,byte *bin,byte *bbuf,byte *out) 
 
73
{
 
74
 
 
75
     long *in  = (long *) bin;
 
76
     long *buf = (long *) bbuf;
 
77
 
 
78
/* ============================================================= */
 
79
   if(npixel > 0) {  /* npixel >  0 -> scanline-processing       */
 
80
/* ============================================================= */
 
81
 
 
82
      int bstep,pstart,pstop,pstep,p;
 
83
      long spotsize,threshold,*errc,*errv;
 
84
      const byte *pixel2stc;
 
85
 
 
86
      if(buf[0] >= 0) { /* run forward */
 
87
        buf[0] = -1;
 
88
        bstep  = 1;
 
89
        pstep  = sdev->color_info.num_components;
 
90
        pstart = 0;
 
91
        pstop  = npixel * pstep;
 
92
 
 
93
      } else {                  /* run backward */
 
94
        buf[0] =  1;
 
95
        bstep  = -1;
 
96
        pstep  = -sdev->color_info.num_components;
 
97
        pstop  = pstep;
 
98
        pstart = (1-npixel) * pstep;
 
99
        out   += npixel-1;
 
100
      }                   /* forward / backward */
 
101
 
 
102
/*    --------------------------------------------------------------------- */
 
103
      if(in == NULL) return 0;  /* almost ignore the 'white calls' */
 
104
/*    --------------------------------------------------------------------- */
 
105
 
 
106
      spotsize  = buf[1];
 
107
      threshold = buf[2];
 
108
      errc      = buf+3;
 
109
      errv      = errc + 2*sdev->color_info.num_components;
 
110
      pixel2stc = pixelconversion[sdev->color_info.num_components];
 
111
 
 
112
      for(p = pstart; p != pstop; p += pstep) { /* loop over pixels */
 
113
         int c;     /* component-number */
 
114
         int pixel; /* internal pxel-value */
 
115
 
 
116
         pixel = 0;
 
117
 
 
118
         for(c = 0; c < sdev->color_info.num_components; c++) { /* comp */
 
119
            long cv; /* component value */
 
120
 
 
121
            cv = in[p+c] + errv[p+c] + errc[c] - ((errc[c]+4)>>3);
 
122
            if(cv > threshold) {
 
123
               pixel |= 1<<c;
 
124
               cv    -= spotsize;
 
125
            }
 
126
            errv[p+c-pstep] += ((3*cv+8)>>4);        /* 3/16 */
 
127
            errv[p+c      ]  = ((5*cv  )>>4)         /* 5/16 */
 
128
                             + ((errc[c]+4)>>3);     /* 1/16 (rest) */
 
129
            errc[c]          = cv                    /* 8/16 (neu) */
 
130
                             - ((5*cv  )>>4)
 
131
                             - ((3*cv+8)>>4);
 
132
         }                                                      /* comp */
 
133
 
 
134
         *out = pixel2stc[pixel];
 
135
         out += bstep;
 
136
      }                                         /* loop over pixels */
 
137
 
 
138
 
 
139
/* ============================================================= */
 
140
   } else {          /* npixel <= 0 -> initialisation            */
 
141
/* ============================================================= */
 
142
 
 
143
      int i,i2do;
 
144
      long rand_max;
 
145
      double offset,scale;
 
146
 
 
147
/*
 
148
 * check wether the number of components is valid
 
149
 */
 
150
      if((sdev->color_info.num_components < 0)                         ||
 
151
         (sdev->color_info.num_components >= countof(pixelconversion)) ||
 
152
         (pixelconversion[sdev->color_info.num_components] == NULL)) return -1;
 
153
 
 
154
/*
 
155
 * check wether stcdither & TYPE are correct
 
156
 */
 
157
      if(( sdev->stc.dither                    == NULL) ||
 
158
         ((sdev->stc.dither->flags & STC_TYPE) != STC_LONG))         return -2;
 
159
 
 
160
/*
 
161
 * check wether the buffer-size is sufficiently large
 
162
 */
 
163
      if(((sdev->stc.dither->flags/STC_SCAN) < 1) ||
 
164
         ( sdev->stc.dither->bufadd          <
 
165
          (3 + 3*sdev->color_info.num_components)))                  return -3;
 
166
/*
 
167
 * must neither have STC_DIRECT nor STC_WHITE
 
168
 */
 
169
      if(sdev->stc.dither->flags & (STC_DIRECT | STC_WHITE))         return -4;
 
170
 
 
171
/*
 
172
 * compute initial values
 
173
 */
 
174
/* -- direction */
 
175
     buf[0] = 1;
 
176
 
 
177
/* -- "spotsize" */
 
178
     scale  = sdev->stc.dither->minmax[1];
 
179
     buf[1] = (long)(scale + (scale > 0.0 ? 0.5 : -0.5));
 
180
 
 
181
/* -- "threshold" */
 
182
     offset = sdev->stc.dither->minmax[0];
 
183
     scale -= offset;
 
184
     if((offset+0.5*scale) > 0.0) buf[2] = (long)(offset + 0.5*scale + 0.5);
 
185
     else                         buf[2] = (long)(offset + 0.5*scale - 0.5);
 
186
 
 
187
/*
 
188
 *   random values, that do not exceed half of normal value
 
189
 */
 
190
     i2do  = sdev->color_info.num_components * (3-npixel);
 
191
     rand_max = 0;
 
192
 
 
193
     if(sdev->stc.flags & STCDFLAG0) {
 
194
 
 
195
        for(i = 0; i < i2do; ++i) buf[i+3] = 0;
 
196
 
 
197
     } else {
 
198
 
 
199
        for(i = 0; i < i2do; ++i) {
 
200
           buf[i+3] = rand();
 
201
           if(buf[i+3] > rand_max) rand_max = buf[i+3];
 
202
        }
 
203
 
 
204
        scale = (double) buf[1] / (double) rand_max;
 
205
 
 
206
        for(i = 0; i < sdev->color_info.num_components; ++ i)
 
207
           buf[i+3] = (long)(0.25000*scale*(buf[i+3]-rand_max/2));
 
208
 
 
209
        for(     ; i < i2do; ++i) /* includes 2 additional pixels ! */
 
210
           buf[i+3] = (long)(0.28125*scale*(buf[i+3]-rand_max/2));
 
211
 
 
212
     }
 
213
 
 
214
/* ============================================================= */
 
215
   } /* scanline-processing or initialisation */
 
216
/* ============================================================= */
 
217
 
 
218
   return 0;
 
219
}
 
220
 
 
221
/*
 
222
 * Experimental CMYK-Algorithm
 
223
 */
 
224
 
 
225
int 
 
226
stc_fscmyk(stcolor_device *sdev,int npixel,byte *bin,byte *bbuf,byte *out) 
 
227
{
 
228
      long *in  = (long *) bin;
 
229
      long *buf = (long *) bbuf;
 
230
 
 
231
/* ============================================================= */
 
232
   if(npixel > 0) {  /* npixel >  0 -> scanline-processing       */
 
233
/* ============================================================= */
 
234
 
 
235
      int bstep,pstart,pstop,pstep,p;
 
236
      long spotsize,threshold,*errc,*errv;
 
237
 
 
238
      if(buf[0] >= 0) { /* run forward */
 
239
        buf[0] = -1;
 
240
        bstep  = 1;
 
241
        pstep  = 4;
 
242
        pstart = 0;
 
243
        pstop  = npixel * pstep;
 
244
 
 
245
      } else {                  /* run backward */
 
246
        buf[0] =  1;
 
247
        bstep  = -1;
 
248
        pstep  = -4;
 
249
        pstop  = pstep;
 
250
        pstart = (1-npixel) * pstep;
 
251
        out   += npixel-1;
 
252
      }                   /* forward / backward */
 
253
 
 
254
      spotsize  = buf[1];
 
255
      threshold = buf[2];
 
256
      errc      = buf+3;
 
257
      errv      = errc + 2*4;
 
258
 
 
259
      for(p = 0; p < 4; ++p) errc[p] = 0;
 
260
 
 
261
      for(p = pstart; p != pstop; p += pstep) { /* loop over pixels */
 
262
         int c;     /* component-number */
 
263
         int pixel; /* internal pxel-value */
 
264
         long cv,k;
 
265
 
 
266
/*
 
267
 * Black is treated first, with conventional Floyd-Steinberg
 
268
 */
 
269
         k  = in[p+3];
 
270
         cv = k + errv[p+3] + errc[3] - ((errc[3]+4)>>3);
 
271
 
 
272
         if(cv > threshold) {
 
273
            pixel  = BLACK;
 
274
            cv    -= spotsize;
 
275
         } else {
 
276
            pixel  = 0;
 
277
         }
 
278
 
 
279
         errv[p+3-pstep] += ((3*cv+8)>>4);        /* 3/16 */
 
280
         errv[p+3      ]  = ((5*cv  )>>4)         /* 5/16 */
 
281
                          + ((errc[3]+4)>>3);     /* 1/16 (rest) */
 
282
         errc[3]          = cv                    /* 8/16 (neu) */
 
283
                          - ((5*cv  )>>4)
 
284
                          - ((3*cv+8)>>4);
 
285
 
 
286
/*
 
287
 * color-handling changes with black fired or not
 
288
 */
 
289
         if(pixel) {
 
290
 
 
291
/* -------- firing of black causes all colors to fire too */
 
292
 
 
293
            for(c = 0; c < 3; ++c) {
 
294
               cv  = in[p+c] > k ? in[p+c] : k;
 
295
               cv += errv[p+c] + errc[c] - ((errc[c]+4)>>3)-spotsize;
 
296
               if(cv <= (threshold-spotsize)) cv = threshold-spotsize+1;
 
297
 
 
298
               errv[p+c-pstep] += ((3*cv+8)>>4);        /* 3/16 */
 
299
               errv[p+c      ]  = ((5*cv  )>>4)         /* 5/16 */
 
300
                                + ((errc[c]+4)>>3);     /* 1/16 (rest) */
 
301
               errc[c]          = cv                    /* 8/16 (neu) */
 
302
                                - ((5*cv  )>>4)
 
303
                                - ((3*cv+8)>>4);
 
304
            }
 
305
 
 
306
         } else {
 
307
 
 
308
/* -------- if black did not fire, only colors w. larger values may fire */
 
309
 
 
310
            for(c = 0; c < 3; ++c) {
 
311
 
 
312
               cv  = in[p+c];
 
313
 
 
314
               if(cv > k) { /* May Fire */
 
315
                  cv += errv[p+c] + errc[c] - ((errc[c]+4)>>3);
 
316
                  if(cv > threshold) {
 
317
                     cv -= spotsize;
 
318
                     pixel |= CYAN>>c;
 
319
                  }
 
320
               } else {     /* Must not fire */
 
321
                  cv = k + errv[p+c] + errc[c] - ((errc[c]+4)>>3);
 
322
                  if(cv > threshold ) cv =  threshold;
 
323
               }
 
324
 
 
325
               errv[p+c-pstep] += ((3*cv+8)>>4);        /* 3/16 */
 
326
               errv[p+c      ]  = ((5*cv  )>>4)         /* 5/16 */
 
327
                                + ((errc[c]+4)>>3);     /* 1/16 (rest) */
 
328
               errc[c]          = cv                    /* 8/16 (neu) */
 
329
                                - ((5*cv  )>>4)
 
330
                                - ((3*cv+8)>>4);
 
331
            }
 
332
         }
 
333
 
 
334
         *out = pixel;
 
335
         out += bstep;
 
336
      }                                         /* loop over pixels */
 
337
 
 
338
 
 
339
/* ============================================================= */
 
340
   } else {          /* npixel <= 0 -> initialisation            */
 
341
/* ============================================================= */
 
342
 
 
343
      int i,i2do;
 
344
      long rand_max;
 
345
      double offset,scale;
 
346
 
 
347
/*
 
348
 * check wether the number of components is valid
 
349
 */
 
350
      if(sdev->color_info.num_components != 4)                       return -1;
 
351
 
 
352
/*
 
353
 * check wether stcdither & TYPE are correct
 
354
 */
 
355
      if(( sdev->stc.dither                    == NULL) ||
 
356
         ((sdev->stc.dither->flags & STC_TYPE) != STC_LONG))         return -2;
 
357
 
 
358
/*
 
359
 * check wether the buffer-size is sufficiently large
 
360
 */
 
361
      if(((sdev->stc.dither->flags/STC_SCAN) < 1) ||
 
362
         ( sdev->stc.dither->bufadd          <
 
363
          (3 + 3*sdev->color_info.num_components)))                  return -3;
 
364
/*
 
365
 * must neither have STC_DIRECT nor STC_WHITE
 
366
 */
 
367
      if(sdev->stc.dither->flags & (STC_DIRECT | STC_WHITE))         return -4;
 
368
 
 
369
/*
 
370
 * compute initial values
 
371
 */
 
372
/* -- direction */
 
373
     buf[0] = 1;
 
374
 
 
375
/* -- "spotsize" */
 
376
     scale  = sdev->stc.dither->minmax[1];
 
377
     buf[1] = (long)(scale + (scale > 0.0 ? 0.5 : -0.5));
 
378
 
 
379
/* -- "threshold" */
 
380
     offset = sdev->stc.dither->minmax[0];
 
381
     scale -= offset;
 
382
     if(sdev->stc.flags & STCDFLAG1) {
 
383
        buf[2] = (long)((sdev->stc.extv[0][sdev->stc.sizv[0]-1] - 
 
384
                sdev->stc.extv[0][0]) * scale / 2.0 + offset);
 
385
     } else {
 
386
        if((offset+0.5*scale) > 0.0) buf[2] = (long)(offset + 0.5*scale + 0.5);
 
387
        else                         buf[2] = (long)(offset + 0.5*scale - 0.5);
 
388
     }
 
389
 
 
390
/*
 
391
 *   random values, that do not exceed half of normal value
 
392
 */
 
393
     i2do  = sdev->color_info.num_components * (3-npixel);
 
394
     rand_max = 0;
 
395
 
 
396
     if(sdev->stc.flags & STCDFLAG0) {
 
397
 
 
398
        for(i = 0; i < i2do; ++i) buf[i+3] = 0;
 
399
 
 
400
     } else {
 
401
 
 
402
        for(i = 0; i < i2do; ++i) {
 
403
           buf[i+3] = rand();
 
404
           if(buf[i+3] > rand_max) rand_max = buf[i+3];
 
405
        }
 
406
 
 
407
        scale = (double) buf[1] / (double) rand_max;
 
408
 
 
409
        for(i = 0; i < sdev->color_info.num_components; ++ i)
 
410
           buf[i+3] = (long)(0.25000*scale*(buf[i+3]-rand_max/2));
 
411
 
 
412
        for(     ; i < i2do; ++i) /* includes 2 additional pixels ! */
 
413
           buf[i+3] = (long)(0.28125*scale*(buf[i+3]-rand_max/2));
 
414
 
 
415
     }
 
416
 
 
417
/* ============================================================= */
 
418
   } /* scanline-processing or initialisation */
 
419
/* ============================================================= */
 
420
 
 
421
   return 0;
 
422
}