libgimpprint API Reference: src/main/dither-impl.h Source File

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_8h-source.html,v 1.1.1.2 2004/12/22 23:48:58 jlovell 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_8h-source.html,v 1.1.1.2 2004/12/22 23:48:58 jlovell Exp $".
    00260  */