diqtfs.h

00001 /*
00002  *
00003  *  Copyright (C) 2002-2005, OFFIS
00004  *
00005  *  This software and supporting documentation were developed by
00006  *
00007  *    Kuratorium OFFIS e.V.
00008  *    Healthcare Information and Communication Systems
00009  *    Escherweg 2
00010  *    D-26121 Oldenburg, Germany
00011  *
00012  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
00013  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
00014  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
00015  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
00016  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
00017  *
00018  *  Module:  dcmimage
00019  *
00020  *  Author:  Marco Eichelberg
00021  *
00022  *  Purpose: class DcmQuantFloydSteinberg
00023  *
00024  *  Last Update:      $Author: meichel $
00025  *  Update Date:      $Date: 2005/12/08 16:01:46 $
00026  *  CVS/RCS Revision: $Revision: 1.4 $
00027  *  Status:           $State: Exp $
00028  *
00029  *  CVS/RCS Log at end of file
00030  *
00031  */
00032 
00033 
00034 #ifndef DIQTFS_H
00035 #define DIQTFS_H
00036 
00037 
00038 #include "dcmtk/config/osconfig.h"
00039 #include "dcmtk/dcmimage/diqtpix.h"   /* for DcmQuantPixel */
00040 #include "dcmtk/ofstd/ofcond.h"    /* for OFCondition */
00041 
00042 
00046 #define DcmQuantFloydSteinbergScale 1024
00047 
00048 
00052 class DcmQuantFloydSteinberg
00053 {
00054 public:
00055 
00057   DcmQuantFloydSteinberg();
00058 
00060   ~DcmQuantFloydSteinberg();
00061 
00067   OFCondition initialize(unsigned long cols);
00068   
00075   inline void adjust(DcmQuantPixel& px, long col, long maxval)
00076   {
00077     register long sr = px.getRed()   + thisrerr[col + 1] / DcmQuantFloydSteinbergScale;
00078     register long sg = px.getGreen() + thisgerr[col + 1] / DcmQuantFloydSteinbergScale;
00079     register long sb = px.getBlue()  + thisberr[col + 1] / DcmQuantFloydSteinbergScale;
00080     if ( sr < 0 ) sr = 0;
00081     else if ( sr > OFstatic_cast(long, maxval) ) sr = maxval;
00082     if ( sg < 0 ) sg = 0;
00083     else if ( sg > OFstatic_cast(long, maxval) ) sg = maxval;
00084     if ( sb < 0 ) sb = 0;
00085     else if ( sb > OFstatic_cast(long, maxval) ) sb = maxval;
00086     px.assign(OFstatic_cast(DcmQuantComponent, sr), OFstatic_cast(DcmQuantComponent, sg), OFstatic_cast(DcmQuantComponent, sb));
00087   }
00088 
00094   inline void propagate(const DcmQuantPixel& px, const DcmQuantPixel& mapped, long col)
00095   {
00096     register long err;
00097 
00098     /* Propagate Floyd-Steinberg error terms. */
00099     if ( fs_direction )
00100     {
00101         err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
00102         thisrerr[col + 2] += ( err * 7 ) / 16;
00103         nextrerr[col    ] += ( err * 3 ) / 16;
00104         nextrerr[col + 1] += ( err * 5 ) / 16;
00105         nextrerr[col + 2] += ( err     ) / 16;
00106         err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
00107         thisgerr[col + 2] += ( err * 7 ) / 16;
00108         nextgerr[col    ] += ( err * 3 ) / 16;
00109         nextgerr[col + 1] += ( err * 5 ) / 16;
00110         nextgerr[col + 2] += ( err     ) / 16;
00111         err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
00112         thisberr[col + 2] += ( err * 7 ) / 16;
00113         nextberr[col    ] += ( err * 3 ) / 16;
00114         nextberr[col + 1] += ( err * 5 ) / 16;
00115         nextberr[col + 2] += ( err     ) / 16;
00116     }
00117     else
00118     {
00119         err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
00120         thisrerr[col    ] += ( err * 7 ) / 16;
00121         nextrerr[col + 2] += ( err * 3 ) / 16;
00122         nextrerr[col + 1] += ( err * 5 ) / 16;
00123         nextrerr[col    ] += ( err     ) / 16;
00124         err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
00125         thisgerr[col    ] += ( err * 7 ) / 16;
00126         nextgerr[col + 2] += ( err * 3 ) / 16;
00127         nextgerr[col + 1] += ( err * 5 ) / 16;
00128         nextgerr[col    ] += ( err     ) / 16;
00129         err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
00130         thisberr[col    ] += ( err * 7 ) / 16;
00131         nextberr[col + 2] += ( err * 3 ) / 16;
00132         nextberr[col + 1] += ( err * 5 ) / 16;
00133         nextberr[col    ] += ( err     ) / 16;
00134     }
00135   }
00136 
00144   inline void startRow(long& col, long& limitcol)
00145   {
00146     for (unsigned long c = 0; c < columns + 2; ++c)
00147       nextrerr[c] = nextgerr[c] = nextberr[c] = 0;
00148   
00149     if (fs_direction)
00150     {
00151         col = 0;
00152         limitcol = columns;
00153     }
00154     else
00155     {
00156         col = columns - 1;
00157         limitcol = -1;
00158     }
00159   }
00160   
00165   inline void finishRow()
00166   {
00167     temperr = thisrerr;
00168     thisrerr = nextrerr;
00169     nextrerr = temperr;
00170     temperr = thisgerr;
00171     thisgerr = nextgerr;
00172     nextgerr = temperr;
00173     temperr = thisberr;
00174     thisberr = nextberr;
00175     nextberr = temperr;
00176     fs_direction = ! fs_direction;
00177   }
00178 
00183   inline void nextCol(long& col) const
00184   {
00185     if (fs_direction) ++col; else --col;
00186   }
00187 
00188 private:
00189 
00191   void cleanup();
00192 
00194   DcmQuantFloydSteinberg(const DcmQuantFloydSteinberg& src);
00195 
00197   DcmQuantFloydSteinberg& operator=(const DcmQuantFloydSteinberg& src);
00198 
00200   long *thisrerr;
00201 
00203   long *nextrerr;
00204   
00206   long *thisgerr;
00207 
00209   long *nextgerr;
00210 
00212   long *thisberr;
00213 
00215   long *nextberr;
00216 
00218   long *temperr;
00219 
00223   int fs_direction;
00224   
00226   unsigned long columns;
00227 
00228 };
00229 
00230 
00231 #endif
00232 
00233 
00234 /*
00235  * CVS/RCS Log:
00236  * $Log: diqtfs.h,v $
00237  * Revision 1.4  2005/12/08 16:01:46  meichel
00238  * Changed include path schema for all DCMTK header files
00239  *
00240  * Revision 1.3  2003/12/23 12:16:59  joergr
00241  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00242  * Updated copyright header.
00243  *
00244  * Revision 1.2  2002/05/15 09:53:30  meichel
00245  * Minor corrections to avoid warnings on Sun CC 2.0.1
00246  *
00247  * Revision 1.1  2002/01/25 13:32:04  meichel
00248  * Initial release of new color quantization classes and
00249  *   the dcmquant tool in module dcmimage.
00250  *
00251  *
00252  */


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5