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

src/main/dither-ordered.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: dither-ordered.c,v 1.16 2004/05/07 19:20:30 rleigh Exp $"
00003  *
00004  *   Ordered dither algorithm
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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 #include <gimp-print/gimp-print.h>
00032 #include "gimp-print-internal.h"
00033 #include <gimp-print/gimp-print-intl-internal.h>
00034 #include "dither-impl.h"
00035 #include "dither-inlined-functions.h"
00036 
00037 static inline void
00038 print_color_ordered(const stpi_dither_t *d, stpi_dither_channel_t *dc, int val,
00039                     int x, int y, unsigned char bit, int length)
00040 {
00041   int i;
00042   int j;
00043   unsigned bits;
00044   int levels = dc->nlevels - 1;
00045 
00046   /*
00047    * Look for the appropriate range into which the input value falls.
00048    * Notice that we use the input, not the error, to decide what dot type
00049    * to print (if any).  We actually use the "density" input to permit
00050    * the caller to use something other that simply the input value, if it's
00051    * desired to use some function of overall density, rather than just
00052    * this color's input, for this purpose.
00053    */
00054   for (i = levels; i >= 0; i--)
00055     {
00056       stpi_dither_segment_t *dd = &(dc->ranges[i]);
00057 
00058       if (val > dd->lower->value)
00059         {
00060           /*
00061            * Where are we within the range.
00062            */
00063 
00064           unsigned rangepoint = val - dd->lower->value;
00065           if (dd->value_span < 65535)
00066             rangepoint = rangepoint * 65535 / dd->value_span;
00067 
00068           if (rangepoint >= ditherpoint(d, &(dc->dithermat), x))
00069             bits = dd->upper->bits;
00070           else
00071             bits = dd->lower->bits;
00072 
00073           if (bits)
00074             {
00075               unsigned char *tptr = dc->ptr + d->ptr_offset;
00076 
00077               /*
00078                * Lay down all of the bits in the pixel.
00079                */
00080               set_row_ends(dc, x);
00081               for (j = 1; j <= bits; j += j, tptr += length)
00082                 {
00083                   if (j & bits)
00084                     tptr[0] |= bit;
00085                 }
00086 
00087             }
00088           return;
00089         }
00090     }
00091 }
00092 
00093 
00094 void
00095 stpi_dither_ordered(stp_vars_t *v,
00096                     int row,
00097                     const unsigned short *raw,
00098                     int duplicate_line,
00099                     int zero_mask,
00100                     const unsigned char *mask)
00101 {
00102   stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00103   int           x,
00104                 length;
00105   unsigned char bit;
00106   int i;
00107   int one_bit_only = 1;
00108 
00109   int xerror, xstep, xmod;
00110 
00111   if ((zero_mask & ((1 << CHANNEL_COUNT(d)) - 1)) ==
00112       ((1 << CHANNEL_COUNT(d)) - 1))
00113     return;
00114 
00115   length = (d->dst_width + 7) / 8;
00116 
00117   bit = 128;
00118   xstep  = CHANNEL_COUNT(d) * (d->src_width / d->dst_width);
00119   xmod   = d->src_width % d->dst_width;
00120   xerror = 0;
00121 
00122   for (i = 0; i < CHANNEL_COUNT(d); i++)
00123     {
00124       stpi_dither_channel_t *dc = &(CHANNEL(d, i));
00125       if (dc->nlevels != 1 || dc->ranges[0].upper->bits != 1)
00126         one_bit_only = 0;
00127     }
00128 
00129   if (one_bit_only)
00130     {
00131       for (x = 0; x < d->dst_width; x ++)
00132         {
00133           if (!mask || (*(mask + d->ptr_offset) & bit))
00134             {
00135               for (i = 0; i < CHANNEL_COUNT(d); i++)
00136                 {
00137                   if (raw[i] &&
00138                       raw[i] >= ditherpoint(d, &(CHANNEL(d, i).dithermat), x))
00139                     {
00140                       set_row_ends(&(CHANNEL(d, i)), x);
00141                       CHANNEL(d, i).ptr[d->ptr_offset] |= bit;
00142                     }
00143                 }
00144             }
00145           ADVANCE_UNIDIRECTIONAL(d, bit, raw, CHANNEL_COUNT(d),
00146                                  xerror, xstep, xmod);
00147         }
00148     }
00149   else
00150     {
00151       for (x = 0; x != d->dst_width; x ++)
00152         {
00153           if (!mask || (*(mask + d->ptr_offset) & bit))
00154             {
00155               for (i = 0; i < CHANNEL_COUNT(d); i++)
00156                 {
00157                   if (CHANNEL(d, i).ptr && raw[i])
00158                     print_color_ordered(d, &(CHANNEL(d, i)), raw[i], x, row,
00159                                         bit, length);
00160                 }
00161             }
00162           ADVANCE_UNIDIRECTIONAL(d, bit, raw, CHANNEL_COUNT(d), xerror,
00163                                  xstep, xmod);
00164         }
00165     }
00166 }

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