Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/dither-impl.h

Go to the documentation of this file.
00001 /*
00002  * "$Id: dither-impl.h,v 1.22 2004/05/07 19:20:30 rleigh 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 
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  * An end of a dither segment, describing one ink
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  * A segment of the entire 0-65535 intensity range.
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;          /* With Floyd-Steinberg dithering, control */
00103                                 /* how much randomness is applied to the */
00104                                 /* threshold values (0-65535). */
00105   unsigned bit_max;
00106   unsigned signif_bits;
00107   unsigned density;
00108   double darkness;              /* Relative darkness of this ink */
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;               /* aux_freefunc for dither should free this */
00128 } stpi_dither_channel_t;
00129 
00130 typedef struct dither
00131 {
00132   int src_width;                /* Input width */
00133   int dst_width;                /* Output width */
00134 
00135   int spread;                   /* With Floyd-Steinberg, how widely the */
00136   int spread_mask;              /* error is distributed.  This should be */
00137                                 /* between 12 (very broad distribution) and */
00138                                 /* 19 (very narrow) */
00139 
00140   int stpi_dither_type;
00141 
00142   int adaptive_limit;
00143 
00144   int x_aspect;                 /* Aspect ratio numerator */
00145   int y_aspect;                 /* Aspect ratio denominator */
00146 
00147   double transition;            /* Exponential scaling for transition region */
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;                /* When dither is first called, calculate
00159                                  * some things */
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 /* GIMP_PRINT_INTERNAL_DITHER_IMPL_H */
00256 /*
00257  * End of "$Id: dither-impl.h,v 1.22 2004/05/07 19:20:30 rleigh Exp $".
00258  */

Generated on Wed May 12 20:21:28 2004 for libgimpprint API Reference by doxygen1.2.17