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 DISCALET_H
00035 #define DISCALET_H
00036
00037 #include "dcmtk/config/osconfig.h"
00038 #include "dcmtk/dcmdata/dctypes.h"
00039 #include "dcmtk/ofstd/ofconsol.h"
00040 #include "dcmtk/ofstd/ofcast.h"
00041 #include "dcmtk/ofstd/ofstream.h"
00042
00043 #include "dcmtk/dcmimgle/ditranst.h"
00044 #include "dcmtk/dcmimgle/dipxrept.h"
00045 #include "dcmtk/dcmimgle/diutils.h"
00046
00047
00048
00049
00050
00051
00052 #define SCALE_FACTOR 4096
00053 #define HALFSCALE_FACTOR 2048
00054
00055
00056
00057
00058
00059
00060
00061
00062 static inline void setScaleValues(Uint16 data[],
00063 const Uint16 min,
00064 const Uint16 max)
00065 {
00066 register Uint16 remainder = max % min;
00067 Uint16 step0 = max / min;
00068 Uint16 step1 = max / min;
00069 if (remainder > OFstatic_cast(Uint16, min / 2))
00070 {
00071 remainder = min - remainder;
00072 ++step0;
00073 } else
00074 ++step1;
00075 const double count = OFstatic_cast(double, min) / (OFstatic_cast(double, remainder) + 1);
00076 register Uint16 i;
00077 register double c = count;
00078 for (i = 0; i < min; ++i)
00079 {
00080 if ((i >= OFstatic_cast(Uint16, c)) && (remainder > 0))
00081 {
00082 --remainder;
00083 c += count;
00084 data[i] = step1;
00085 }
00086 else
00087 data[i] = step0;
00088 }
00089 }
00090
00091
00092
00093
00094
00095
00099 template<class T>
00100 class DiScaleTemplate
00101 : public DiTransTemplate<T>
00102 {
00103
00104 public:
00105
00120 DiScaleTemplate(const int planes,
00121 const Uint16 columns,
00122 const Uint16 rows,
00123 const signed long left_pos,
00124 const signed long top_pos,
00125 const Uint16 src_cols,
00126 const Uint16 src_rows,
00127 const Uint16 dest_cols,
00128 const Uint16 dest_rows,
00129 const Uint32 frames,
00130 const int bits = 0)
00131 : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),
00132 Left(left_pos),
00133 Top(top_pos),
00134 Columns(columns),
00135 Rows(rows)
00136 {
00137 }
00138
00149 DiScaleTemplate(const int planes,
00150 const Uint16 src_cols,
00151 const Uint16 src_rows,
00152 const Uint16 dest_cols,
00153 const Uint16 dest_rows,
00154 const Uint32 frames,
00155 const int bits = 0)
00156 : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),
00157 Left(0),
00158 Top(0),
00159 Columns(src_cols),
00160 Rows(src_rows)
00161 {
00162 }
00163
00166 virtual ~DiScaleTemplate()
00167 {
00168 }
00169
00177 void scaleData(const T *src[],
00178 T *dest[],
00179 const int interpolate,
00180 const T value = 0)
00181 {
00182 if ((src != NULL) && (dest != NULL))
00183 {
00184 #ifdef DEBUG
00185 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_DebugMessages))
00186 {
00187 ofConsole.lockCout() << "C/R: " << Columns << " " << Rows << endl
00188 << "L/T: " << Left << " " << Top << endl
00189 << "SX/Y: " << this->Src_X << " " << this->Src_Y << endl
00190 << "DX/Y: " << this->Dest_X << " " << this->Dest_Y << endl;
00191 ofConsole.unlockCout();
00192 }
00193 #endif
00194 if ((Left + OFstatic_cast(signed long, this->Src_X) <= 0) || (Top + OFstatic_cast(signed long, this->Src_Y) <= 0) ||
00195 (Left >= OFstatic_cast(signed long, Columns)) || (Top >= OFstatic_cast(signed long, Rows)))
00196 {
00197 #ifdef DEBUG
00198 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00199 {
00200 ofConsole.lockCerr() << "INFO: clipping area is fully outside the image boundaries !" << endl;
00201 ofConsole.unlockCerr();
00202 }
00203 #endif
00204 fillPixel(dest, value);
00205 }
00206 else if ((this->Src_X == this->Dest_X) && (this->Src_Y == this->Dest_Y))
00207 {
00208 if ((Left == 0) && (Top == 0) && (Columns == this->Src_X) && (Rows == this->Src_Y))
00209 copyPixel(src, dest);
00210 else if ((Left >= 0) && (OFstatic_cast(Uint16, Left + this->Src_X) <= Columns) &&
00211 (Top >= 0) && (OFstatic_cast(Uint16, Top + this->Src_Y) <= Rows))
00212 clipPixel(src, dest);
00213 else
00214 clipBorderPixel(src, dest, value);
00215 }
00216 else if ((interpolate == 1) && (this->Bits <= MAX_INTERPOLATION_BITS))
00217 interpolatePixel(src, dest);
00218 else if ((interpolate == 2) && (this->Dest_X >= this->Src_X) && (this->Dest_Y >= this->Src_Y))
00219 expandPixel(src, dest);
00220 else if ((interpolate == 2) && (this->Src_X >= this->Dest_X) && (this->Src_Y >= this->Dest_Y))
00221 reducePixel(src, dest);
00222 else if ((this->Dest_X % this->Src_X == 0) && (this->Dest_Y % this->Src_Y == 0))
00223 replicatePixel(src, dest);
00224 else if ((this->Src_X % this->Dest_X == 0) && (this->Src_Y % this->Dest_Y == 0))
00225 suppressPixel(src, dest);
00226 else
00227 scalePixel(src, dest);
00228 }
00229 }
00230
00231 protected:
00232
00234 const signed long Left;
00236 const signed long Top;
00238 const Uint16 Columns;
00240 const Uint16 Rows;
00241
00242
00243 private:
00244
00251 void clipPixel(const T *src[],
00252 T *dest[])
00253 {
00254 const unsigned long x_feed = Columns - this->Src_X;
00255 const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00256 register Uint16 x;
00257 register Uint16 y;
00258 register const T *p;
00259 register T *q;
00260 for (int j = 0; j < this->Planes; ++j)
00261 {
00262 p = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00263 q = dest[j];
00264 for (unsigned long f = this->Frames; f != 0; --f)
00265 {
00266 for (y = this->Dest_Y; y != 0; --y)
00267 {
00268 for (x = this->Dest_X; x != 0; --x)
00269 *(q++) = *(p++);
00270 p += x_feed;
00271 }
00272 p += y_feed;
00273 }
00274 }
00275 }
00276
00284 void clipBorderPixel(const T *src[],
00285 T *dest[],
00286 const T value)
00287 {
00288 const Uint16 s_left = (Left > 0) ? OFstatic_cast(Uint16, Left) : 0;
00289 const Uint16 s_top = (Top > 0) ? OFstatic_cast(Uint16, Top) : 0;
00290 const Uint16 d_left = (Left < 0 ? OFstatic_cast(Uint16, -Left) : 0);
00291 const Uint16 d_top = (Top < 0) ? OFstatic_cast(Uint16, -Top) : 0;
00292 const Uint16 d_right = (OFstatic_cast(unsigned long, this->Src_X) + OFstatic_cast(unsigned long, s_left) <
00293 OFstatic_cast(unsigned long, Columns) + OFstatic_cast(unsigned long, d_left)) ?
00294 (this->Src_X - 1) : (Columns + d_left - s_left - 1);
00295 const Uint16 d_bottom = (OFstatic_cast(unsigned long, this->Src_Y) + OFstatic_cast(unsigned long, s_top) <
00296 OFstatic_cast(unsigned long, Rows) + OFstatic_cast(unsigned long, d_top)) ?
00297 (this->Src_Y - 1) : (Rows + d_top - s_top - 1);
00298 const Uint16 x_count = d_right - d_left + 1;
00299 const Uint16 y_count = d_bottom - d_top + 1;
00300 const unsigned long s_start = OFstatic_cast(unsigned long, s_top) * OFstatic_cast(unsigned long, Columns) + s_left;
00301 const unsigned long x_feed = Columns - x_count;
00302 const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - y_count) * Columns;
00303 const unsigned long t_feed = OFstatic_cast(unsigned long, d_top) * OFstatic_cast(unsigned long, this->Src_X);
00304 const unsigned long b_feed = OFstatic_cast(unsigned long, this->Src_Y - d_bottom - 1) * OFstatic_cast(unsigned long, this->Src_X);
00305
00306
00307
00308
00309
00310
00311
00312
00313 register Uint16 x;
00314 register Uint16 y;
00315 register unsigned long i;
00316 register const T *p;
00317 register T *q;
00318 for (int j = 0; j < this->Planes; ++j)
00319 {
00320 p = src[j] + s_start;
00321 q = dest[j];
00322 for (unsigned long f = this->Frames; f != 0; --f)
00323 {
00324 for (i = t_feed; i != 0; --i)
00325 *(q++) = value;
00326 for (y = y_count; y != 0; --y)
00327 {
00328 x = 0;
00329 while (x < d_left)
00330 {
00331 *(q++) = value;
00332 ++x;
00333 }
00334 while (x <= d_right)
00335 {
00336 *(q++) = *(p++);
00337 ++x;
00338 }
00339 while (x < this->Src_X)
00340 {
00341 *(q++) = value;
00342 ++x;
00343 }
00344 p += x_feed;
00345 }
00346 for (i = b_feed; i != 0; --i)
00347 *(q++) = value;
00348 p += y_feed;
00349 }
00350 }
00351 }
00352
00359 void replicatePixel(const T *src[],
00360 T *dest[])
00361 {
00362 const Uint16 x_factor = this->Dest_X / this->Src_X;
00363 const Uint16 y_factor = this->Dest_Y / this->Src_Y;
00364 const unsigned long x_feed = Columns;
00365 const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00366 const T *sp;
00367 register Uint16 x;
00368 register Uint16 y;
00369 register Uint16 dx;
00370 register Uint16 dy;
00371 register const T *p;
00372 register T *q;
00373 register T value;
00374 for (int j = 0; j < this->Planes; ++j)
00375 {
00376 sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00377 q = dest[j];
00378 for (Uint32 f = this->Frames; f != 0; --f)
00379 {
00380 for (y = this->Src_Y; y != 0; --y)
00381 {
00382 for (dy = y_factor; dy != 0; --dy)
00383 {
00384 for (x = this->Src_X, p = sp; x != 0; --x)
00385 {
00386 value = *(p++);
00387 for (dx = x_factor; dx != 0; --dx)
00388 *(q++) = value;
00389 }
00390 }
00391 sp += x_feed;
00392 }
00393 sp += y_feed;
00394 }
00395 }
00396 }
00397
00404 void suppressPixel(const T *src[],
00405 T *dest[])
00406 {
00407 const unsigned int x_divisor = this->Src_X / this->Dest_X;
00408 const unsigned long x_feed = OFstatic_cast(unsigned long, this->Src_Y / this->Dest_Y) * OFstatic_cast(unsigned long, Columns) - this->Src_X;
00409 const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00410 register Uint16 x;
00411 register Uint16 y;
00412 register const T *p;
00413 register T *q;
00414 for (int j = 0; j < this->Planes; ++j)
00415 {
00416 p = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00417 q = dest[j];
00418 for (Uint32 f = this->Frames; f != 0; --f)
00419 {
00420 for (y = this->Dest_Y; y != 0; --y)
00421 {
00422 for (x = this->Dest_X; x != 0; --x)
00423 {
00424 *(q++) = *p;
00425 p += x_divisor;
00426 }
00427 p += x_feed;
00428 }
00429 p += y_feed;
00430 }
00431 }
00432 }
00433
00440 void scalePixel(const T *src[],
00441 T *dest[])
00442 {
00443 const Uint16 xmin = (this->Dest_X < this->Src_X) ? this->Dest_X : this->Src_X;
00444 const Uint16 ymin = (this->Dest_Y < this->Src_Y) ? this->Dest_Y : this->Src_Y;
00445 Uint16 *x_step = new Uint16[xmin];
00446 Uint16 *y_step = new Uint16[ymin];
00447 Uint16 *x_fact = new Uint16[xmin];
00448 Uint16 *y_fact = new Uint16[ymin];
00449
00450
00451
00452
00453
00454
00455 if ((x_step != NULL) && (y_step != NULL) && (x_fact != NULL) && (y_fact != NULL))
00456 {
00457 register Uint16 x;
00458 register Uint16 y;
00459 if (this->Dest_X < this->Src_X)
00460 setScaleValues(x_step, this->Dest_X, this->Src_X);
00461 else if (this->Dest_X > this->Src_X)
00462 setScaleValues(x_fact, this->Src_X, this->Dest_X);
00463 if (this->Dest_X <= this->Src_X)
00464 OFBitmanipTemplate<Uint16>::setMem(x_fact, 1, xmin);
00465 if (this->Dest_X >= this->Src_X)
00466 OFBitmanipTemplate<Uint16>::setMem(x_step, 1, xmin);
00467 x_step[xmin - 1] += Columns - this->Src_X;
00468 if (this->Dest_Y < this->Src_Y)
00469 setScaleValues(y_step, this->Dest_Y, this->Src_Y);
00470 else if (this->Dest_Y > this->Src_Y)
00471 setScaleValues(y_fact, this->Src_Y, this->Dest_Y);
00472 if (this->Dest_Y <= this->Src_Y)
00473 OFBitmanipTemplate<Uint16>::setMem(y_fact, 1, ymin);
00474 if (this->Dest_Y >= this->Src_Y)
00475 OFBitmanipTemplate<Uint16>::setMem(y_step, 1, ymin);
00476 y_step[ymin - 1] += Rows - this->Src_Y;
00477 const T *sp;
00478 register Uint16 dx;
00479 register Uint16 dy;
00480 register const T *p;
00481 register T *q;
00482 register T value;
00483 for (int j = 0; j < this->Planes; ++j)
00484 {
00485 sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00486 q = dest[j];
00487 for (Uint32 f = 0; f < this->Frames; ++f)
00488 {
00489 for (y = 0; y < ymin; ++y)
00490 {
00491 for (dy = 0; dy < y_fact[y]; ++dy)
00492 {
00493 for (x = 0, p = sp; x < xmin; ++x)
00494 {
00495 value = *p;
00496 for (dx = 0; dx < x_fact[x]; ++dx)
00497 *(q++) = value;
00498 p += x_step[x];
00499 }
00500 }
00501 sp += OFstatic_cast(unsigned long, y_step[y]) * OFstatic_cast(unsigned long, Columns);
00502 }
00503 }
00504 }
00505 }
00506 delete[] x_step;
00507 delete[] y_step;
00508 delete[] x_fact;
00509 delete[] y_fact;
00510 }
00511
00512
00518 void interpolatePixel(const T *src[],
00519 T *dest[])
00520 {
00521 if ((this->Src_X != Columns) || (this->Src_Y != Rows))
00522 {
00523 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Errors))
00524 {
00525 ofConsole.lockCerr() << "ERROR: interpolated scaling and clipping at the same time not implemented" << endl
00526 << " ... ignoring clipping region !" << endl;
00527 ofConsole.unlockCerr();
00528 }
00529 this->Src_X = Columns;
00530 this->Src_Y = Rows;
00531 }
00532
00533
00534
00535
00536
00537
00538 register Uint16 x;
00539 register Uint16 y;
00540 register const T *p;
00541 register T *q;
00542 T const *sp = NULL;
00543 T const *fp;
00544 T *sq;
00545
00546 const unsigned long sxscale = OFstatic_cast(unsigned long, (OFstatic_cast(double, this->Dest_X) / OFstatic_cast(double, this->Src_X)) * SCALE_FACTOR);
00547 const unsigned long syscale = OFstatic_cast(unsigned long, (OFstatic_cast(double, this->Dest_Y) / OFstatic_cast(double, this->Src_Y)) * SCALE_FACTOR);
00548 DiPixelRepresentationTemplate<T> rep;
00549 const signed long maxvalue = DicomImageClass::maxval(this->Bits - rep.isSigned());
00550
00551 T *xtemp = new T[this->Src_X];
00552 signed long *xvalue = new signed long[this->Src_X];
00553
00554 if ((xtemp == NULL) || (xvalue == NULL))
00555 {
00556 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Errors))
00557 {
00558 ofConsole.lockCerr() << "ERROR: can't allocate temporary buffers for interpolation scaling !" << endl;
00559 ofConsole.unlockCerr();
00560 }
00561
00562 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y) * this->Frames;
00563 for (int j = 0; j < this->Planes; ++j)
00564 OFBitmanipTemplate<T>::zeroMem(dest[j], count);
00565 }
00566 else
00567 {
00568 for (int j = 0; j < this->Planes; ++j)
00569 {
00570 fp = src[j];
00571 sq = dest[j];
00572 for (Uint32 f = this->Frames; f != 0; --f)
00573 {
00574 for (x = 0; x < this->Src_X; ++x)
00575 xvalue[x] = HALFSCALE_FACTOR;
00576 register unsigned long yfill = SCALE_FACTOR;
00577 register unsigned long yleft = syscale;
00578 register int yneed = 1;
00579 int ysrc = 0;
00580 for (y = 0; y < this->Dest_Y; ++y)
00581 {
00582 if (this->Src_Y == this->Dest_Y)
00583 {
00584 sp = fp;
00585 for (x = this->Src_X, p = sp, q = xtemp; x != 0; --x)
00586 *(q++) = *(p++);
00587 fp += this->Src_X;
00588 }
00589 else
00590 {
00591 while (yleft < yfill)
00592 {
00593 if (yneed && (ysrc < OFstatic_cast(int, this->Src_Y)))
00594 {
00595 sp = fp;
00596 fp += this->Src_X;
00597 ++ysrc;
00598 }
00599 for (x = 0, p = sp; x < this->Src_X; ++x)
00600 xvalue[x] += yleft * OFstatic_cast(signed long, *(p++));
00601 yfill -= yleft;
00602 yleft = syscale;
00603 yneed = 1;
00604 }
00605 if (yneed && (ysrc < OFstatic_cast(int, this->Src_Y)))
00606 {
00607 sp = fp;
00608 fp += this->Src_X;
00609 ++ysrc;
00610 yneed = 0;
00611 }
00612 for (x = 0, p = sp, q = xtemp; x < this->Src_X; ++x)
00613 {
00614 register signed long v = xvalue[x] + yfill * OFstatic_cast(signed long, *(p++));
00615 v /= SCALE_FACTOR;
00616 *(q++) = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00617 xvalue[x] = HALFSCALE_FACTOR;
00618 }
00619 yleft -= yfill;
00620 if (yleft == 0)
00621 {
00622 yleft = syscale;
00623 yneed = 1;
00624 }
00625 yfill = SCALE_FACTOR;
00626 }
00627 if (this->Src_X == this->Dest_X)
00628 {
00629 for (x = this->Dest_X, p = xtemp, q = sq; x != 0; --x)
00630 *(q++) = *(p++);
00631 sq += this->Dest_X;
00632 }
00633 else
00634 {
00635 register signed long v = HALFSCALE_FACTOR;
00636 register unsigned long xfill = SCALE_FACTOR;
00637 register unsigned long xleft;
00638 register int xneed = 0;
00639 q = sq;
00640 for (x = 0, p = xtemp; x < this->Src_X; ++x, ++p)
00641 {
00642 xleft = sxscale;
00643 while (xleft >= xfill)
00644 {
00645 if (xneed)
00646 {
00647 ++q;
00648 v = HALFSCALE_FACTOR;
00649 }
00650 v += xfill * OFstatic_cast(signed long, *p);
00651 v /= SCALE_FACTOR;
00652 *q = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00653 xleft -= xfill;
00654 xfill = SCALE_FACTOR;
00655 xneed = 1;
00656 }
00657 if (xleft > 0)
00658 {
00659 if (xneed)
00660 {
00661 ++q;
00662 v = HALFSCALE_FACTOR;
00663 xneed = 0;
00664 }
00665 v += xleft * OFstatic_cast(signed long, *p);
00666 xfill -= xleft;
00667 }
00668 }
00669 if (xfill > 0)
00670 v += xfill * OFstatic_cast(signed long, *(--p));
00671 if (!xneed)
00672 {
00673 v /= SCALE_FACTOR;
00674 *q = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00675 }
00676 sq += this->Dest_X;
00677 }
00678 }
00679 }
00680 }
00681 }
00682 delete[] xtemp;
00683 delete[] xvalue;
00684 }
00685
00686
00692 void expandPixel(const T *src[],
00693 T *dest[])
00694 {
00695 #ifdef DEBUG
00696 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals))
00697 {
00698 ofConsole.lockCerr() << "INFO: expandPixel with interpolated c't algorithm" << endl;
00699 ofConsole.unlockCerr();
00700 }
00701 #endif
00702 const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
00703 const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
00704 const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
00705 const T *sp;
00706 double bx, ex;
00707 double by, ey;
00708 int bxi, exi;
00709 int byi, eyi;
00710 unsigned long offset;
00711 double value, sum;
00712 double x_part, y_part;
00713 double l_factor, r_factor;
00714 double t_factor, b_factor;
00715 register int xi;
00716 register int yi;
00717 register Uint16 x;
00718 register Uint16 y;
00719 register const T *p;
00720 register T *q;
00721
00722
00723
00724
00725
00726
00727 for (int j = 0; j < this->Planes; ++j)
00728 {
00729 sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00730 q = dest[j];
00731 for (Uint32 f = 0; f < this->Frames; ++f)
00732 {
00733 for (y = 0; y < this->Dest_Y; ++y)
00734 {
00735 by = y_factor * OFstatic_cast(double, y);
00736 ey = y_factor * (OFstatic_cast(double, y) + 1.0);
00737 byi = OFstatic_cast(int, by);
00738 eyi = OFstatic_cast(int, ey);
00739 if (OFstatic_cast(double, eyi) == ey)
00740 --eyi;
00741 y_part = OFstatic_cast(double, eyi) / y_factor;
00742 b_factor = y_part - OFstatic_cast(double, y);
00743 t_factor = (OFstatic_cast(double, y) + 1.0) - y_part;
00744 for (x = 0; x < this->Dest_X; ++x)
00745 {
00746 value = 0;
00747 bx = x_factor * OFstatic_cast(double, x);
00748 ex = x_factor * (OFstatic_cast(double, x) + 1.0);
00749 bxi = OFstatic_cast(int, bx);
00750 exi = OFstatic_cast(int, ex);
00751 if (OFstatic_cast(double, exi) == ex)
00752 --exi;
00753 x_part = OFstatic_cast(double, exi) / x_factor;
00754 l_factor = x_part - OFstatic_cast(double, x);
00755 r_factor = (OFstatic_cast(double, x) + 1.0) - x_part;
00756 offset = OFstatic_cast(unsigned long, byi - 1) * OFstatic_cast(unsigned long, Columns);
00757 for (yi = byi; yi <= eyi; ++yi)
00758 {
00759 offset += Columns;
00760 p = sp + offset + OFstatic_cast(unsigned long, bxi);
00761 for (xi = bxi; xi <= exi; ++xi)
00762 {
00763 sum = OFstatic_cast(double, *(p++));
00764 if (bxi != exi)
00765 {
00766 if (xi == bxi)
00767 sum *= l_factor;
00768 else
00769 sum *= r_factor;
00770 }
00771 if (byi != eyi)
00772 {
00773 if (yi == byi)
00774 sum *= b_factor;
00775 else
00776 sum *= t_factor;
00777 }
00778 value += sum;
00779 }
00780 }
00781 *(q++) = OFstatic_cast(T, value + 0.5);
00782 }
00783 }
00784 sp += f_size;
00785 }
00786 }
00787 }
00788
00789
00795 void reducePixel(const T *src[],
00796 T *dest[])
00797 {
00798 #ifdef DEBUG
00799 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Informationals | DicomImageClass::DL_Warnings))
00800 {
00801 ofConsole.lockCerr() << "INFO: reducePixel with interpolated c't algorithm ... still a little BUGGY !" << endl;
00802 ofConsole.unlockCerr();
00803 }
00804 #endif
00805 const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
00806 const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
00807 const double xy_factor = x_factor * y_factor;
00808 const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
00809 const T *sp;
00810 double bx, ex;
00811 double by, ey;
00812 int bxi, exi;
00813 int byi, eyi;
00814 unsigned long offset;
00815 double value, sum;
00816 double l_factor, r_factor;
00817 double t_factor, b_factor;
00818 register int xi;
00819 register int yi;
00820 register Uint16 x;
00821 register Uint16 y;
00822 register const T *p;
00823 register T *q;
00824
00825
00826
00827
00828
00829
00830 for (int j = 0; j < this->Planes; ++j)
00831 {
00832 sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00833 q = dest[j];
00834 for (Uint32 f = 0; f < this->Frames; ++f)
00835 {
00836 for (y = 0; y < this->Dest_Y; ++y)
00837 {
00838 by = y_factor * OFstatic_cast(double, y);
00839 ey = y_factor * (OFstatic_cast(double, y) + 1.0);
00840 byi = OFstatic_cast(int, by);
00841 eyi = OFstatic_cast(int, ey);
00842 if (OFstatic_cast(double, eyi) == ey)
00843 --eyi;
00844 b_factor = 1 + OFstatic_cast(double, byi) - by;
00845 t_factor = ey - OFstatic_cast(double, eyi);
00846 for (x = 0; x < this->Dest_X; ++x)
00847 {
00848 value = 0;
00849 bx = x_factor * OFstatic_cast(double, x);
00850 ex = x_factor * (OFstatic_cast(double, x) + 1.0);
00851 bxi = OFstatic_cast(int, bx);
00852 exi = OFstatic_cast(int, ex);
00853 if (OFstatic_cast(double, exi) == ex)
00854 --exi;
00855 l_factor = 1 + OFstatic_cast(double, bxi) - bx;
00856 r_factor = ex - OFstatic_cast(double, exi);
00857 offset = OFstatic_cast(unsigned long, byi - 1) * OFstatic_cast(unsigned long, Columns);
00858 for (yi = byi; yi <= eyi; ++yi)
00859 {
00860 offset += Columns;
00861 p = sp + offset + OFstatic_cast(unsigned long, bxi);
00862 for (xi = bxi; xi <= exi; ++xi)
00863 {
00864 sum = OFstatic_cast(double, *(p++)) / xy_factor;
00865 if (xi == bxi)
00866 sum *= l_factor;
00867 else if (xi == exi)
00868 sum *= r_factor;
00869 if (yi == byi)
00870 sum *= b_factor;
00871 else if (yi == eyi)
00872 sum *= t_factor;
00873 value += sum;
00874 }
00875 }
00876 *(q++) = OFstatic_cast(T, value + 0.5);
00877 }
00878 }
00879 sp += f_size;
00880 }
00881 }
00882 }
00883 };
00884
00885 #endif
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984