1 /*
2 * "$Id: print-dither.c,v 1.44.4.5 2002/10/27 17:48:18 rwisi Exp $"
3 *
4 * Print plug-in driver utility functions for the GIMP.
5 *
6 * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
7 * Robert Krawitz (rlk@alum.mit.edu)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * Revision History:
24 *
25 * See ChangeLog
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 #include <gimp-print/gimp-print.h>
32 #include "gimp-print-internal.h"
33 #include "print-dither.h"
34 #include <gimp-print/gimp-print-intl-internal.h>
35 #include <limits.h>
36 #include <math.h>
37 #include <string.h>
38
39 #ifdef __GNUC__
40 #define inline __inline__
41 #endif
42
43 #define D_FLOYD_HYBRID 0
44 #define D_ADAPTIVE_BASE 4
45 #define D_ADAPTIVE_HYBRID (D_ADAPTIVE_BASE | D_FLOYD_HYBRID)
46 #define D_ORDERED_BASE 8
47 #define D_ORDERED (D_ORDERED_BASE)
48 #define D_FAST_BASE 16
49 #define D_FAST (D_FAST_BASE)
50 #define D_VERY_FAST (D_FAST_BASE + 1)
51 #define D_EVENTONE 32
52
53 #define DITHER_FAST_STEPS (6)
54
55 typedef struct
56 {
57 const char *name;
58 const char *text;
59 int id;
60 } dither_algo_t;
61
62 static const dither_algo_t dither_algos[] =
63 {
64 { "Adaptive", N_ ("Adaptive Hybrid"), D_ADAPTIVE_HYBRID },
65 { "Ordered", N_ ("Ordered"), D_ORDERED },
66 { "Fast", N_ ("Fast"), D_FAST },
67 { "VeryFast", N_ ("Very Fast"), D_VERY_FAST },
68 { "Floyd", N_ ("Hybrid Floyd-Steinberg"), D_FLOYD_HYBRID },
69 /* Note to translators: "EvenTone" is the proper name, rather than a */
70 /* descriptive name, of this algorithm. */
71 { "EvenTone", N_ ("EvenTone"), D_EVENTONE }
72 };
73
74 static const int num_dither_algos = sizeof(dither_algos)/sizeof(dither_algo_t);
75
76 #define ERROR_ROWS 2
77
78 #define MAX_SPREAD 32
79
80 /*
81 * An end of a dither segment, describing one ink
82 */
83
84 typedef struct ink_defn
85 {
86 unsigned range;
87 unsigned value;
88 unsigned bits;
89 unsigned dot_size;
90 int subchannel;
91 } ink_defn_t;
92
93 /*
94 * A segment of the entire 0-65535 intensity range.
95 */
96
97 typedef struct dither_segment
98 {
99 ink_defn_t *lower;
100 ink_defn_t *upper;
101 unsigned range_span;
102 unsigned value_span;
103 int is_same_ink;
104 int is_equal;
105 } dither_segment_t;
106
107 typedef struct dither_channel
108 {
109 unsigned randomizer; /* With Floyd-Steinberg dithering, control */
110 /* how much randomness is applied to the */
111 /* threshold values (0-65535). With ordered */
112 /* dithering, how much randomness is added */
113 /* to the matrix value. */
114 int k_level; /* Amount of each ink (in 64ths) required */
115 /* to create equivalent black */
116 int darkness; /* Perceived "darkness" of each ink, */
117 /* in 64ths, to calculate CMY-K transitions */
118 int nlevels;
119 unsigned bit_max;
120 unsigned signif_bits;
121 unsigned density;
122
123 int v;
124 int o;
125 int b;
126 int very_fast;
127 int subchannels;
128
129 int maxdot; /* Maximum dot size */
130
131 ink_defn_t *ink_list;
132
133 dither_segment_t *ranges;
134 int **errs;
135 unsigned short *vals;
136
137 dither_matrix_t pick;
138 dither_matrix_t dithermat;
139 int *row_ends[2];
140 unsigned char **ptrs;
141 } dither_channel_t;
142
143 typedef struct {
144 int d2x, d2y, dx2, dy2;
145 int aspect;
146 int **dx, **dy, **r_sq;
147 int *recip;
148 } eventone_t;
149
150 typedef struct dither
151 {
152 int src_width; /* Input width */
153 int dst_width; /* Output width */
154
155 int density; /* Desired density, 0-1.0 (scaled 0-65535) */
156 int black_density; /* Desired density, 0-1.0 (scaled 0-65535) */
157 int k_lower; /* Transition range (lower/upper) for CMY */
158 int k_upper; /* vs. K */
159 int density2; /* Density * 2 */
160 int densityh; /* Density / 2 */
161 unsigned dlb_range;
162 unsigned bound_range;
163
164 int spread; /* With Floyd-Steinberg, how widely the */
165 int spread_mask; /* error is distributed. This should be */
166 /* between 12 (very broad distribution) and */
167 /* 19 (very narrow) */
168
169 int dither_type;
170
171 int d_cutoff; /* When ordered dither is used, threshold */
172 /* above which no randomness is used. */
173 double adaptive_input;
174 int adaptive_input_set;
175 int adaptive_limit;
176
177 int x_aspect; /* Aspect ratio numerator */
178 int y_aspect; /* Aspect ratio denominator */
179
180 double transition; /* Exponential scaling for transition region */
181
182 int *offset0_table;
183 int *offset1_table;
184
185 int oversampling;
186 int last_line_was_empty;
187 int ptr_offset;
188 int n_channels;
189 int n_input_channels;
190 int error_rows;
191
192 int dither_class; /* mono, black, or CMYK */
193
194 dither_matrix_t dither_matrix;
195 dither_matrix_t transition_matrix;
196 dither_channel_t *channel;
197
198 unsigned short virtual_dot_scale[65536];
199 void (*ditherfunc)(const unsigned short *, int, struct dither *, int, int);
200 eventone_t *eventone;
201 stp_vars_t v;
202 } dither_t;
203
204 typedef void ditherfunc_t(const unsigned short *, int, struct dither *, int, int);
205
206 static ditherfunc_t
207 stp_dither_monochrome,
208 stp_dither_monochrome_very_fast,
209 stp_dither_black_fast,
210 stp_dither_black_very_fast,
211 stp_dither_black_ordered,
212 stp_dither_black_ed,
213 stp_dither_black_et,
214 stp_dither_cmyk_fast,
215 stp_dither_cmyk_very_fast,
216 stp_dither_cmyk_ordered,
217 stp_dither_cmyk_ed,
218 stp_dither_cmyk_et,
219 stp_dither_raw_cmyk_fast,
220 stp_dither_raw_cmyk_very_fast,
221 stp_dither_raw_cmyk_ordered,
222 stp_dither_raw_cmyk_ed,
223 stp_dither_raw_cmyk_et;
224
225
226 #define CHANNEL(d, c) ((d)->channel[(c)])
227
228 #define SAFE_FREE(x) \
229 do \
230 { \
231 if ((x)) \
232 stp_free((char *)(x)); \
233 ((x)) = NULL; \
234 } while (0)
235
236 /*
237 * Bayer's dither matrix using Judice, Jarvis, and Ninke recurrence relation
238 * http://www.cs.rit.edu/~sxc7922/Project/CRT.htm
239 */
240
241 static const unsigned sq2[] =
242 {
243 0, 2,
244 3, 1
245 };
246
247 size_t
stp_dither_algorithm_count(void)248 stp_dither_algorithm_count(void)
249 {
250 return num_dither_algos;
251 }
252
253 const char *
stp_dither_algorithm_name(int id)254 stp_dither_algorithm_name(int id)
255 {
256 if (id < 0 || id >= num_dither_algos)
257 return NULL;
258 return (dither_algos[id].name);
259 }
260
261 const char *
stp_dither_algorithm_text(int id)262 stp_dither_algorithm_text(int id)
263 {
264 if (id < 0 || id >= num_dither_algos)
265 return NULL;
266 return _(dither_algos[id].text);
267 }
268
269 /*
270 * These really belong with print-dither.c. However, inlining has yielded
271 * significant (measured) speedup, even with the more complicated dither
272 * function. --rlk 20011219
273 */
274
275 static inline unsigned
ditherpoint_fast(const dither_t * d,dither_matrix_t * mat,int x)276 ditherpoint_fast(const dither_t *d, dither_matrix_t *mat, int x)
277 {
278 return mat->matrix[(mat->last_y_mod+((x + mat->x_offset) & mat->fast_mask))];
279 }
280
281 static inline unsigned
ditherpoint(const dither_t * d,dither_matrix_t * mat,int x)282 ditherpoint(const dither_t *d, dither_matrix_t *mat, int x)
283 {
284 if (mat->fast_mask)
285 return mat->matrix[(mat->last_y_mod +
286 ((x + mat->x_offset) & mat->fast_mask))];
287 /*
288 * This rather bizarre code is an attempt to avoid having to compute a lot
289 * of modulus and multiplication operations, which are typically slow.
290 */
291
292 if (x == mat->last_x + 1)
293 {
294 mat->last_x_mod++;
295 mat->index++;
296 if (mat->last_x_mod >= mat->x_size)
297 {
298 mat->last_x_mod -= mat->x_size;
299 mat->index -= mat->x_size;
300 }
301 }
302 else if (x == mat->last_x - 1)
303 {
304 mat->last_x_mod--;
305 mat->index--;
306 if (mat->last_x_mod < 0)
307 {
308 mat->last_x_mod += mat->x_size;
309 mat->index += mat->x_size;
310 }
311 }
312 else if (x == mat->last_x)
313 {
314 }
315 else
316 {
317 mat->last_x_mod = (x + mat->x_offset) % mat->x_size;
318 mat->index = mat->last_x_mod + mat->last_y_mod;
319 }
320 mat->last_x = x;
321 return mat->matrix[mat->index];
322 }
323
324 static void
reverse_row_ends(dither_t * d)325 reverse_row_ends(dither_t *d)
326 {
327 int i, j;
328 for (i = 0; i < d->n_channels; i++)
329 for (j = 0; j < CHANNEL(d, i).subchannels; j++)
330 {
331 int tmp = CHANNEL(d, i).row_ends[0][j];
332 CHANNEL(d, i).row_ends[0][j] =
333 CHANNEL(d, i).row_ends[1][j];
334 CHANNEL(d, i).row_ends[1][j] = tmp;
335 }
336 }
337
338 stp_dither_data_t *
stp_create_dither_data(void)339 stp_create_dither_data(void)
340 {
341 stp_dither_data_t *ret = stp_zalloc(sizeof(stp_dither_data_t));
342 ret->channel_count = 0;
343 ret->c = NULL;
344 return ret;
345 }
346
347 void
stp_add_channel(stp_dither_data_t * d,unsigned char * data,unsigned channel,unsigned subchannel)348 stp_add_channel(stp_dither_data_t *d, unsigned char *data,
349 unsigned channel, unsigned subchannel)
350 {
351 stp_channel_t *chan;
352 if (channel >= d->channel_count)
353 {
354 unsigned oc = d->channel_count;
355 d->c = stp_realloc(d->c, sizeof(stp_channel_t) * (channel + 1));
356 (void) memset(d->c + oc, 0, sizeof(stp_channel_t) * (channel + 1 - oc));
357 d->channel_count = channel + 1;
358 }
359 chan = d->c + channel;
360 if (subchannel >= chan->subchannel_count)
361 {
362 unsigned oc = chan->subchannel_count;
363 chan->c =
364 stp_realloc(chan->c, sizeof(unsigned char *) * (subchannel + 1));
365 (void) memset(chan->c + oc, 0,
366 sizeof(unsigned char *) * (subchannel + 1 - oc));
367 chan->subchannel_count = subchannel + 1;
368 }
369 chan->c[subchannel] = data;
370 }
371
372 void
stp_free_dither_data(stp_dither_data_t * d)373 stp_free_dither_data(stp_dither_data_t *d)
374 {
375 int i;
376 for (i = 0; i < d->channel_count; i++)
377 stp_free(d->c[i].c);
378 stp_free(d->c);
379 }
380
381 #define SET_DITHERFUNC(d, func, v) \
382 do \
383 { \
384 stp_dprintf(STP_DBG_COLORFUNC, v, "ditherfunc %s\n", #func); \
385 d->ditherfunc = func; \
386 } while (0)
387
388 void *
stp_init_dither(int in_width,int out_width,int horizontal_aspect,int vertical_aspect,stp_vars_t v)389 stp_init_dither(int in_width, int out_width, int horizontal_aspect,
390 int vertical_aspect, stp_vars_t v)
391 {
392 int i;
393 dither_t *d = stp_zalloc(sizeof(dither_t));
394 stp_simple_dither_range_t r;
395 d->v = v;
396 d->dither_class = stp_get_output_type(v);
397 d->error_rows = ERROR_ROWS;
398
399 d->dither_type = D_ADAPTIVE_HYBRID;
400 for (i = 0; i < num_dither_algos; i++)
401 {
402 if (!strcmp(stp_get_dither_algorithm(v), _(dither_algos[i].name)))
403 {
404 d->dither_type = dither_algos[i].id;
405 break;
406 }
407 }
408 switch (d->dither_class)
409 {
410 case OUTPUT_MONOCHROME:
411 d->n_channels = 1;
412 d->n_input_channels = 1;
413 switch (d->dither_type)
414 {
415 case D_VERY_FAST:
416 SET_DITHERFUNC(d, stp_dither_monochrome_very_fast, v);
417 break;
418 default:
419 SET_DITHERFUNC(d, stp_dither_monochrome, v);
420 break;
421 }
422 break;
423 case OUTPUT_GRAY:
424 d->n_channels = 1;
425 d->n_input_channels = 1;
426 switch (d->dither_type)
427 {
428 case D_FAST:
429 SET_DITHERFUNC(d, stp_dither_black_fast, v);
430 break;
431 case D_VERY_FAST:
432 SET_DITHERFUNC(d, stp_dither_black_very_fast, v);
433 break;
434 case D_ORDERED:
435 SET_DITHERFUNC(d, stp_dither_black_ordered, v);
436 break;
437 case D_EVENTONE:
438 SET_DITHERFUNC(d, stp_dither_black_et, v);
439 break;
440 default:
441 SET_DITHERFUNC(d, stp_dither_black_ed, v);
442 break;
443 }
444 break;
445 case OUTPUT_COLOR:
446 d->n_channels = 4;
447 d->n_input_channels = 3;
448 switch (d->dither_type)
449 {
450 case D_FAST:
451 SET_DITHERFUNC(d, stp_dither_cmyk_fast, v);
452 break;
453 case D_VERY_FAST:
454 SET_DITHERFUNC(d, stp_dither_cmyk_very_fast, v);
455 break;
456 case D_ORDERED:
457 SET_DITHERFUNC(d, stp_dither_cmyk_ordered, v);
458 break;
459 case D_EVENTONE:
460 SET_DITHERFUNC(d, stp_dither_cmyk_et, v);
461 break;
462 default:
463 SET_DITHERFUNC(d, stp_dither_cmyk_ed, v);
464 break;
465 }
466 break;
467 case OUTPUT_RAW_CMYK:
468 d->n_channels = 4;
469 d->n_input_channels = 4;
470 switch (d->dither_type)
471 {
472 case D_FAST:
473 SET_DITHERFUNC(d, stp_dither_raw_cmyk_fast, v);
474 break;
475 case D_VERY_FAST:
476 SET_DITHERFUNC(d, stp_dither_raw_cmyk_very_fast, v);
477 break;
478 case D_ORDERED:
479 SET_DITHERFUNC(d, stp_dither_raw_cmyk_ordered, v);
480 break;
481 case D_EVENTONE:
482 SET_DITHERFUNC(d, stp_dither_raw_cmyk_et, v);
483 break;
484 default:
485 SET_DITHERFUNC(d, stp_dither_raw_cmyk_ed, v);
486 break;
487 }
488 break;
489 }
490 d->channel = stp_zalloc(d->n_channels * sizeof(dither_channel_t));
491 r.value = 1.0;
492 r.bit_pattern = 1;
493 r.subchannel = 0;
494 r.dot_size = 1;
495 for (i = 0; i < d->n_channels; i++)
496 {
497 stp_dither_set_ranges(d, i, 1, &r, 1.0);
498 CHANNEL(d, i).errs = stp_zalloc(d->error_rows * sizeof(int *));
499 }
500 d->offset0_table = NULL;
501 d->offset1_table = NULL;
502 d->x_aspect = horizontal_aspect;
503 d->y_aspect = vertical_aspect;
504 d->transition = 1.0;
505 d->adaptive_input = .75;
506 d->adaptive_input_set = 0;
507
508 if (d->dither_type == D_VERY_FAST)
509 stp_dither_set_iterated_matrix(d, 2, DITHER_FAST_STEPS, sq2, 0, 2, 4);
510 else
511 {
512 stp_dither_matrix_t *mat;
513 int transposed = 0;
514 if (d->y_aspect == d->x_aspect)
515 mat = (stp_dither_matrix_t *) &stp_1_1_matrix;
516 else if (d->y_aspect > d->x_aspect)
517 {
518 transposed = 0;
519 if (d->y_aspect / d->x_aspect == 2)
520 mat = (stp_dither_matrix_t *) &stp_2_1_matrix;
521 else if (d->y_aspect / d->x_aspect == 3)
522 mat = (stp_dither_matrix_t *) &stp_4_1_matrix;
523 else if (d->y_aspect / d->x_aspect == 4)
524 mat = (stp_dither_matrix_t *) &stp_4_1_matrix;
525 else
526 mat = (stp_dither_matrix_t *) &stp_2_1_matrix;
527 }
528 else
529 {
530 transposed = 1;
531 if (d->x_aspect / d->y_aspect == 2)
532 mat = (stp_dither_matrix_t *) &stp_2_1_matrix;
533 else if (d->x_aspect / d->y_aspect == 3)
534 mat = (stp_dither_matrix_t *) &stp_4_1_matrix;
535 else if (d->x_aspect / d->y_aspect == 4)
536 mat = (stp_dither_matrix_t *) &stp_4_1_matrix;
537 else
538 mat = (stp_dither_matrix_t *) &stp_2_1_matrix;
539 }
540 stp_dither_set_matrix(d, mat, transposed, 0, 0);
541 }
542
543 d->src_width = in_width;
544 d->dst_width = out_width;
545
546 stp_dither_set_ink_spread(d, 13);
547 stp_dither_set_black_lower(d, .4);
548 stp_dither_set_black_upper(d, .7);
549 for (i = 0; i <= d->n_channels; i++)
550 {
551 stp_dither_set_black_level(d, i, 1.0);
552 stp_dither_set_randomizer(d, i, 1.0);
553 }
554 stp_dither_set_ink_darkness(d, ECOLOR_C, 2);
555 stp_dither_set_ink_darkness(d, ECOLOR_M, 2);
556 stp_dither_set_ink_darkness(d, ECOLOR_Y, 1);
557 stp_dither_set_density(d, 1.0);
558 return d;
559 }
560
561 static void
preinit_matrix(dither_t * d)562 preinit_matrix(dither_t *d)
563 {
564 int i;
565 for (i = 0; i < d->n_channels; i++)
566 stp_destroy_matrix(&(CHANNEL(d, i).dithermat));
567 stp_destroy_matrix(&(d->dither_matrix));
568 }
569
570 static void
postinit_matrix(dither_t * d,int x_shear,int y_shear)571 postinit_matrix(dither_t *d, int x_shear, int y_shear)
572 {
573 unsigned rc = 1 + (unsigned) ceil(sqrt(d->n_channels));
574 int i, j;
575 int color = 0;
576 unsigned x_n = d->dither_matrix.x_size / rc;
577 unsigned y_n = d->dither_matrix.y_size / rc;
578 if (x_shear || y_shear)
579 stp_shear_matrix(&(d->dither_matrix), x_shear, y_shear);
580 for (i = 0; i < rc; i++)
581 for (j = 0; j < rc; j++)
582 if (color < d->n_channels)
583 {
584 stp_clone_matrix(&(d->dither_matrix), &(CHANNEL(d, color).dithermat),
585 x_n * i, y_n * j);
586 color++;
587 }
588 stp_dither_set_transition(d, d->transition);
589 }
590
591 void
stp_dither_set_iterated_matrix(void * vd,size_t edge,size_t iterations,const unsigned * data,int prescaled,int x_shear,int y_shear)592 stp_dither_set_iterated_matrix(void *vd, size_t edge, size_t iterations,
593 const unsigned *data, int prescaled,
594 int x_shear, int y_shear)
595 {
596 dither_t *d = (dither_t *) vd;
597 preinit_matrix(d);
598 stp_init_iterated_matrix(&(d->dither_matrix), edge, iterations, data);
599 postinit_matrix(d, x_shear, y_shear);
600 }
601
602 void
stp_dither_set_matrix(void * vd,const stp_dither_matrix_t * matrix,int transposed,int x_shear,int y_shear)603 stp_dither_set_matrix(void *vd, const stp_dither_matrix_t *matrix,
604 int transposed, int x_shear, int y_shear)
605 {
606 dither_t *d = (dither_t *) vd;
607 int x = transposed ? matrix->y : matrix->x;
608 int y = transposed ? matrix->x : matrix->y;
609 preinit_matrix(d);
610 if (matrix->bytes == 2)
611 stp_init_matrix_short(&(d->dither_matrix), x, y,
612 (const unsigned short *) matrix->data,
613 transposed, matrix->prescaled);
614 else if (matrix->bytes == 4)
615 stp_init_matrix(&(d->dither_matrix), x, y, (const unsigned *)matrix->data,
616 transposed, matrix->prescaled);
617 postinit_matrix(d, x_shear, y_shear);
618 }
619
620 void
stp_dither_set_transition(void * vd,double exponent)621 stp_dither_set_transition(void *vd, double exponent)
622 {
623 dither_t *d = (dither_t *) vd;
624 unsigned rc = 1 + (unsigned) ceil(sqrt(d->n_channels));
625 int i, j;
626 int color = 0;
627 unsigned x_n = d->dither_matrix.x_size / rc;
628 unsigned y_n = d->dither_matrix.y_size / rc;
629 for (i = 0; i < d->n_channels; i++)
630 stp_destroy_matrix(&(CHANNEL(d, i).pick));
631 stp_destroy_matrix(&(d->transition_matrix));
632 stp_copy_matrix(&(d->dither_matrix), &(d->transition_matrix));
633 d->transition = exponent;
634 if (exponent < .999 || exponent > 1.001)
635 stp_exponential_scale_matrix(&(d->transition_matrix), exponent);
636 for (i = 0; i < rc; i++)
637 for (j = 0; j < rc; j++)
638 if (color < d->n_channels)
639 {
640 stp_clone_matrix(&(d->dither_matrix), &(CHANNEL(d, color).pick),
641 x_n * i, y_n * j);
642 color++;
643 }
644 if (exponent < .999 || exponent > 1.001)
645 for (i = 0; i < 65536; i++)
646 {
647 double dd = i / 65535.0;
648 dd = pow(dd, 1.0 / exponent);
649 d->virtual_dot_scale[i] = dd * 65535;
650 }
651 else
652 for (i = 0; i < 65536; i++)
653 d->virtual_dot_scale[i] = i;
654 }
655
656 void
stp_dither_set_density(void * vd,double density)657 stp_dither_set_density(void *vd, double density)
658 {
659 dither_t *d = (dither_t *) vd;
660 if (density > 1)
661 density = 1;
662 else if (density < 0)
663 density = 0;
664 d->k_upper = d->k_upper * density;
665 d->k_lower = d->k_lower * density;
666 d->density = (int) ((65535 * density) + .5);
667 d->density2 = 2 * d->density;
668 d->densityh = d->density / 2;
669 d->dlb_range = d->density - d->k_lower;
670 d->bound_range = d->k_upper - d->k_lower;
671 d->d_cutoff = d->density / 16;
672 d->adaptive_limit = d->density * d->adaptive_input;
673 stp_dither_set_black_density(vd, density);
674 }
675
676 void
stp_dither_set_black_density(void * vd,double density)677 stp_dither_set_black_density(void *vd, double density)
678 {
679 dither_t *d = (dither_t *) vd;
680 if (density > 1)
681 density = 1;
682 else if (density < 0)
683 density = 0;
684 d->black_density = (int) ((65535 * density) + .5);
685 }
686
687 void
stp_dither_set_adaptive_limit(void * vd,double limit)688 stp_dither_set_adaptive_limit(void *vd, double limit)
689 {
690 dither_t *d = (dither_t *) vd;
691 d->adaptive_input = limit;
692 d->adaptive_input_set = 1;
693 d->adaptive_limit = d->density * limit;
694 }
695
696 void
stp_dither_set_black_lower(void * vd,double k_lower)697 stp_dither_set_black_lower(void *vd, double k_lower)
698 {
699 dither_t *d = (dither_t *) vd;
700 d->k_lower = (int) (k_lower * 65535);
701 }
702
703 void
stp_dither_set_black_upper(void * vd,double k_upper)704 stp_dither_set_black_upper(void *vd, double k_upper)
705 {
706 dither_t *d = (dither_t *) vd;
707 d->k_upper = (int) (k_upper * 65535);
708 }
709
710 void
stp_dither_set_ink_spread(void * vd,int spread)711 stp_dither_set_ink_spread(void *vd, int spread)
712 {
713 dither_t *d = (dither_t *) vd;
714 SAFE_FREE(d->offset0_table);
715 SAFE_FREE(d->offset1_table);
716 if (spread >= 16)
717 {
718 d->spread = 16;
719 }
720 else
721 {
722 int max_offset;
723 int i;
724 d->spread = spread;
725 max_offset = (1 << (16 - spread)) + 1;
726 d->offset0_table = stp_malloc(sizeof(int) * max_offset);
727 d->offset1_table = stp_malloc(sizeof(int) * max_offset);
728 for (i = 0; i < max_offset; i++)
729 {
730 d->offset0_table[i] = (i + 1) * (i + 1);
731 d->offset1_table[i] = ((i + 1) * i) / 2;
732 }
733 }
734 d->spread_mask = (1 << d->spread) - 1;
735 d->adaptive_limit = d->density * d->adaptive_input;
736 }
737
738 void
stp_dither_set_black_level(void * vd,int i,double v)739 stp_dither_set_black_level(void *vd, int i, double v)
740 {
741 dither_t *d = (dither_t *) vd;
742 if (i < 0 || i >= d->n_channels)
743 return;
744 CHANNEL(d, i).k_level = (int) v * 64;
745 }
746
747 void
stp_dither_set_randomizer(void * vd,int i,double v)748 stp_dither_set_randomizer(void *vd, int i, double v)
749 {
750 dither_t *d = (dither_t *) vd;
751 if (i < 0 || i >= d->n_channels)
752 return;
753 CHANNEL(d, i).randomizer = v * 65535;
754 }
755
756 void
stp_dither_set_ink_darkness(void * vd,int i,double v)757 stp_dither_set_ink_darkness(void *vd, int i, double v)
758 {
759 dither_t *d = (dither_t *) vd;
760 if (i < 0 || i >= d->n_channels)
761 return;
762 CHANNEL(d, i).darkness = (int) (v * 64);
763 }
764
765 void
stp_dither_set_light_ink(void * vd,int i,double v,double density)766 stp_dither_set_light_ink(void *vd, int i, double v, double density)
767 {
768 dither_t *d = (dither_t *) vd;
769 stp_simple_dither_range_t range[2];
770 if (i < 0 || i >= d->n_channels || v <= 0 || v > 1)
771 return;
772 range[0].bit_pattern = 1;
773 range[0].subchannel = 1;
774 range[0].value = v;
775 range[0].dot_size = 1;
776 range[1].bit_pattern = 1;
777 range[1].subchannel = 0;
778 range[1].value = 1;
779 range[1].dot_size = 1;
780 stp_dither_set_ranges(vd, i, 2, range, density);
781 }
782
783 static void
stp_dither_finalize_ranges(dither_t * d,dither_channel_t * s)784 stp_dither_finalize_ranges(dither_t *d, dither_channel_t *s)
785 {
786 int max_subchannel = 0;
787 int i;
788 unsigned lbit = s->bit_max;
789 s->signif_bits = 0;
790 while (lbit > 0)
791 {
792 s->signif_bits++;
793 lbit >>= 1;
794 }
795
796 s->maxdot = 0;
797
798 for (i = 0; i < s->nlevels; i++)
799 {
800 if (s->ranges[i].lower->subchannel > max_subchannel)
801 max_subchannel = s->ranges[i].lower->subchannel;
802 if (s->ranges[i].upper->subchannel > max_subchannel)
803 max_subchannel = s->ranges[i].upper->subchannel;
804 if (s->ranges[i].lower->subchannel == s->ranges[i].upper->subchannel &&
805 s->ranges[i].lower->dot_size == s->ranges[i].upper->dot_size)
806 s->ranges[i].is_same_ink = 1;
807 else
808 s->ranges[i].is_same_ink = 0;
809 if (s->ranges[i].range_span > 0 &&
810 (s->ranges[i].value_span > 0 ||
811 s->ranges[i].lower->subchannel != s->ranges[i].upper->subchannel))
812 s->ranges[i].is_equal = 0;
813 else
814 s->ranges[i].is_equal = 1;
815
816 if (s->ranges[i].lower->dot_size > s->maxdot)
817 s->maxdot = s->ranges[i].lower->dot_size;
818 if (s->ranges[i].upper->dot_size > s->maxdot)
819 s->maxdot = s->ranges[i].upper->dot_size;
820
821 stp_dprintf(STP_DBG_INK, d->v,
822 " level %d value[0] %d value[1] %d range[0] %d range[1] %d\n",
823 i, s->ranges[i].lower->value, s->ranges[i].upper->value,
824 s->ranges[i].lower->range, s->ranges[i].upper->range);
825 stp_dprintf(STP_DBG_INK, d->v,
826 " bits[0] %d bits[1] %d subchannel[0] %d subchannel[1] %d\n",
827 s->ranges[i].lower->bits, s->ranges[i].upper->bits,
828 s->ranges[i].lower->subchannel, s->ranges[i].upper->subchannel);
829 stp_dprintf(STP_DBG_INK, d->v,
830 " rangespan %d valuespan %d same_ink %d equal %d\n",
831 s->ranges[i].range_span, s->ranges[i].value_span,
832 s->ranges[i].is_same_ink, s->ranges[i].is_equal);
833 if (!d->adaptive_input_set && i > 0 &&
834 s->ranges[i].lower->range >= d->adaptive_limit)
835 {
836 d->adaptive_limit = s->ranges[i].lower->range + 1;
837 if (d->adaptive_limit > 65535)
838 d->adaptive_limit = 65535;
839 d->adaptive_input = (double) d->adaptive_limit / (double) d->density;
840 stp_dprintf(STP_DBG_INK, d->v,
841 "Setting adaptive limit to %d, input %f\n",
842 d->adaptive_limit, d->adaptive_input);
843 }
844 }
845 if (s->nlevels == 1 && s->ranges[0].upper->bits == 1 &&
846 s->ranges[0].upper->subchannel == 0)
847 s->very_fast = 1;
848 else
849 s->very_fast = 0;
850
851 s->subchannels = max_subchannel + 1;
852 s->row_ends[0] = stp_zalloc(s->subchannels * sizeof(int));
853 s->row_ends[1] = stp_zalloc(s->subchannels * sizeof(int));
854 s->ptrs = stp_zalloc(s->subchannels * sizeof(char *));
855 stp_dprintf(STP_DBG_INK, d->v,
856 " bit_max %d signif_bits %d\n", s->bit_max, s->signif_bits);
857 }
858
859 static void
stp_dither_set_generic_ranges(dither_t * d,dither_channel_t * s,int nlevels,const stp_simple_dither_range_t * ranges,double density)860 stp_dither_set_generic_ranges(dither_t *d, dither_channel_t *s, int nlevels,
861 const stp_simple_dither_range_t *ranges,
862 double density)
863 {
864 int i;
865 SAFE_FREE(s->ranges);
866 SAFE_FREE(s->row_ends[0]);
867 SAFE_FREE(s->row_ends[1]);
868 SAFE_FREE(s->ptrs);
869
870 s->nlevels = nlevels > 1 ? nlevels + 1 : nlevels;
871 s->ranges = (dither_segment_t *)
872 stp_zalloc(s->nlevels * sizeof(dither_segment_t));
873 s->ink_list = (ink_defn_t *)
874 stp_zalloc((s->nlevels + 1) * sizeof(ink_defn_t));
875 s->bit_max = 0;
876 s->density = density * 65535;
877 stp_dprintf(STP_DBG_INK, d->v,
878 "stp_dither_set_generic_ranges nlevels %d density %f\n",
879 nlevels, density);
880 for (i = 0; i < nlevels; i++)
881 stp_dprintf(STP_DBG_INK, d->v,
882 " level %d value %f pattern %x subchannel %d\n", i,
883 ranges[i].value, ranges[i].bit_pattern, ranges[i].subchannel);
884 s->ranges[0].lower = &s->ink_list[0];
885 s->ranges[0].upper = &s->ink_list[1];
886 s->ink_list[0].range = 0;
887 s->ink_list[0].value = ranges[0].value * 65535.0;
888 s->ink_list[0].bits = ranges[0].bit_pattern;
889 s->ink_list[0].subchannel = ranges[0].subchannel;
890 s->ink_list[0].dot_size = ranges[0].dot_size;
891 if (nlevels == 1)
892 s->ink_list[1].range = 65535;
893 else
894 s->ink_list[1].range = ranges[0].value * 65535.0 * density;
895 if (s->ink_list[1].range > 65535)
896 s->ink_list[1].range = 65535;
897 s->ink_list[1].value = ranges[0].value * 65535.0;
898 if (s->ink_list[1].value > 65535)
899 s->ink_list[1].value = 65535;
900 s->ink_list[1].bits = ranges[0].bit_pattern;
901 if (ranges[0].bit_pattern > s->bit_max)
902 s->bit_max = ranges[0].bit_pattern;
903 s->ink_list[1].subchannel = ranges[0].subchannel;
904 s->ink_list[1].dot_size = ranges[0].dot_size;
905 s->ranges[0].range_span = s->ranges[0].upper->range;
906 s->ranges[0].value_span = 0;
907 if (s->nlevels > 1)
908 {
909 for (i = 1; i < nlevels; i++)
910 {
911 int l = i + 1;
912 s->ranges[i].lower = &s->ink_list[i];
913 s->ranges[i].upper = &s->ink_list[l];
914
915 s->ink_list[l].range =
916 (ranges[i].value + ranges[i].value) * 32768.0 * density;
917 if (s->ink_list[l].range > 65535)
918 s->ink_list[l].range = 65535;
919 s->ink_list[l].value = ranges[i].value * 65535.0;
920 if (s->ink_list[l].value > 65535)
921 s->ink_list[l].value = 65535;
922 s->ink_list[l].bits = ranges[i].bit_pattern;
923 if (ranges[i].bit_pattern > s->bit_max)
924 s->bit_max = ranges[i].bit_pattern;
925 s->ink_list[l].subchannel = ranges[i].subchannel;
926 s->ink_list[l].dot_size = ranges[i].dot_size;
927 s->ranges[i].range_span =
928 s->ink_list[l].range - s->ink_list[i].range;
929 s->ranges[i].value_span =
930 s->ink_list[l].value - s->ink_list[i].value;
931 }
932 s->ranges[i].lower = &s->ink_list[i];
933 s->ranges[i].upper = &s->ink_list[i+1];
934 s->ink_list[i+1] = s->ink_list[i];
935 s->ink_list[i+1].range = 65535;
936 s->ranges[i].range_span = s->ink_list[i+1].range - s->ink_list[i].range;
937 s->ranges[i].value_span = s->ink_list[i+1].value - s->ink_list[i].value;
938 }
939 stp_dither_finalize_ranges(d, s);
940 }
941
942 static void
stp_dither_set_generic_ranges_full(dither_t * d,dither_channel_t * s,int nlevels,const stp_full_dither_range_t * ranges,double density)943 stp_dither_set_generic_ranges_full(dither_t *d, dither_channel_t *s,
944 int nlevels,
945 const stp_full_dither_range_t *ranges,
946 double density)
947 {
948 int i, j, k;
949 SAFE_FREE(s->ranges);
950 SAFE_FREE(s->row_ends[0]);
951 SAFE_FREE(s->row_ends[1]);
952 SAFE_FREE(s->ptrs);
953
954 s->nlevels = nlevels+1;
955 s->ranges = (dither_segment_t *)
956 stp_zalloc(s->nlevels * sizeof(dither_segment_t));
957 s->ink_list = (ink_defn_t *)
958 stp_zalloc((s->nlevels * 2) * sizeof(ink_defn_t));
959 s->bit_max = 0;
960 s->density = density * 65535;
961 stp_dprintf(STP_DBG_INK, d->v,
962 "stp_dither_set_ranges nlevels %d density %f\n",
963 nlevels, density);
964 for (i = 0; i < nlevels; i++)
965 stp_dprintf(STP_DBG_INK, d->v,
966 " level %d value: low %f high %f pattern low %x "
967 "high %x subchannel low %d high %d\n", i,
968 ranges[i].value[0], ranges[i].value[1],
969 ranges[i].bits[0], ranges[i].bits[1],ranges[i].subchannel[0],
970 ranges[i].subchannel[1]);
971 for(i=j=0; i < nlevels; i++)
972 {
973 for (k = 0; k < 2; k++)
974 {
975 if (ranges[i].bits[k] > s->bit_max)
976 s->bit_max = ranges[i].bits[k];
977 s->ink_list[2*j+k].dot_size = ranges[i].bits[k]; /* FIXME */
978 s->ink_list[2*j+k].value = ranges[i].value[k] * 65535;
979 s->ink_list[2*j+k].range = s->ink_list[2*j+k].value*density;
980 s->ink_list[2*j+k].bits = ranges[i].bits[k];
981 s->ink_list[2*j+k].subchannel = ranges[i].subchannel[k];
982 }
983 s->ranges[j].lower = &s->ink_list[2*j];
984 s->ranges[j].upper = &s->ink_list[2*j+1];
985 s->ranges[j].range_span = s->ranges[j].upper->range - s->ranges[j].lower->range;
986 s->ranges[j].value_span = s->ranges[j].upper->value - s->ranges[j].lower->value;
987 j++;
988 }
989 s->ink_list[2*j] = s->ink_list[2*(j-1)+1];
990 s->ink_list[2*j+1] = s->ink_list[2*j];
991 s->ink_list[2*j+1].range = 65535;
992 s->ink_list[2*j+1].value = 65535; /* ??? Is this correct ??? */
993 s->ranges[j].lower = &s->ink_list[2*j];
994 s->ranges[j].upper = &s->ink_list[2*j+1];
995 s->ranges[j].range_span = s->ranges[j].upper->range - s->ranges[j].lower->range;
996 s->ranges[j].value_span = 0;
997 s->nlevels = j+1;
998 stp_dither_finalize_ranges(d, s);
999 }
1000
1001 void
stp_dither_set_ranges(void * vd,int color,int nlevels,const stp_simple_dither_range_t * ranges,double density)1002 stp_dither_set_ranges(void *vd, int color, int nlevels,
1003 const stp_simple_dither_range_t *ranges, double density)
1004 {
1005 dither_t *d = (dither_t *) vd;
1006 if (color < 0 || color >= d->n_channels)
1007 return;
1008 stp_dither_set_generic_ranges(d, &(CHANNEL(d, color)), nlevels,
1009 ranges, density);
1010 }
1011
1012 void
stp_dither_set_ranges_simple(void * vd,int color,int nlevels,const double * levels,double density)1013 stp_dither_set_ranges_simple(void *vd, int color, int nlevels,
1014 const double *levels, double density)
1015 {
1016 stp_simple_dither_range_t *r =
1017 stp_malloc(nlevels * sizeof(stp_simple_dither_range_t));
1018 int i;
1019 for (i = 0; i < nlevels; i++)
1020 {
1021 r[i].bit_pattern = i + 1;
1022 r[i].dot_size = i + 1;
1023 r[i].value = levels[i];
1024 r[i].subchannel = 0;
1025 }
1026 stp_dither_set_ranges(vd, color, nlevels, r, density);
1027 stp_free(r);
1028 }
1029
1030 void
stp_dither_set_ranges_full(void * vd,int color,int nlevels,const stp_full_dither_range_t * ranges,double density)1031 stp_dither_set_ranges_full(void *vd, int color, int nlevels,
1032 const stp_full_dither_range_t *ranges,
1033 double density)
1034 {
1035 dither_t *d = (dither_t *) vd;
1036 stp_dither_set_generic_ranges_full(d, &(CHANNEL(d, color)), nlevels,
1037 ranges, density);
1038 }
1039
1040 void
stp_free_dither(void * vd)1041 stp_free_dither(void *vd)
1042 {
1043 dither_t *d = (dither_t *) vd;
1044 int i;
1045 int j;
1046 for (j = 0; j < d->n_channels; j++)
1047 {
1048 SAFE_FREE(CHANNEL(d, j).vals);
1049 SAFE_FREE(CHANNEL(d, j).row_ends[0]);
1050 SAFE_FREE(CHANNEL(d, j).row_ends[1]);
1051 SAFE_FREE(CHANNEL(d, j).ptrs);
1052 if (CHANNEL(d, j).errs)
1053 {
1054 for (i = 0; i < d->error_rows; i++)
1055 SAFE_FREE(CHANNEL(d, j).errs[i]);
1056 SAFE_FREE(CHANNEL(d, j).errs);
1057 }
1058 SAFE_FREE(CHANNEL(d, j).ranges);
1059 stp_destroy_matrix(&(CHANNEL(d, j).pick));
1060 stp_destroy_matrix(&(CHANNEL(d, j).dithermat));
1061 }
1062 SAFE_FREE(d->offset0_table);
1063 SAFE_FREE(d->offset1_table);
1064 stp_destroy_matrix(&(d->dither_matrix));
1065 stp_destroy_matrix(&(d->transition_matrix));
1066 if (d->eventone) {
1067 eventone_t *et = d->eventone;
1068 stp_free(et->recip);
1069 for (i=0; i<d->n_channels; i++) {
1070 stp_free(et->dx[i]);
1071 stp_free(et->dy[i]);
1072 stp_free(et->r_sq[i]);
1073 }
1074 stp_free(et->r_sq);
1075 stp_free(et->dx);
1076 stp_free(et->dy);
1077 stp_free(d->eventone);
1078 }
1079 stp_free(d);
1080 }
1081
1082 int
stp_dither_get_first_position(void * vd,int color,int subchannel)1083 stp_dither_get_first_position(void *vd, int color, int subchannel)
1084 {
1085 dither_t *d = (dither_t *) vd;
1086 if (color < 0 || color >= d->n_channels)
1087 return -1;
1088 return CHANNEL(d, color).row_ends[0][subchannel];
1089 }
1090
1091 int
stp_dither_get_last_position(void * vd,int color,int subchannel)1092 stp_dither_get_last_position(void *vd, int color, int subchannel)
1093 {
1094 dither_t *d = (dither_t *) vd;
1095 if (color < 0 || color >= d->n_channels)
1096 return -1;
1097 return CHANNEL(d, color).row_ends[0][subchannel];
1098 }
1099
1100 static int *
get_errline(dither_t * d,int row,int color)1101 get_errline(dither_t *d, int row, int color)
1102 {
1103 if (row < 0 || color < 0 || color >= d->n_channels)
1104 return NULL;
1105 if (CHANNEL(d, color).errs[row & 1])
1106 return CHANNEL(d, color).errs[row & 1] + MAX_SPREAD;
1107 else
1108 {
1109 int size = 2 * MAX_SPREAD + (16 * ((d->dst_width + 7) / 8));
1110 CHANNEL(d, color).errs[row & 1] = stp_zalloc(size * sizeof(int));
1111 return CHANNEL(d, color).errs[row & 1] + MAX_SPREAD;
1112 }
1113 }
1114
1115 #define ADVANCE_UNIDIRECTIONAL(d, bit, input, width, xerror, xmod) \
1116 do \
1117 { \
1118 bit >>= 1; \
1119 if (bit == 0) \
1120 { \
1121 d->ptr_offset++; \
1122 bit = 128; \
1123 } \
1124 if (d->src_width == d->dst_width) \
1125 input += (width); \
1126 else \
1127 { \
1128 input += xstep; \
1129 xerror += xmod; \
1130 if (xerror >= d->dst_width) \
1131 { \
1132 xerror -= d->dst_width; \
1133 input += (width); \
1134 } \
1135 } \
1136 } while (0)
1137
1138 #define ADVANCE_REVERSE(d, bit, input, width, xerror, xmod) \
1139 do \
1140 { \
1141 if (bit == 128) \
1142 { \
1143 d->ptr_offset--; \
1144 bit = 1; \
1145 } \
1146 else \
1147 bit <<= 1; \
1148 if (d->src_width == d->dst_width) \
1149 input -= (width); \
1150 else \
1151 { \
1152 input -= xstep; \
1153 xerror -= xmod; \
1154 if (xerror < 0) \
1155 { \
1156 xerror += d->dst_width; \
1157 input -= (width); \
1158 } \
1159 } \
1160 } while (0)
1161
1162 #define ADVANCE_BIDIRECTIONAL(d, bit, in, dir, width, xer, xmod, err, N, S) \
1163 do \
1164 { \
1165 int i; \
1166 int j; \
1167 for (i = 0; i < N; i++) \
1168 for (j = 0; j < S; j++) \
1169 err[i][j] += dir; \
1170 if (dir == 1) \
1171 ADVANCE_UNIDIRECTIONAL(d, bit, in, width, xer, xmod); \
1172 else \
1173 ADVANCE_REVERSE(d, bit, in, width, xer, xmod); \
1174 } while (0)
1175
1176 /*
1177 * Add the error to the input value. Notice that we micro-optimize this
1178 * to save a division when appropriate.
1179 */
1180
1181 #define UPDATE_COLOR(color, dither) (\
1182 ((dither) >= 0)? \
1183 (color) + ((dither) >> 3): \
1184 (color) - ((-(dither)) >> 3))
1185
1186 /*
1187 * For Floyd-Steinberg, distribute the error residual. We spread the
1188 * error to nearby points, spreading more broadly in lighter regions to
1189 * achieve more uniform distribution of color. The actual distribution
1190 * is a triangular function.
1191 */
1192
1193 static inline int
update_dither(dither_t * d,int channel,int width,int direction,int * error0,int * error1)1194 update_dither(dither_t *d, int channel, int width,
1195 int direction, int *error0, int *error1)
1196 {
1197 int r = CHANNEL(d, channel).v;
1198 int o = CHANNEL(d, channel).o;
1199 int tmp = r;
1200 int i, dist, dist1;
1201 int delta, delta1;
1202 int offset;
1203 if (tmp == 0)
1204 return error0[direction];
1205 if (tmp > 65535)
1206 tmp = 65535;
1207 if (d->spread >= 16 || o >= 2048)
1208 {
1209 tmp += tmp;
1210 tmp += tmp;
1211 error1[0] += tmp;
1212 return error0[direction] + tmp;
1213 }
1214 else
1215 {
1216 int tmpo = o << 5;
1217 offset = ((65535 - tmpo) >> d->spread) +
1218 ((tmp & d->spread_mask) > (tmpo & d->spread_mask));
1219 }
1220 switch (offset)
1221 {
1222 case 0:
1223 tmp += tmp;
1224 tmp += tmp;
1225 error1[0] += tmp;
1226 return error0[direction] + tmp;
1227 case 1:
1228 error1[-1] += tmp;
1229 error1[1] += tmp;
1230 tmp += tmp;
1231 error1[0] += tmp;
1232 tmp += tmp;
1233 return error0[direction] + tmp;
1234 default:
1235 tmp += tmp;
1236 tmp += tmp;
1237 dist = tmp / d->offset0_table[offset];
1238 dist1 = tmp / d->offset1_table[offset];
1239 delta = dist;
1240 delta1 = dist1;
1241 for (i = -offset; i; i++)
1242 {
1243 error1[i] += delta;
1244 error1[-i] += delta;
1245 error0[i] += delta1;
1246 error0[-i] += delta1;
1247 delta1 += dist1;
1248 delta += dist;
1249 }
1250 error1[0] += delta;
1251 return error0[direction];
1252 }
1253 }
1254
1255 #define USMIN(a, b) ((a) < (b) ? (a) : (b))
1256
1257 static inline int
compute_black(const dither_t * d)1258 compute_black(const dither_t *d)
1259 {
1260 int answer = INT_MAX;
1261 int i;
1262 for (i = 1; i < d->n_channels; i++)
1263 answer = USMIN(answer, CHANNEL(d, i).v);
1264 return answer;
1265 }
1266
1267 static inline void
set_row_ends(dither_channel_t * dc,int x,int subchannel)1268 set_row_ends(dither_channel_t *dc, int x, int subchannel)
1269 {
1270 if (dc->row_ends[0][subchannel] == -1)
1271 dc->row_ends[0][subchannel] = x;
1272 dc->row_ends[1][subchannel] = x;
1273 }
1274
1275 /*
1276 * Print a single dot. This routine has become awfully complicated
1277 * awfully fast!
1278 */
1279
1280 static inline int
print_color(const dither_t * d,dither_channel_t * dc,int x,int y,unsigned char bit,int length,int dontprint,int dither_type)1281 print_color(const dither_t *d, dither_channel_t *dc, int x, int y,
1282 unsigned char bit, int length, int dontprint, int dither_type)
1283 {
1284 int base = dc->b;
1285 int density = dc->o;
1286 int adjusted = dc->v;
1287 unsigned randomizer = dc->randomizer;
1288 dither_matrix_t *pick_matrix = &(dc->pick);
1289 dither_matrix_t *dither_matrix = &(dc->dithermat);
1290 unsigned rangepoint = 32768;
1291 unsigned virtual_value;
1292 unsigned vmatrix;
1293 int i;
1294 int j;
1295 int subchannel;
1296 unsigned char *tptr;
1297 unsigned bits;
1298 unsigned v;
1299 unsigned dot_size;
1300 int levels = dc->nlevels - 1;
1301 int dither_value = adjusted;
1302 dither_segment_t *dd;
1303 ink_defn_t *lower;
1304 ink_defn_t *upper;
1305
1306 if (base <= 0 || density <= 0 ||
1307 (adjusted <= 0 && !(dither_type & D_ADAPTIVE_BASE)))
1308 return adjusted;
1309 if (density > 65535)
1310 density = 65535;
1311
1312 /*
1313 * Look for the appropriate range into which the input value falls.
1314 * Notice that we use the input, not the error, to decide what dot type
1315 * to print (if any). We actually use the "density" input to permit
1316 * the caller to use something other that simply the input value, if it's
1317 * desired to use some function of overall density, rather than just
1318 * this color's input, for this purpose.
1319 */
1320 for (i = levels; i >= 0; i--)
1321 {
1322 dd = &(dc->ranges[i]);
1323
1324 if (density <= dd->lower->range)
1325 continue;
1326
1327 /*
1328 * If we're using an adaptive dithering method, decide whether
1329 * to use the Floyd-Steinberg or the ordered method based on the
1330 * input value.
1331 */
1332 if (dither_type & D_ADAPTIVE_BASE)
1333 {
1334 dither_type -= D_ADAPTIVE_BASE;
1335
1336 if (base <= d->adaptive_limit)
1337 {
1338 dither_type = D_ORDERED;
1339 dither_value = base;
1340 }
1341 else if (adjusted <= 0)
1342 return adjusted;
1343 }
1344
1345 /*
1346 * Where are we within the range. If we're going to print at
1347 * all, this determines the probability of printing the darker
1348 * vs. the lighter ink. If the inks are identical (same value
1349 * and darkness), it doesn't matter.
1350 *
1351 * We scale the input linearly against the top and bottom of the
1352 * range.
1353 */
1354
1355 lower = dd->lower;
1356 upper = dd->upper;
1357
1358 if (!dd->is_equal)
1359 rangepoint =
1360 ((unsigned) (density - lower->range)) * 65535 / dd->range_span;
1361
1362 /*
1363 * Compute the virtual dot size that we're going to print.
1364 * This is somewhere between the two candidate dot sizes.
1365 * This is scaled between the high and low value.
1366 */
1367
1368 if (dd->value_span == 0)
1369 virtual_value = upper->value;
1370 else if (dd->range_span == 0)
1371 virtual_value = (upper->value + lower->value) / 2;
1372 else
1373 virtual_value = lower->value +
1374 (dd->value_span * d->virtual_dot_scale[rangepoint] / 65535);
1375
1376 /*
1377 * Reduce the randomness as the base value increases, to get
1378 * smoother output in the midtones. Idea suggested by
1379 * Thomas Tonino.
1380 */
1381 if (dither_type & D_ORDERED_BASE)
1382 randomizer = 65535; /* With ordered dither, we need this */
1383 else if (randomizer > 0)
1384 {
1385 if (base > d->d_cutoff)
1386 randomizer = 0;
1387 else if (base > d->d_cutoff / 2)
1388 randomizer = randomizer * 2 * (d->d_cutoff - base) / d->d_cutoff;
1389 }
1390
1391 /*
1392 * Compute the comparison value to decide whether to print at
1393 * all. If there is no randomness, simply divide the virtual
1394 * dotsize by 2 to get standard "pure" Floyd-Steinberg (or "pure"
1395 * matrix dithering, which degenerates to a threshold).
1396 */
1397 if (randomizer == 0)
1398 vmatrix = virtual_value / 2;
1399 else
1400 {
1401 /*
1402 * First, compute a value between 0 and 65535 that will be
1403 * scaled to produce an offset from the desired threshold.
1404 */
1405 vmatrix = ditherpoint(d, dither_matrix, x);
1406 /*
1407 * Now, scale the virtual dot size appropriately. Note that
1408 * we'll get something evenly distributed between 0 and
1409 * the virtual dot size, centered on the dot size / 2,
1410 * which is the normal threshold value.
1411 */
1412 vmatrix = vmatrix * virtual_value / 65535;
1413 if (randomizer != 65535)
1414 {
1415 /*
1416 * We want vmatrix to be scaled between 0 and
1417 * virtual_value when randomizer is 65535 (fully random).
1418 * When it's less, we want it to scale through part of
1419 * that range. In all cases, it should center around
1420 * virtual_value / 2.
1421 *
1422 * vbase is the bottom of the scaling range.
1423 */
1424 unsigned vbase = virtual_value * (65535u - randomizer) /
1425 131070u;
1426 vmatrix = vmatrix * randomizer / 65535;
1427 vmatrix += vbase;
1428 }
1429 } /* randomizer != 0 */
1430
1431 /*
1432 * After all that, printing is almost an afterthought.
1433 * Pick the actual dot size (using a matrix here) and print it.
1434 */
1435 if (dither_value >= vmatrix)
1436 {
1437 ink_defn_t *subc;
1438
1439 if (dd->is_same_ink)
1440 subc = upper;
1441 else
1442 {
1443 rangepoint = rangepoint * dc->density / 65535u;
1444 if (rangepoint >= ditherpoint(d, pick_matrix, x))
1445 subc = upper;
1446 else
1447 subc = lower;
1448 }
1449 subchannel = subc->subchannel;
1450 bits = subc->bits;
1451 v = subc->value;
1452 dot_size = subc->dot_size;
1453 tptr = dc->ptrs[subchannel] + d->ptr_offset;
1454
1455 /*
1456 * Lay down all of the bits in the pixel.
1457 */
1458 if (dontprint < v)
1459 {
1460 set_row_ends(dc, x, subchannel);
1461 for (j = 1; j <= bits; j += j, tptr += length)
1462 {
1463 if (j & bits)
1464 tptr[0] |= bit;
1465 }
1466 }
1467 if (dither_type & D_ORDERED_BASE)
1468 adjusted = -(int) v / 2;
1469 else
1470 adjusted -= v;
1471 }
1472 return adjusted;
1473 }
1474 return adjusted;
1475 }
1476
1477 static inline int
print_color_ordered(const dither_t * d,dither_channel_t * dc,int x,int y,unsigned char bit,int length,int dontprint)1478 print_color_ordered(const dither_t *d, dither_channel_t *dc, int x, int y,
1479 unsigned char bit, int length, int dontprint)
1480 {
1481 int density = dc->o;
1482 int adjusted = dc->v;
1483 dither_matrix_t *pick_matrix = &(dc->pick);
1484 dither_matrix_t *dither_matrix = &(dc->dithermat);
1485 unsigned rangepoint;
1486 unsigned virtual_value;
1487 unsigned vmatrix;
1488 int i;
1489 int j;
1490 int subchannel;
1491 unsigned char *tptr;
1492 unsigned bits;
1493 unsigned v;
1494 unsigned dot_size;
1495 int levels = dc->nlevels - 1;
1496 int dither_value = adjusted;
1497 dither_segment_t *dd;
1498 ink_defn_t *lower;
1499 ink_defn_t *upper;
1500
1501 if (adjusted <= 0 || density <= 0)
1502 return 0;
1503 if (density > 65535)
1504 density = 65535;
1505
1506 /*
1507 * Look for the appropriate range into which the input value falls.
1508 * Notice that we use the input, not the error, to decide what dot type
1509 * to print (if any). We actually use the "density" input to permit
1510 * the caller to use something other that simply the input value, if it's
1511 * desired to use some function of overall density, rather than just
1512 * this color's input, for this purpose.
1513 */
1514 for (i = levels; i >= 0; i--)
1515 {
1516 dd = &(dc->ranges[i]);
1517
1518 if (density <= dd->lower->range)
1519 continue;
1520
1521 /*
1522 * Where are we within the range. If we're going to print at
1523 * all, this determines the probability of printing the darker
1524 * vs. the lighter ink. If the inks are identical (same value
1525 * and darkness), it doesn't matter.
1526 *
1527 * We scale the input linearly against the top and bottom of the
1528 * range.
1529 */
1530
1531 lower = dd->lower;
1532 upper = dd->upper;
1533
1534 if (dd->is_equal)
1535 rangepoint = 32768;
1536 else
1537 rangepoint =
1538 ((unsigned) (density - lower->range)) * 65535 / dd->range_span;
1539
1540 /*
1541 * Compute the virtual dot size that we're going to print.
1542 * This is somewhere between the two candidate dot sizes.
1543 * This is scaled between the high and low value.
1544 */
1545
1546 if (dd->value_span == 0)
1547 virtual_value = upper->value;
1548 else if (dd->range_span == 0)
1549 virtual_value = (upper->value + lower->value) / 2;
1550 else
1551 virtual_value = lower->value +
1552 (dd->value_span * d->virtual_dot_scale[rangepoint] / 65535);
1553
1554 /*
1555 * Compute the comparison value to decide whether to print at
1556 * all. If there is no randomness, simply divide the virtual
1557 * dotsize by 2 to get standard "pure" Floyd-Steinberg (or "pure"
1558 * matrix dithering, which degenerates to a threshold).
1559 */
1560 /*
1561 * First, compute a value between 0 and 65535 that will be
1562 * scaled to produce an offset from the desired threshold.
1563 */
1564 vmatrix = ditherpoint(d, dither_matrix, x);
1565 /*
1566 * Now, scale the virtual dot size appropriately. Note that
1567 * we'll get something evenly distributed between 0 and
1568 * the virtual dot size, centered on the dot size / 2,
1569 * which is the normal threshold value.
1570 */
1571 vmatrix = vmatrix * virtual_value / 65535;
1572
1573 /*
1574 * After all that, printing is almost an afterthought.
1575 * Pick the actual dot size (using a matrix here) and print it.
1576 */
1577 if (dither_value >= vmatrix)
1578 {
1579 ink_defn_t *subc;
1580
1581 if (dd->is_same_ink)
1582 subc = upper;
1583 else
1584 {
1585 rangepoint = rangepoint * dc->density / 65535u;
1586 if (rangepoint >= ditherpoint(d, pick_matrix, x))
1587 subc = upper;
1588 else
1589 subc = lower;
1590 }
1591 subchannel = subc->subchannel;
1592 bits = subc->bits;
1593 v = subc->value;
1594 dot_size = subc->dot_size;
1595 tptr = dc->ptrs[subchannel] + d->ptr_offset;
1596
1597 /*
1598 * Lay down all of the bits in the pixel.
1599 */
1600 if (dontprint < v)
1601 {
1602 set_row_ends(dc, x, subchannel);
1603 for (j = 1; j <= bits; j += j, tptr += length)
1604 {
1605 if (j & bits)
1606 tptr[0] |= bit;
1607 }
1608 return v;
1609 }
1610 }
1611 return 0;
1612 }
1613 return 0;
1614 }
1615
1616 static inline void
print_color_fast(const dither_t * d,dither_channel_t * dc,int x,int y,unsigned char bit,int length)1617 print_color_fast(const dither_t *d, dither_channel_t *dc, int x, int y,
1618 unsigned char bit, int length)
1619 {
1620 int density = dc->o;
1621 int adjusted = dc->v;
1622 dither_matrix_t *dither_matrix = &(dc->dithermat);
1623 int i;
1624 int levels = dc->nlevels - 1;
1625 int j;
1626 unsigned char *tptr;
1627 unsigned bits;
1628
1629 if (density <= 0 || adjusted <= 0)
1630 return;
1631 for (i = levels; i >= 0; i--)
1632 {
1633 dither_segment_t *dd = &(dc->ranges[i]);
1634 unsigned vmatrix;
1635 unsigned rangepoint;
1636 unsigned dpoint;
1637 unsigned range0;
1638 ink_defn_t *subc;
1639
1640 range0 = dd->lower->range;
1641 if (density <= range0)
1642 continue;
1643 dpoint = ditherpoint(d, dither_matrix, x);
1644
1645 if (dd->is_same_ink)
1646 subc = dd->upper;
1647 else
1648 {
1649 rangepoint = ((density - range0) << 16) / dd->range_span;
1650 rangepoint = (rangepoint * dc->density) >> 16;
1651 if (rangepoint >= dpoint)
1652 subc = dd->upper;
1653 else
1654 subc = dd->lower;
1655 }
1656 vmatrix = (subc->value * dpoint) >> 16;
1657
1658 /*
1659 * After all that, printing is almost an afterthought.
1660 * Pick the actual dot size (using a matrix here) and print it.
1661 */
1662 if (adjusted >= vmatrix)
1663 {
1664 int subchannel = subc->subchannel;
1665 bits = subc->bits;
1666 tptr = dc->ptrs[subchannel] + d->ptr_offset;
1667 set_row_ends(dc, x, subchannel);
1668
1669 /*
1670 * Lay down all of the bits in the pixel.
1671 */
1672 for (j = 1; j <= bits; j += j, tptr += length)
1673 {
1674 if (j & bits)
1675 tptr[0] |= bit;
1676 }
1677 }
1678 return;
1679 }
1680 }
1681
1682 static inline void
update_cmyk(dither_t * d)1683 update_cmyk(dither_t *d)
1684 {
1685 int ak;
1686 int i;
1687 int kdarkness = 0;
1688 unsigned ks, kl;
1689 int ub, lb;
1690 int ok;
1691 int bk;
1692 unsigned density;
1693 int k = CHANNEL(d, ECOLOR_K).o;
1694
1695 ub = d->k_upper;
1696 lb = d->k_lower;
1697 density = d->density;
1698
1699 /*
1700 * Calculate total ink amount.
1701 * If there is a lot of ink, black gets added sooner. Saves ink
1702 * and with a lot of ink the black doesn't show as speckles.
1703 *
1704 * k already contains the grey contained in CMY.
1705 * First we find out if the color is darker than the K amount
1706 * suggests, and we look up where is value is between
1707 * lowerbound and density:
1708 */
1709
1710 for (i = 1; i < d->n_channels; i++)
1711 kdarkness += CHANNEL(d, i).o * CHANNEL(d, i).darkness / 64;
1712 kdarkness -= d->density2;
1713
1714 if (kdarkness > (k + k + k))
1715 ok = kdarkness / 3;
1716 else
1717 ok = k;
1718 if (ok <= lb)
1719 kl = 0;
1720 else if (ok >= density)
1721 kl = density;
1722 else
1723 kl = (unsigned) ( ok - lb ) * density / d->dlb_range;
1724
1725 /*
1726 * We have a second value, ks, that will be the scaler.
1727 * ks is initially showing where the original black
1728 * amount is between upper and lower bounds:
1729 */
1730
1731 if (k >= ub)
1732 ks = density;
1733 else if (k <= lb)
1734 ks = 0;
1735 else
1736 ks = (unsigned) (k - lb) * density / d->bound_range;
1737
1738 /*
1739 * ks is then processed by a second order function that produces
1740 * an S curve: 2ks - ks^2. This is then multiplied by the
1741 * darkness value in kl. If we think this is too complex the
1742 * following line can be tried instead:
1743 * ak = ks;
1744 */
1745 ak = ks;
1746 if (kl == 0 || ak == 0)
1747 k = 0;
1748 else if (ak == density)
1749 k = kl;
1750 else
1751 k = (unsigned) kl * (unsigned) ak / density;
1752 ok = k;
1753 bk = k;
1754 if (bk > 0 && density != d->black_density)
1755 bk = (unsigned) bk * (unsigned) d->black_density / density;
1756 if (bk > 65535)
1757 bk = 65535;
1758
1759 if (k && ak && ok > 0)
1760 {
1761 int i;
1762 /*
1763 * Because black is always fairly neutral, we do not have to
1764 * calculate the amount to take out of CMY. The result will
1765 * be a bit dark but that is OK. If things are okay CMY
1766 * cannot go negative here - unless extra K is added in the
1767 * previous block. We multiply by ak to prevent taking out
1768 * too much. This prevents dark areas from becoming very
1769 * dull.
1770 */
1771
1772 if (ak == density)
1773 ok = k;
1774 else
1775 ok = (unsigned) k * (unsigned) ak / density;
1776
1777 for (i = 1; i < d->n_channels; i++)
1778 {
1779 if (CHANNEL(d, i).k_level == 64)
1780 CHANNEL(d, i).v -= ok;
1781 else
1782 CHANNEL(d, i).v -= (ok * CHANNEL(d, i).k_level) >> 6;
1783 if (CHANNEL(d, i).v < 0)
1784 CHANNEL(d, i).v = 0;
1785 }
1786 }
1787 else
1788 for (i = 1; i < d->n_channels; i++)
1789 CHANNEL(d, i).v = CHANNEL(d, i).o;
1790 CHANNEL(d, ECOLOR_K).b = bk;
1791 CHANNEL(d, ECOLOR_K).v = k;
1792 }
1793
1794 static int
shared_ed_initializer(dither_t * d,int row,int duplicate_line,int zero_mask,int length,int direction,int **** error,int ** ndither)1795 shared_ed_initializer(dither_t *d,
1796 int row,
1797 int duplicate_line,
1798 int zero_mask,
1799 int length,
1800 int direction,
1801 int ****error,
1802 int **ndither)
1803 {
1804 int i, j;
1805 if (!duplicate_line)
1806 {
1807 if ((zero_mask & ((1 << d->n_input_channels) - 1)) !=
1808 ((1 << d->n_input_channels) - 1))
1809 d->last_line_was_empty = 0;
1810 else
1811 d->last_line_was_empty++;
1812 }
1813 else if (d->last_line_was_empty)
1814 d->last_line_was_empty++;
1815 if (d->last_line_was_empty >= 5)
1816 return 0;
1817 else if (d->last_line_was_empty == 4)
1818 {
1819 for (i = 0; i < d->n_channels; i++)
1820 for (j = 0; j < d->error_rows; j++)
1821 memset(get_errline(d, row + j, i), 0, d->dst_width * sizeof(int));
1822 return 0;
1823 }
1824 d->ptr_offset = (direction == 1) ? 0 : length - 1;
1825
1826 *error = stp_malloc(d->n_channels * sizeof(int **));
1827 *ndither = stp_malloc(d->n_channels * sizeof(int));
1828 for (i = 0; i < d->n_channels; i++)
1829 {
1830 (*error)[i] = stp_malloc(d->error_rows * sizeof(int *));
1831 for (j = 0; j < d->error_rows; j++)
1832 {
1833 (*error)[i][j] = get_errline(d, row + j, i);
1834 if (j == d->error_rows - 1)
1835 memset((*error)[i][j], 0, d->dst_width * sizeof(int));
1836 if (direction == -1)
1837 (*error)[i][j] += d->dst_width - 1;
1838 }
1839 (*ndither)[i] = (*error)[i][0][0];
1840 }
1841 return 1;
1842 }
1843
1844
1845 #define V_WHITE 0
1846 #define V_CYAN (1<<ECOLOR_C)
1847 #define V_MAGENTA (1<<ECOLOR_M)
1848 #define V_YELLOW (1<<ECOLOR_Y)
1849 #define V_BLUE (V_CYAN|V_MAGENTA)
1850 #define V_GREEN (V_CYAN|V_YELLOW)
1851 #define V_RED (V_MAGENTA|V_YELLOW)
1852 #define V_BLACK (V_CYAN|V_MAGENTA|V_YELLOW)
1853
1854 static inline int
pick_vertex(int c,int m,int y,int k)1855 pick_vertex(int c, int m, int y, int k)
1856 {
1857 int best;
1858 int tmax, vmax;
1859
1860 if (c+m+y <= 65535) {
1861 best = V_WHITE; vmax = 65535-c-m-y; /* White */
1862 if (c > vmax) { best = V_CYAN; vmax = c; } /* Cyan */
1863 if (m > vmax) { best = V_MAGENTA; vmax = m; } /* Magenta */
1864 if (y > vmax) { best = V_YELLOW; vmax = y; } /* Yellow */
1865 } else if (c+m+y >= 2*65535) {
1866 best = V_BLACK; vmax = c+m+y-2*65535; /* Black */
1867 if ((tmax = 65535-y) > vmax) {best = V_BLUE; vmax = tmax; } /* Blue */
1868 if ((tmax = 65535-m) > vmax) {best = V_GREEN; vmax = tmax; } /* Green */
1869 if ((tmax = 65535-c) > vmax) {best = V_RED; vmax = tmax; } /* Red */
1870 } else if (m+c <= 65535) {
1871 if (m+y <= 65535) {
1872 best = V_GREEN; vmax = c+m+y-65535; /* Green */
1873 if (m > vmax) {best = V_MAGENTA; vmax = m;} /* Magenta */
1874 if ((tmax = 65535-m-y) > vmax) {best = V_CYAN; vmax = tmax;} /* Cyan */
1875 if ((tmax = 65535-c-m) > vmax) {best = V_YELLOW; vmax = tmax;} /* Yellow */
1876 } else {
1877 best = V_RED; vmax = m+y-65535; /* Red */
1878 if (c > vmax) { best = V_GREEN; vmax = c;} /* Green */
1879 if ((tmax = 65535-y) > vmax) {best = V_MAGENTA; vmax = tmax;} /* Magenta */
1880 if ((tmax = 65535-m-c) > vmax) {best = V_YELLOW; vmax = tmax;} /* Yellow */
1881 }
1882 } else {
1883 if (m+y > 65535) {
1884 best = V_MAGENTA; vmax = 2*65535-m-c-y; /* Magenta */
1885 if ((tmax = c+m-65535) > vmax) { best = V_BLUE; vmax = tmax; } /* Blue */
1886 if ((tmax = y+m-65535) > vmax) { best = V_RED; vmax = tmax; } /* Red */
1887 if ((tmax = 65535-m) > vmax) { best = V_GREEN; vmax = tmax; } /* Green */
1888 } else {
1889 best = V_CYAN; vmax = 65535-y-m; /* Cyan */
1890 if ((tmax = c+m-65535) > vmax) { best = V_BLUE; vmax = tmax; } /* Blue */
1891 if ((tmax = 65535-c) > vmax) { best = V_MAGENTA; vmax = tmax; } /* Magenta */
1892 if (y > vmax) { best = V_GREEN; vmax = y;} /* Green */
1893 }
1894 }
1895
1896 if (k >= 32768) {
1897 best |= (1 << ECOLOR_K);
1898 }
1899
1900 return best;
1901 }
1902
1903 typedef struct {
1904 int dx, dy, r_sq, wetness, ri, point;
1905 int maxdot_dens; /* Max dot size * density */
1906 int maxdot_wet; /* Maximum wetness allowed */
1907 dither_segment_t dr;
1908 } et_chdata_t;
1909
find_segment(dither_t * d,dither_channel_t * dc,int wetness,int density,dither_segment_t * range)1910 static inline void find_segment(dither_t *d, dither_channel_t *dc, int wetness, int density, dither_segment_t *range)
1911 {
1912 int i;
1913 ink_defn_t *di;
1914 int max_dot;
1915
1916 if (wetness < 0) max_dot = 0;
1917 else max_dot = wetness >> 16;
1918
1919 range->lower = range->upper = dc->ranges[0].lower;
1920
1921 for (i = dc->nlevels-1; i > 0; i--) {
1922 di = dc->ranges[i].lower;
1923 if (density < di->value) continue;
1924 if (max_dot < di->dot_size) continue;
1925 range->lower = di;
1926 range->upper = di;
1927 break;
1928 }
1929
1930 for (; i < dc->nlevels; i++) {
1931 di = dc->ranges[i].upper;
1932 if (max_dot < di->dot_size) continue;
1933 range->upper = di;
1934 if (density < di->value) break;
1935 }
1936 }
1937
1938 #define EVEN_C1 256
1939 #define EVEN_C2 222 /* = sqrt(3)/2 * EVEN_C1 */
1940
1941 static inline void
eventone_init(dither_t * d,et_chdata_t ** cd)1942 eventone_init(dither_t *d, et_chdata_t **cd)
1943 {
1944 int i;
1945 eventone_t *et = d->eventone;
1946
1947 if (!et) {
1948
1949 et = stp_zalloc(sizeof(eventone_t));
1950
1951 { int xa, ya;
1952 xa = d->x_aspect / d->y_aspect;
1953 if (xa == 0) xa = 1;
1954 et->dx2 = xa * xa;
1955 et->d2x = 2 * et->dx2;
1956
1957 ya = d->y_aspect / d->x_aspect;
1958 if (ya == 0) ya = 1;
1959 et->dy2 = ya * ya;
1960 et->d2y = 2 * et->dy2;
1961
1962 et->aspect = EVEN_C2 / (xa * ya);
1963 }
1964
1965 et->recip = stp_malloc(65536 * sizeof(int));
1966 et->dx = stp_malloc(sizeof(int *) * d->n_channels);
1967 et->dy = stp_malloc(sizeof(int *) * d->n_channels);
1968 et->r_sq = stp_malloc(sizeof(int *) * d->n_channels);
1969
1970 for (i=0; i < d->n_channels; i++) {
1971 int x;
1972 et->dx[i] = stp_malloc(sizeof(int) * d->dst_width);
1973 et->dy[i] = stp_malloc(sizeof(int) * d->dst_width);
1974 et->r_sq[i] = stp_zalloc(sizeof(int) * d->dst_width);
1975 for (x = 0; x < d->dst_width; x++) {
1976 et->dx[i][x] = et->dx2;
1977 et->dy[i][x] = et->dy2;
1978 }
1979 }
1980
1981 for (i=0; i < 65536; i++) {
1982 if (i == 0)
1983 et->recip[i] = EVEN_C1 * 65536;
1984 else
1985 et->recip[i] = EVEN_C1 * 65536 / i;
1986 }
1987
1988 for (i = 0; i < d->n_channels; i++) {
1989 CHANNEL(d, i).ranges[0].lower->value = 0;
1990 CHANNEL(d, i).ranges[0].lower->range = 0;
1991 CHANNEL(d, i).ranges[0].lower->bits = 0;
1992 CHANNEL(d, i).ranges[0].lower->subchannel = 0;
1993 CHANNEL(d, i).ranges[0].lower->dot_size = 0;
1994 }
1995
1996 d->eventone = et;
1997 }
1998
1999 { et_chdata_t *p;
2000 *cd = stp_malloc(sizeof(et_chdata_t) * d->n_channels);
2001
2002 for (i = 0, p = *cd; i < d->n_channels; i++, p++)
2003 {
2004 p->wetness = 0;
2005 p->maxdot_dens = CHANNEL(d, i).maxdot * d->density;
2006 p->maxdot_wet = (65536 + d->density / 2) * CHANNEL(d, i).maxdot;
2007 p->dx = et->dx2;
2008 p->dy = et->dy2;
2009 p->r_sq = 0;
2010 }
2011 }
2012 }
2013
2014 static inline void
advance_eventone_pre(dither_t * d,et_chdata_t * cd,eventone_t * et,int x)2015 advance_eventone_pre(dither_t *d, et_chdata_t *cd, eventone_t *et, int x)
2016 {
2017 int i;
2018
2019 for (i=0; i < d->n_channels; cd++, i++) {
2020 if (cd->r_sq + cd->dx <= et->r_sq[i][x]) { /* Do our eventone calculations */
2021 cd->r_sq += cd->dx; /* Nearest pixel same as last one */
2022 cd->dx += et->d2x;
2023 } else {
2024 cd->dx = et->dx[i][x]; /* Nearest pixel is from a previous line */
2025 cd->dy = et->dy[i][x];
2026 cd->r_sq = et->r_sq[i][x];
2027 }
2028 }
2029 }
2030
2031 static inline void
advance_eventone_post(dither_t * d,et_chdata_t * cd,eventone_t * et,int x)2032 advance_eventone_post(dither_t *d, et_chdata_t *cd, eventone_t *et, int x)
2033 {
2034 int i;
2035 int t;
2036
2037 for (i=0; i < d->n_channels; cd++, i++) {
2038 if (cd->point > 0) {
2039 cd->r_sq = 0;
2040 cd->dx = et->dx2;
2041 cd->dy = et->dy2;
2042 }
2043 t = et->r_sq[i][x] + et->dy[i][x];
2044 et->dy[i][x] += et->d2y;
2045 if (cd->r_sq + cd->dy < t) {
2046 t = cd->r_sq + cd->dy;
2047 et->dx[i][x] = cd->dx;
2048 et->dy[i][x] = cd->dy + et->d2y;
2049 }
2050 if (t > 65535) {
2051 t = 65535;
2052 }
2053 et->r_sq[i][x] = t;
2054 }
2055 }
2056
2057 static inline int
eventone_adjust(dither_segment_t * range,eventone_t * et,int r_sq,int base,int value)2058 eventone_adjust(dither_segment_t *range, eventone_t *et, int r_sq, int base, int value)
2059 {
2060 unsigned upper;
2061 unsigned lower;
2062 unsigned value_span;
2063 int ditherpoint;
2064
2065 lower = range->lower->value;
2066 upper = range->upper->value;
2067 value_span = upper - lower;
2068
2069 if (value >= upper) {
2070 ditherpoint = 65535;
2071 } else {
2072 if (value <= lower) {
2073 ditherpoint = 0;
2074 } else {
2075 ditherpoint = ((unsigned)(value - lower) << 16) / value_span;
2076 }
2077 /* Adjust for Eventone here */
2078 if (lower == 0) {
2079 ditherpoint += r_sq * et->aspect;
2080 if (base < upper) {
2081 ditherpoint -= et->recip[(base<<16) / value_span];
2082 }
2083 if (ditherpoint > 65535) ditherpoint = 65535;
2084 else if (ditherpoint < 0) ditherpoint = 0;
2085 }
2086 }
2087 return ditherpoint;
2088 }
2089
2090 static inline void
print_all_inks(dither_t * d,et_chdata_t * cd,int print_inks,int pick,unsigned char bit,int length)2091 print_all_inks(dither_t *d, et_chdata_t *cd, int print_inks, int pick, unsigned char bit, int length)
2092 {
2093 int i, mask;
2094 for (i = 0, mask = 1; i < d->n_channels; mask <<= 1, cd++, i++) {
2095 int j;
2096 ink_defn_t *subc;
2097 int bits;
2098 unsigned char *tptr;
2099
2100 if (!(print_inks & mask)) continue;
2101
2102 subc = (pick & mask) ? cd->dr.upper : cd->dr.lower;
2103 bits = subc->bits;
2104 if (bits == 0) continue;
2105
2106 tptr = CHANNEL(d, i).ptrs[subc->subchannel] + d->ptr_offset;
2107 cd->wetness += subc->dot_size << 16;
2108
2109 for (j=1; j <= bits; j+=j, tptr += length) {
2110 if (j & bits) *tptr |= bit;
2111 }
2112 }
2113 }
2114
2115 static inline void
diffuse_error(dither_t * d,int * ndither,int *** error,int aspect,int direction)2116 diffuse_error(dither_t *d, int *ndither, int ***error, int aspect, int direction)
2117 {
2118 int i;
2119 int fraction, frac_2, frac_3;
2120 int *err;
2121 static const int diff_fact[] = {1, 10, 16, 23, 32};
2122 int factor = diff_fact[aspect];
2123
2124 for (i=0; i < d->n_channels; i++, ndither++, error++) {
2125 fraction = (*ndither + (factor>>1)) / factor;
2126 frac_2 = fraction + fraction;
2127 frac_3 = frac_2 + fraction;
2128 err = (*error)[1];
2129 err[0] += frac_3;
2130 err[-direction] += frac_2;
2131 *ndither += (*error)[0][direction] - frac_2 - frac_3;
2132 }
2133 }
2134
2135 /*
2136 * Dithering functions!
2137 *
2138 * Documentation moved to README.dither
2139 */
2140
2141 /*
2142 * 'stp_dither_monochrome()' - Dither grayscale pixels to black using a hard
2143 * threshold. This is for use with predithered output, or for text
2144 * or other pure black and white only.
2145 */
2146
2147 static void
stp_dither_monochrome(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2148 stp_dither_monochrome(const unsigned short *gray,
2149 int row,
2150 dither_t *d,
2151 int duplicate_line,
2152 int zero_mask)
2153 {
2154 int x,
2155 xerror,
2156 xstep,
2157 xmod,
2158 length;
2159 unsigned char bit,
2160 *kptr;
2161 dither_channel_t *dc = &(CHANNEL(d, ECOLOR_K));
2162 dither_matrix_t *kdither = &(dc->dithermat);
2163 unsigned bits = dc->signif_bits;
2164 int j;
2165 unsigned char *tptr;
2166 int dst_width = d->dst_width;
2167 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2168 ((1 << d->n_input_channels) - 1))
2169 return;
2170
2171 kptr = CHANNEL(d, ECOLOR_K).ptrs[0];
2172 length = (d->dst_width + 7) / 8;
2173
2174 bit = 128;
2175 x = 0;
2176
2177 xstep = d->src_width / d->dst_width;
2178 xmod = d->src_width % d->dst_width;
2179 xerror = 0;
2180 for (x = 0; x < dst_width; x++)
2181 {
2182 if (gray[0] && (d->density >= ditherpoint(d, kdither, x)))
2183 {
2184 tptr = kptr + d->ptr_offset;
2185 set_row_ends(dc, x, 0);
2186 for (j = 0; j < bits; j++, tptr += length)
2187 tptr[0] |= bit;
2188 }
2189 ADVANCE_UNIDIRECTIONAL(d, bit, gray, 1, xerror, xmod);
2190 }
2191 }
2192
2193 static void
stp_dither_monochrome_very_fast(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2194 stp_dither_monochrome_very_fast(const unsigned short *gray,
2195 int row,
2196 dither_t *d,
2197 int duplicate_line,
2198 int zero_mask)
2199 {
2200 int x,
2201 xerror,
2202 xstep,
2203 xmod,
2204 length;
2205 unsigned char bit,
2206 *kptr;
2207 dither_channel_t *dc = &(CHANNEL(d, ECOLOR_K));
2208 dither_matrix_t *kdither = &(dc->dithermat);
2209 int dst_width = d->dst_width;
2210 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2211 ((1 << d->n_input_channels) - 1))
2212 return;
2213 if (!dc->very_fast)
2214 {
2215 stp_dither_monochrome(gray, row, d, duplicate_line, zero_mask);
2216 return;
2217 }
2218
2219 kptr = CHANNEL(d, ECOLOR_K).ptrs[0];
2220 length = (d->dst_width + 7) / 8;
2221
2222 bit = 128;
2223 x = 0;
2224
2225 xstep = d->src_width / d->dst_width;
2226 xmod = d->src_width % d->dst_width;
2227 xerror = 0;
2228 for (x = 0; x < dst_width; x++)
2229 {
2230 if (gray[0] && (d->density > ditherpoint_fast(d, kdither, x)))
2231 {
2232 set_row_ends(dc, x, 0);
2233 kptr[d->ptr_offset] |= bit;
2234 }
2235 ADVANCE_UNIDIRECTIONAL(d, bit, gray, 1, xerror, xmod);
2236 }
2237 }
2238
2239 /*
2240 * 'stp_dither_black()' - Dither grayscale pixels to black.
2241 * This is for grayscale output.
2242 */
2243
2244 static void
stp_dither_black_fast(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2245 stp_dither_black_fast(const unsigned short *gray,
2246 int row,
2247 dither_t *d,
2248 int duplicate_line,
2249 int zero_mask)
2250 {
2251 int x,
2252 length;
2253 unsigned char bit;
2254 int dst_width = d->dst_width;
2255 int xerror, xstep, xmod;
2256
2257 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2258 ((1 << d->n_input_channels) - 1))
2259 return;
2260 length = (d->dst_width + 7) / 8;
2261
2262 bit = 128;
2263 xstep = d->src_width / d->dst_width;
2264 xmod = d->src_width % d->dst_width;
2265 xerror = 0;
2266
2267 for (x = 0; x < dst_width; x++)
2268 {
2269 CHANNEL(d, ECOLOR_K).v = gray[0];
2270 CHANNEL(d, ECOLOR_K).o = gray[0];
2271 print_color_fast(d, &(CHANNEL(d, ECOLOR_K)), x, row, bit, length);
2272 ADVANCE_UNIDIRECTIONAL(d, bit, gray, 1, xerror, xmod);
2273 }
2274 }
2275
2276 static void
stp_dither_black_very_fast(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2277 stp_dither_black_very_fast(const unsigned short *gray,
2278 int row,
2279 dither_t *d,
2280 int duplicate_line,
2281 int zero_mask)
2282 {
2283 int x,
2284 length;
2285 unsigned char bit;
2286 dither_channel_t *dc = &CHANNEL(d, ECOLOR_K);
2287 int dst_width = d->dst_width;
2288 int xerror, xstep, xmod;
2289 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2290 ((1 << d->n_input_channels) - 1))
2291 return;
2292 if (!dc->very_fast)
2293 {
2294 stp_dither_black_fast(gray, row, d, duplicate_line, zero_mask);
2295 return;
2296 }
2297 length = (d->dst_width + 7) / 8;
2298
2299 bit = 128;
2300 xstep = d->src_width / d->dst_width;
2301 xmod = d->src_width % d->dst_width;
2302 xerror = 0;
2303
2304 for (x = 0; x < dst_width; x++)
2305 {
2306 if (gray[0] > ditherpoint_fast(d, &(dc->dithermat), x))
2307 {
2308 set_row_ends(dc, x, 0);
2309 dc->ptrs[0][d->ptr_offset] |= bit;
2310 }
2311 ADVANCE_UNIDIRECTIONAL(d, bit, gray, 1, xerror, xmod);
2312 }
2313 }
2314
2315 static void
stp_dither_black_ordered(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2316 stp_dither_black_ordered(const unsigned short *gray,
2317 int row,
2318 dither_t *d,
2319 int duplicate_line,
2320 int zero_mask)
2321 {
2322
2323 int x,
2324 length;
2325 unsigned char bit;
2326 int terminate;
2327 int xerror, xstep, xmod;
2328
2329 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2330 ((1 << d->n_input_channels) - 1))
2331 return;
2332
2333 length = (d->dst_width + 7) / 8;
2334
2335 bit = 128;
2336 x = 0;
2337 terminate = d->dst_width;
2338 xstep = d->src_width / d->dst_width;
2339 xmod = d->src_width % d->dst_width;
2340 xerror = 0;
2341
2342 for (x = 0; x < terminate; x ++)
2343 {
2344 CHANNEL(d, ECOLOR_K).o = CHANNEL(d, ECOLOR_K).v = gray[0];
2345 print_color_ordered(d, &(CHANNEL(d, ECOLOR_K)), x, row, bit, length, 0);
2346 ADVANCE_UNIDIRECTIONAL(d, bit, gray, 1, xerror, xmod);
2347 }
2348 }
2349
2350 static void
stp_dither_black_ed(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2351 stp_dither_black_ed(const unsigned short *gray,
2352 int row,
2353 dither_t *d,
2354 int duplicate_line,
2355 int zero_mask)
2356 {
2357 int i;
2358 int x,
2359 length;
2360 unsigned char bit;
2361 int ***error;
2362 int *ndither;
2363 int terminate;
2364 int direction = row & 1 ? 1 : -1;
2365 int xerror, xstep, xmod;
2366
2367 length = (d->dst_width + 7) / 8;
2368
2369 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
2370 direction, &error, &ndither))
2371 return;
2372
2373 x = (direction == 1) ? 0 : d->dst_width - 1;
2374 bit = 1 << (7 - (x & 7));
2375 xstep = d->src_width / d->dst_width;
2376 xmod = d->src_width % d->dst_width;
2377 xerror = (xmod * x) % d->dst_width;
2378 terminate = (direction == 1) ? d->dst_width : -1;
2379
2380 if (direction == -1)
2381 gray += d->src_width - 1;
2382
2383 for (; x != terminate; x += direction)
2384 {
2385 CHANNEL(d, ECOLOR_K).b = gray[0];
2386 CHANNEL(d, ECOLOR_K).o = gray[0];
2387 CHANNEL(d, ECOLOR_K).v = UPDATE_COLOR(gray[0], ndither[ECOLOR_K]);
2388 CHANNEL(d, ECOLOR_K).v = print_color(d, &(CHANNEL(d, ECOLOR_K)), x, row,
2389 bit, length, 0, d->dither_type);
2390 ndither[ECOLOR_K] = update_dither(d, ECOLOR_K, d->src_width, direction,
2391 error[ECOLOR_K][0],error[ECOLOR_K][1]);
2392 ADVANCE_BIDIRECTIONAL(d, bit, gray, direction, 1, xerror, xmod, error,
2393 1, d->error_rows);
2394 }
2395 stp_free(ndither);
2396 for (i = 1; i < d->n_channels; i++)
2397 stp_free(error[i]);
2398 stp_free(error);
2399 if (direction == -1)
2400 reverse_row_ends(d);
2401 }
2402
2403 static void
stp_dither_black_et(const unsigned short * gray,int row,dither_t * d,int duplicate_line,int zero_mask)2404 stp_dither_black_et(const unsigned short *gray,
2405 int row,
2406 dither_t *d,
2407 int duplicate_line,
2408 int zero_mask)
2409 {
2410 int x,
2411 length;
2412 unsigned char bit;
2413 int i;
2414 int *ndither;
2415 eventone_t *et;
2416 et_chdata_t *cd;
2417
2418 int ***error;
2419 int terminate;
2420 int direction = row & 1 ? 1 : -1;
2421 int xerror, xstep, xmod;
2422 int aspect = d->y_aspect / d->x_aspect;
2423
2424 if (aspect >= 4) { aspect = 4; }
2425 else if (aspect >= 2) { aspect = 2; }
2426 else aspect = 1;
2427
2428 length = (d->dst_width + 7) / 8;
2429 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
2430 direction, &error, &ndither))
2431 return;
2432
2433 eventone_init(d, &cd);
2434 et = d->eventone;
2435
2436 x = (direction == 1) ? 0 : d->dst_width - 1;
2437 bit = 1 << (7 - (x & 7));
2438 xstep = d->src_width / d->dst_width;
2439 xmod = d->src_width % d->dst_width;
2440 xerror = (xmod * x) % d->dst_width;
2441 terminate = (direction == 1) ? d->dst_width : -1;
2442 if (direction == -1) {
2443 gray += d->src_width - 1;
2444 }
2445
2446 QUANT(6);
2447 for (; x != terminate; x += direction)
2448 { int pick, print_inks;
2449
2450 advance_eventone_pre(d, cd, et, x);
2451
2452 { int value = *gray;
2453 int base = value;
2454 int maxwet;
2455
2456 CHANNEL(d, ECOLOR_K).b = value;
2457 CHANNEL(d, ECOLOR_K).v = value;
2458 CHANNEL(d, ECOLOR_K).o = value;
2459
2460 if ((cd->wetness -= cd->maxdot_dens) < 0) cd->wetness = 0;
2461
2462 value = *ndither + base;
2463 if (value < 0) value = 0; /* Dither can make this value negative */
2464
2465 maxwet = (CHANNEL(d, ECOLOR_K).b * CHANNEL(d,ECOLOR_K).maxdot >> 1)
2466 + cd->maxdot_wet - cd->wetness;
2467
2468 find_segment(d, &CHANNEL(d, ECOLOR_K), maxwet, value, &cd->dr);
2469
2470 cd->ri = eventone_adjust(&cd->dr, et, cd->r_sq, base, value);
2471 }
2472
2473 pick = cd[ECOLOR_K].ri > 32768 ? (1<<ECOLOR_K) : 0;
2474
2475 { if (pick & (1 << ECOLOR_K)) {
2476 cd->point = cd->dr.upper->value;
2477 } else {
2478 cd->point = cd->dr.lower->value;
2479 }
2480
2481 advance_eventone_post(d, cd, et, x);
2482
2483 print_inks = (1 << ECOLOR_K);
2484
2485 /* Adjust error values for dither */
2486 ndither[ECOLOR_K] += 2 * (CHANNEL(d, ECOLOR_K).b - cd->point);
2487 }
2488
2489 /* Now we can finally print it! */
2490
2491 print_all_inks(d, cd, print_inks, pick, bit, length);
2492
2493 QUANT(11);
2494
2495 /* Diffuse the error round a bit */
2496 diffuse_error(d, ndither, error, aspect, direction);
2497
2498 QUANT(12);
2499 ADVANCE_BIDIRECTIONAL(d, bit, gray, direction, 1, xerror, xmod, error,
2500 d->n_channels, ERROR_ROWS);
2501 QUANT(13);
2502 }
2503
2504 stp_free(cd);
2505 stp_free(ndither);
2506 for (i = 0; i < d->n_channels; i++)
2507 stp_free(error[i]);
2508 stp_free(error);
2509 }
2510
2511 static void
stp_dither_cmy_fast(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2512 stp_dither_cmy_fast(const unsigned short *cmy,
2513 int row,
2514 dither_t *d,
2515 int duplicate_line,
2516 int zero_mask)
2517 {
2518 int x,
2519 length;
2520 unsigned char bit;
2521 int i;
2522 int dst_width = d->dst_width;
2523 int xerror, xstep, xmod;
2524
2525 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2526 ((1 << d->n_input_channels) - 1))
2527 return;
2528
2529 length = (d->dst_width + 7) / 8;
2530
2531 bit = 128;
2532 xstep = 3 * (d->src_width / d->dst_width);
2533 xmod = d->src_width % d->dst_width;
2534 xerror = 0;
2535 x = 0;
2536
2537 QUANT(14);
2538 for (; x != dst_width; x++)
2539 {
2540 CHANNEL(d, ECOLOR_C).v = CHANNEL(d, ECOLOR_C).o = cmy[0];
2541 CHANNEL(d, ECOLOR_M).v = CHANNEL(d, ECOLOR_M).o = cmy[1];
2542 CHANNEL(d, ECOLOR_Y).v = CHANNEL(d, ECOLOR_Y).o = cmy[2];
2543
2544 for (i = 1; i < d->n_channels; i++)
2545 print_color_fast(d, &(CHANNEL(d, i)), x, row, bit, length);
2546 QUANT(16);
2547 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
2548 QUANT(17);
2549 }
2550 }
2551
2552 static void
stp_dither_cmy_very_fast(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2553 stp_dither_cmy_very_fast(const unsigned short *cmy,
2554 int row,
2555 dither_t *d,
2556 int duplicate_line,
2557 int zero_mask)
2558 {
2559 int x,
2560 length;
2561 unsigned char bit;
2562 int i;
2563 int dst_width = d->dst_width;
2564 int xerror, xstep, xmod;
2565
2566 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2567 ((1 << d->n_input_channels) - 1))
2568 return;
2569
2570 for (i = 1; i < d->n_channels; i++)
2571 if (!(CHANNEL(d, i).very_fast))
2572 {
2573 stp_dither_cmy_fast(cmy, row, d, duplicate_line, zero_mask);
2574 return;
2575 }
2576
2577 length = (d->dst_width + 7) / 8;
2578
2579 bit = 128;
2580 xstep = 3 * (d->src_width / d->dst_width);
2581 xmod = d->src_width % d->dst_width;
2582 xerror = 0;
2583 x = 0;
2584
2585 QUANT(14);
2586 for (; x != dst_width; x++)
2587 {
2588 CHANNEL(d, ECOLOR_C).v = cmy[0];
2589 CHANNEL(d, ECOLOR_M).v = cmy[1];
2590 CHANNEL(d, ECOLOR_Y).v = cmy[2];
2591
2592 for (i = 1; i < d->n_channels; i++)
2593 {
2594 dither_channel_t *dc = &(CHANNEL(d, i));
2595 if (dc->v > ditherpoint_fast(d, &(dc->dithermat), x))
2596 {
2597 set_row_ends(dc, x, 0);
2598 dc->ptrs[0][d->ptr_offset] |= bit;
2599 }
2600 }
2601 QUANT(16);
2602 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
2603 QUANT(17);
2604 }
2605 }
2606
2607 static void
stp_dither_cmy_ordered(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2608 stp_dither_cmy_ordered(const unsigned short *cmy,
2609 int row,
2610 dither_t *d,
2611 int duplicate_line,
2612 int zero_mask)
2613 {
2614 int x,
2615 length;
2616 unsigned char bit;
2617 int i;
2618
2619 int terminate;
2620 int xerror, xstep, xmod;
2621
2622 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2623 ((1 << d->n_input_channels) - 1))
2624 return;
2625 length = (d->dst_width + 7) / 8;
2626
2627 bit = 128;
2628 xstep = 3 * (d->src_width / d->dst_width);
2629 xmod = d->src_width % d->dst_width;
2630 xerror = 0;
2631 x = 0;
2632 terminate = d->dst_width;
2633
2634 QUANT(6);
2635 for (; x != terminate; x ++)
2636 {
2637 CHANNEL(d, ECOLOR_C).v = CHANNEL(d, ECOLOR_C).o = cmy[0];
2638 CHANNEL(d, ECOLOR_M).v = CHANNEL(d, ECOLOR_M).o = cmy[1];
2639 CHANNEL(d, ECOLOR_Y).v = CHANNEL(d, ECOLOR_Y).o = cmy[2];
2640 QUANT(9);
2641 for (i = 1; i < d->n_channels; i++)
2642 print_color_ordered(d, &(CHANNEL(d, i)), x, row, bit, length, 0);
2643 QUANT(12);
2644 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
2645 QUANT(13);
2646 }
2647 }
2648
2649 static void
stp_dither_cmy_ed(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2650 stp_dither_cmy_ed(const unsigned short *cmy,
2651 int row,
2652 dither_t *d,
2653 int duplicate_line,
2654 int zero_mask)
2655 {
2656 int x,
2657 length;
2658 unsigned char bit;
2659 int i;
2660 int *ndither;
2661 int ***error;
2662
2663 int terminate;
2664 int direction = row & 1 ? 1 : -1;
2665 int xerror, xstep, xmod;
2666
2667 length = (d->dst_width + 7) / 8;
2668
2669 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
2670 direction, &error, &ndither))
2671 return;
2672
2673 x = (direction == 1) ? 0 : d->dst_width - 1;
2674 bit = 1 << (7 - (x & 7));
2675 xstep = 3 * (d->src_width / d->dst_width);
2676 xmod = d->src_width % d->dst_width;
2677 xerror = (xmod * x) % d->dst_width;
2678 terminate = (direction == 1) ? d->dst_width : -1;
2679
2680 if (direction == -1)
2681 cmy += (3 * (d->src_width - 1));
2682
2683 QUANT(6);
2684 for (; x != terminate; x += direction)
2685 {
2686 CHANNEL(d, ECOLOR_C).v = cmy[0];
2687 CHANNEL(d, ECOLOR_M).v = cmy[1];
2688 CHANNEL(d, ECOLOR_Y).v = cmy[2];
2689
2690 for (i = 1; i < d->n_channels; i++)
2691 {
2692 QUANT(9);
2693 CHANNEL(d, i).o = CHANNEL(d, i).b = CHANNEL(d, i).v;
2694 CHANNEL(d, i).v = UPDATE_COLOR(CHANNEL(d, i).v, ndither[i]);
2695 CHANNEL(d, i).v = print_color(d, &(CHANNEL(d, i)), x, row, bit,
2696 length, 0, d->dither_type);
2697 ndither[i] = update_dither(d, i, d->src_width,
2698 direction, error[i][0], error[i][1]);
2699 QUANT(10);
2700 }
2701
2702 QUANT(12);
2703 ADVANCE_BIDIRECTIONAL(d, bit, cmy, direction, 3, xerror, xmod, error,
2704 d->n_channels, d->error_rows);
2705 QUANT(13);
2706 }
2707 stp_free(ndither);
2708 for (i = 1; i < d->n_channels; i++)
2709 stp_free(error[i]);
2710 stp_free(error);
2711 if (direction == -1)
2712 reverse_row_ends(d);
2713 }
2714
2715 static void
stp_dither_cmy_et(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2716 stp_dither_cmy_et(const unsigned short *cmy,
2717 int row,
2718 dither_t *d,
2719 int duplicate_line,
2720 int zero_mask)
2721 {
2722 int x,
2723 length;
2724 unsigned char bit;
2725 int i;
2726 int *ndither;
2727 eventone_t *et;
2728 et_chdata_t *cd;
2729
2730 int ***error;
2731 int terminate;
2732 int direction = row & 1 ? 1 : -1;
2733 int xerror, xstep, xmod;
2734 int aspect = d->y_aspect / d->x_aspect;
2735
2736 if (aspect >= 4) { aspect = 4; }
2737 else if (aspect >= 2) { aspect = 2; }
2738 else aspect = 1;
2739
2740 length = (d->dst_width + 7) / 8;
2741 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
2742 direction, &error, &ndither))
2743 return;
2744
2745 eventone_init(d, &cd);
2746 et = d->eventone;
2747
2748 x = (direction == 1) ? 0 : d->dst_width - 1;
2749 bit = 1 << (7 - (x & 7));
2750 xstep = 3 * (d->src_width / d->dst_width);
2751 xmod = d->src_width % d->dst_width;
2752 xerror = (xmod * x) % d->dst_width;
2753 terminate = (direction == 1) ? d->dst_width : -1;
2754 if (direction == -1) {
2755 cmy += (3 * (d->src_width - 1));
2756 }
2757
2758 QUANT(6);
2759 for (; x != terminate; x += direction)
2760 { int pick, print_inks;
2761
2762 advance_eventone_pre(d, cd, et, x);
2763
2764 for (i=1; i < d->n_channels; i++) {
2765 int value = cmy[i-1];
2766
2767 CHANNEL(d, i).o = value; /* Remember value we want printed here */
2768 CHANNEL(d, i).v = value;
2769 CHANNEL(d, i).b = value;
2770 }
2771
2772 for (i=1; i < d->n_channels; i++) {
2773 int value;
2774 int base;
2775 int maxwet;
2776 et_chdata_t *p = &cd[i];
2777
2778 if ((p->wetness -= p->maxdot_dens) < 0) p->wetness = 0;
2779
2780 base = CHANNEL(d, i).b;
2781 value = ndither[i] + base;
2782 if (value < 0) value = 0; /* Dither can make this value negative */
2783
2784 maxwet = (CHANNEL(d, i).b * CHANNEL(d, i).maxdot >> 1)
2785 + p->maxdot_wet - p->wetness;
2786
2787 find_segment(d, &CHANNEL(d, i), maxwet, value, &p->dr);
2788
2789 p->ri = eventone_adjust(&p->dr, et, p->r_sq, base, value);
2790 }
2791
2792 pick = pick_vertex(cd[ECOLOR_C].ri, cd[ECOLOR_M].ri, cd[ECOLOR_Y].ri, 0);
2793
2794 { for (i=1; i < d->n_channels; i++) {
2795 if (pick & (1 << i)) {
2796 cd[i].point = cd[i].dr.upper->value;
2797 } else {
2798 cd[i].point = cd[i].dr.lower->value;
2799 }
2800 }
2801
2802 advance_eventone_post(d, cd, et, x);
2803
2804 print_inks = (1 << ECOLOR_C)|(1 << ECOLOR_M)|(1<<ECOLOR_Y);
2805
2806 /* Adjust error values for dither */
2807 for (i=1; i < d->n_channels; i++) {
2808 ndither[i] += 2 * (CHANNEL(d, i).b - cd[i].point);
2809 }
2810 }
2811
2812 /* Now we can finally print it! */
2813
2814 print_all_inks(d, cd, print_inks, pick, bit, length);
2815
2816 QUANT(11);
2817
2818 /* Diffuse the error round a bit */
2819 diffuse_error(d, ndither, error, aspect, direction);
2820
2821 QUANT(12);
2822 ADVANCE_BIDIRECTIONAL(d, bit, cmy, direction, 3, xerror, xmod, error,
2823 d->n_channels, ERROR_ROWS);
2824 QUANT(13);
2825 }
2826
2827 stp_free(cd);
2828 stp_free(ndither);
2829 for (i = 0; i < d->n_channels; i++)
2830 stp_free(error[i]);
2831 stp_free(error);
2832 }
2833
2834 static void
stp_dither_cmyk_fast(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2835 stp_dither_cmyk_fast(const unsigned short *cmy,
2836 int row,
2837 dither_t *d,
2838 int duplicate_line,
2839 int zero_mask)
2840 {
2841 int x,
2842 length;
2843 unsigned char bit;
2844 int i;
2845
2846 int dst_width = d->dst_width;
2847 int xerror, xstep, xmod;
2848
2849 if (!CHANNEL(d, ECOLOR_K).ptrs[0])
2850 {
2851 stp_dither_cmy_fast(cmy, row, d, duplicate_line, zero_mask);
2852 return;
2853 }
2854
2855 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2856 ((1 << d->n_input_channels) - 1))
2857 return;
2858
2859 length = (d->dst_width + 7) / 8;
2860
2861 bit = 128;
2862 xstep = 3 * (d->src_width / d->dst_width);
2863 xmod = d->src_width % d->dst_width;
2864 xerror = 0;
2865 x = 0;
2866
2867 QUANT(14);
2868 for (; x != dst_width; x++)
2869 {
2870 int nonzero = 0;
2871 nonzero |= CHANNEL(d, ECOLOR_C).v = cmy[0];
2872 nonzero |= CHANNEL(d, ECOLOR_M).v = cmy[1];
2873 nonzero |= CHANNEL(d, ECOLOR_Y).v = cmy[2];
2874 CHANNEL(d, ECOLOR_C).o = cmy[0];
2875 CHANNEL(d, ECOLOR_M).o = cmy[1];
2876 CHANNEL(d, ECOLOR_Y).o = cmy[2];
2877
2878 if (nonzero)
2879 {
2880 int ok;
2881 unsigned lb = d->k_lower;
2882 unsigned ub = d->k_upper;
2883 int k = compute_black(d);
2884 if (k < lb)
2885 k = 0;
2886 else if (k < ub)
2887 k = (k - lb) * ub / d->bound_range;
2888 for (i = 1; i < d->n_channels; i++)
2889 CHANNEL(d, i).v -= k;
2890 ok = k;
2891 if (ok > 0 && d->density != d->black_density)
2892 ok = (unsigned) ok * (unsigned) d->black_density / d->density;
2893 if (ok > 65535)
2894 ok = 65535;
2895 QUANT(15);
2896 CHANNEL(d, ECOLOR_K).v = k;
2897 CHANNEL(d, ECOLOR_K).o = ok;
2898
2899 for (i = 0; i < d->n_channels; i++)
2900 print_color_fast(d, &(CHANNEL(d, i)), x, row, bit, length);
2901 QUANT(16);
2902 }
2903 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
2904 QUANT(17);
2905 }
2906 }
2907
2908 static void
stp_dither_cmyk_very_fast(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2909 stp_dither_cmyk_very_fast(const unsigned short *cmy,
2910 int row,
2911 dither_t *d,
2912 int duplicate_line,
2913 int zero_mask)
2914 {
2915 int x,
2916 length;
2917 unsigned char bit;
2918 int i;
2919
2920 int dst_width = d->dst_width;
2921 int xerror, xstep, xmod;
2922
2923 if (!CHANNEL(d, ECOLOR_K).ptrs[0])
2924 {
2925 stp_dither_cmy_very_fast(cmy, row, d, duplicate_line, zero_mask);
2926 return;
2927 }
2928
2929 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
2930 ((1 << d->n_input_channels) - 1))
2931 return;
2932
2933 for (i = 0; i < d->n_channels; i++)
2934 if (!(CHANNEL(d, i).very_fast))
2935 {
2936 stp_dither_cmyk_fast(cmy, row, d, duplicate_line, zero_mask);
2937 return;
2938 }
2939
2940 length = (d->dst_width + 7) / 8;
2941
2942 bit = 128;
2943 xstep = 3 * (d->src_width / d->dst_width);
2944 xmod = d->src_width % d->dst_width;
2945 xerror = 0;
2946 x = 0;
2947
2948 QUANT(14);
2949 for (; x != dst_width; x++)
2950 {
2951 int nonzero = 0;
2952 nonzero |= CHANNEL(d, ECOLOR_C).v = cmy[0];
2953 nonzero |= CHANNEL(d, ECOLOR_M).v = cmy[1];
2954 nonzero |= CHANNEL(d, ECOLOR_Y).v = cmy[2];
2955
2956 if (nonzero)
2957 {
2958 int k = compute_black(d);
2959 for (i = 1; i < d->n_channels; i++)
2960 CHANNEL(d, i).v -= k;
2961 QUANT(15);
2962 CHANNEL(d, ECOLOR_K).v = k;
2963
2964 for (i = 0; i < d->n_channels; i++)
2965 {
2966 dither_channel_t *dc = &(CHANNEL(d, i));
2967 if (dc->v > ditherpoint_fast(d, &(dc->dithermat), x))
2968 {
2969 set_row_ends(dc, x, 0);
2970 dc->ptrs[0][d->ptr_offset] |= bit;
2971 }
2972 }
2973 QUANT(16);
2974 }
2975 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
2976 QUANT(17);
2977 }
2978 }
2979
2980 static void
stp_dither_cmyk_ordered(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)2981 stp_dither_cmyk_ordered(const unsigned short *cmy,
2982 int row,
2983 dither_t *d,
2984 int duplicate_line,
2985 int zero_mask)
2986 {
2987 int x,
2988 length;
2989 unsigned char bit;
2990 int i;
2991
2992 int terminate;
2993 int xerror, xstep, xmod;
2994
2995 if (!CHANNEL(d, ECOLOR_K).ptrs[0])
2996 {
2997 stp_dither_cmy_ordered(cmy, row, d, duplicate_line, zero_mask);
2998 return;
2999 }
3000
3001 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
3002 ((1 << d->n_input_channels) - 1))
3003 return;
3004
3005 length = (d->dst_width + 7) / 8;
3006
3007 bit = 128;
3008 xstep = 3 * (d->src_width / d->dst_width);
3009 xmod = d->src_width % d->dst_width;
3010 xerror = 0;
3011 x = 0;
3012 terminate = d->dst_width;
3013
3014 QUANT(6);
3015 for (; x != terminate; x ++)
3016 {
3017 int nonzero = 0;
3018 int printed_black = 0;
3019 CHANNEL(d, ECOLOR_C).v = cmy[0];
3020 CHANNEL(d, ECOLOR_M).v = cmy[1];
3021 CHANNEL(d, ECOLOR_Y).v = cmy[2];
3022 for (i = 0; i < d->n_channels; i++)
3023 nonzero |= CHANNEL(d, i).o = CHANNEL(d, i).v;
3024
3025 if (nonzero)
3026 {
3027 QUANT(7);
3028
3029 CHANNEL(d, ECOLOR_K).o = CHANNEL(d, ECOLOR_K).v = compute_black(d);
3030
3031 if (CHANNEL(d, ECOLOR_K).v > 0)
3032 update_cmyk(d);
3033
3034 QUANT(9);
3035
3036 if (d->density != d->black_density)
3037 CHANNEL(d, ECOLOR_K).v =
3038 CHANNEL(d, ECOLOR_K).v * d->black_density / d->density;
3039
3040 for (i = 0; i < d->n_channels; i++)
3041 {
3042 int tmp = print_color_ordered(d, &(CHANNEL(d, i)), x, row, bit,
3043 length, printed_black);
3044 if (i == ECOLOR_K && d->density <= 45000)
3045 printed_black = CHANNEL(d, i).v - tmp;
3046 }
3047 QUANT(12);
3048 }
3049 ADVANCE_UNIDIRECTIONAL(d, bit, cmy, 3, xerror, xmod);
3050 QUANT(13);
3051 }
3052 }
3053
3054 static void
stp_dither_cmyk_ed(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)3055 stp_dither_cmyk_ed(const unsigned short *cmy,
3056 int row,
3057 dither_t *d,
3058 int duplicate_line,
3059 int zero_mask)
3060 {
3061 int x,
3062 length;
3063 unsigned char bit;
3064 int i;
3065 int *ndither;
3066 int ***error;
3067
3068 int terminate;
3069 int direction = row & 1 ? 1 : -1;
3070 int xerror, xstep, xmod;
3071
3072 if (!CHANNEL(d, ECOLOR_K).ptrs[0])
3073 {
3074 stp_dither_cmy_ed(cmy, row, d, duplicate_line, zero_mask);
3075 return;
3076 }
3077
3078 length = (d->dst_width + 7) / 8;
3079 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
3080 direction, &error, &ndither))
3081 return;
3082
3083 x = (direction == 1) ? 0 : d->dst_width - 1;
3084 bit = 1 << (7 - (x & 7));
3085 xstep = 3 * (d->src_width / d->dst_width);
3086 xmod = d->src_width % d->dst_width;
3087 xerror = (xmod * x) % d->dst_width;
3088 terminate = (direction == 1) ? d->dst_width : -1;
3089
3090 if (direction == -1)
3091 cmy += (3 * (d->src_width - 1));
3092
3093 QUANT(6);
3094 for (; x != terminate; x += direction)
3095 {
3096 int nonzero = 0;
3097 int printed_black = 0;
3098 CHANNEL(d, ECOLOR_C).v = cmy[0];
3099 CHANNEL(d, ECOLOR_M).v = cmy[1];
3100 CHANNEL(d, ECOLOR_Y).v = cmy[2];
3101 for (i = 0; i < d->n_channels; i++)
3102 nonzero |= (CHANNEL(d, i).o = CHANNEL(d, i).v);
3103
3104 if (nonzero)
3105 {
3106 QUANT(7);
3107
3108 CHANNEL(d, ECOLOR_K).v = compute_black(d);
3109 CHANNEL(d, ECOLOR_K).o = CHANNEL(d, ECOLOR_K).v;
3110 CHANNEL(d, ECOLOR_K).b = 0;
3111
3112 /*
3113 * At this point we've computed the basic CMYK separations.
3114 * Now we adjust the levels of each to improve the print quality.
3115 */
3116
3117 if (CHANNEL(d, ECOLOR_K).v > 0)
3118 update_cmyk(d);
3119
3120 for (i = 1; i < d->n_channels; i++)
3121 CHANNEL(d, i).b = CHANNEL(d, i).v;
3122
3123 QUANT(8);
3124 /*
3125 * We've done all of the cmyk separations at this point.
3126 * Now to do the dithering.
3127 *
3128 * At this point:
3129 *
3130 * bk = Amount of black printed with black ink
3131 * ak = Adjusted "raw" K value
3132 * k = raw K value derived from CMY
3133 * oc, om, oy = raw CMY values assuming no K component
3134 * c, m, y = CMY values adjusted for the presence of K
3135 *
3136 * The main reason for this rather elaborate setup, where we have
3137 * 8 channels at this point, is to handle variable intensities
3138 * (in particular light and dark variants) of inks. Very dark regions
3139 * with slight color tints should be printed with dark inks, not with
3140 * the light inks that would be implied by the small amount of
3141 * remnant CMY.
3142 *
3143 * It's quite likely that for simple four-color printers ordinary
3144 * CMYK separations would work. It's possible that they would work
3145 * for variable dot sizes, too.
3146 */
3147
3148 QUANT(9);
3149
3150 if (d->density != d->black_density)
3151 CHANNEL(d, ECOLOR_K).v =
3152 CHANNEL(d, ECOLOR_K).v * d->black_density / d->density;
3153
3154 CHANNEL(d, ECOLOR_K).o = CHANNEL(d, ECOLOR_K).b;
3155
3156 for (i = 0; i < d->n_channels; i++)
3157 {
3158 int tmp;
3159 CHANNEL(d, i).v = UPDATE_COLOR(CHANNEL(d, i).v, ndither[i]);
3160 tmp = print_color(d, &(CHANNEL(d, i)), x, row, bit, length,
3161 printed_black, d->dither_type);
3162 if (i == ECOLOR_K && d->density <= 45000)
3163 printed_black = CHANNEL(d, i).v - tmp;
3164 CHANNEL(d, i).v = tmp;
3165 }
3166 }
3167 else
3168 for (i = 0; i < d->n_channels; i++)
3169 CHANNEL(d, i).v = UPDATE_COLOR(CHANNEL(d, i).v, ndither[i]);
3170
3171 QUANT(11);
3172 for (i = 0; i < d->n_channels; i++)
3173 ndither[i] = update_dither(d, i, d->src_width,
3174 direction, error[i][0], error[i][1]);
3175
3176 QUANT(12);
3177 ADVANCE_BIDIRECTIONAL(d, bit, cmy, direction, 3, xerror, xmod, error,
3178 d->n_channels, d->error_rows);
3179 QUANT(13);
3180 }
3181 stp_free(ndither);
3182 for (i = 1; i < d->n_channels; i++)
3183 stp_free(error[i]);
3184 stp_free(error);
3185 if (direction == -1)
3186 reverse_row_ends(d);
3187 }
3188
3189 /* This code uses the Eventone dither algorithm. This is described
3190 * at the website http://www.artofcode.com/eventone/
3191 * This algorithm is covered by US Patents 5,055,942 and 5,917,614
3192 * and was invented by Raph Levien <raph@acm.org>
3193 * It was made available to be used free of charge in open source
3194 * code.
3195 */
3196
3197 static void
stp_dither_cmyk_et(const unsigned short * cmy,int row,dither_t * d,int duplicate_line,int zero_mask)3198 stp_dither_cmyk_et(const unsigned short *cmy,
3199 int row,
3200 dither_t *d,
3201 int duplicate_line,
3202 int zero_mask)
3203 {
3204 int x,
3205 length;
3206 unsigned char bit;
3207 int i;
3208 int *ndither;
3209 eventone_t *et;
3210 et_chdata_t *cd;
3211
3212 int ***error;
3213 int terminate;
3214 int direction = row & 1 ? 1 : -1;
3215 int xerror, xstep, xmod;
3216 int aspect = d->y_aspect / d->x_aspect;
3217
3218 if (!CHANNEL(d, ECOLOR_K).ptrs[0])
3219 {
3220 stp_dither_cmy_et(cmy, row, d, duplicate_line, zero_mask);
3221 return;
3222 }
3223
3224 if (aspect >= 4) { aspect = 4; }
3225 else if (aspect >= 2) { aspect = 2; }
3226 else aspect = 1;
3227
3228 length = (d->dst_width + 7) / 8;
3229 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
3230 direction, &error, &ndither))
3231 return;
3232
3233 eventone_init(d, &cd);
3234 et = d->eventone;
3235
3236 x = (direction == 1) ? 0 : d->dst_width - 1;
3237 bit = 1 << (7 - (x & 7));
3238 xstep = 3 * (d->src_width / d->dst_width);
3239 xmod = d->src_width % d->dst_width;
3240 xerror = (xmod * x) % d->dst_width;
3241 terminate = (direction == 1) ? d->dst_width : -1;
3242 if (direction == -1) {
3243 cmy += (3 * (d->src_width - 1));
3244 }
3245
3246 QUANT(6);
3247 for (; x != terminate; x += direction)
3248 { int pick, print_inks;
3249
3250 advance_eventone_pre(d, cd, et, x);
3251
3252 CHANNEL(d, ECOLOR_K).b = 0;
3253
3254 for (i=1; i < d->n_channels; i++) {
3255 int value = cmy[i-1];
3256
3257 CHANNEL(d, i).o = value; /* Remember value we want printed here */
3258 CHANNEL(d, i).v = value;
3259 if (i == 1 || value < CHANNEL(d, ECOLOR_K).o)
3260 CHANNEL(d, ECOLOR_K).o = value; /* Set black to minimum of C,M,Y */
3261 }
3262
3263 CHANNEL(d, ECOLOR_K).v = CHANNEL(d, ECOLOR_K).o;
3264 if (CHANNEL(d, ECOLOR_K).v > 0) {
3265 update_cmyk(d);
3266 }
3267
3268 for (i = 1; i < d->n_channels; i++)
3269 CHANNEL(d, i).b = CHANNEL(d, i).v;
3270
3271 for (i=0; i < d->n_channels; i++) {
3272 int base;
3273 int value;
3274 int maxwet;
3275 et_chdata_t *p = &cd[i];
3276
3277 if ((p->wetness -= p->maxdot_dens) < 0) p->wetness = 0;
3278
3279 base = CHANNEL(d, i).b;
3280 value = ndither[i] + base;
3281 if (value < 0) value = 0; /* Dither can make this value negative */
3282
3283 maxwet = (CHANNEL(d, i).b * CHANNEL(d, i).maxdot >> 1)
3284 + p->maxdot_wet - p->wetness;
3285
3286 find_segment(d, &CHANNEL(d, i), maxwet, value, &p->dr);
3287
3288 p->ri = eventone_adjust(&p->dr, et, p->r_sq, base, value);
3289 }
3290
3291 pick = pick_vertex(cd[ECOLOR_C].ri, cd[ECOLOR_M].ri, cd[ECOLOR_Y].ri, cd[ECOLOR_K].ri);
3292
3293 { int useblack = 0; /* Do we print black at all? */
3294 int printed_black;
3295 int adjusted_black;
3296
3297 for (i=0; i < d->n_channels; i++) {
3298 if (pick & (1 << i)) {
3299 cd[i].point = cd[i].dr.upper->value;
3300 } else {
3301 cd[i].point = cd[i].dr.lower->value;
3302 }
3303 }
3304
3305 printed_black = cd[ECOLOR_K].point;
3306 adjusted_black = printed_black;
3307 if (printed_black > 0 && d->black_density != d->density) {
3308 adjusted_black = (unsigned)printed_black * (unsigned)d->density / d->black_density;
3309 }
3310
3311 advance_eventone_post(d, cd, et, x);
3312
3313 /* Only print the black ink if it means we can avoid printing another ink, otherwise we're just wasting ink */
3314
3315 if (printed_black > 0) {
3316 for (i=1; i < d->n_channels; i++) {
3317 if (cd[i].point <= adjusted_black) {
3318 useblack = 1;
3319 break;
3320 }
3321 }
3322 }
3323
3324 /* Find which channels we actually print */
3325
3326 /* Adjust colours to print based on black ink */
3327 if (useblack) {
3328 print_inks = (1 << ECOLOR_K);
3329 for (i=1; i < d->n_channels; i++) {
3330 if (cd[i].point > adjusted_black) {
3331 print_inks |= (1 << i);
3332 }
3333 }
3334 } else {
3335 print_inks = (1 << ECOLOR_C)|(1 << ECOLOR_M)|(1<<ECOLOR_Y);
3336 }
3337
3338 /* Adjust error values for dither */
3339 ndither[ECOLOR_K] += 2 * (CHANNEL(d, ECOLOR_K).b - printed_black);
3340 for (i=1; i < d->n_channels; i++) {
3341 ndither[i] += 2 * (CHANNEL(d, i).b - cd[i].point);
3342 }
3343 }
3344
3345 /* Now we can finally print it! */
3346
3347 print_all_inks(d, cd, print_inks, pick, bit, length);
3348
3349 QUANT(11);
3350
3351 /* Diffuse the error round a bit */
3352 diffuse_error(d, ndither, error, aspect, direction);
3353
3354 QUANT(12);
3355 ADVANCE_BIDIRECTIONAL(d, bit, cmy, direction, 3, xerror, xmod, error,
3356 d->n_channels, ERROR_ROWS);
3357 QUANT(13);
3358 }
3359
3360 stp_free(cd);
3361 stp_free(ndither);
3362 for (i = 0; i < d->n_channels; i++)
3363 stp_free(error[i]);
3364 stp_free(error);
3365 }
3366
3367 static void
stp_dither_raw_cmyk_fast(const unsigned short * cmyk,int row,dither_t * d,int duplicate_line,int zero_mask)3368 stp_dither_raw_cmyk_fast(const unsigned short *cmyk,
3369 int row,
3370 dither_t *d,
3371 int duplicate_line,
3372 int zero_mask)
3373 {
3374 int x,
3375 length;
3376 unsigned char bit;
3377 int i;
3378
3379 int dst_width = d->dst_width;
3380 int xerror, xstep, xmod;
3381 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
3382 ((1 << d->n_input_channels) - 1))
3383 return;
3384
3385 length = (d->dst_width + 7) / 8;
3386
3387 bit = 128;
3388 xstep = 4 * (d->src_width / d->dst_width);
3389 xmod = d->src_width % d->dst_width;
3390 xerror = 0;
3391 x = 0;
3392
3393 QUANT(14);
3394 for (; x != dst_width; x++)
3395 {
3396 int extra_k;
3397 CHANNEL(d, ECOLOR_C).v = cmyk[0];
3398 CHANNEL(d, ECOLOR_M).v = cmyk[1];
3399 CHANNEL(d, ECOLOR_Y).v = cmyk[2];
3400 CHANNEL(d, ECOLOR_K).v = cmyk[3];
3401 extra_k = compute_black(d) + CHANNEL(d, ECOLOR_K).v;
3402 for (i = 0; i < d->n_channels; i++)
3403 {
3404 CHANNEL(d, i).o = CHANNEL(d, i).v;
3405 if (i != ECOLOR_K)
3406 CHANNEL(d, i).o += extra_k;
3407 if (CHANNEL(d, i).ptrs[0])
3408 print_color_fast(d, &(CHANNEL(d, i)), x, row, bit, length);
3409 }
3410 QUANT(16);
3411 ADVANCE_UNIDIRECTIONAL(d, bit, cmyk, 4, xerror, xmod);
3412 QUANT(17);
3413 }
3414 }
3415
3416 static void
stp_dither_raw_cmyk_very_fast(const unsigned short * cmyk,int row,dither_t * d,int duplicate_line,int zero_mask)3417 stp_dither_raw_cmyk_very_fast(const unsigned short *cmyk,
3418 int row,
3419 dither_t *d,
3420 int duplicate_line,
3421 int zero_mask)
3422 {
3423 int x,
3424 length;
3425 unsigned char bit;
3426 int i;
3427
3428 int dst_width = d->dst_width;
3429 int xerror, xstep, xmod;
3430 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
3431 ((1 << d->n_input_channels) - 1))
3432 return;
3433
3434 for (i = 0; i < d->n_channels; i++)
3435 if (!(CHANNEL(d, i).very_fast))
3436 {
3437 stp_dither_raw_cmyk_fast(cmyk, row, d, duplicate_line, zero_mask);
3438 return;
3439 }
3440
3441 length = (d->dst_width + 7) / 8;
3442
3443 bit = 128;
3444 xstep = 4 * (d->src_width / d->dst_width);
3445 xmod = d->src_width % d->dst_width;
3446 xerror = 0;
3447 x = 0;
3448
3449 QUANT(14);
3450 for (; x != dst_width; x++)
3451 {
3452 int extra_k;
3453 CHANNEL(d, ECOLOR_C).v = cmyk[0];
3454 CHANNEL(d, ECOLOR_M).v = cmyk[1];
3455 CHANNEL(d, ECOLOR_Y).v = cmyk[2];
3456 CHANNEL(d, ECOLOR_K).v = cmyk[3];
3457 extra_k = compute_black(d) + CHANNEL(d, ECOLOR_K).v;
3458 for (i = 0; i < d->n_channels; i++)
3459 {
3460 dither_channel_t *dc = &(CHANNEL(d, i));
3461 if (dc->ptrs[0] && dc->v > ditherpoint_fast(d, &(dc->dithermat), x))
3462 {
3463 set_row_ends(dc, x, 0);
3464 dc->ptrs[0][d->ptr_offset] |= bit;
3465 }
3466 }
3467 QUANT(16);
3468 ADVANCE_UNIDIRECTIONAL(d, bit, cmyk, 4, xerror, xmod);
3469 QUANT(17);
3470 }
3471 }
3472
3473 static void
stp_dither_raw_cmyk_ordered(const unsigned short * cmyk,int row,dither_t * d,int duplicate_line,int zero_mask)3474 stp_dither_raw_cmyk_ordered(const unsigned short *cmyk,
3475 int row,
3476 dither_t *d,
3477 int duplicate_line,
3478 int zero_mask)
3479 {
3480 int x,
3481 length;
3482 unsigned char bit;
3483 int i;
3484
3485 int terminate;
3486 int xerror, xstep, xmod;
3487
3488 if ((zero_mask & ((1 << d->n_input_channels) - 1)) ==
3489 ((1 << d->n_input_channels) - 1))
3490 return;
3491
3492 length = (d->dst_width + 7) / 8;
3493
3494 bit = 128;
3495 xstep = 4 * (d->src_width / d->dst_width);
3496 xmod = d->src_width % d->dst_width;
3497 xerror = 0;
3498 x = 0;
3499 terminate = d->dst_width;
3500
3501 QUANT(6);
3502 for (; x != terminate; x ++)
3503 {
3504 int extra_k;
3505 CHANNEL(d, ECOLOR_K).v = cmyk[3];
3506 CHANNEL(d, ECOLOR_C).v = cmyk[0];
3507 CHANNEL(d, ECOLOR_M).v = cmyk[1];
3508 CHANNEL(d, ECOLOR_Y).v = cmyk[2];
3509 extra_k = compute_black(d) + CHANNEL(d, ECOLOR_K).v;
3510 for (i = 0; i < d->n_channels; i++)
3511 {
3512 CHANNEL(d, i).o = CHANNEL(d, i).v;
3513 if (i != ECOLOR_K)
3514 CHANNEL(d, i).o += extra_k;
3515 print_color_ordered(d, &(CHANNEL(d, i)), x, row, bit, length, 0);
3516 }
3517
3518 QUANT(11);
3519 ADVANCE_UNIDIRECTIONAL(d, bit, cmyk, 4, xerror, xmod);
3520 QUANT(13);
3521 }
3522 }
3523
3524
3525 static void
stp_dither_raw_cmyk_ed(const unsigned short * cmyk,int row,dither_t * d,int duplicate_line,int zero_mask)3526 stp_dither_raw_cmyk_ed(const unsigned short *cmyk,
3527 int row,
3528 dither_t *d,
3529 int duplicate_line,
3530 int zero_mask)
3531 {
3532 int x,
3533 length;
3534 unsigned char bit;
3535 int i;
3536 int *ndither;
3537 int ***error;
3538
3539 int terminate;
3540 int direction = row & 1 ? 1 : -1;
3541 int xerror, xstep, xmod;
3542
3543 length = (d->dst_width + 7) / 8;
3544 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
3545 direction, &error, &ndither))
3546 return;
3547
3548 x = (direction == 1) ? 0 : d->dst_width - 1;
3549 bit = 1 << (7 - (x & 7));
3550 xstep = 4 * (d->src_width / d->dst_width);
3551 xmod = d->src_width % d->dst_width;
3552 xerror = (xmod * x) % d->dst_width;
3553 terminate = (direction == 1) ? d->dst_width : -1;
3554
3555 if (direction == -1)
3556 cmyk += (4 * (d->src_width - 1));
3557
3558 QUANT(6);
3559 for (; x != terminate; x += direction)
3560 {
3561 int extra_k;
3562 CHANNEL(d, ECOLOR_K).v = cmyk[3];
3563 CHANNEL(d, ECOLOR_C).v = cmyk[0];
3564 CHANNEL(d, ECOLOR_M).v = cmyk[1];
3565 CHANNEL(d, ECOLOR_Y).v = cmyk[2];
3566 extra_k = compute_black(d) + CHANNEL(d, ECOLOR_K).v;
3567 for (i = 0; i < d->n_channels; i++)
3568 {
3569 CHANNEL(d, i).o = CHANNEL(d, i).v;
3570 if (i != ECOLOR_K)
3571 CHANNEL(d, i).o += extra_k;
3572 CHANNEL(d, i).b = CHANNEL(d, i).v;
3573 CHANNEL(d, i).v = UPDATE_COLOR(CHANNEL(d, i).v, ndither[i]);
3574 CHANNEL(d, i).v = print_color(d, &(CHANNEL(d, i)), x, row, bit,
3575 length, 0, d->dither_type);
3576 ndither[i] = update_dither(d, i, d->src_width,
3577 direction, error[i][0], error[i][1]);
3578 }
3579 QUANT(12);
3580 ADVANCE_BIDIRECTIONAL(d, bit, cmyk, direction, 4, xerror, xmod, error,
3581 d->n_channels, d->error_rows);
3582 QUANT(13);
3583 }
3584 stp_free(ndither);
3585 for (i = 1; i < d->n_channels; i++)
3586 stp_free(error[i]);
3587 stp_free(error);
3588 if (direction == -1)
3589 reverse_row_ends(d);
3590 }
3591
3592 static void
stp_dither_raw_cmyk_et(const unsigned short * cmyk,int row,dither_t * d,int duplicate_line,int zero_mask)3593 stp_dither_raw_cmyk_et(const unsigned short *cmyk,
3594 int row,
3595 dither_t *d,
3596 int duplicate_line,
3597 int zero_mask)
3598 {
3599 int x,
3600 length;
3601 unsigned char bit;
3602 int i;
3603 int *ndither;
3604 eventone_t *et;
3605 et_chdata_t *cd;
3606
3607 int ***error;
3608 int terminate;
3609 int direction = row & 1 ? 1 : -1;
3610 int xerror, xstep, xmod;
3611 int aspect = d->y_aspect / d->x_aspect;
3612
3613 if (aspect >= 4) { aspect = 4; }
3614 else if (aspect >= 2) { aspect = 2; }
3615 else aspect = 1;
3616
3617 length = (d->dst_width + 7) / 8;
3618 if (!shared_ed_initializer(d, row, duplicate_line, zero_mask, length,
3619 direction, &error, &ndither))
3620 return;
3621
3622 eventone_init(d, &cd);
3623 et = d->eventone;
3624
3625 x = (direction == 1) ? 0 : d->dst_width - 1;
3626 bit = 1 << (7 - (x & 7));
3627 xstep = 4 * (d->src_width / d->dst_width);
3628 xmod = d->src_width % d->dst_width;
3629 xerror = (xmod * x) % d->dst_width;
3630 terminate = (direction == 1) ? d->dst_width : -1;
3631 if (direction == -1) {
3632 cmyk += (4 * (d->src_width - 1));
3633 }
3634
3635 QUANT(6);
3636 for (; x != terminate; x += direction)
3637 { int pick, print_inks;
3638
3639 advance_eventone_pre(d, cd, et, x);
3640
3641 { int value = cmyk[3]; /* Order of input is C,M,Y,K */
3642 CHANNEL(d, ECOLOR_K).o = value; /* Remember value we want printed here */
3643 CHANNEL(d, ECOLOR_K).v = value;
3644 CHANNEL(d, ECOLOR_K).b = value;
3645 }
3646
3647 for (i=1; i < d->n_channels; i++) {
3648 int value = cmyk[i-1];
3649 CHANNEL(d, i).o = value; /* Remember value we want printed here */
3650 CHANNEL(d, i).v = value;
3651 CHANNEL(d, i).b = value;
3652 }
3653
3654 for (i=0; i < d->n_channels; i++) {
3655 int value;
3656 int base;
3657 int maxwet;
3658 et_chdata_t *p = &cd[i];
3659
3660 if ((p->wetness -= p->maxdot_dens) < 0) p->wetness = 0;
3661
3662 base = CHANNEL(d, i).b;
3663 value = ndither[i] + base;
3664 if (value < 0) value = 0; /* Dither can make this value negative */
3665
3666 maxwet = (CHANNEL(d, i).b * CHANNEL(d, i).maxdot >> 1)
3667 + p->maxdot_wet - p->wetness;
3668
3669 find_segment(d, &CHANNEL(d, i), maxwet, value, &p->dr);
3670
3671 p->ri = eventone_adjust(&p->dr, et, p->r_sq, base, value);
3672 }
3673
3674 pick = pick_vertex(cd[ECOLOR_C].ri, cd[ECOLOR_M].ri, cd[ECOLOR_Y].ri, cd[ECOLOR_K].ri);
3675
3676 { int useblack = 0; /* Do we print black at all? */
3677 int printed_black;
3678 int adjusted_black;
3679
3680 for (i=0; i < d->n_channels; i++) {
3681 if (pick & (1 << i)) {
3682 cd[i].point = cd[i].dr.upper->value;
3683 } else {
3684 cd[i].point = cd[i].dr.lower->value;
3685 }
3686 }
3687
3688 printed_black = cd[ECOLOR_K].point;
3689 adjusted_black = printed_black;
3690 if (printed_black > 0 && d->black_density != d->density) {
3691 adjusted_black = (unsigned)printed_black * (unsigned)d->density / d->black_density;
3692 }
3693
3694 advance_eventone_post(d, cd, et, x);
3695
3696 /* Only print the black ink if it means we can avoid printing another ink, otherwise we're just wasting ink */
3697
3698 if (printed_black > 0) {
3699 for (i=1; i < d->n_channels; i++) {
3700 if (cd[i].point <= adjusted_black) {
3701 useblack = 1;
3702 break;
3703 }
3704 }
3705 }
3706
3707 /* Find which channels we actually print */
3708
3709 /* Adjust colours to print based on black ink */
3710 if (useblack) {
3711 print_inks = (1 << ECOLOR_K);
3712 for (i=1; i < d->n_channels; i++) {
3713 if (cd[i].point > adjusted_black) {
3714 print_inks |= (1 << i);
3715 }
3716 }
3717 } else {
3718 print_inks = (1 << ECOLOR_C)|(1 << ECOLOR_M)|(1<<ECOLOR_Y);
3719 }
3720
3721 /* Adjust error values for dither */
3722 ndither[ECOLOR_K] += 2 * (CHANNEL(d, ECOLOR_K).b - printed_black);
3723 for (i=1; i < d->n_channels; i++) {
3724 ndither[i] += 2 * (CHANNEL(d, i).b - cd[i].point);
3725 }
3726 }
3727
3728 /* Now we can finally print it! */
3729
3730 print_all_inks(d, cd, print_inks, pick, bit, length);
3731
3732 QUANT(11);
3733
3734 /* Diffuse the error round a bit */
3735 diffuse_error(d, ndither, error, aspect, direction);
3736
3737 QUANT(12);
3738 ADVANCE_BIDIRECTIONAL(d, bit, cmyk, direction, 4, xerror, xmod, error,
3739 d->n_channels, ERROR_ROWS);
3740 QUANT(13);
3741 }
3742
3743 stp_free(cd);
3744 stp_free(ndither);
3745 for (i = 0; i < d->n_channels; i++)
3746 stp_free(error[i]);
3747 stp_free(error);
3748 }
3749
3750 void
stp_dither(const unsigned short * input,int row,void * vd,stp_dither_data_t * dt,int duplicate_line,int zero_mask)3751 stp_dither(const unsigned short *input,
3752 int row,
3753 void *vd,
3754 stp_dither_data_t *dt,
3755 int duplicate_line,
3756 int zero_mask)
3757 {
3758 int i, j;
3759 dither_t *d = (dither_t *) vd;
3760 for (i = 0; i < d->n_channels; i++)
3761 {
3762 for (j = 0; j < CHANNEL(d, i).subchannels; j++)
3763 {
3764 if (i >= dt->channel_count || j >= dt->c[i].subchannel_count)
3765 CHANNEL(d, i).ptrs[j] = NULL;
3766 else
3767 CHANNEL(d, i).ptrs[j] = dt->c[i].c[j];
3768 if (CHANNEL(d, i).ptrs[j])
3769 memset(CHANNEL(d, i).ptrs[j], 0,
3770 (d->dst_width + 7) / 8 * CHANNEL(d, i).signif_bits);
3771 CHANNEL(d, i).row_ends[0][j] = -1;
3772 CHANNEL(d, i).row_ends[1][j] = -1;
3773 }
3774 stp_matrix_set_row(&(CHANNEL(d, i).dithermat), row);
3775 stp_matrix_set_row(&(CHANNEL(d, i).pick), row);
3776 }
3777 d->ptr_offset = 0;
3778 (d->ditherfunc)(input, row, d, duplicate_line, zero_mask);
3779 }
3780