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
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"
00040 #include "dcmtk/ofstd/ofcond.h"
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
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
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252