00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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"
00036 #include "dcmtk/ofstd/ofcond.h"
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
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
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251