Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/main/dither-impl.h

Go to the documentation of this file.
00001 /*
00002  * "$Id: dither-impl.h,v 1.23 2004/07/24 02:22:30 rlk Exp $"
00003  *
00004  *   Internal implementation of dither algorithms
00005  *
00006  *   Copyright 1997-2003 Michael Sweet (mike@easysw.com) and
00007  *      Robert Krawitz (rlk@alum.mit.edu)
00008  *
00009  *   This program is free software; you can redistribute it and/or modify it
00010  *   under the terms of the GNU General Public License as published by the Free
00011  *   Software Foundation; either version 2 of the License, or (at your option)
00012  *   any later version.
00013  *
00014  *   This program is distributed in the hope that it will be useful, but
00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017  *   for more details.
00018  *
00019  *   You should have received a copy of the GNU General Public License
00020  *   along with this program; if not, write to the Free Software
00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022  *
00023  * Revision History:
00024  *
00025  *   See ChangeLog
00026  */
00027 
00028 /*
00029  * This file must include only standard C header files.  The core code must
00030  * compile on generic platforms that don't support glib, gimp, gtk, etc.
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  * An end of a dither segment, describing one ink
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  * A segment of the entire 0-65535 intensity range.
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;          /* With Floyd-Steinberg dithering, control */
00104                                 /* how much randomness is applied to the */
00105                                 /* threshold values (0-65535). */
00106   unsigned bit_max;
00107   unsigned signif_bits;
00108   unsigned density;
00109   double darkness;              /* Relative darkness of this ink */
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;               /* aux_freefunc for dither should free this */
00129 } stpi_dither_channel_t;
00130 
00131 typedef struct dither
00132 {
00133   int src_width;                /* Input width */
00134   int dst_width;                /* Output width */
00135 
00136   int spread;                   /* With Floyd-Steinberg, how widely the */
00137   int spread_mask;              /* error is distributed.  This should be */
00138                                 /* between 12 (very broad distribution) and */
00139                                 /* 19 (very narrow) */
00140 
00141   int stpi_dither_type;
00142 
00143   int adaptive_limit;
00144 
00145   int x_aspect;                 /* Aspect ratio numerator */
00146   int y_aspect;                 /* Aspect ratio denominator */
00147 
00148   double transition;            /* Exponential scaling for transition region */
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;                /* When dither is first called, calculate
00160                                  * some things */
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 /* GIMP_PRINT_INTERNAL_DITHER_IMPL_H */
00258 /*
00259  * End of "$Id: dither-impl.h,v 1.23 2004/07/24 02:22:30 rlk Exp $".
00260  */

Generated on Wed Aug 25 07:56:13 2004 for libgimpprint API Reference by doxygen 1.3.6