OFFIS DCMTK  Version 3.6.0
diqtfs.h
1 /*
2  *
3  * Copyright (C) 2002-2010, OFFIS e.V.
4  * All rights reserved. See COPYRIGHT file for details.
5  *
6  * This software and supporting documentation were developed by
7  *
8  * OFFIS e.V.
9  * R&D Division Health
10  * Escherweg 2
11  * D-26121 Oldenburg, Germany
12  *
13  *
14  * Module: dcmimage
15  *
16  * Author: Marco Eichelberg
17  *
18  * Purpose: class DcmQuantFloydSteinberg
19  *
20  * Last Update: $Author: joergr $
21  * Update Date: $Date: 2010-10-14 13:16:29 $
22  * CVS/RCS Revision: $Revision: 1.5 $
23  * Status: $State: Exp $
24  *
25  * CVS/RCS Log at end of file
26  *
27  */
28 
29 
30 #ifndef DIQTFS_H
31 #define DIQTFS_H
32 
33 
34 #include "dcmtk/config/osconfig.h"
35 #include "dcmtk/dcmimage/diqtpix.h" /* for DcmQuantPixel */
36 #include "dcmtk/ofstd/ofcond.h" /* for OFCondition */
37 
38 
42 #define DcmQuantFloydSteinbergScale 1024
43 
44 
49 {
50 public:
51 
54 
57 
63  OFCondition initialize(unsigned long cols);
64 
71  inline void adjust(DcmQuantPixel& px, long col, long maxval)
72  {
73  register long sr = px.getRed() + thisrerr[col + 1] / DcmQuantFloydSteinbergScale;
74  register long sg = px.getGreen() + thisgerr[col + 1] / DcmQuantFloydSteinbergScale;
75  register long sb = px.getBlue() + thisberr[col + 1] / DcmQuantFloydSteinbergScale;
76  if ( sr < 0 ) sr = 0;
77  else if ( sr > OFstatic_cast(long, maxval) ) sr = maxval;
78  if ( sg < 0 ) sg = 0;
79  else if ( sg > OFstatic_cast(long, maxval) ) sg = maxval;
80  if ( sb < 0 ) sb = 0;
81  else if ( sb > OFstatic_cast(long, maxval) ) sb = maxval;
82  px.assign(OFstatic_cast(DcmQuantComponent, sr), OFstatic_cast(DcmQuantComponent, sg), OFstatic_cast(DcmQuantComponent, sb));
83  }
84 
90  inline void propagate(const DcmQuantPixel& px, const DcmQuantPixel& mapped, long col)
91  {
92  register long err;
93 
94  /* Propagate Floyd-Steinberg error terms. */
95  if ( fs_direction )
96  {
97  err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
98  thisrerr[col + 2] += ( err * 7 ) / 16;
99  nextrerr[col ] += ( err * 3 ) / 16;
100  nextrerr[col + 1] += ( err * 5 ) / 16;
101  nextrerr[col + 2] += ( err ) / 16;
102  err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
103  thisgerr[col + 2] += ( err * 7 ) / 16;
104  nextgerr[col ] += ( err * 3 ) / 16;
105  nextgerr[col + 1] += ( err * 5 ) / 16;
106  nextgerr[col + 2] += ( err ) / 16;
107  err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
108  thisberr[col + 2] += ( err * 7 ) / 16;
109  nextberr[col ] += ( err * 3 ) / 16;
110  nextberr[col + 1] += ( err * 5 ) / 16;
111  nextberr[col + 2] += ( err ) / 16;
112  }
113  else
114  {
115  err = ( OFstatic_cast(long, px.getRed()) - OFstatic_cast(long, mapped.getRed()) ) * DcmQuantFloydSteinbergScale;
116  thisrerr[col ] += ( err * 7 ) / 16;
117  nextrerr[col + 2] += ( err * 3 ) / 16;
118  nextrerr[col + 1] += ( err * 5 ) / 16;
119  nextrerr[col ] += ( err ) / 16;
120  err = ( OFstatic_cast(long, px.getGreen()) - OFstatic_cast(long, mapped.getGreen()) ) * DcmQuantFloydSteinbergScale;
121  thisgerr[col ] += ( err * 7 ) / 16;
122  nextgerr[col + 2] += ( err * 3 ) / 16;
123  nextgerr[col + 1] += ( err * 5 ) / 16;
124  nextgerr[col ] += ( err ) / 16;
125  err = ( OFstatic_cast(long, px.getBlue()) - OFstatic_cast(long, mapped.getBlue()) ) * DcmQuantFloydSteinbergScale;
126  thisberr[col ] += ( err * 7 ) / 16;
127  nextberr[col + 2] += ( err * 3 ) / 16;
128  nextberr[col + 1] += ( err * 5 ) / 16;
129  nextberr[col ] += ( err ) / 16;
130  }
131  }
132 
140  inline void startRow(long& col, long& limitcol)
141  {
142  for (unsigned long c = 0; c < columns + 2; ++c)
143  nextrerr[c] = nextgerr[c] = nextberr[c] = 0;
144 
145  if (fs_direction)
146  {
147  col = 0;
148  limitcol = columns;
149  }
150  else
151  {
152  col = columns - 1;
153  limitcol = -1;
154  }
155  }
156 
161  inline void finishRow()
162  {
163  temperr = thisrerr;
164  thisrerr = nextrerr;
165  nextrerr = temperr;
166  temperr = thisgerr;
167  thisgerr = nextgerr;
168  nextgerr = temperr;
169  temperr = thisberr;
170  thisberr = nextberr;
171  nextberr = temperr;
173  }
174 
179  inline void nextCol(long& col) const
180  {
181  if (fs_direction) ++col; else --col;
182  }
183 
184 private:
185 
187  void cleanup();
188 
191 
194 
196  long *thisrerr;
197 
199  long *nextrerr;
200 
202  long *thisgerr;
203 
205  long *nextgerr;
206 
208  long *thisberr;
209 
211  long *nextberr;
212 
214  long *temperr;
215 
220 
222  unsigned long columns;
223 
224 };
225 
226 
227 #endif
228 
229 
230 /*
231  * CVS/RCS Log:
232  * $Log: diqtfs.h,v $
233  * Revision 1.5 2010-10-14 13:16:29 joergr
234  * Updated copyright header. Added reference to COPYRIGHT file.
235  *
236  * Revision 1.4 2005/12/08 16:01:46 meichel
237  * Changed include path schema for all DCMTK header files
238  *
239  * Revision 1.3 2003/12/23 12:16:59 joergr
240  * Adapted type casts to new-style typecast operators defined in ofcast.h.
241  * Updated copyright header.
242  *
243  * Revision 1.2 2002/05/15 09:53:30 meichel
244  * Minor corrections to avoid warnings on Sun CC 2.0.1
245  *
246  * Revision 1.1 2002/01/25 13:32:04 meichel
247  * Initial release of new color quantization classes and
248  * the dcmquant tool in module dcmimage.
249  *
250  *
251  */


Generated on Thu Dec 20 2012 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.8.2