libgimpprint API Reference: src/main/dither-very-fast.c Source File

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

# src/main/dither-very-fast.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: dither-very-fast_8c-source.html,v 1.1.1.2 2004/12/22 23:48:59 jlovell 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 }