dcmimage/include/dcmtk/dcmimage/diqtfs.h

00001 /*
00002  *
00003  *  Copyright (C) 2002-2010, OFFIS e.V.
00004  *  All rights reserved.  See COPYRIGHT file for details.
00005  *
00006  *  This software and supporting documentation were developed by
00007  *
00008  *    OFFIS e.V.
00009  *    R&D Division Health
00010  *    Escherweg 2
00011  *    D-26121 Oldenburg, Germany
00012  *
00013  *
00014  *  Module:  dcmimage
00015  *
00016  *  Author:  Marco Eichelberg
00017  *
00018  *  Purpose: class DcmQuantFloydSteinberg
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-14 13:16:29 $
00022  *  CVS/RCS Revision: $Revision: 1.5 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 
00030 #ifndef DIQTFS_H
00031 #define DIQTFS_H
00032 
00033 
00034 #include "dcmtk/config/osconfig.h"
00035 #include "dcmtk/dcmimage/diqtpix.h"   /* for DcmQuantPixel */
00036 #include "dcmtk/ofstd/ofcond.h"    /* for OFCondition */
00037 
00038 
00042 #define DcmQuantFloydSteinbergScale 1024
00043 
00044 
00048 class DcmQuantFloydSteinberg
00049 {
00050 public:
00051 
00053   DcmQuantFloydSteinberg();
00054 
00056   ~DcmQuantFloydSteinberg();
00057 
00063   OFCondition initialize(unsigned long cols);
00064   
00071   inline void adjust(DcmQuantPixel& px, long col, long maxval)
00072   {
00073     register long sr = px.getRed()   + thisrerr[col + 1] / DcmQuantFloydSteinbergScale;
00074     register long sg = px.getGreen() + thisgerr[col + 1] / DcmQuantFloydSteinbergScale;
00075     register long sb = px.getBlue()  + thisberr[col + 1] / DcmQuantFloydSteinbergScale;
00076     if ( sr < 0 ) sr = 0;
00077     else if ( sr > OFstatic_cast(long, maxval) ) sr = maxval;
00078     if ( sg < 0 ) sg = 0;
00079     else if ( sg > OFstatic_cast(long, maxval) ) sg = maxval;
00080     if ( sb < 0 ) sb = 0;
00081     else if ( sb > OFstatic_cast(long, maxval) ) sb = maxval;
00082     px.assign(OFstatic_cast(DcmQuantComponent, sr), OFstatic_cast(DcmQuantComponent, sg), OFstatic_cast(DcmQuantComponent, sb));
00083   }
00084 
00090   inline void propagate(const DcmQuantPixel& px, const DcmQuantPixel& mapped, long col)
00091   {
00092     register long err;
00093 
00094     /* Propagate Floyd-Steinberg error terms. */
00095     if ( fs_direction )
00096     {
00097         err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
00098         thisrerr[col + 2] += ( err * 7 ) / 16;
00099         nextrerr[col    ] += ( err * 3 ) / 16;
00100         nextrerr[col + 1] += ( err * 5 ) / 16;
00101         nextrerr[col + 2] += ( err     ) / 16;
00102         err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
00103         thisgerr[col + 2] += ( err * 7 ) / 16;
00104         nextgerr[col    ] += ( err * 3 ) / 16;
00105         nextgerr[col + 1] += ( err * 5 ) / 16;
00106         nextgerr[col + 2] += ( err     ) / 16;
00107         err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
00108         thisberr[col + 2] += ( err * 7 ) / 16;
00109         nextberr[col    ] += ( err * 3 ) / 16;
00110         nextberr[col + 1] += ( err * 5 ) / 16;
00111         nextberr[col + 2] += ( err     ) / 16;
00112     }
00113     else
00114     {
00115         err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
00116         thisrerr[col    ] += ( err * 7 ) / 16;
00117         nextrerr[col + 2] += ( err * 3 ) / 16;
00118         nextrerr[col + 1] += ( err * 5 ) / 16;
00119         nextrerr[col    ] += ( err     ) / 16;
00120         err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
00121         thisgerr[col    ] += ( err * 7 ) / 16;
00122         nextgerr[col + 2] += ( err * 3 ) / 16;
00123         nextgerr[col + 1] += ( err * 5 ) / 16;
00124         nextgerr[col    ] += ( err     ) / 16;
00125         err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
00126         thisberr[col    ] += ( err * 7 ) / 16;
00127         nextberr[col + 2] += ( err * 3 ) / 16;
00128         nextberr[col + 1] += ( err * 5 ) / 16;
00129         nextberr[col    ] += ( err     ) / 16;
00130     }
00131   }
00132 
00140   inline void startRow(long& col, long& limitcol)
00141   {
00142     for (unsigned long c = 0; c < columns + 2; ++c)
00143       nextrerr[c] = nextgerr[c] = nextberr[c] = 0;
00144   
00145     if (fs_direction)
00146     {
00147         col = 0;
00148         limitcol = columns;
00149     }
00150     else
00151     {
00152         col = columns - 1;
00153         limitcol = -1;
00154     }
00155   }
00156   
00161   inline void finishRow()
00162   {
00163     temperr = thisrerr;
00164     thisrerr = nextrerr;
00165     nextrerr = temperr;
00166     temperr = thisgerr;
00167     thisgerr = nextgerr;
00168     nextgerr = temperr;
00169     temperr = thisberr;
00170     thisberr = nextberr;
00171     nextberr = temperr;
00172     fs_direction = ! fs_direction;
00173   }
00174 
00179   inline void nextCol(long& col) const
00180   {
00181     if (fs_direction) ++col; else --col;
00182   }
00183 
00184 private:
00185 
00187   void cleanup();
00188 
00190   DcmQuantFloydSteinberg(const DcmQuantFloydSteinberg& src);
00191 
00193   DcmQuantFloydSteinberg& operator=(const DcmQuantFloydSteinberg& src);
00194 
00196   long *thisrerr;
00197 
00199   long *nextrerr;
00200   
00202   long *thisgerr;
00203 
00205   long *nextgerr;
00206 
00208   long *thisberr;
00209 
00211   long *nextberr;
00212 
00214   long *temperr;
00215 
00219   int fs_direction;
00220   
00222   unsigned long columns;
00223 
00224 };
00225 
00226 
00227 #endif
00228 
00229 
00230 /*
00231  * CVS/RCS Log:
00232  * $Log: diqtfs.h,v $
00233  * Revision 1.5  2010-10-14 13:16:29  joergr
00234  * Updated copyright header. Added reference to COPYRIGHT file.
00235  *
00236  * Revision 1.4  2005/12/08 16:01:46  meichel
00237  * Changed include path schema for all DCMTK header files
00238  *
00239  * Revision 1.3  2003/12/23 12:16:59  joergr
00240  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00241  * Updated copyright header.
00242  *
00243  * Revision 1.2  2002/05/15 09:53:30  meichel
00244  * Minor corrections to avoid warnings on Sun CC 2.0.1
00245  *
00246  * Revision 1.1  2002/01/25 13:32:04  meichel
00247  * Initial release of new color quantization classes and
00248  *   the dcmquant tool in module dcmimage.
00249  *
00250  *
00251  */


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1