00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef GIMP_PRINT_INTERNAL_DITHER_IMPL_H
00034 #define GIMP_PRINT_INTERNAL_DITHER_IMPL_H
00035
00036 #ifdef __cplusplus
00037 extern "C" {
00038 #endif
00039
00040 #include <limits.h>
00041
00042 #ifdef __GNUC__
00043 #define inline __inline__
00044 #endif
00045
00046 #define D_FLOYD_HYBRID 0
00047 #define D_ADAPTIVE_BASE 4
00048 #define D_ADAPTIVE_HYBRID (D_ADAPTIVE_BASE | D_FLOYD_HYBRID)
00049 #define D_ORDERED_BASE 8
00050 #define D_ORDERED (D_ORDERED_BASE)
00051 #define D_FAST_BASE 16
00052 #define D_FAST (D_FAST_BASE)
00053 #define D_VERY_FAST (D_FAST_BASE + 1)
00054 #define D_EVENTONE 32
00055 #define D_UNITONE 64
00056 #define D_HYBRID_EVENTONE (D_ORDERED_BASE | D_EVENTONE)
00057 #define D_HYBRID_UNITONE (D_ORDERED_BASE | D_UNITONE)
00058 #define D_PREDITHERED 128
00059
00060 #define DITHER_FAST_STEPS (6)
00061
00062 typedef struct
00063 {
00064 const char *name;
00065 const char *text;
00066 int id;
00067 } stpi_dither_algorithm_t;
00068
00069 #define ERROR_ROWS 2
00070
00071 #define MAX_SPREAD 32
00072
00073 typedef void stpi_ditherfunc_t(stp_vars_t *, int, const unsigned short *, int,
00074 int, const unsigned char *);
00075
00076
00077
00078
00079
00080 typedef struct ink_defn
00081 {
00082 unsigned range;
00083 unsigned value;
00084 unsigned bits;
00085 } stpi_ink_defn_t;
00086
00087
00088
00089
00090
00091 typedef struct dither_segment
00092 {
00093 stpi_ink_defn_t *lower;
00094 stpi_ink_defn_t *upper;
00095 unsigned range_span;
00096 unsigned value_span;
00097 int is_same_ink;
00098 int is_equal;
00099 } stpi_dither_segment_t;
00100
00101 typedef struct dither_channel
00102 {
00103 unsigned randomizer;
00104
00105
00106 unsigned bit_max;
00107 unsigned signif_bits;
00108 unsigned density;
00109 double darkness;
00110
00111 int v;
00112 int o;
00113 int b;
00114 int very_fast;
00115
00116 stpi_ink_defn_t *ink_list;
00117
00118 int nlevels;
00119 stpi_dither_segment_t *ranges;
00120
00121 int error_rows;
00122 int **errs;
00123
00124 stp_dither_matrix_impl_t pick;
00125 stp_dither_matrix_impl_t dithermat;
00126 int row_ends[2];
00127 unsigned char *ptr;
00128 void *aux_data;
00129 } stpi_dither_channel_t;
00130
00131 typedef struct dither
00132 {
00133 int src_width;
00134 int dst_width;
00135
00136 int spread;
00137 int spread_mask;
00138
00139
00140
00141 int stpi_dither_type;
00142
00143 int adaptive_limit;
00144
00145 int x_aspect;
00146 int y_aspect;
00147
00148 double transition;
00149
00150 int *offset0_table;
00151 int *offset1_table;
00152
00153 int d_cutoff;
00154
00155 int last_line_was_empty;
00156 int ptr_offset;
00157 int error_rows;
00158
00159 int finalized;
00160
00161
00162 stp_dither_matrix_impl_t dither_matrix;
00163 stp_dither_matrix_impl_t transition_matrix;
00164 stpi_dither_channel_t *channel;
00165 unsigned channel_count;
00166 unsigned total_channel_count;
00167 unsigned *channel_index;
00168 unsigned *subchannel_count;
00169
00170 stpi_ditherfunc_t *ditherfunc;
00171 void *aux_data;
00172 void (*aux_freefunc)(struct dither *);
00173 } stpi_dither_t;
00174
00175 #define CHANNEL(d, c) ((d)->channel[(c)])
00176 #define CHANNEL_COUNT(d) ((d)->total_channel_count)
00177
00178 #define USMIN(a, b) ((a) < (b) ? (a) : (b))
00179
00180
00181 extern stpi_ditherfunc_t stpi_dither_predithered;
00182 extern stpi_ditherfunc_t stpi_dither_very_fast;
00183 extern stpi_ditherfunc_t stpi_dither_ordered;
00184 extern stpi_ditherfunc_t stpi_dither_ed;
00185 extern stpi_ditherfunc_t stpi_dither_et;
00186 extern stpi_ditherfunc_t stpi_dither_ut;
00187
00188 extern void stpi_dither_reverse_row_ends(stpi_dither_t *d);
00189 extern int stpi_dither_translate_channel(stp_vars_t *v, unsigned channel,
00190 unsigned subchannel);
00191 extern void stpi_dither_channel_destroy(stpi_dither_channel_t *channel);
00192 extern void stpi_dither_finalize(stp_vars_t *v);
00193 extern int *stpi_dither_get_errline(stpi_dither_t *d, int row, int color);
00194
00195
00196 #define ADVANCE_UNIDIRECTIONAL(d, bit, input, width, xerror, xstep, xmod) \
00197 do \
00198 { \
00199 bit >>= 1; \
00200 if (bit == 0) \
00201 { \
00202 d->ptr_offset++; \
00203 bit = 128; \
00204 } \
00205 input += xstep; \
00206 if (xmod) \
00207 { \
00208 xerror += xmod; \
00209 if (xerror >= d->dst_width) \
00210 { \
00211 xerror -= d->dst_width; \
00212 input += (width); \
00213 } \
00214 } \
00215 } while (0)
00216
00217 #define ADVANCE_REVERSE(d, bit, input, width, xerror, xstep, xmod) \
00218 do \
00219 { \
00220 if (bit == 128) \
00221 { \
00222 d->ptr_offset--; \
00223 bit = 1; \
00224 } \
00225 else \
00226 bit <<= 1; \
00227 input -= xstep; \
00228 if (xmod) \
00229 { \
00230 xerror -= xmod; \
00231 if (xerror < 0) \
00232 { \
00233 xerror += d->dst_width; \
00234 input -= (width); \
00235 } \
00236 } \
00237 } while (0)
00238
00239 #define ADVANCE_BIDIRECTIONAL(d,bit,in,dir,width,xer,xstep,xmod,err,S) \
00240 do \
00241 { \
00242 int ii; \
00243 int jj; \
00244 for (ii = 0; ii < width; ii++) \
00245 for (jj = 0; jj < S; jj++) \
00246 err[ii][jj] += dir; \
00247 if (dir == 1) \
00248 ADVANCE_UNIDIRECTIONAL(d, bit, in, width, xer, xstep, xmod); \
00249 else \
00250 ADVANCE_REVERSE(d, bit, in, width, xer, xstep, xmod); \
00251 } while (0)
00252
00253 #ifdef __cplusplus
00254 }
00255 #endif
00256
00257 #endif
00258
00259
00260