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

src/main/dither-very-fast.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: dither-very-fast.c,v 1.14 2004/05/07 19:20:30 rleigh Exp $"
00003  *
00004  *   Very fast 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_very_fast(const stpi_dither_t *d, stpi_dither_channel_t *dc,
00039                       int val, int x, int y, unsigned char bit,
00040                       unsigned bits, int length)
00041 {
00042   int j;
00043   if (bits && val >= ditherpoint(d, &(dc->dithermat), x))
00044     {
00045       unsigned char *tptr = dc->ptr + d->ptr_offset;
00046 
00047       /*
00048        * Lay down all of the bits in the pixel.
00049        */
00050       set_row_ends(dc, x);
00051       for (j = 1; j <= bits; j += j, tptr += length)
00052         {
00053           if (j & bits)
00054             tptr[0] |= bit;
00055         }
00056     }
00057 }
00058 
00059 void
00060 stpi_dither_very_fast(stp_vars_t *v,
00061                       int row,
00062                       const unsigned short *raw,
00063                       int duplicate_line,
00064                       int zero_mask,
00065                       const unsigned char *mask)
00066 {
00067   stpi_dither_t *d = (stpi_dither_t *) stp_get_component_data(v, "Dither");
00068   int           x,
00069                 length;
00070   unsigned char *bit_patterns;
00071   unsigned char bit;
00072   int i;
00073   int one_bit_only = 1;
00074 
00075   int xerror, xstep, xmod;
00076 
00077   if ((zero_mask & ((1 << CHANNEL_COUNT(d)) - 1)) ==
00078       ((1 << CHANNEL_COUNT(d)) - 1))
00079     return;
00080 
00081   length = (d->dst_width + 7) / 8;
00082 
00083   bit = 128;
00084   xstep  = CHANNEL_COUNT(d) * (d->src_width / d->dst_width);
00085   xmod   = d->src_width % d->dst_width;
00086   xerror = 0;
00087 
00088   bit_patterns = stp_zalloc(sizeof(unsigned char) * CHANNEL_COUNT(d));
00089   for (i = 0; i < CHANNEL_COUNT(d); i++)
00090     {
00091       stpi_dither_channel_t *dc = &(CHANNEL(d, i));
00092       if (dc->nlevels > 0)
00093         bit_patterns[i] = dc->ranges[dc->nlevels - 1].upper->bits;
00094       if (bit_patterns[i] != 1)
00095         one_bit_only = 0;
00096     }
00097   if (one_bit_only)
00098     {
00099       for (x = 0; x < d->dst_width; x ++)
00100         {
00101           if (!mask || (*(mask + d->ptr_offset) & bit))
00102             {
00103               for (i = 0; i < CHANNEL_COUNT(d); i++)
00104                 {
00105                   if (raw[i] &&
00106                       raw[i] >= ditherpoint(d, &(CHANNEL(d, i).dithermat), x))
00107                     {
00108                       set_row_ends(&(CHANNEL(d, i)), x);
00109                       CHANNEL(d, i).ptr[d->ptr_offset] |= bit;
00110                     }
00111                 }
00112             }
00113           ADVANCE_UNIDIRECTIONAL(d, bit, raw, CHANNEL_COUNT(d),
00114                                  xerror, xstep, xmod);
00115         }
00116     }
00117   else
00118     {
00119       for (x = 0; x < d->dst_width; x ++)
00120         {
00121           if (!mask || (*(mask + d->ptr_offset) & bit))
00122             {
00123               for (i = 0; i < CHANNEL_COUNT(d); i++)
00124                 {
00125                   if (CHANNEL(d, i).ptr && raw[i])
00126                     print_color_very_fast(d, &(CHANNEL(d, i)), raw[i], x, row,
00127                                           bit, bit_patterns[i], length);
00128                 }
00129             }
00130           ADVANCE_UNIDIRECTIONAL(d, bit, raw, CHANNEL_COUNT(d),
00131                                  xerror, xstep, xmod);
00132         }
00133     }
00134   stp_free(bit_patterns);
00135 }

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