]>
git.ipfire.org Git - thirdparty/cups.git/blob - driver/dither.c
dfefed7c1d872fa8c0c69324657f42e8eeace1a8
4 * Dithering routines for CUPS.
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1993-2005 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * cupsDitherDelete() - Free a dithering buffer.
18 * cupsDitherLine() - Dither a line of pixels...
19 * cupsDitherNew() - Create a dithering buffer.
23 * Include necessary headers.
31 * 'cupsDitherDelete()' - Free a dithering buffer.
33 * Returns 0 on success, -1 on failure.
37 cupsDitherDelete(cups_dither_t
*d
) /* I - Dithering buffer */
45 * 'cupsDitherLine()' - Dither a line of pixels...
49 cupsDitherLine(cups_dither_t
*d
, /* I - Dither data */
50 const cups_lut_t
*lut
, /* I - Lookup table */
51 const short *data
, /* I - Separation data */
53 /* I - Number of components */
54 unsigned char *p
) /* O - Pixels */
56 register int x
, /* Horizontal position in line... */
57 pixel
, /* Current adjusted pixel... */
58 e
, /* Current error */
59 e0
,e1
,e2
; /* Error values */
60 register int errval0
, /* First half of error value */
61 errval1
, /* Second half of error value */
62 errbase
, /* Base multiplier */
63 errbase0
, /* Base multiplier for large values */
64 errbase1
, /* Base multiplier for small values */
65 errrange
; /* Range of random multiplier */
66 register int *p0
, /* Error buffer pointers... */
68 static char logtable
[16384]; /* Error magnitude for randomness */
69 static char loginit
= 0; /* Has the table been initialized? */
75 * Initialize a logarithmic table for the magnitude of randomness
82 for (x
= 1; x
< 2049; x
++)
83 logtable
[x
] = (int)(log(x
/ 16.0) / log(2.0) + 1.0);
84 for (; x
< 16384; x
++)
85 logtable
[x
] = logtable
[2049];
91 * Dither from left to right:
94 * e1 e2 == p1[-1] p1[0]
98 p1
= d
->errors
+ 2 + d
->width
+ 4;
104 * Error diffuse each output pixel...
109 x
--, p0
++, p1
++, p
++, data
+= num_channels
)
112 * Skip blank pixels...
126 * Compute the net pixel brightness and brightness error. Set a dot
130 pixel
= lut
[*data
].intensity
+ e0
/ 128;
132 if (pixel
> CUPS_MAX_LUT
)
133 pixel
= CUPS_MAX_LUT
;
137 *p
= lut
[pixel
].pixel
;
138 e
= lut
[pixel
].error
;
141 * Set the randomness factor...
145 errrange
= logtable
[e
];
147 errrange
= logtable
[-e
];
149 errbase
= 8 - errrange
;
150 errrange
= errrange
* 2 + 1;
153 * Randomize the error value.
158 errbase0
= errbase
+ (CUPS_RAND() % errrange
);
159 errbase1
= errbase
+ (CUPS_RAND() % errrange
);
162 errbase0
= errbase1
= errbase
;
166 * 3/16 5/16 1/16 = e1 e2
169 errval0
= errbase0
* e
;
170 errval1
= (16 - errbase0
) * e
;
171 e0
= p0
[1] + 7 * errval0
;
172 e1
= e2
+ 5 * errval1
;
174 errval0
= errbase1
* e
;
175 errval1
= (16 - errbase1
) * e
;
177 p1
[-1] = e1
+ 3 * errval1
;
183 * Dither from right to left:
186 * e2 e1 == p1[0] p1[1]
189 p0
= d
->errors
+ d
->width
+ 1 + d
->width
+ 4;
190 p1
= d
->errors
+ d
->width
+ 1;
192 data
+= num_channels
* (d
->width
- 1);
198 * Error diffuse each output pixel...
203 x
--, p0
--, p1
--, p
--, data
-= num_channels
)
206 * Skip blank pixels...
220 * Compute the net pixel brightness and brightness error. Set a dot
224 pixel
= lut
[*data
].intensity
+ e0
/ 128;
226 if (pixel
> CUPS_MAX_LUT
)
227 pixel
= CUPS_MAX_LUT
;
231 *p
= lut
[pixel
].pixel
;
232 e
= lut
[pixel
].error
;
235 * Set the randomness factor...
239 errrange
= logtable
[e
];
241 errrange
= logtable
[-e
];
243 errbase
= 8 - errrange
;
244 errrange
= errrange
* 2 + 1;
247 * Randomize the error value.
252 errbase0
= errbase
+ (CUPS_RAND() % errrange
);
253 errbase1
= errbase
+ (CUPS_RAND() % errrange
);
256 errbase0
= errbase1
= errbase
;
260 * 3/16 5/16 1/16 = e1 e2
263 errval0
= errbase0
* e
;
264 errval1
= (16 - errbase0
) * e
;
265 e0
= p0
[-1] + 7 * errval0
;
266 e1
= e2
+ 5 * errval1
;
268 errval0
= errbase1
* e
;
269 errval1
= (16 - errbase1
) * e
;
271 p1
[1] = e1
+ 3 * errval1
;
276 * Update to the next row...
284 * 'cupsDitherNew()' - Create an error-diffusion dithering buffer.
287 cups_dither_t
* /* O - New state array */
288 cupsDitherNew(int width
) /* I - Width of output in pixels */
290 cups_dither_t
*d
; /* New dithering buffer */
293 if ((d
= (cups_dither_t
*)calloc(1, sizeof(cups_dither_t
) +
295 sizeof(int))) == NULL
)