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