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 */