dcmimgle/include/dcmtk/dcmimgle/discalet.h

00001 /*
00002  *
00003  *  Copyright (C) 1996-2010, OFFIS e.V.
00004  *  All rights reserved.  See COPYRIGHT file for details.
00005  *
00006  *  This software and supporting documentation were developed by
00007  *
00008  *    OFFIS e.V.
00009  *    R&D Division Health
00010  *    Escherweg 2
00011  *    D-26121 Oldenburg, Germany
00012  *
00013  *
00014  *  Module:  dcmimgle
00015  *
00016  *  Author:  Joerg Riesmeier
00017  *
00018  *  Purpose: DicomScaleTemplates (Header)
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-14 13:16:27 $
00022  *  CVS/RCS Revision: $Revision: 1.35 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 
00030 #ifndef DISCALET_H
00031 #define DISCALET_H
00032 
00033 #include "dcmtk/config/osconfig.h"
00034 
00035 #include "dcmtk/ofstd/ofcast.h"
00036 
00037 #include "dcmtk/dcmimgle/ditranst.h"
00038 #include "dcmtk/dcmimgle/dipxrept.h"
00039 
00040 
00041 /*---------------------*
00042  *  macro definitions  *
00043  *---------------------*/
00044 
00045 #define SCALE_FACTOR 4096
00046 #define HALFSCALE_FACTOR 2048
00047 
00048 
00049 /*--------------------*
00050  *  helper functions  *
00051  *--------------------*/
00052 
00053 // help function to set scaling values
00054 static inline void setScaleValues(Uint16 data[],
00055                                   const Uint16 min,
00056                                   const Uint16 max)
00057 {
00058     register Uint16 remainder = max % min;
00059     Uint16 step0 = max / min;
00060     Uint16 step1 = max / min;
00061     if (remainder > OFstatic_cast(Uint16, min / 2))
00062     {
00063         remainder = min - remainder;
00064         ++step0;
00065     } else
00066         ++step1;
00067     const double count = OFstatic_cast(double, min) / (OFstatic_cast(double, remainder) + 1);
00068     register Uint16 i;
00069     register double c = count;
00070     for (i = 0; i < min; ++i)
00071     {
00072         if ((i >= OFstatic_cast(Uint16, c)) && (remainder > 0))
00073         {
00074             --remainder;
00075             c += count;
00076             data[i] = step1;
00077         }
00078         else
00079             data[i] = step0;
00080     }
00081 }
00082 
00083 // cubic value interpolation using Catmull-Rom formula.
00084 // the interpolated pixel lies between the second and the third original pixels
00085 static inline double cubicValue(const double v1,
00086                                 const double v2,
00087                                 const double v3,
00088                                 const double v4,
00089                                 const double dD,
00090                                 const double minVal,
00091                                 const double maxVal)
00092 {
00093     double dVal = 0.5 * ((((-v1 + 3 * v2 - 3 * v3 + v4) * dD + (2 * v1 - 5 * v2 + 4 * v3 - v4)) * dD + (-v1 + v3)) * dD + (v2 + v2));
00094     return (dVal < minVal) ? minVal : ((dVal > maxVal) ? maxVal : dVal);
00095 }
00096 
00097 
00098 /*---------------------*
00099  *  class declaration  *
00100  *---------------------*/
00101 
00105 template<class T>
00106 class DiScaleTemplate
00107   : public DiTransTemplate<T>
00108 {
00109 
00110  public:
00111 
00126     DiScaleTemplate(const int planes,
00127                     const Uint16 columns,           /* resolution of source image */
00128                     const Uint16 rows,
00129                     const signed long left_pos,     /* origin of clipping area */
00130                     const signed long top_pos,
00131                     const Uint16 src_cols,          /* extension of clipping area */
00132                     const Uint16 src_rows,
00133                     const Uint16 dest_cols,         /* extension of destination image */
00134                     const Uint16 dest_rows,
00135                     const Uint32 frames,            /* number of frames */
00136                     const int bits = 0)
00137       : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),
00138         Left(left_pos),
00139         Top(top_pos),
00140         Columns(columns),
00141         Rows(rows)
00142     {
00143     }
00144 
00155     DiScaleTemplate(const int planes,
00156                     const Uint16 src_cols,          /* resolution of source image */
00157                     const Uint16 src_rows,
00158                     const Uint16 dest_cols,         /* resolution of destination image */
00159                     const Uint16 dest_rows,
00160                     const Uint32 frames,            /* number of frames */
00161                     const int bits = 0)
00162       : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames, bits),
00163         Left(0),
00164         Top(0),
00165         Columns(src_cols),
00166         Rows(src_rows)
00167     {
00168     }
00169 
00172     virtual ~DiScaleTemplate()
00173     {
00174     }
00175 
00180     inline int isSigned() const
00181     {
00182         const DiPixelRepresentationTemplate<T> rep;
00183         return rep.isSigned();
00184     }
00185 
00194     void scaleData(const T *src[],
00195                    T *dest[],
00196                    const int interpolate,
00197                    const T value = 0)
00198     {
00199         if ((src != NULL) && (dest != NULL))
00200         {
00201             DCMIMGLE_TRACE("Col/Rows: " << Columns << " " << Rows << OFendl
00202                         << "Left/Top: " << Left << " " << Top << OFendl
00203                         << "Src  X/Y: " << this->Src_X << " " << this->Src_Y << OFendl
00204                         << "Dest X/Y: " << this->Dest_X << " " << this->Dest_Y);
00205             if ((Left + OFstatic_cast(signed long, this->Src_X) <= 0) || (Top + OFstatic_cast(signed long, this->Src_Y) <= 0) ||
00206                 (Left >= OFstatic_cast(signed long, Columns)) || (Top >= OFstatic_cast(signed long, Rows)))
00207             {                                                                         // no image to be displayed
00208                 DCMIMGLE_DEBUG("clipping area is fully outside the image boundaries");
00209                 fillPixel(dest, value);                                               // ... fill bitmap
00210             }
00211             else if ((this->Src_X == this->Dest_X) && (this->Src_Y == this->Dest_Y))  // no scaling
00212             {
00213                 if ((Left == 0) && (Top == 0) && (Columns == this->Src_X) && (Rows == this->Src_Y))
00214                     copyPixel(src, dest);                                             // copying
00215                 else if ((Left >= 0) && (OFstatic_cast(Uint16, Left + this->Src_X) <= Columns) &&
00216                          (Top >= 0) && (OFstatic_cast(Uint16, Top + this->Src_Y) <= Rows))
00217                     clipPixel(src, dest);                                             // clipping
00218                 else
00219                     clipBorderPixel(src, dest, value);                                // clipping (with border)
00220             }
00221             else if ((interpolate == 1) && (this->Bits <= MAX_INTERPOLATION_BITS))
00222                 interpolatePixel(src, dest);                                          // interpolation (pbmplus)
00223             else if ((interpolate == 4) && (this->Dest_X >= this->Src_X) && (this->Dest_Y >= this->Src_Y) &&
00224                      (this->Src_X >= 3) && (this->Src_Y >= 3))
00225                 bicubicPixel(src, dest);                                              // bicubic magnification
00226             else if ((interpolate >= 3) && (this->Dest_X >= this->Src_X) && (this->Dest_Y >= this->Src_Y) &&
00227                      (this->Src_X >= 2) && (this->Src_Y >= 2))
00228                 bilinearPixel(src, dest);                                             // bilinear magnification
00229             else if ((interpolate >= 1) && (this->Dest_X >= this->Src_X) && (this->Dest_Y >= this->Src_Y))
00230                 expandPixel(src, dest);                                               // interpolated expansion (c't)
00231             else if ((interpolate >= 1) && (this->Src_X >= this->Dest_X) && (this->Src_Y >= this->Dest_Y))
00232                 reducePixel(src, dest);                                               // interpolated reduction (c't)
00233             else if ((interpolate >= 1) && (this->Bits <= MAX_INTERPOLATION_BITS))
00234                 interpolatePixel(src, dest);                                          // interpolation (pbmplus), fallback
00235             else if ((this->Dest_X % this->Src_X == 0) && (this->Dest_Y % this->Src_Y == 0))
00236                 replicatePixel(src, dest);                                            // replication
00237             else if ((this->Src_X % this->Dest_X == 0) && (this->Src_Y % this->Dest_Y == 0))
00238                 suppressPixel(src, dest);                                             // supression
00239             else
00240                 scalePixel(src, dest);                                                // general scaling
00241         }
00242     }
00243 
00244  protected:
00245 
00247     const signed long Left;
00249     const signed long Top;
00251     const Uint16 Columns;
00253     const Uint16 Rows;
00254 
00255 
00256  private:
00257 
00264     void clipPixel(const T *src[],
00265                    T *dest[])
00266     {
00267         DCMIMGLE_DEBUG("using clip image to specified area algorithm");
00268         const unsigned long x_feed = Columns - this->Src_X;
00269         const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00270         register Uint16 x;
00271         register Uint16 y;
00272         register const T *p;
00273         register T *q;
00274         for (int j = 0; j < this->Planes; ++j)
00275         {
00276             p = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00277             q = dest[j];
00278             for (unsigned long f = this->Frames; f != 0; --f)
00279             {
00280                 for (y = this->Dest_Y; y != 0; --y)
00281                 {
00282                     for (x = this->Dest_X; x != 0; --x)
00283                         *(q++) = *(p++);
00284                     p += x_feed;
00285                 }
00286                 p += y_feed;
00287             }
00288         }
00289     }
00290 
00297     void clipBorderPixel(const T *src[],
00298                          T *dest[],
00299                          const T value)
00300     {
00301         DCMIMGLE_DEBUG("using clip image to specified area and add border algorithm");
00302         const Uint16 s_left = (Left > 0) ? OFstatic_cast(Uint16, Left) : 0;
00303         const Uint16 s_top = (Top > 0) ? OFstatic_cast(Uint16, Top) : 0;
00304         const Uint16 d_left = (Left < 0 ? OFstatic_cast(Uint16, -Left) : 0);
00305         const Uint16 d_top = (Top < 0) ? OFstatic_cast(Uint16, -Top) : 0;
00306         const Uint16 d_right = (OFstatic_cast(unsigned long, this->Src_X) + OFstatic_cast(unsigned long, s_left) <
00307                                 OFstatic_cast(unsigned long, Columns) + OFstatic_cast(unsigned long, d_left)) ?
00308                                (this->Src_X - 1) : (Columns + d_left - s_left - 1);
00309         const Uint16 d_bottom = (OFstatic_cast(unsigned long, this->Src_Y) + OFstatic_cast(unsigned long, s_top) <
00310                                  OFstatic_cast(unsigned long, Rows) + OFstatic_cast(unsigned long, d_top)) ?
00311                                 (this->Src_Y - 1) : (Rows + d_top - s_top - 1);
00312         const Uint16 x_count = d_right - d_left + 1;
00313         const Uint16 y_count = d_bottom - d_top + 1;
00314         const unsigned long s_start = OFstatic_cast(unsigned long, s_top) * OFstatic_cast(unsigned long, Columns) + s_left;
00315         const unsigned long x_feed = Columns - x_count;
00316         const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - y_count) * Columns;
00317         const unsigned long t_feed = OFstatic_cast(unsigned long, d_top) * OFstatic_cast(unsigned long, this->Src_X);
00318         const unsigned long b_feed = OFstatic_cast(unsigned long, this->Src_Y - d_bottom - 1) * OFstatic_cast(unsigned long, this->Src_X);
00319 
00320         /*
00321          *  The approach is to divide the destination image in up to four areas outside the source image
00322          *  plus one area for the source image. The for and while loops are scanning linearly over the
00323          *  destination image and setting the appropriate value depending on the current area. This is
00324          *  different from most of the other algorithms in this toolkit where the source image is scanned
00325          *  linearly.
00326          */
00327         register Uint16 x;
00328         register Uint16 y;
00329         register unsigned long i;
00330         register const T *p;
00331         register T *q;
00332         for (int j = 0; j < this->Planes; ++j)
00333         {
00334             p = src[j] + s_start;
00335             q = dest[j];
00336             for (unsigned long f = this->Frames; f != 0; --f)
00337             {
00338                 for (i = t_feed; i != 0; --i)               // top
00339                     *(q++) = value;
00340                 for (y = y_count; y != 0; --y)              // middle part:
00341                 {
00342                     x = 0;
00343                     while (x < d_left)                      // - left
00344                     {
00345                         *(q++) = value;
00346                         ++x;
00347                     }
00348                     while (x <= d_right)                    // - middle
00349                     {
00350                         *(q++) = *(p++);
00351                         ++x;
00352                     }
00353                     while (x < this->Src_X)                 // - right
00354                     {
00355                         *(q++) = value;
00356                         ++x;
00357                     }
00358                     p += x_feed;
00359                 }
00360                 for (i = b_feed; i != 0; --i)               // bottom
00361                     *(q++) = value;
00362                 p += y_feed;
00363             }
00364         }
00365     }
00366 
00373     void replicatePixel(const T *src[],
00374                         T *dest[])
00375     {
00376         DCMIMGLE_DEBUG("using replicate pixel scaling algorithm without interpolation");
00377         const Uint16 x_factor = this->Dest_X / this->Src_X;
00378         const Uint16 y_factor = this->Dest_Y / this->Src_Y;
00379         const unsigned long x_feed = Columns;
00380         const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00381         const T *sp;
00382         register Uint16 x;
00383         register Uint16 y;
00384         register Uint16 dx;
00385         register Uint16 dy;
00386         register const T *p;
00387         register T *q;
00388         register T value;
00389         for (int j = 0; j < this->Planes; ++j)
00390         {
00391             sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00392             q = dest[j];
00393             for (unsigned long f = this->Frames; f != 0; --f)
00394             {
00395                 for (y = this->Src_Y; y != 0; --y)
00396                 {
00397                     for (dy = y_factor; dy != 0; --dy)
00398                     {
00399                         for (x = this->Src_X, p = sp; x != 0; --x)
00400                         {
00401                             value = *(p++);
00402                             for (dx = x_factor; dx != 0; --dx)
00403                                 *(q++) = value;
00404                         }
00405                     }
00406                     sp += x_feed;
00407                 }
00408                 sp += y_feed;
00409             }
00410         }
00411     }
00412 
00419     void suppressPixel(const T *src[],
00420                        T *dest[])
00421     {
00422         DCMIMGLE_DEBUG("using suppress pixel scaling algorithm without interpolation");
00423         const unsigned int x_divisor = this->Src_X / this->Dest_X;
00424         const unsigned long x_feed = OFstatic_cast(unsigned long, this->Src_Y / this->Dest_Y) * OFstatic_cast(unsigned long, Columns) - this->Src_X;
00425         const unsigned long y_feed = OFstatic_cast(unsigned long, Rows - this->Src_Y) * OFstatic_cast(unsigned long, Columns);
00426         register Uint16 x;
00427         register Uint16 y;
00428         register const T *p;
00429         register T *q;
00430         for (int j = 0; j < this->Planes; ++j)
00431         {
00432             p = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00433             q = dest[j];
00434             for (unsigned long f = this->Frames; f != 0; --f)
00435             {
00436                 for (y = this->Dest_Y; y != 0; --y)
00437                 {
00438                     for (x = this->Dest_X; x != 0; --x)
00439                     {
00440                         *(q++) = *p;
00441                         p += x_divisor;
00442                     }
00443                     p += x_feed;
00444                 }
00445                 p += y_feed;
00446             }
00447         }
00448     }
00449 
00456     void scalePixel(const T *src[],
00457                     T *dest[])
00458     {
00459         DCMIMGLE_DEBUG("using free scaling algorithm without interpolation");
00460         const Uint16 xmin = (this->Dest_X < this->Src_X) ? this->Dest_X : this->Src_X;  // minimum width
00461         const Uint16 ymin = (this->Dest_Y < this->Src_Y) ? this->Dest_Y : this->Src_Y;  // minimum height
00462         Uint16 *x_step = new Uint16[xmin];
00463         Uint16 *y_step = new Uint16[ymin];
00464         Uint16 *x_fact = new Uint16[xmin];
00465         Uint16 *y_fact = new Uint16[ymin];
00466 
00467        /*
00468         *  Approach: If one pixel line has to be added or removed it is taken from the middle of the image (1/2).
00469         *  For two lines it is at 1/3 and 2/3 of the image and so on. It sounds easy but it was a hard job ;-)
00470         */
00471 
00472         if ((x_step != NULL) && (y_step != NULL) && (x_fact != NULL) && (y_fact != NULL))
00473         {
00474             register Uint16 x;
00475             register Uint16 y;
00476             if (this->Dest_X < this->Src_X)
00477                 setScaleValues(x_step, this->Dest_X, this->Src_X);
00478             else if (this->Dest_X > this->Src_X)
00479                 setScaleValues(x_fact, this->Src_X, this->Dest_X);
00480             if (this->Dest_X <= this->Src_X)
00481                 OFBitmanipTemplate<Uint16>::setMem(x_fact, 1, xmin);  // initialize with default values
00482             if (this->Dest_X >= this->Src_X)
00483                 OFBitmanipTemplate<Uint16>::setMem(x_step, 1, xmin);  // initialize with default values
00484             x_step[xmin - 1] += Columns - this->Src_X;                // skip to next line
00485             if (this->Dest_Y < this->Src_Y)
00486                 setScaleValues(y_step, this->Dest_Y, this->Src_Y);
00487             else if (this->Dest_Y > this->Src_Y)
00488                 setScaleValues(y_fact, this->Src_Y, this->Dest_Y);
00489             if (this->Dest_Y <= this->Src_Y)
00490                 OFBitmanipTemplate<Uint16>::setMem(y_fact, 1, ymin);  // initialize with default values
00491             if (this->Dest_Y >= this->Src_Y)
00492                 OFBitmanipTemplate<Uint16>::setMem(y_step, 1, ymin);  // initialize with default values
00493             y_step[ymin - 1] += Rows - this->Src_Y;                   // skip to next frame
00494             const T *sp;
00495             register Uint16 dx;
00496             register Uint16 dy;
00497             register const T *p;
00498             register T *q;
00499             register T value;
00500             for (int j = 0; j < this->Planes; ++j)
00501             {
00502                 sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00503                 q = dest[j];
00504                 for (unsigned long f = 0; f < this->Frames; ++f)
00505                 {
00506                     for (y = 0; y < ymin; ++y)
00507                     {
00508                         for (dy = 0; dy < y_fact[y]; ++dy)
00509                         {
00510                             for (x = 0, p = sp; x < xmin; ++x)
00511                             {
00512                                 value = *p;
00513                                 for (dx = 0; dx < x_fact[x]; ++dx)
00514                                     *(q++) = value;
00515                                 p += x_step[x];
00516                             }
00517                         }
00518                         sp += OFstatic_cast(unsigned long, y_step[y]) * OFstatic_cast(unsigned long, Columns);
00519                     }
00520                 }
00521             }
00522         }
00523         delete[] x_step;
00524         delete[] y_step;
00525         delete[] x_fact;
00526         delete[] y_fact;
00527     }
00528 
00529 
00535     void interpolatePixel(const T *src[],
00536                           T *dest[])
00537     {
00538         DCMIMGLE_DEBUG("using scaling algorithm with interpolation from pbmplus toolkit");
00539         if ((this->Src_X != Columns) || (this->Src_Y != Rows))
00540         {
00541             DCMIMGLE_ERROR("interpolated scaling and clipping at the same time not implemented ... ignoring clipping region");
00542             this->Src_X = Columns;            // temporarily removed 'const' for 'Src_X' in class 'DiTransTemplate'
00543             this->Src_Y = Rows;               //                             ... 'Src_Y' ...
00544         }
00545 
00546         /*
00547          *   based on scaling algorithm from "Extended Portable Bitmap Toolkit" (pbmplus10dec91)
00548          *   (adapted to be used with signed pixel representation, inverse images - mono1,
00549          *    various bit depths, multi-frame and multi-plane/color images)
00550          */
00551 
00552         register Uint16 x;
00553         register Uint16 y;
00554         register const T *p;
00555         register T *q;
00556         const T *sp = NULL;                         // initialization avoids compiler warning
00557         const T *fp;
00558         T *sq;
00559 
00560         const unsigned long sxscale = OFstatic_cast(unsigned long, (OFstatic_cast(double, this->Dest_X) / OFstatic_cast(double, this->Src_X)) * SCALE_FACTOR);
00561         const unsigned long syscale = OFstatic_cast(unsigned long, (OFstatic_cast(double, this->Dest_Y) / OFstatic_cast(double, this->Src_Y)) * SCALE_FACTOR);
00562         const signed long maxvalue = DicomImageClass::maxval(this->Bits - isSigned());
00563 
00564         T *xtemp = new T[this->Src_X];
00565         signed long *xvalue = new signed long[this->Src_X];
00566 
00567         if ((xtemp == NULL) || (xvalue == NULL))
00568         {
00569             DCMIMGLE_ERROR("can't allocate temporary buffers for interpolation scaling");
00570             clearPixel(dest);
00571         } else {
00572             for (int j = 0; j < this->Planes; ++j)
00573             {
00574                 fp = src[j];
00575                 sq = dest[j];
00576                 for (unsigned long f = this->Frames; f != 0; --f)
00577                 {
00578                     for (x = 0; x < this->Src_X; ++x)
00579                         xvalue[x] = HALFSCALE_FACTOR;
00580                     register unsigned long yfill = SCALE_FACTOR;
00581                     register unsigned long yleft = syscale;
00582                     register int yneed = 1;
00583                     int ysrc = 0;
00584                     for (y = 0; y < this->Dest_Y; ++y)
00585                     {
00586                         if (this->Src_Y == this->Dest_Y)
00587                         {
00588                             sp = fp;
00589                             for (x = this->Src_X, p = sp, q = xtemp; x != 0; --x)
00590                                 *(q++) = *(p++);
00591                             fp += this->Src_X;
00592                         }
00593                         else
00594                         {
00595                             while (yleft < yfill)
00596                             {
00597                                 if (yneed && (ysrc < OFstatic_cast(int, this->Src_Y)))
00598                                 {
00599                                     sp = fp;
00600                                     fp += this->Src_X;
00601                                     ++ysrc;
00602                                 }
00603                                 for (x = 0, p = sp; x < this->Src_X; ++x)
00604                                     xvalue[x] += yleft * OFstatic_cast(signed long, *(p++));
00605                                 yfill -= yleft;
00606                                 yleft = syscale;
00607                                 yneed = 1;
00608                             }
00609                             if (yneed && (ysrc < OFstatic_cast(int, this->Src_Y)))
00610                             {
00611                                 sp = fp;
00612                                 fp += this->Src_X;
00613                                 ++ysrc;
00614                                 yneed = 0;
00615                             }
00616                             register signed long v;
00617                             for (x = 0, p = sp, q = xtemp; x < this->Src_X; ++x)
00618                             {
00619                                 v = xvalue[x] + yfill * OFstatic_cast(signed long, *(p++));
00620                                 v /= SCALE_FACTOR;
00621                                 *(q++) = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00622                                 xvalue[x] = HALFSCALE_FACTOR;
00623                             }
00624                             yleft -= yfill;
00625                             if (yleft == 0)
00626                             {
00627                                 yleft = syscale;
00628                                 yneed = 1;
00629                             }
00630                             yfill = SCALE_FACTOR;
00631                         }
00632                         if (this->Src_X == this->Dest_X)
00633                         {
00634                             for (x = this->Dest_X, p = xtemp, q = sq; x != 0; --x)
00635                                 *(q++) = *(p++);
00636                             sq += this->Dest_X;
00637                         }
00638                         else
00639                         {
00640                             register signed long v = HALFSCALE_FACTOR;
00641                             register unsigned long xfill = SCALE_FACTOR;
00642                             register unsigned long xleft;
00643                             register int xneed = 0;
00644                             q = sq;
00645                             for (x = 0, p = xtemp; x < this->Src_X; ++x, ++p)
00646                             {
00647                                 xleft = sxscale;
00648                                 while (xleft >= xfill)
00649                                 {
00650                                     if (xneed)
00651                                     {
00652                                         ++q;
00653                                         v = HALFSCALE_FACTOR;
00654                                     }
00655                                     v += xfill * OFstatic_cast(signed long, *p);
00656                                     v /= SCALE_FACTOR;
00657                                     *q = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00658                                     xleft -= xfill;
00659                                     xfill = SCALE_FACTOR;
00660                                     xneed = 1;
00661                                 }
00662                                 if (xleft > 0)
00663                                 {
00664                                     if (xneed)
00665                                     {
00666                                         ++q;
00667                                         v = HALFSCALE_FACTOR;
00668                                         xneed = 0;
00669                                     }
00670                                     v += xleft * OFstatic_cast(signed long, *p);
00671                                     xfill -= xleft;
00672                                 }
00673                             }
00674                             if (xfill > 0)
00675                                 v += xfill * OFstatic_cast(signed long, *(--p));
00676                             if (!xneed)
00677                             {
00678                                 v /= SCALE_FACTOR;
00679                                 *q = OFstatic_cast(T, (v > maxvalue) ? maxvalue : v);
00680                             }
00681                             sq += this->Dest_X;
00682                         }
00683                     }
00684                 }
00685             }
00686         }
00687         delete[] xtemp;
00688         delete[] xvalue;
00689     }
00690 
00691 
00697     void expandPixel(const T *src[],
00698                      T *dest[])
00699     {
00700         DCMIMGLE_DEBUG("using expand pixel scaling algorithm with interpolation from c't magazine");
00701         const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
00702         const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
00703         const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
00704         const T *sp;
00705         double bx, ex;
00706         double by, ey;
00707         int bxi, exi;
00708         int byi, eyi;
00709         unsigned long offset;
00710         double value, sum;
00711         double x_part, y_part;
00712         double l_factor, r_factor;
00713         double t_factor, b_factor;
00714         register int xi;
00715         register int yi;
00716         register Uint16 x;
00717         register Uint16 y;
00718         register const T *p;
00719         register T *q;
00720 
00721         /*
00722          *   based on scaling algorithm from "c't - Magazin fuer Computertechnik" (c't 11/94)
00723          *   (adapted to be used with signed pixel representation, inverse images - mono1,
00724          *    various bit depths, multi-frame and multi-plane/color images, combined clipping/scaling)
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 (unsigned long 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) * OFstatic_cast(unsigned long, Columns);
00757                         for (yi = byi; yi <= eyi; ++yi)
00758                         {
00759                             p = sp + offset + bxi;
00760                             for (xi = bxi; xi <= exi; ++xi)
00761                             {
00762                                 sum = OFstatic_cast(double, *(p++));
00763                                 if (bxi != exi)
00764                                 {
00765                                     if (xi == bxi)
00766                                         sum *= l_factor;
00767                                     else
00768                                         sum *= r_factor;
00769                                 }
00770                                 if (byi != eyi)
00771                                 {
00772                                     if (yi == byi)
00773                                         sum *= b_factor;
00774                                     else
00775                                         sum *= t_factor;
00776                                 }
00777                                 value += sum;
00778                             }
00779                             offset += Columns;
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         DCMIMGLE_DEBUG("using reduce pixel scaling algorithm with interpolation from c't magazine");
00799         const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
00800         const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
00801         const double xy_factor = x_factor * y_factor;
00802         const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
00803         const T *sp;
00804         double bx, ex;
00805         double by, ey;
00806         int bxi, exi;
00807         int byi, eyi;
00808         unsigned long offset;
00809         double value, sum;
00810         double l_factor, r_factor;
00811         double t_factor, b_factor;
00812         register int xi;
00813         register int yi;
00814         register Uint16 x;
00815         register Uint16 y;
00816         register const T *p;
00817         register T *q;
00818 
00819         /*
00820          *   based on scaling algorithm from "c't - Magazin fuer Computertechnik" (c't 11/94)
00821          *   (adapted to be used with signed pixel representation, inverse images - mono1,
00822          *    various bit depths, multi-frame and multi-plane/color images, combined clipping/scaling)
00823          */
00824 
00825         for (int j = 0; j < this->Planes; ++j)
00826         {
00827             sp = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00828             q = dest[j];
00829             for (unsigned long f = 0; f < this->Frames; ++f)
00830             {
00831                 for (y = 0; y < this->Dest_Y; ++y)
00832                 {
00833                     by = y_factor * OFstatic_cast(double, y);
00834                     ey = y_factor * (OFstatic_cast(double, y) + 1.0);
00835                     byi = OFstatic_cast(int, by);
00836                     eyi = OFstatic_cast(int, ey);
00837                     if (OFstatic_cast(double, eyi) == ey)
00838                         --eyi;
00839                     b_factor = 1 + OFstatic_cast(double, byi) - by;
00840                     t_factor = ey - OFstatic_cast(double, eyi);
00841                     for (x = 0; x < this->Dest_X; ++x)
00842                     {
00843                         value = 0;
00844                         bx = x_factor * OFstatic_cast(double, x);
00845                         ex = x_factor * (OFstatic_cast(double, x) + 1.0);
00846                         bxi = OFstatic_cast(int, bx);
00847                         exi = OFstatic_cast(int, ex);
00848                         if (OFstatic_cast(double, exi) == ex)
00849                             --exi;
00850                         l_factor = 1 + OFstatic_cast(double, bxi) - bx;
00851                         r_factor = ex - OFstatic_cast(double, exi);
00852                         offset = OFstatic_cast(unsigned long, byi) * OFstatic_cast(unsigned long, Columns);
00853                         for (yi = byi; yi <= eyi; ++yi)
00854                         {
00855                             p = sp + offset + bxi;
00856                             for (xi = bxi; xi <= exi; ++xi)
00857                             {
00858                                 sum = OFstatic_cast(double, *(p++)) / xy_factor;
00859                                 if (xi == bxi)
00860                                     sum *= l_factor;
00861                                 else if (xi == exi)
00862                                     sum *= r_factor;
00863                                 if (yi == byi)
00864                                     sum *= b_factor;
00865                                 else if (yi == eyi)
00866                                     sum *= t_factor;
00867                                 value += sum;
00868                             }
00869                             offset += Columns;
00870                         }
00871                         *(q++) = OFstatic_cast(T, value + 0.5);
00872                     }
00873                 }
00874                 sp += f_size;
00875             }
00876         }
00877     }
00878 
00884     void bilinearPixel(const T *src[],
00885                        T *dest[])
00886     {
00887         DCMIMGLE_DEBUG("using magnification algorithm with bilinear interpolation contributed by Eduard Stanescu");
00888         const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
00889         const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
00890         const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
00891         const unsigned long l_offset = OFstatic_cast(unsigned long, this->Src_Y - 1) * OFstatic_cast(unsigned long, this->Dest_X);
00892         register Uint16 x;
00893         register Uint16 y;
00894         register T *pD;
00895         register T *pCurrTemp;
00896         register const T *pCurrSrc;
00897         Uint16 nSrcIndex;
00898         double dOff;
00899         T *pT;
00900         const T *pS;
00901         const T *pF;
00902 
00903         // buffer used for storing temporarily the interpolated lines
00904         T *pTemp = new T[OFstatic_cast(unsigned long, this->Src_Y) * OFstatic_cast(unsigned long, this->Dest_X)];
00905         if (pTemp == NULL)
00906         {
00907             DCMIMGLE_ERROR("can't allocate temporary buffer for interpolation scaling");
00908             clearPixel(dest);
00909         } else {
00910 
00911             /*
00912              *   based on scaling algorithm contributed by Eduard Stanescu
00913              *   (adapted to be used with signed pixel representation, inverse images - mono1,
00914              *    various bit depths, multi-frame multi-plane/color images, combined clipping/scaling)
00915              */
00916 
00917             for (int j = 0; j < this->Planes; ++j)
00918             {
00919                 pF = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
00920                 pD = dest[j];
00921                 for (unsigned long f = this->Frames; f != 0; --f)
00922                 {
00923                     pT = pCurrTemp = pTemp;
00924                     pS = pCurrSrc = pF;
00925                     // first, interpolate the columns:
00926                     // column 0, just copy the source data column 0
00927                     for (y = this->Src_Y; y != 0; --y)
00928                     {
00929                         *(pCurrTemp) = *(pCurrSrc);
00930                         pCurrSrc += Columns;
00931                         pCurrTemp += this->Dest_X;
00932                     }
00933                     pCurrSrc = pS;
00934                     nSrcIndex = 0;
00935                     // column 1 to column Dest_X - 1
00936                     for (x = 1; x < this->Dest_X - 1; ++x)
00937                     {
00938                         pCurrTemp = ++pT;
00939                         dOff = x * x_factor - nSrcIndex;
00940                         dOff = (1.0 < dOff) ? 1.0 : dOff;
00941                         for (y = 0; y < this->Src_Y; ++y)
00942                         {
00943                             *(pCurrTemp) = OFstatic_cast(T, *(pCurrSrc) + (*(pCurrSrc + 1) - *(pCurrSrc)) * dOff);
00944                             pCurrSrc += Columns;
00945                             pCurrTemp += this->Dest_X;
00946                         }
00947                         // don't go beyond the source data
00948                         if ((nSrcIndex < this->Src_X - 2) &&  (x * x_factor >= nSrcIndex + 1))
00949                         {
00950                             pS++;
00951                             nSrcIndex++;
00952                         }
00953                         pCurrSrc = pS;
00954                     }
00955                     pCurrTemp = ++pT;
00956                     // last column, just copy the source data column Src_X
00957                     for (y = this->Src_Y; y != 0; --y)
00958                     {
00959                         *(pCurrTemp) = *(pCurrSrc);
00960                         pCurrSrc += Columns;
00961                         pCurrTemp += this->Dest_X;
00962                     }
00963                     // now the columns are interpolated in temp buffer, so interpolate the lines
00964                     pT = pCurrTemp = pTemp;
00965                     // line 0, just copy the temp buffer line 0
00966                     for (x = this->Dest_X; x != 0; --x)
00967                        *(pD++) = *(pCurrTemp++);
00968                     nSrcIndex = 0;
00969                     pCurrTemp = pTemp;
00970                     for (y = 1; y < this->Dest_Y - 1; ++y)
00971                     {
00972                         dOff = y * y_factor - nSrcIndex;
00973                         dOff = (1.0 < dOff) ? 1.0 : dOff;
00974                         for (x = this->Dest_X; x != 0; --x)
00975                         {
00976                             *(pD++) = OFstatic_cast(T, *(pCurrTemp) + (*(pCurrTemp + this->Dest_X) - *(pCurrTemp)) * dOff);
00977                             pCurrTemp++;
00978                         }
00979                         // don't go beyond the source data
00980                         if ((nSrcIndex < this->Src_Y - 2) && (y * y_factor >= nSrcIndex + 1))
00981                         {
00982                             pT += this->Dest_X;
00983                             nSrcIndex++;
00984                         }
00985                         pCurrTemp = pT;
00986                     }
00987                     // the last line, just copy the temp buffer line Src_X
00988                     pCurrTemp = pTemp + l_offset;
00989                     for (x = this->Dest_X; x != 0; --x)
00990                         *(pD++) = *(pCurrTemp++);
00991                     // skip to next frame
00992                     pF += f_size;
00993                 }
00994             }
00995         }
00996         delete[] pTemp;
00997     }
00998 
01004     void bicubicPixel(const T *src[],
01005                       T *dest[])
01006     {
01007         DCMIMGLE_DEBUG("using magnification algorithm with bicubic interpolation contributed by Eduard Stanescu");
01008         const double minVal = (isSigned()) ? -OFstatic_cast(double, DicomImageClass::maxval(this->Bits - 1, 0)) : 0.0;
01009         const double maxVal = OFstatic_cast(double, DicomImageClass::maxval(this->Bits - isSigned()));
01010         const double x_factor = OFstatic_cast(double, this->Src_X) / OFstatic_cast(double, this->Dest_X);
01011         const double y_factor = OFstatic_cast(double, this->Src_Y) / OFstatic_cast(double, this->Dest_Y);
01012         const Uint16 xDelta = OFstatic_cast(Uint16, 1 / x_factor);
01013         const Uint16 yDelta = OFstatic_cast(Uint16, 1 / y_factor);
01014         const unsigned long f_size = OFstatic_cast(unsigned long, Rows) * OFstatic_cast(unsigned long, Columns);
01015         const unsigned long l_offset = OFstatic_cast(unsigned long, this->Src_Y - 1) * OFstatic_cast(unsigned long, this->Dest_X);
01016         register Uint16 x;
01017         register Uint16 y;
01018         register T *pD;
01019         register T *pCurrTemp;
01020         register const T *pCurrSrc;
01021         Uint16 nSrcIndex;
01022         double dOff;
01023         T *pT;
01024         const T *pS;
01025         const T *pF;
01026 
01027         // buffer used for storing temporarily the interpolated lines
01028         T *pTemp = pT = pCurrTemp = new T[OFstatic_cast(unsigned long, this->Src_Y) * OFstatic_cast(unsigned long, this->Dest_X)];
01029         if (pTemp == NULL)
01030         {
01031             DCMIMGLE_ERROR("can't allocate temporary buffer for interpolation scaling");
01032             clearPixel(dest);
01033         } else {
01034 
01035             /*
01036              *   based on scaling algorithm contributed by Eduard Stanescu
01037              *   (adapted to be used with signed pixel representation, inverse images - mono1,
01038              *    various bit depths, multi-frame multi-plane/color images, combined clipping/scaling)
01039              */
01040 
01041             for (int j = 0; j < this->Planes; ++j)
01042             {
01043                 pF = src[j] + OFstatic_cast(unsigned long, Top) * OFstatic_cast(unsigned long, Columns) + Left;
01044                 pD = dest[j];
01045                 for (unsigned long f = this->Frames; f != 0; --f)
01046                 {
01047                     pT = pCurrTemp = pTemp;
01048                     pS = pCurrSrc = pF;
01049                     // first, interpolate the columns:
01050                     // column 0, just copy the source data column 0
01051                     for (y = this->Src_Y; y != 0; --y)
01052                     {
01053                         *(pCurrTemp) = *(pCurrSrc);
01054                         pCurrSrc += Columns;
01055                         pCurrTemp += this->Dest_X;
01056                     }
01057                     pCurrSrc = pS;
01058                     // for the next few columns, linear interpolation
01059                     for (x = 1; x < xDelta + 1; ++x)
01060                     {
01061                         pCurrSrc = pS;
01062                         pCurrTemp = ++pT;
01063                         dOff = x * x_factor;
01064                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01065                         for (y = this->Src_Y; y != 0; --y)
01066                         {
01067                             *(pCurrTemp) = OFstatic_cast(T, *(pCurrSrc) + (*(pCurrSrc + 1) - *(pCurrSrc)) * dOff);
01068                             pCurrSrc += Columns;
01069                             pCurrTemp += this->Dest_X;
01070                         }
01071                     }
01072                     nSrcIndex = 1;
01073                     pCurrSrc = ++pS;
01074                     // the majority of the columns
01075                     for (x = xDelta + 1; x < this->Dest_X - 2 * xDelta; ++x)
01076                     {
01077                         pCurrTemp = ++pT;
01078                         dOff = x * x_factor - nSrcIndex;
01079                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01080                         for (y = this->Src_Y; y != 0; --y)
01081                         {
01082                             *(pCurrTemp) = OFstatic_cast(T, cubicValue(*(pCurrSrc - 1), *(pCurrSrc), *(pCurrSrc + 1), *(pCurrSrc + 2), dOff, minVal, maxVal));
01083                             pCurrSrc += Columns;
01084                             pCurrTemp += this->Dest_X;
01085                         }
01086                         // don't go beyond the source data
01087                         if ((nSrcIndex < this->Src_X - 3) && (x * x_factor >= nSrcIndex + 1))
01088                         {
01089                             pS++;
01090                             nSrcIndex++;
01091                         }
01092                         pCurrSrc = pS;
01093                     }
01094                     // last few columns except the very last one, linear interpolation
01095                     for (x = this->Dest_X - 2 * xDelta; x < this->Dest_X - 1; ++x)
01096                     {
01097                         pCurrTemp = ++pT;
01098                         dOff = x * x_factor - nSrcIndex;
01099                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01100                         for (y = this->Src_Y; y != 0; --y)
01101                         {
01102                             *(pCurrTemp) = OFstatic_cast(T, *(pCurrSrc) + (*(pCurrSrc + 1) - *(pCurrSrc)) * dOff);
01103                             pCurrSrc += Columns;
01104                             pCurrTemp += this->Dest_X;
01105                         }
01106                         // don't go beyond the source data
01107                         if ((nSrcIndex < this->Src_X - 2) && (x * x_factor >= nSrcIndex + 1))
01108                         {
01109                             pS++;
01110                             nSrcIndex++;
01111                         }
01112                         pCurrSrc = pS;
01113                     }
01114                     // last column, just copy the source data column Src_X
01115                     pCurrTemp = pTemp + this->Dest_X - 1;
01116                     pCurrSrc = pF + this->Src_X - 1;
01117                     for (y = this->Src_Y; y != 0; --y)
01118                     {
01119                         *(pCurrTemp) = *(pCurrSrc);
01120                         pCurrSrc += Columns;
01121                         pCurrTemp += this->Dest_X;
01122                     }
01123                     // now the columns are interpolated in temp buffer, so interpolate the lines
01124                     pT = pCurrTemp = pTemp;
01125                     // line 0, just copy the temp buffer line 0
01126                     for (x = this->Dest_X; x != 0; --x)
01127                         *(pD++) = *(pCurrTemp++);
01128                     // for the next few lines, linear interpolation between line 0 and 1 of the temp buffer
01129                     for (y = 1; y < yDelta + 1; ++y)
01130                     {
01131                         pCurrTemp = pTemp;
01132                         dOff = y * y_factor;
01133                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01134                         for (x = this->Dest_X; x != 0; --x)
01135                         {
01136                             *(pD++) = OFstatic_cast(T, *(pCurrTemp) + (*(pCurrTemp + this->Dest_X) - *(pCurrTemp)) * dOff);
01137                             pCurrTemp++;
01138                         }
01139                     }
01140                     nSrcIndex = 1;
01141                     pCurrTemp = pT = pTemp + this->Dest_X;
01142                     for (y = yDelta + 1; y < this->Dest_Y - yDelta - 1; ++y)
01143                     {
01144                         dOff = y * y_factor - nSrcIndex;
01145                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01146                         for (x = this->Dest_X; x != 0; --x)
01147                         {
01148                             *(pD++) = OFstatic_cast(T, cubicValue(*(pCurrTemp - this->Dest_X),*(pCurrTemp), *(pCurrTemp + this->Dest_X),
01149                                                                   *(pCurrTemp + this->Dest_X + this->Dest_X), dOff, minVal, maxVal));
01150                             pCurrTemp++;
01151                         }
01152                         // don't go beyond the source data
01153                         if ((nSrcIndex < this->Src_Y - 3) && (y * y_factor >= nSrcIndex + 1))
01154                         {
01155                             pT += this->Dest_X;
01156                             nSrcIndex++;
01157                         }
01158                         pCurrTemp = pT;
01159                     }
01160                     // the last few lines except the very last one, linear interpolation in between the second last and the last lines
01161                     pCurrTemp = pT = pTemp + OFstatic_cast(unsigned long, this->Src_Y - 2) * OFstatic_cast(unsigned long, this->Dest_X);
01162                     for (y = this->Dest_Y - yDelta - 1; y < this->Dest_Y - 1; ++y)
01163                     {
01164                         dOff = y * y_factor - nSrcIndex;
01165                         dOff = (1.0 < dOff) ? 1.0 : dOff;
01166                         for (x = this->Dest_X; x != 0; --x)
01167                         {
01168                             *(pD++) = OFstatic_cast(T, *(pCurrTemp) + (*(pCurrTemp + this->Dest_X) - *(pCurrTemp)) * dOff);
01169                             pCurrTemp++;
01170                         }
01171                         pCurrTemp = pT;
01172                     }
01173                     // the the last line, just copy the temp buffer line Src_X
01174                     pCurrTemp = pTemp + l_offset;
01175                     for (x = this->Dest_X; x != 0; --x)
01176                         *(pD++) = *(pCurrTemp++);
01177                     // skip to next frame
01178                     pF += f_size;
01179                 }
01180             }
01181         }
01182         delete[] pTemp;
01183     }
01184 };
01185 
01186 #endif
01187 
01188 
01189 /*
01190  *
01191  * CVS/RCS Log:
01192  * $Log: discalet.h,v $
01193  * Revision 1.35  2010-10-14 13:16:27  joergr
01194  * Updated copyright header. Added reference to COPYRIGHT file.
01195  *
01196  * Revision 1.34  2010-03-01 09:08:47  uli
01197  * Removed some unnecessary include directives in the headers.
01198  *
01199  * Revision 1.33  2009-11-25 15:49:25  joergr
01200  * Removed inclusion of header file "ofconsol.h".
01201  *
01202  * Revision 1.32  2009-10-28 14:38:17  joergr
01203  * Fixed minor issues in log output.
01204  *
01205  * Revision 1.31  2009-10-28 09:53:40  uli
01206  * Switched to logging mechanism provided by the "new" oflog module.
01207  *
01208  * Revision 1.30  2008-05-21 10:12:27  joergr
01209  * Fixed bug in c't scaling algorithm (expandPixel) which could cause a crash
01210  * (possible integer underflow/overflow).
01211  *
01212  * Revision 1.29  2008-05-20 15:26:45  joergr
01213  * Fixed small issue in bicubic image scaling algorithm (in clipping mode).
01214  *
01215  * Revision 1.28  2008-05-20 13:16:38  joergr
01216  * Fixed issue with signed pixel data in bicubic interpolation algorithm.
01217  * Use the pbmplus scaling algorithm as the second best fallback if the c't
01218  * algorithm cannot be used (e.g. up and down-scaling on different axes).
01219  * Replaced macro call by inline function (approx. same performance).
01220  *
01221  * Revision 1.27  2008-05-20 10:37:00  joergr
01222  * Added new bilinear and bicubic scaling algorithms for image magnification.
01223  * Now the c't scaling algorithm is used as a fallback if the preferred
01224  * algorithm with interpolation is not applicable.
01225  * Fixed bug in c't scaling algorithm (reducePixel) which could cause a crash.
01226  *
01227  * Revision 1.26  2006/08/15 16:30:11  meichel
01228  * Updated the code in module dcmimgle to correctly compile when
01229  *   all standard C++ classes remain in namespace std.
01230  *
01231  * Revision 1.25  2005/12/08 16:48:09  meichel
01232  * Changed include path schema for all DCMTK header files
01233  *
01234  * Revision 1.24  2004/04/21 10:00:36  meichel
01235  * Minor modifications for compilation with gcc 3.4.0
01236  *
01237  * Revision 1.23  2004/01/05 14:52:20  joergr
01238  * Removed acknowledgements with e-mail addresses from CVS log.
01239  *
01240  * Revision 1.22  2003/12/23 15:53:22  joergr
01241  * Replaced post-increment/decrement operators by pre-increment/decrement
01242  * operators where appropriate (e.g. 'i++' by '++i').
01243  *
01244  * Revision 1.21  2003/12/09 10:25:06  joergr
01245  * Adapted type casts to new-style typecast operators defined in ofcast.h.
01246  * Removed leading underscore characters from preprocessor symbols (reserved
01247  * symbols). Updated copyright header.
01248  *
01249  * Revision 1.20  2002/12/09 13:32:56  joergr
01250  * Renamed parameter/local variable to avoid name clashes with global
01251  * declaration left and/or right (used for as iostream manipulators).
01252  *
01253  * Revision 1.19  2002/04/16 13:53:12  joergr
01254  * Added configurable support for C++ ANSI standard includes (e.g. streams).
01255  *
01256  * Revision 1.18  2001/06/01 15:49:51  meichel
01257  * Updated copyright header
01258  *
01259  * Revision 1.17  2000/05/03 09:46:29  joergr
01260  * Removed most informational and some warning messages from release built
01261  * (#ifndef DEBUG).
01262  *
01263  * Revision 1.16  2000/04/28 12:32:33  joergr
01264  * DebugLevel - global for the module - now derived from OFGlobal (MT-safe).
01265  *
01266  * Revision 1.15  2000/04/27 13:08:42  joergr
01267  * Dcmimgle library code now consistently uses ofConsole for error output.
01268  *
01269  * Revision 1.14  2000/03/08 16:24:24  meichel
01270  * Updated copyright header.
01271  *
01272  * Revision 1.13  2000/03/07 16:15:13  joergr
01273  * Added explicit type casts to make Sun CC 2.0.1 happy.
01274  *
01275  * Revision 1.12  2000/03/03 14:09:14  meichel
01276  * Implemented library support for redirecting error messages into memory
01277  *   instead of printing them to stdout/stderr for GUI applications.
01278  *
01279  * Revision 1.11  1999/11/19 12:37:19  joergr
01280  * Fixed bug in scaling method "reducePixel" (reported by gcc 2.7.2.1).
01281  *
01282  * Revision 1.10  1999/09/17 13:07:20  joergr
01283  * Added/changed/completed DOC++ style comments in the header files.
01284  * Enhanced efficiency of some "for" loops.
01285  *
01286  * Revision 1.9  1999/08/25 16:41:55  joergr
01287  * Added new feature: Allow clipping region to be outside the image
01288  * (overlapping).
01289  *
01290  * Revision 1.8  1999/07/23 14:09:24  joergr
01291  * Added new interpolation algorithm for scaling.
01292  *
01293  * Revision 1.7  1999/04/28 14:55:05  joergr
01294  * Introduced new scheme for the debug level variable: now each level can be
01295  * set separately (there is no "include" relationship).
01296  *
01297  * Revision 1.6  1999/03/24 17:20:24  joergr
01298  * Added/Modified comments and formatting.
01299  *
01300  * Revision 1.5  1999/02/11 16:42:10  joergr
01301  * Removed inline declarations from several methods.
01302  *
01303  * Revision 1.4  1999/02/03 17:35:14  joergr
01304  * Moved global functions maxval() and determineRepresentation() to class
01305  * DicomImageClass (as static methods).
01306  *
01307  * Revision 1.3  1998/12/22 14:39:44  joergr
01308  * Added some preparation to enhance interpolated scaling (clipping and
01309  * scaling) in the future.
01310  *
01311  * Revision 1.2  1998/12/16 16:39:45  joergr
01312  * Implemented combined clipping and scaling for pixel replication and
01313  * suppression.
01314  *
01315  * Revision 1.1  1998/11/27 15:47:11  joergr
01316  * Added copyright message.
01317  * Combined clipping and scaling methods.
01318  *
01319  * Revision 1.4  1998/05/11 14:53:29  joergr
01320  * Added CVS/RCS header to each file.
01321  *
01322  *
01323  */


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1