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
00059 #define DITHER_FAST_STEPS (6)
00060
00061 typedef struct
00062 {
00063 const char *name;
00064 const char *text;
00065 int id;
00066 } stpi_dither_algorithm_t;
00067
00068 #define ERROR_ROWS 2
00069
00070 #define MAX_SPREAD 32
00071
00072 typedef void stpi_ditherfunc_t(stp_vars_t *, int, const unsigned short *, int,
00073 int, const unsigned char *);
00074
00075
00076
00077
00078
00079 typedef struct ink_defn
00080 {
00081 unsigned range;
00082 unsigned value;
00083 unsigned bits;
00084 } stpi_ink_defn_t;
00085
00086
00087
00088
00089
00090 typedef struct dither_segment
00091 {
00092 stpi_ink_defn_t *lower;
00093 stpi_ink_defn_t *upper;
00094 unsigned range_span;
00095 unsigned value_span;
00096 int is_same_ink;
00097 int is_equal;
00098 } stpi_dither_segment_t;
00099
00100 typedef struct dither_channel
00101 {
00102 unsigned randomizer;
00103
00104
00105 unsigned bit_max;
00106 unsigned signif_bits;
00107 unsigned density;
00108 double darkness;
00109
00110 int v;
00111 int o;
00112 int b;
00113 int very_fast;
00114
00115 stpi_ink_defn_t *ink_list;
00116
00117 int nlevels;
00118 stpi_dither_segment_t *ranges;
00119
00120 int error_rows;
00121 int **errs;
00122
00123 stp_dither_matrix_impl_t pick;
00124 stp_dither_matrix_impl_t dithermat;
00125 int row_ends[2];
00126 unsigned char *ptr;
00127 void *aux_data;
00128 } stpi_dither_channel_t;
00129
00130 typedef struct dither
00131 {
00132 int src_width;
00133 int dst_width;
00134
00135 int spread;
00136 int spread_mask;
00137
00138
00139
00140 int stpi_dither_type;
00141
00142 int adaptive_limit;
00143
00144 int x_aspect;
00145 int y_aspect;
00146
00147 double transition;
00148
00149 int *offset0_table;
00150 int *offset1_table;
00151
00152 int d_cutoff;
00153
00154 int last_line_was_empty;
00155 int ptr_offset;
00156 int error_rows;
00157
00158 int finalized;
00159
00160
00161 stp_dither_matrix_impl_t dither_matrix;
00162 stp_dither_matrix_impl_t transition_matrix;
00163 stpi_dither_channel_t *channel;
00164 unsigned channel_count;
00165 unsigned total_channel_count;
00166 unsigned *channel_index;
00167 unsigned *subchannel_count;
00168
00169 stpi_ditherfunc_t *ditherfunc;
00170 void *aux_data;
00171 void (*aux_freefunc)(struct dither *);
00172 } stpi_dither_t;
00173
00174 #define CHANNEL(d, c) ((d)->channel[(c)])
00175 #define CHANNEL_COUNT(d) ((d)->total_channel_count)
00176
00177 #define USMIN(a, b) ((a) < (b) ? (a) : (b))
00178
00179
00180 extern stpi_ditherfunc_t stpi_dither_very_fast;
00181 extern stpi_ditherfunc_t stpi_dither_ordered;
00182 extern stpi_ditherfunc_t stpi_dither_ed;
00183 extern stpi_ditherfunc_t stpi_dither_et;
00184 extern stpi_ditherfunc_t stpi_dither_ut;
00185
00186 extern void stpi_dither_reverse_row_ends(stpi_dither_t *d);
00187 extern int stpi_dither_translate_channel(stp_vars_t *v, unsigned channel,
00188 unsigned subchannel);
00189 extern void stpi_dither_channel_destroy(stpi_dither_channel_t *channel);
00190 extern void stpi_dither_finalize(stp_vars_t *v);
00191 extern int *stpi_dither_get_errline(stpi_dither_t *d, int row, int color);
00192
00193
00194 #define ADVANCE_UNIDIRECTIONAL(d, bit, input, width, xerror, xstep, xmod) \
00195 do \
00196 { \
00197 bit >>= 1; \
00198 if (bit == 0) \
00199 { \
00200 d->ptr_offset++; \
00201 bit = 128; \
00202 } \
00203 input += xstep; \
00204 if (xmod) \
00205 { \
00206 xerror += xmod; \
00207 if (xerror >= d->dst_width) \
00208 { \
00209 xerror -= d->dst_width; \
00210 input += (width); \
00211 } \
00212 } \
00213 } while (0)
00214
00215 #define ADVANCE_REVERSE(d, bit, input, width, xerror, xstep, xmod) \
00216 do \
00217 { \
00218 if (bit == 128) \
00219 { \
00220 d->ptr_offset--; \
00221 bit = 1; \
00222 } \
00223 else \
00224 bit <<= 1; \
00225 input -= xstep; \
00226 if (xmod) \
00227 { \
00228 xerror -= xmod; \
00229 if (xerror < 0) \
00230 { \
00231 xerror += d->dst_width; \
00232 input -= (width); \
00233 } \
00234 } \
00235 } while (0)
00236
00237 #define ADVANCE_BIDIRECTIONAL(d,bit,in,dir,width,xer,xstep,xmod,err,S) \
00238 do \
00239 { \
00240 int ii; \
00241 int jj; \
00242 for (ii = 0; ii < width; ii++) \
00243 for (jj = 0; jj < S; jj++) \
00244 err[ii][jj] += dir; \
00245 if (dir == 1) \
00246 ADVANCE_UNIDIRECTIONAL(d, bit, in, width, xer, xstep, xmod); \
00247 else \
00248 ADVANCE_REVERSE(d, bit, in, width, xer, xstep, xmod); \
00249 } while (0)
00250
00251 #ifdef __cplusplus
00252 }
00253 #endif
00254
00255 #endif
00256
00257
00258