dcmimgle/include/dcmtk/dcmimgle/dimoopxt.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: DicomMonoOutputPixelTemplate (Header)
00019  *
00020  *  Last Update:      $Author: joergr $
00021  *  Update Date:      $Date: 2010-10-28 10:58:38 $
00022  *  CVS/RCS Revision: $Revision: 1.54 $
00023  *  Status:           $State: Exp $
00024  *
00025  *  CVS/RCS Log at end of file
00026  *
00027  */
00028 
00029 
00030 #ifndef DIMOOPXT_H
00031 #define DIMOOPXT_H
00032 
00033 #include "dcmtk/config/osconfig.h"
00034 
00035 #include "dcmtk/ofstd/ofcast.h"
00036 #include "dcmtk/ofstd/ofbmanip.h"
00037 
00038 #include "dcmtk/dcmimgle/dimoopx.h"
00039 #include "dcmtk/dcmimgle/dimopx.h"
00040 #include "dcmtk/dcmimgle/diluptab.h"
00041 #include "dcmtk/dcmimgle/diovlay.h"
00042 #include "dcmtk/dcmimgle/dipxrept.h"
00043 #include "dcmtk/dcmimgle/didispfn.h"
00044 #include "dcmtk/dcmimgle/didislut.h"
00045 
00046 #ifdef PASTEL_COLOR_OUTPUT
00047 #include "dimcopxt.h"
00048 #endif
00049 
00050 #define INCLUDE_CMATH
00051 #include "dcmtk/ofstd/ofstdinc.h"
00052 
00053 
00054 /*---------------------*
00055  *  class declaration  *
00056  *---------------------*/
00057 
00060 template<class T1, class T2, class T3>
00061 class DiMonoOutputPixelTemplate
00062   : public DiMonoOutputPixel,
00063     public DiPixelRepresentationTemplate<T3>
00064 {
00065 
00066  public:
00067 
00087     DiMonoOutputPixelTemplate(void *buffer,
00088                               const DiMonoPixel *pixel,
00089                               DiOverlay *overlays[2],
00090                               const DiLookupTable *vlut,
00091                               const DiLookupTable *plut,
00092                               DiDisplayFunction *disp,
00093                               const EF_VoiLutFunction vfunc,
00094                               const double center,
00095                               const double width,
00096                               const Uint32 low,
00097                               const Uint32 high,
00098                               const Uint16 columns,
00099                               const Uint16 rows,
00100                               const unsigned long frame,
00101 #ifdef PASTEL_COLOR_OUTPUT
00102                               const unsigned long frames,
00103 #else
00104                               const unsigned long /*frames*/,
00105 #endif
00106                               const int pastel = 0)
00107       : DiMonoOutputPixel(pixel, OFstatic_cast(unsigned long, columns) * OFstatic_cast(unsigned long, rows), frame,
00108                           OFstatic_cast(unsigned long, fabs(OFstatic_cast(double, high - low)))),
00109         Data(NULL),
00110         DeleteData(buffer == NULL),
00111         ColorData(NULL)
00112     {
00113         if ((pixel != NULL) && (Count > 0) && (FrameSize >= Count))
00114         {
00115             if (pastel)
00116 #ifdef PASTEL_COLOR_OUTPUT
00117                 color(buffer, pixel, frame, frames);
00118 #else
00119                 DCMIMGLE_ERROR("pastel color output not supported");
00120 #endif
00121             else
00122             {
00123                 DCMIMGLE_TRACE("monochrome output image - columns: " << columns << ", rows: " << rows << ", frame: " << frame);
00124                 DCMIMGLE_TRACE("monochrome output values - low: " << OFstatic_cast(unsigned long, low) << ", high: "
00125                     << OFstatic_cast(unsigned long, high) << ((low > high) ? " (inverted)" : ""));
00126                 Data = OFstatic_cast(T3 *, buffer);
00127                 if ((vlut != NULL) && (vlut->isValid()))            // valid VOI LUT ?
00128                     voilut(pixel, frame * FrameSize, vlut, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
00129                 else
00130                 {
00131                     if (width < 1)                                  // no valid window according to supplement 33
00132                         nowindow(pixel, frame * FrameSize, plut, disp, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
00133                     else if (vfunc == EFV_Sigmoid)
00134                         sigmoid(pixel, frame * FrameSize, plut, disp, center, width, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
00135                     else // linear
00136                         window(pixel, frame * FrameSize, plut, disp, center, width, OFstatic_cast(T3, low), OFstatic_cast(T3, high));
00137                 }
00138                 overlay(overlays, disp, columns, rows, frame);      // add (visible) overlay planes to output bitmap
00139             }
00140         }
00141     }
00142 
00145     virtual ~DiMonoOutputPixelTemplate()
00146     {
00147         if (DeleteData)
00148             delete[] Data;
00149         delete ColorData;
00150     }
00151 
00156     inline EP_Representation getRepresentation() const
00157     {
00158         return DiPixelRepresentationTemplate<T3>::getRepresentation();
00159     }
00160 
00165     inline size_t getItemSize() const
00166     {
00167         return (ColorData != NULL) ? ColorData->getItemSize() : sizeof(T3);
00168     }
00169 
00174     inline const void *getData() const
00175     {
00176         return (ColorData != NULL) ? ColorData->getData() : OFstatic_cast(const void *, Data);
00177     }
00178 
00183     virtual void *getDataPtr()
00184     {
00185         return (ColorData != NULL) ? ColorData->getDataPtr() : OFstatic_cast(void *, Data);
00186     }
00187 
00190     inline void removeDataReference()
00191     {
00192         Data = NULL;
00193         DeleteData = 0;
00194     }
00195 
00202     inline int writePPM(STD_NAMESPACE ostream& stream) const
00203     {
00204         if (Data != NULL)
00205         {
00206             register unsigned long i;
00207             for (i = 0; i < FrameSize; ++i)
00208                 stream << OFstatic_cast(unsigned long, Data[i]) << " ";    // typecast to resolve problems with 'char'
00209             return 1;
00210         }
00211         if (ColorData != NULL)
00212             return ColorData->writePPM(stream);
00213         return 0;
00214     }
00215 
00222     inline int writePPM(FILE *stream) const
00223     {
00224         if (Data != NULL)
00225         {
00226             register unsigned long i;
00227             for (i = 0; i < FrameSize; ++i)
00228                 fprintf(stream, "%lu ", OFstatic_cast(unsigned long, Data[i]));
00229             return 1;
00230         }
00231         if (ColorData != NULL)
00232             return ColorData->writePPM(stream);
00233         return 0;
00234     }
00235 
00236 
00237  protected:
00238 
00241     inline void determineUsedValues()
00242     {
00243         if ((UsedValues == NULL) && (MaxValue > 0) && (MaxValue < MAX_TABLE_ENTRY_COUNT))
00244         {
00245             UsedValues = new Uint8[MaxValue + 1];
00246             if (UsedValues != NULL)
00247             {
00248                 OFBitmanipTemplate<Uint8>::zeroMem(UsedValues, MaxValue + 1); // initialize array
00249                 register const T3 *p = Data;
00250                 register Uint8 *q = UsedValues;
00251                 register unsigned long i;
00252                 for (i = Count; i != 0; --i)
00253                     *(q + *(p++)) = 1;                                        // mark used entries
00254             }
00255         }
00256     }
00257 
00258 
00259  private:
00260 
00267     inline void createDisplayLUT(const DiDisplayLUT *&dlut,
00268                                  DiDisplayFunction *disp,
00269                                  const int bits)
00270     {
00271         if ((disp != NULL) && (disp->isValid()))
00272         {                                                                     // create Display LUT
00273             dlut = disp->getLookupTable(bits);
00274             if ((dlut != NULL) && (dlut->isValid()))                          // LUT is valid
00275             {
00276                 DCMIMGLE_DEBUG("using display transformation");
00277             } else {
00278                 DCMIMGLE_WARN("can't create display LUT ... ignoring display transformation");
00279                 dlut = NULL;
00280             }
00281         }
00282     }
00283 
00289     inline int initOptimizationLUT(T3 *&lut,
00290                                    const unsigned long ocnt)
00291     {
00292         int result = 0;
00293         if ((sizeof(T1) <= 2) && (Count > 3 * ocnt))                          // optimization criteria
00294         {                                                                     // use LUT for optimization
00295             lut = new T3[ocnt];
00296             if (lut != NULL)
00297             {
00298                 DCMIMGLE_DEBUG("using optimized routine with additional LUT (" << ocnt << " entries)");
00299                 result = 1;
00300             }
00301         }
00302         return result;
00303     }
00304 
00305 #ifdef PASTEL_COLOR_OUTPUT
00306     void color(void *buffer,                               // create true color pastel image
00307                const DiMonoPixel *inter,
00308                const unsigned long frame,
00309                const unsigned long frames)
00310     {
00311         ColorData = new DiMonoColorOutputPixelTemplate<T1, T3>(buffer, inter, frame, frames);
00312         if (ColorData != NULL)
00313             DCMIMGLE_DEBUG(">>> COLOR <<<");
00314     }
00315 #endif
00316 
00327     void voilut(const DiMonoPixel *inter,
00328                 const Uint32 start,
00329                 const DiLookupTable *vlut,
00330                 const DiLookupTable *plut,
00331                 DiDisplayFunction *disp,
00332                 const T3 low,
00333                 const T3 high)
00334     {
00335         const T1 *pixel = OFstatic_cast(const T1 *, inter->getData());
00336         if ((pixel != NULL) && (vlut != NULL))
00337         {
00338             if (Data == NULL)
00339                 Data = new T3[FrameSize];
00340             if (Data != NULL)
00341             {
00342                 DCMIMGLE_DEBUG("applying VOI transformation with LUT (" << vlut->getCount() << " entries)");
00343                 const DiDisplayLUT *dlut = NULL;
00344                 const double minvalue = vlut->getMinValue();
00345                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low) + 1;
00346                 register unsigned long i;
00347                 if (minvalue == vlut->getMaxValue())                                    // LUT has only one entry or all entries are equal
00348                 {
00349                     T3 value;
00350                     if ((plut != NULL) && (plut->isValid()))                            // has presentation LUT
00351                     {
00352                         DCMIMGLE_DEBUG("applying presentation LUT transformation");
00353                         createDisplayLUT(dlut, disp, plut->getBits());
00354                         const Uint32 value2 = OFstatic_cast(Uint32, (minvalue / OFstatic_cast(double, vlut->getAbsMaxRange())) * plut->getCount());
00355                         if (dlut != NULL)                                               // perform display transformation
00356                         {
00357                             DCMIMGLE_TRACE("monochrome rendering: VOI LUT #1 - UNTESTED");
00358                             if (low > high)                                             // invers
00359                                 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getAbsMaxRange() - plut->getValue(value2) - 1)));
00360                             else                                                        // normal
00361                                 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, plut->getValue(value2))));
00362                         } else {                                                        // don't use display: invalid or absent
00363                             DCMIMGLE_TRACE("monochrome rendering: VOI LUT #2");
00364                             value = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * outrange / OFstatic_cast(double, plut->getAbsMaxRange()));
00365                         }
00366                     } else {                                                            // has no presentation LUT
00367                         createDisplayLUT(dlut, disp, vlut->getBits());
00368                         if (dlut != NULL)                                               // perform display transformation
00369                         {
00370                             DCMIMGLE_TRACE("monochrome rendering: VOI LUT #3 - UNTESTED");
00371                             if (low > high)                                             // invers
00372                                 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, vlut->getAbsMaxRange() - minvalue - 1)));
00373                             else                                                        // normal
00374                                 value = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, minvalue)));
00375                         } else {                                                        // don't use display: invalid or absent
00376                             DCMIMGLE_TRACE("monochrome rendering: VOI LUT #4");
00377                             value = OFstatic_cast(T3, OFstatic_cast(double, low) + (minvalue / OFstatic_cast(double, vlut->getAbsMaxRange())) * outrange);
00378                         }
00379                     }
00380                     OFBitmanipTemplate<T3>::setMem(Data, value, Count);                 // set output pixels to LUT value
00381                 } else {
00382                     register T2 value = 0;
00383                     const T2 absmin = OFstatic_cast(T2, inter->getAbsMinimum());
00384                     const T2 firstentry = vlut->getFirstEntry(value);                   // choose signed/unsigned method
00385                     const T2 lastentry = vlut->getLastEntry(value);
00386                     const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
00387                     register const T1 *p = pixel + start;
00388                     register T3 *q = Data;
00389                     T3 *lut = NULL;
00390                     if ((plut != NULL) && (plut->isValid()))                            // has presentation LUT
00391                     {
00392                         DCMIMGLE_DEBUG("applying presentation LUT transformation");
00393                         createDisplayLUT(dlut, disp, plut->getBits());
00394                         register Uint32 value2;                                         // presentation LUT is always unsigned
00395                         const Uint32 pcnt = plut->getCount();
00396                         const double gradient1 = OFstatic_cast(double, pcnt) / OFstatic_cast(double, vlut->getAbsMaxRange());
00397                         const Uint32 firstvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getFirstValue()) * gradient1);
00398                         const Uint32 lastvalue = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getLastValue()) * gradient1);
00399                         if (initOptimizationLUT(lut, ocnt))
00400                         {                                                                 // use LUT for optimization
00401                             q = lut;
00402                             if (dlut != NULL)                                             // perform display transformation
00403                             {
00404                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #5");
00405                                 if (low > high)                                           // inverse
00406                                 {
00407                                     const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1);
00408                                     for (i = 0; i < ocnt; ++i)
00409                                     {
00410                                         value = OFstatic_cast(T2, i) + absmin;
00411                                         if (value <= firstentry)
00412                                             value2 = firstvalue;
00413                                         else if (value >= lastentry)
00414                                             value2 = lastvalue;
00415                                         else
00416                                             value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00417                                         *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value2))));
00418                                     }
00419                                 } else {                                                  // normal
00420                                     for (i = 0; i < ocnt; ++i)
00421                                     {
00422                                         value = OFstatic_cast(T2, i) + absmin;
00423                                         if (value <= firstentry)
00424                                             value2 = firstvalue;
00425                                         else if (value >= lastentry)
00426                                             value2 = lastvalue;
00427                                         else
00428                                             value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00429                                         *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value2)));
00430                                     }
00431                                 }
00432                             } else {                                                      // don't use display: invalid or absent
00433                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #6");
00434                                 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange());
00435                                 for (i = 0; i < ocnt; ++i)
00436                                 {
00437                                     value = OFstatic_cast(T2, i) + absmin;
00438                                     if (value <= firstentry)
00439                                         value2 = firstvalue;
00440                                     else if (value >= lastentry)
00441                                         value2 = lastvalue;
00442                                     else
00443                                         value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00444                                     *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2);
00445                                 }
00446                             }
00447                             const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum());  // points to 'zero' entry
00448                             q = Data;
00449                             for (i = Count; i != 0; --i)                                  // apply LUT
00450                                 *(q++) = *(lut0 + (*(p++)));
00451                         }
00452                         if (lut == NULL)                                                  // use "normal" transformation
00453                         {
00454                             if (dlut != NULL)                                             // perform display transformation
00455                             {
00456                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #7");
00457                                 if (low > high)                                           // inverse
00458                                 {
00459                                     const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1);
00460                                     for (i = Count; i != 0; --i)
00461                                     {
00462                                         value = OFstatic_cast(T2, *(p++));                // pixel value
00463                                         if (value <= firstentry)
00464                                             value2 = firstvalue;
00465                                         else if (value >= lastentry)
00466                                             value2 = lastvalue;
00467                                         else
00468                                             value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00469                                         *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value2))));
00470                                     }
00471                                 } else {                                                  // normal
00472                                     for (i = Count; i != 0; --i)
00473                                     {
00474                                         value = OFstatic_cast(T2, *(p++));                // pixel value
00475                                         if (value <= firstentry)
00476                                             value2 = firstvalue;
00477                                         else if (value >= lastentry)
00478                                             value2 = lastvalue;
00479                                         else
00480                                             value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00481                                         *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value2)));
00482                                     }
00483                                 }
00484                             } else {                                                      // don't use display: invalid or absent
00485                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #8");
00486                                 const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange());
00487                                 for (i = Count; i != 0; --i)
00488                                 {
00489                                     value = OFstatic_cast(T2, *(p++));                    // pixel value
00490                                     if (value <= firstentry)
00491                                         value2 = firstvalue;
00492                                     else if (value >= lastentry)
00493                                         value2 = lastvalue;
00494                                     else
00495                                         value2 = OFstatic_cast(Uint32, OFstatic_cast(double, vlut->getValue(value)) * gradient1);
00496                                     *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2);
00497                                 }
00498                             }
00499                         }
00500                     } else {                                                              // has no presentation LUT
00501                         createDisplayLUT(dlut, disp, vlut->getBits());
00502                         const double gradient = outrange / OFstatic_cast(double, vlut->getAbsMaxRange());
00503                         const T3 firstvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getFirstValue()) * gradient);
00504                         const T3 lastvalue = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getLastValue()) * gradient);
00505                         if (initOptimizationLUT(lut, ocnt))
00506                         {                                                                 // use LUT for optimization
00507                             q = lut;
00508                             if (dlut != NULL)                                             // perform display transformation
00509                             {
00510                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #9");
00511                                 if (low > high)                                           // inverse
00512                                 {
00513                                     const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1);
00514                                     for (i = 0; i < ocnt; ++i)
00515                                     {
00516                                         value = OFstatic_cast(T2, i) + absmin;
00517                                         if (value < firstentry)
00518                                             value = firstentry;
00519                                         else if (value > lastentry)
00520                                             value = lastentry;
00521                                         *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->getValue(value))));
00522                                     }
00523                                 } else {                                                  // normal
00524                                     for (i = 0; i < ocnt; ++i)
00525                                     {
00526                                         value = OFstatic_cast(T2, i) + absmin;
00527                                         if (value < firstentry)
00528                                             value = firstentry;
00529                                         else if (value > lastentry)
00530                                             value = lastentry;
00531                                         *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->getValue(value)));
00532                                     }
00533                                 }
00534                             } else {                                                      // don't use display: invalid or absent
00535                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #10");
00536                                 for (i = 0; i < ocnt; ++i)                                // calculating LUT entries
00537                                 {
00538                                     value = OFstatic_cast(T2, i) + absmin;
00539                                     if (value <= firstentry)
00540                                         *(q++) = firstvalue;
00541                                     else if (value >= lastentry)
00542                                         *(q++) = lastvalue;
00543                                     else
00544                                         *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getValue(value)) * gradient);
00545                                 }
00546                             }
00547                             const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum());   // points to 'zero' entry
00548                             q = Data;
00549                             for (i = Count; i != 0; --i)                                  // apply LUT
00550                                 *(q++) = *(lut0 + (*(p++)));
00551                         }
00552                         if (lut == NULL)                                                  // use "normal" transformation
00553                         {
00554                             if (dlut != NULL)                                             // perform display transformation
00555                             {
00556                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #11");
00557                                 if (low > high)                                           // inverse
00558                                 {
00559                                     const Uint16 maxvalue = OFstatic_cast(Uint16, vlut->getAbsMaxRange() - 1);
00560                                     for (i = Count; i != 0; --i)
00561                                     {
00562                                         value = OFstatic_cast(T2, *(p++));
00563                                         if (value < firstentry)
00564                                             value = firstentry;
00565                                         else if (value > lastentry)
00566                                             value = lastentry;
00567                                         *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - vlut->getValue(value))));
00568                                     }
00569                                 } else {                                                  // normal
00570                                     for (i = Count; i != 0; --i)
00571                                     {
00572                                         value = OFstatic_cast(T2, *(p++));
00573                                         if (value < firstentry)
00574                                             value = firstentry;
00575                                         else if (value > lastentry)
00576                                             value = lastentry;
00577                                         *(q++) = OFstatic_cast(T3, dlut->getValue(vlut->getValue(value)));
00578                                     }
00579                                 }
00580                             } else {                                                      // don't use display: invalid or absent
00581                                 DCMIMGLE_TRACE("monochrome rendering: VOI LUT #12");
00582                                 for (i = 0; i < Count; ++i)
00583                                 {
00584                                     value = OFstatic_cast(T2, *(p++));
00585                                     if (value <= firstentry)
00586                                         *(q++) = firstvalue;
00587                                     else if (value >= lastentry)
00588                                         *(q++) = lastvalue;
00589                                     else
00590                                         *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, vlut->getValue(value)) * gradient);
00591                                 }
00592                             }
00593                         }
00594                     }
00595                     delete[] lut;
00596                 }
00597                 if (Count < FrameSize)
00598                     OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count);     // set remaining pixels of frame to zero
00599             }
00600         } else
00601             Data = NULL;
00602     }
00603 
00613     void nowindow(const DiMonoPixel *inter,
00614                   const Uint32 start,
00615                   const DiLookupTable *plut,
00616                   DiDisplayFunction *disp,
00617                   const T3 low,
00618                   const T3 high)
00619     {
00620         const DiDisplayLUT *dlut = NULL;
00621         const T1 *pixel = OFstatic_cast(const T1 *, inter->getData());
00622         if (pixel != NULL)
00623         {
00624             if (Data == NULL)                                                         // create new output buffer
00625                 Data = new T3[FrameSize];
00626             if (Data != NULL)
00627             {
00628                 DCMIMGLE_DEBUG("applying no VOI transformation (linear scaling)");
00629                 const double absmin = inter->getAbsMinimum();
00630                 const double absmax = inter->getAbsMaximum();
00631                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low) + 1;
00632                 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
00633                 register const T1 *p = pixel + start;
00634                 register T3 *q = Data;
00635                 register unsigned long i;
00636                 T3 *lut = NULL;
00637                 if ((plut != NULL) && (plut->isValid()))                              // has presentation LUT
00638                 {
00639                     DCMIMGLE_DEBUG("applying presentation LUT transformation");
00640                     createDisplayLUT(dlut, disp, plut->getBits());
00641                     register Uint32 value;                                            // presentation LUT is always unsigned
00642                     const double gradient1 = OFstatic_cast(double, plut->getCount()) / inter->getAbsMaxRange();
00643                     const double gradient2 = outrange / OFstatic_cast(double, plut->getAbsMaxRange());
00644                     if (initOptimizationLUT(lut, ocnt))
00645                     {                                                                 // use LUT for optimization
00646                         q = lut;
00647                         if (dlut != NULL)                                             // perform display transformation
00648                         {
00649                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #1");
00650                             if (low > high)                                           // inverse
00651                             {
00652                                 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1);
00653                                 for (i = 0; i < ocnt; ++i)
00654                                 {
00655                                     value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1);
00656                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value))));
00657                                 }
00658                             } else {                                                  // normal
00659                                 for (i = 0; i < ocnt; ++i)
00660                                 {
00661                                     value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1);
00662                                     *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value)));
00663                                 }
00664                             }
00665                         } else {                                                      // don't use display: invalid or absent
00666                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #2");
00667                             for (i = 0; i < ocnt; ++i)
00668                             {
00669                                 value = OFstatic_cast(Uint32, OFstatic_cast(double, i) * gradient1);
00670                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value)) * gradient2);
00671                             }
00672                         }
00673                         const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum());  // points to 'zero' entry
00674                         q = Data;
00675                         for (i = Count; i != 0; --i)                                  // apply LUT
00676                             *(q++) = *(lut0 + (*(p++)));
00677                     }
00678                     if (lut == NULL)                                                  // use "normal" transformation
00679                     {
00680                         if (dlut != NULL)                                             // perform display transformation
00681                         {
00682                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #3");
00683                             if (low > high)                                           // inverse
00684                             {
00685                                 const Uint16 maxvalue = OFstatic_cast(Uint16, plut->getAbsMaxRange() - 1);
00686                                 for (i = Count; i != 0; --i)
00687                                 {
00688                                     value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1);
00689                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, maxvalue - plut->getValue(value))));
00690                                 }
00691                             } else {                                                  // normal
00692                                 for (i = Count; i != 0; --i)
00693                                 {
00694                                     value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1);
00695                                     *(q++) = OFstatic_cast(T3, dlut->getValue(plut->getValue(value)));
00696                                 }
00697                             }
00698                         } else {                                                      // don't use display: invalid or absent
00699                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #4");
00700                             for (i = Count; i != 0; --i)
00701                             {
00702                                 value = OFstatic_cast(Uint32, (OFstatic_cast(double, *(p++)) - absmin) * gradient1);
00703                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value)) * gradient2);
00704                             }
00705                         }
00706                     }
00707                 } else {                                                              // has no presentation LUT
00708                     createDisplayLUT(dlut, disp, inter->getBits());
00709                     register const double gradient = outrange / (inter->getAbsMaxRange());
00710                     if (initOptimizationLUT(lut, ocnt))
00711                     {                                                                 // use LUT for optimization
00712                         q = lut;
00713                         if (dlut != NULL)                                             // perform display transformation
00714                         {
00715                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #5");
00716                             if (low > high)                                           // inverse
00717                             {
00718                                 for (i = ocnt; i != 0; --i)                           // calculating LUT entries
00719                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i - 1)));
00720                             } else {                                                  // normal
00721                                 for (i = 0; i < ocnt; ++i)                            // calculating LUT entries
00722                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, i)));
00723                             }
00724                         } else {                                                      // don't use display: invalid or absent
00725                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #6");
00726                             for (i = 0; i < ocnt; ++i)                                // calculating LUT entries
00727                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, i) * gradient);
00728                         }
00729                         const T3 *lut0 = lut - OFstatic_cast(T2, inter->getAbsMinimum());  // points to 'zero' entry
00730                         q = Data;
00731                         for (i = Count; i != 0; --i)                                  // apply LUT
00732                             *(q++) = *(lut0 + (*(p++)));
00733                     }
00734                     if (lut == NULL)                                                  // use "normal" transformation
00735                     {
00736                         if (dlut != NULL)                                             // perform display transformation
00737                         {
00738                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #7");
00739                             if (low > high)                                           // inverse
00740                             {
00741                                 for (i = Count; i != 0; --i)
00742                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, absmax - (OFstatic_cast(double, *(p++)) - absmin))));
00743                             } else {                                                  // normal
00744                                 for (i = Count; i != 0; --i)
00745                                     *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, OFstatic_cast(double, *(p++)) - absmin)));
00746                             }
00747                         } else {                                                      // don't use display: invalid or absent
00748                             DCMIMGLE_TRACE("monochrome rendering: VOI NONE #8");
00749                             for (i = Count; i != 0; --i)
00750                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + (OFstatic_cast(double, *(p++)) - absmin) * gradient);
00751                         }
00752                     }
00753                 }
00754                 delete[] lut;
00755                 if (Count < FrameSize)
00756                     OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count); // set remaining pixels of frame to zero
00757             }
00758         } else
00759             Data = NULL;
00760     }
00761 
00773     void sigmoid(const DiMonoPixel *inter,
00774                  const Uint32 start,
00775                  const DiLookupTable *plut,
00776                  DiDisplayFunction *disp,
00777                  const double center,
00778                  const double width,
00779                  const T3 low,
00780                  const T3 high)
00781     {
00782         const T1 *pixel = OFstatic_cast(const T1 *, inter->getData());
00783         if (pixel != NULL)
00784         {
00785             if (Data == NULL)
00786                 Data = new T3[FrameSize];                                             // create new output buffer
00787             if (Data != NULL)
00788             {
00789                 DCMIMGLE_DEBUG("applying sigmoid VOI transformation with window center = " << center << ", width = " << width);
00790                 const DiDisplayLUT *dlut = NULL;
00791                 const double absmin = inter->getAbsMinimum();
00792                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low);  // output range
00793                 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
00794                 register const T1 *p = pixel + start;
00795                 register T3 *q = Data;
00796                 register unsigned long i;
00797                 register double value;
00798                 T3 *lut = NULL;
00799                 if ((plut != NULL) && (plut->isValid()))                              // has presentation LUT
00800                 {
00801                     DCMIMGLE_DEBUG("applying presentation LUT transformation");
00802                     createDisplayLUT(dlut, disp, plut->getBits());
00803                     register Uint32 value2;                                           // presentation LUT is always unsigned
00804                     const double plutcnt_1 = OFstatic_cast(double, plut->getCount() - 1);
00805                     const double plutmax_1 = OFstatic_cast(double, plut->getAbsMaxRange() - 1);
00806                     if (initOptimizationLUT(lut, ocnt))
00807                     {                                                                 // use LUT for optimization
00808                         q = lut;
00809                         if (dlut != NULL)                                             // perform display transformation
00810                         {
00811                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #1");
00812                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
00813                             const double offset = (low > high) ? maxvalue : 0;
00814                             const double gradient = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
00815                             for (i = 0; i < ocnt; ++i)
00816                             {
00817                                 value = OFstatic_cast(double, i) + absmin;
00818                                 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
00819                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient)));
00820                             }
00821                         } else {                                                      // don't use display: invalid or absent
00822                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #2");
00823                             const double gradient = outrange / plutmax_1;
00824                             for (i = 0; i < ocnt; ++i)
00825                             {
00826                                 value = OFstatic_cast(double, i) + absmin;
00827                                 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
00828                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient);
00829                             }
00830                         }
00831                         const T3 *lut0 = lut - OFstatic_cast(T2, absmin);             // points to 'zero' entry
00832                         q = Data;
00833                         for (i = Count; i != 0; --i)                                  // apply LUT
00834                             *(q++) = *(lut0 + (*(p++)));
00835                     }
00836                     if (lut == NULL)                                                  // use "normal" transformation
00837                     {
00838                         if (dlut != NULL)                                             // perform display transformation
00839                         {
00840                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #3");
00841                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
00842                             const double offset = (low > high) ? maxvalue : 0;
00843                             const double gradient = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
00844                             for (i = Count; i != 0; --i)
00845                             {
00846                                 value = OFstatic_cast(double, *(p++));
00847                                 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
00848                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient)));
00849                             }
00850                         } else {                                                      // don't use display: invalid or absent
00851                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #4");
00852                             const double gradient = outrange / plutmax_1;
00853                             for (i = Count; i != 0; --i)
00854                             {
00855                                 value = OFstatic_cast(double, *(p++));
00856                                 value2 = OFstatic_cast(Uint32, plutcnt_1 / (1 + exp(-4 * (value - center) / width)));
00857                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient);
00858                             }
00859                         }
00860                     }
00861                 } else {                                                              // has no presentation LUT
00862                     createDisplayLUT(dlut, disp, bitsof(T1));
00863                     if (initOptimizationLUT(lut, ocnt))
00864                     {                                                                 // use LUT for optimization
00865                         q = lut;
00866                         if (dlut != NULL)                                             // perform display transformation
00867                         {
00868                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #5");
00869                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
00870                             const double outrange2 = (low > high) ? -maxvalue : maxvalue;
00871                             const double offset = (low > high) ? maxvalue : 0;
00872                             for (i = 0; i < ocnt; ++i)                                // calculating LUT entries
00873                             {
00874                                 value = OFstatic_cast(double, i) + absmin;
00875                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + outrange2 / (1 + exp(-4 * (value - center) / width)))));
00876                             }
00877                         } else {                                                      // don't use display: invalid or absent
00878                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #6");
00879                             for (i = 0; i < ocnt; ++i)                                // calculating LUT entries
00880                             {
00881                                 value = OFstatic_cast(double, i) + absmin;
00882                                 *(q++) = OFstatic_cast(T3, outrange / (1 + exp(-4 * (value - center) / width)));
00883                             }
00884                         }
00885                         const T3 *lut0 = lut - OFstatic_cast(T2, absmin);             // points to 'zero' entry
00886                         q = Data;
00887                         for (i = Count; i != 0; --i)                                  // apply LUT
00888                             *(q++) = *(lut0 + (*(p++)));
00889                     }
00890                     if (lut == NULL)                                                  // use "normal" transformation
00891                     {
00892                         if (dlut != NULL)                                             // perform display transformation
00893                         {
00894                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #7");
00895                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
00896                             const double outrange2 = (low > high) ? -maxvalue : maxvalue;
00897                             const double offset = (low > high) ? maxvalue : 0;
00898                             for (i = Count; i != 0; --i)
00899                             {
00900                                 value = OFstatic_cast(double, *(p++));
00901                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + outrange2 / (1 + exp(-4 * (value - center) / width)))));
00902                             }
00903                         } else {                                                      // don't use display: invalid or absent
00904                             DCMIMGLE_TRACE("monochrome rendering: VOI SIGMOID #8");
00905                             for (i = Count; i != 0; --i)
00906                             {
00907                                 value = OFstatic_cast(double, *(p++));
00908                                 *(q++) = OFstatic_cast(T3, outrange / (1 + exp(-4 * (value - center) / width)));
00909                             }
00910                         }
00911                     }
00912                 }
00913                 delete[] lut;
00914                 if (Count < FrameSize)
00915                     OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count);        // set remaining pixels of frame to zero
00916             }
00917         } else
00918             Data = NULL;
00919     }
00920 
00932     void window(const DiMonoPixel *inter,
00933                 const Uint32 start,
00934                 const DiLookupTable *plut,
00935                 DiDisplayFunction *disp,
00936                 const double center,
00937                 const double width,
00938                 const T3 low,
00939                 const T3 high)
00940     {
00941         const T1 *pixel = OFstatic_cast(const T1 *, inter->getData());
00942         if (pixel != NULL)
00943         {
00944             if (Data == NULL)
00945                 Data = new T3[FrameSize];                                             // create new output buffer
00946             if (Data != NULL)
00947             {
00948                 DCMIMGLE_DEBUG("applying linear VOI transformation with window center = " << center << ", width = " << width);
00949                 const DiDisplayLUT *dlut = NULL;
00950                 const double absmin = inter->getAbsMinimum();
00951                 const double width_1 = width - 1;
00952                 const double leftBorder = center - 0.5 - width_1 / 2;                 // window borders, according to supplement 33
00953                 const double rightBorder = center - 0.5 + width_1 / 2;
00954                 const double outrange = OFstatic_cast(double, high) - OFstatic_cast(double, low);  // output range
00955                 const unsigned long ocnt = OFstatic_cast(unsigned long, inter->getAbsMaxRange());  // number of LUT entries
00956                 register const T1 *p = pixel + start;
00957                 register T3 *q = Data;
00958                 register unsigned long i;
00959                 register double value;
00960                 T3 *lut = NULL;
00961                 if ((plut != NULL) && (plut->isValid()))                              // has presentation LUT
00962                 {
00963                     DCMIMGLE_DEBUG("applying presentation LUT transformation");
00964                     createDisplayLUT(dlut, disp, plut->getBits());
00965                     register Uint32 value2;                                           // presentation LUT is always unsigned
00966                     const Uint32 pcnt = plut->getCount();
00967                     const double plutmax_1 = OFstatic_cast(double, plut->getAbsMaxRange()) - 1;
00968                     const double gradient1 = (width_1 == 0) ? 0 : OFstatic_cast(double, pcnt - 1) / width_1;
00969                     if (initOptimizationLUT(lut, ocnt))
00970                     {                                                                 // use LUT for optimization
00971                         q = lut;
00972                         if (dlut != NULL)                                             // perform display transformation
00973                         {
00974                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #1");
00975                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
00976                             const double offset = (low > high) ? maxvalue : 0;
00977                             const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
00978                             for (i = 0; i < ocnt; ++i)
00979                             {
00980                                 value = OFstatic_cast(double, i) + absmin;            // pixel value
00981                                 if (value <= leftBorder)
00982                                     value2 = 0;                                       // first LUT index
00983                                 else if (value > rightBorder)
00984                                     value2 = pcnt - 1;                                // last LUT index
00985                                 else
00986                                     value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
00987                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient2)));
00988                             }
00989                         } else {                                                      // don't use display: invalid or absent
00990                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #2");
00991                             const double gradient2 = outrange / plutmax_1;
00992                             for (i = 0; i < ocnt; ++i)
00993                             {
00994                                 value = OFstatic_cast(double, i) + absmin;            // pixel value
00995                                 if (value <= leftBorder)
00996                                     value2 = 0;                                       // first LUT index
00997                                 else if (value > rightBorder)
00998                                     value2 = pcnt - 1;                                // last LUT index
00999                                 else
01000                                     value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
01001                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2);
01002                             }
01003                         }
01004                         const T3 *lut0 = lut - OFstatic_cast(T2, absmin);             // points to 'zero' entry
01005                         q = Data;
01006                         for (i = Count; i != 0; --i)                                  // apply LUT
01007                             *(q++) = *(lut0 + (*(p++)));
01008                     }
01009                     if (lut == NULL)                                                  // use "normal" transformation
01010                     {
01011                         if (dlut != NULL)                                             // perform display transformation
01012                         {
01013                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #3");
01014                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
01015                             const double offset = (low > high) ? maxvalue : 0;
01016                             const double gradient2 = (low > high) ? (-maxvalue / plutmax_1) : (maxvalue / plutmax_1);
01017                             for (i = Count; i != 0; --i)
01018                             {
01019                                 value = OFstatic_cast(double, *(p++));                // pixel value
01020                                 if (value <= leftBorder)
01021                                     value2 = 0;                                       // first LUT index
01022                                 else if (value > rightBorder)
01023                                     value2 = pcnt - 1;                                // last LUT index
01024                                 else
01025                                     value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
01026                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + OFstatic_cast(double, plut->getValue(value2)) * gradient2)));
01027                             }
01028                         } else {                                                      // don't use display: invalid or absent
01029                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #4");
01030                             const double gradient2 = outrange / plutmax_1;
01031                             for (i = Count; i != 0; --i)
01032                             {
01033                                 value = OFstatic_cast(double, *(p++));                // pixel value
01034                                 if (value <= leftBorder)
01035                                     value2 = 0;                                       // first LUT index
01036                                 else if (value > rightBorder)
01037                                     value2 = pcnt - 1;                                // last LUT index
01038                                 else
01039                                     value2 = OFstatic_cast(Uint32, (value - leftBorder) * gradient1);
01040                                 *(q++) = OFstatic_cast(T3, OFstatic_cast(double, low) + OFstatic_cast(double, plut->getValue(value2)) * gradient2);
01041                             }
01042                         }
01043                     }
01044                 } else {                                                              // has no presentation LUT
01045                     createDisplayLUT(dlut, disp, bitsof(T1));
01046                     if (initOptimizationLUT(lut, ocnt))
01047                     {                                                                 // use LUT for optimization
01048                         q = lut;
01049                         if (dlut != NULL)                                             // perform display transformation
01050                         {
01051                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #5");
01052                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
01053                             const double offset = (low > high) ? maxvalue : 0;
01054                             const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1));
01055                             for (i = 0; i < ocnt; ++i)                                // calculating LUT entries
01056                             {
01057                                 value = OFstatic_cast(double, i) + absmin - leftBorder;
01058                                 if (value < 0)                                               // left border
01059                                     value = 0;
01060                                 else if (value > width_1)                                    // right border
01061                                     value = width_1;
01062                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient)));  // calculate value
01063                             }
01064                         } else {                                                       // don't use display: invalid or absent
01065                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #6");
01066                             const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange);
01067                             const double gradient = (width_1 == 0) ? 0 : outrange / width_1;
01068                             for (i = 0; i < ocnt; ++i)                                 // calculating LUT entries
01069                             {
01070                                 value = OFstatic_cast(double, i) + absmin;
01071                                 if (value <= leftBorder)
01072                                     *(q++) = low;                                            // black/white
01073                                 else if (value > rightBorder)
01074                                     *(q++) = high;                                           // white/black
01075                                 else
01076                                     *(q++) = OFstatic_cast(T3, offset + value * gradient);   // gray value
01077                             }
01078                         }
01079                         const T3 *lut0 = lut - OFstatic_cast(T2, absmin);             // points to 'zero' entry
01080                         q = Data;
01081                         for (i = Count; i != 0; --i)                                  // apply LUT
01082                             *(q++) = *(lut0 + (*(p++)));
01083                     }
01084                     if (lut == NULL)                                                  // use "normal" transformation
01085                     {
01086                         if (dlut != NULL)                                             // perform display transformation
01087                         {
01088                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #7");
01089                             const double maxvalue = OFstatic_cast(double, dlut->getCount() - 1);
01090                             const double offset = (low > high) ? maxvalue : 0;
01091                             const double gradient = (width_1 == 0) ? 0 : ((low > high) ? (-maxvalue / width_1) : (maxvalue / width_1));
01092                             for (i = Count; i != 0; --i)                              // calculating LUT entries
01093                             {
01094                                 value = OFstatic_cast(double, *(p++)) - leftBorder;
01095                                 if (value < 0)                                               // left border
01096                                     value = 0;
01097                                 else if (value > width_1)                                    // right border
01098                                     value = width_1;
01099                                 *(q++) = OFstatic_cast(T3, dlut->getValue(OFstatic_cast(Uint16, offset + value * gradient)));  // calculate value
01100                             }
01101                         } else {                                                      // don't use display: invalid or absent
01102                             DCMIMGLE_TRACE("monochrome rendering: VOI LINEAR #8");
01103                             const double offset = (width_1 == 0) ? 0 : (high - ((center - 0.5) / width_1 + 0.5) * outrange);
01104                             const double gradient = (width_1 == 0) ? 0 : outrange / width_1;
01105                             for (i = Count; i != 0; --i)
01106                             {
01107                                 value = OFstatic_cast(double, *(p++));
01108                                 if (value <= leftBorder)
01109                                     *(q++) = low;                                            // black/white
01110                                 else if (value > rightBorder)
01111                                     *(q++) = high;                                           // white/black
01112                                 else
01113                                     *(q++) = OFstatic_cast(T3, offset + value * gradient);   // gray value
01114                             }
01115                         }
01116                     }
01117                 }
01118                 delete[] lut;
01119                 if (Count < FrameSize)
01120                     OFBitmanipTemplate<T3>::zeroMem(Data + Count, FrameSize - Count);        // set remaining pixels of frame to zero
01121             }
01122         } else
01123             Data = NULL;
01124     }
01125 
01126 
01135     void overlay(DiOverlay *overlays[2],
01136                  DiDisplayFunction *disp,
01137                  const Uint16 columns,
01138                  const Uint16 rows,
01139                  const unsigned long frame)
01140     {
01141         if ((Data != NULL) && (overlays != NULL))
01142         {
01143             for (unsigned int j = 0; j < 2; ++j)
01144             {
01145                 if (overlays[j] != NULL)
01146                 {
01147                     if (overlays[j]->getCount() > 0)
01148                         DCMIMGLE_DEBUG("applying " << ((j == 0) ? "built-in" : "additional") << " overlay planes");
01149                     const signed long left_pos = overlays[j]->getLeft();
01150                     const signed long top_pos = overlays[j]->getTop();
01151                     register DiOverlayPlane *plane;
01152                     for (unsigned int i = 0; i < overlays[j]->getCount(); ++i)
01153                     {
01154                         plane = overlays[j]->getPlane(i);
01155                         if ((plane != NULL) && plane->isVisible() && plane->reset(frame))
01156                         {
01157                             register T3 *q;
01158                             register Uint16 x;
01159                             register Uint16 y;
01160                             const Uint16 xmin = (plane->getLeft(left_pos) > 0) ? plane->getLeft(left_pos) : 0;
01161                             const Uint16 ymin = (plane->getTop(top_pos) > 0) ? plane->getTop(top_pos) : 0;
01162                             const Uint16 xmax = (plane->getRight(left_pos) < columns) ? plane->getRight(left_pos) : columns;
01163                             const Uint16 ymax = (plane->getBottom(top_pos) < rows) ? plane->getBottom(top_pos) : rows;
01164                             const T3 maxvalue = OFstatic_cast(T3, DicomImageClass::maxval(bitsof(T3)));
01165                             switch (plane->getMode())
01166                             {
01167                                 case EMO_Replace:
01168                                 {
01169                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'replace' mode");
01170                                     const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue);
01171                                     for (y = ymin; y < ymax; ++y)
01172                                     {
01173                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01174                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01175                                         for (x = xmin; x < xmax; ++x, ++q)
01176                                         {
01177                                             if (plane->getNextBit())
01178                                                 *q = fore;
01179                                         }
01180                                     }
01181                                     break;
01182                                 }
01183                                 case EMO_ThresholdReplace:
01184                                 {
01185                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'threshold replace' mode");
01186                                     const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue);
01187                                     const T3 thresh = OFstatic_cast(T3, plane->getThreshold() * maxvalue);
01188                                     for (y = ymin; y < ymax; ++y)
01189                                     {
01190                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01191                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01192                                         for (x = xmin; x < xmax; ++x, ++q)
01193                                         {
01194                                             if (plane->getNextBit())
01195                                                 *q = (*q <= thresh) ? fore : 1;
01196                                         }
01197                                     }
01198                                     break;
01199                                 }
01200                                 case EMO_Complement:
01201                                 {
01202                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'complement' mode");
01203                                     const T3 thresh = OFstatic_cast(T3, DicomImageClass::maxval(bitsof(T3) / 2));
01204                                     for (y = ymin; y < ymax; ++y)
01205                                     {
01206                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01207                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01208                                         for (x = xmin; x < xmax; ++x, ++q)
01209                                         {
01210                                             if (plane->getNextBit())
01211                                                 *q = (*q <= thresh) ? maxvalue : 0;
01212                                         }
01213                                     }
01214                                     break;
01215                                 }
01216                                 case EMO_InvertBitmap:
01217                                 {
01218                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'invert bitmap' mode");
01219                                     const T3 fore = OFstatic_cast(T3, plane->getForeground() * maxvalue);
01220                                     for (y = ymin; y < ymax; ++y)
01221                                     {
01222                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01223                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01224                                         for (x = xmin; x < xmax; ++x, ++q)
01225                                         {
01226                                             if (!plane->getNextBit())
01227                                                 *q = fore;
01228                                         }
01229                                     }
01230                                     break;
01231                                 }
01232                                 case EMO_RegionOfInterest:
01233                                 {
01234                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'region of interest' mode");
01235                                     const int dim = bitsof(T3) / 2;
01236                                     for (y = ymin; y < ymax; ++y)
01237                                     {
01238                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01239                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01240                                         for (x = xmin; x < xmax; ++x, ++q)
01241                                         {
01242                                             if (!plane->getNextBit())
01243                                                 *q = *q >> dim;
01244                                         }
01245                                     }
01246                                     break;
01247                                 }
01248                                 case EMO_BitmapShutter:
01249                                 {
01250                                     DCMIMGLE_DEBUG("applying overlay plane " << (i + 1) << " with 'bitmap shutter' mode");
01251                                     register T3 fore = OFstatic_cast(T3, OFstatic_cast(double, maxvalue) * OFstatic_cast(double, plane->getPValue()) / OFstatic_cast(double, DicomImageClass::maxval(WIDTH_OF_PVALUES)));
01252                                     if ((disp != NULL) && (disp->isValid()))
01253                                     {
01254                                         const DiDisplayLUT *dlut = disp->getLookupTable(WIDTH_OF_PVALUES);
01255                                         if ((dlut != NULL) && (dlut->isValid()))
01256                                             fore = OFstatic_cast(T3, dlut->getValue(plane->getPValue()));
01257                                     }
01258                                     for (y = ymin; y < ymax; ++y)
01259                                     {
01260                                         plane->setStart(OFstatic_cast(Uint16, left_pos + xmin), OFstatic_cast(Uint16, top_pos + y));
01261                                         q = Data + OFstatic_cast(unsigned long, y) * OFstatic_cast(unsigned long, columns) + OFstatic_cast(unsigned long, xmin);
01262                                         for (x = xmin; x < xmax; ++x, ++q)
01263                                         {
01264                                             if (plane->getNextBit())
01265                                                 *q = fore;
01266                                         }
01267                                     }
01268                                     break;
01269                                 }
01270                                 default: /* e.g. EMO_Default */
01271                                     DCMIMGLE_WARN("unhandled overlay mode (" << OFstatic_cast(int, plane->getMode()) << ")");
01272                             }
01273                         }
01274                     }
01275                 }
01276             }
01277         }
01278     }
01279 
01280 
01282     T3 *Data;
01284     int DeleteData;
01285 
01286 #ifdef PASTEL_COLOR_OUTPUT
01287     DiMonoColorOutputPixelTemplate<T1, T3> *ColorData;
01288 #else
01289     // dummy variable
01290     DiMonoOutputPixel *ColorData;
01291 #endif
01292 
01293  // --- declarations to avoid compiler warnings
01294 
01295     DiMonoOutputPixelTemplate(const DiMonoOutputPixelTemplate<T1,T2,T3> &);
01296     DiMonoOutputPixelTemplate<T1,T2,T3> &operator=(const DiMonoOutputPixelTemplate<T1,T2,T3> &);
01297 };
01298 
01299 
01300 #endif
01301 
01302 
01303 /*
01304  *
01305  * CVS/RCS Log:
01306  * $Log: dimoopxt.h,v $
01307  * Revision 1.54  2010-10-28 10:58:38  joergr
01308  * Implemented missing rendering code for sigmoid VOI LUT function.
01309  * Added more trace log messages which might be helpful for detailed debugging.
01310  *
01311  * Revision 1.53  2010-10-14 13:16:26  joergr
01312  * Updated copyright header. Added reference to COPYRIGHT file.
01313  *
01314  * Revision 1.52  2010-10-05 15:25:10  joergr
01315  * Added preliminary support for VOI LUT function. Please note, however, that
01316  * the sigmoid transformation is not yet implemented.
01317  * In debug mode, output more details on overlay plane to the logger.
01318  *
01319  * Revision 1.51  2010-03-01 09:08:47  uli
01320  * Removed some unnecessary include directives in the headers.
01321  *
01322  * Revision 1.50  2009-11-25 16:08:26  joergr
01323  * Removed inclusion of header file "ofconsol.h".
01324  * Revised logging messages. Added more logging messages.
01325  *
01326  * Revision 1.49  2009-10-28 14:38:16  joergr
01327  * Fixed minor issues in log output.
01328  *
01329  * Revision 1.48  2009-10-28 09:53:40  uli
01330  * Switched to logging mechanism provided by the "new" oflog module.
01331  *
01332  * Revision 1.47  2006-08-15 16:30:11  meichel
01333  * Updated the code in module dcmimgle to correctly compile when
01334  *   all standard C++ classes remain in namespace std.
01335  *
01336  * Revision 1.46  2005/12/08 16:47:54  meichel
01337  * Changed include path schema for all DCMTK header files
01338  *
01339  * Revision 1.45  2005/03/09 17:30:42  joergr
01340  * Added support for new overlay mode "invert bitmap".
01341  *
01342  * Revision 1.44  2004/02/06 11:07:50  joergr
01343  * Distinguish more clearly between const and non-const access to pixel data.
01344  *
01345  * Revision 1.43  2003/12/23 15:53:22  joergr
01346  * Replaced post-increment/decrement operators by pre-increment/decrement
01347  * operators where appropriate (e.g. 'i++' by '++i').
01348  *
01349  * Revision 1.42  2003/12/23 10:51:52  joergr
01350  * Updated documentation to get rid of doxygen warnings.
01351  *
01352  * Revision 1.41  2003/12/09 16:49:11  joergr
01353  * Adapted type casts to new-style typecast operators defined in ofcast.h.
01354  * Removed leading underscore characters from preprocessor symbols (reserved
01355  * symbols). Updated copyright header.
01356  *
01357  * Revision 1.40  2003/06/12 15:08:34  joergr
01358  * Fixed inconsistent API documentation reported by Doxygen.
01359  *
01360  * Revision 1.39  2002/12/09 13:32:53  joergr
01361  * Renamed parameter/local variable to avoid name clashes with global
01362  * declaration left and/or right (used for as iostream manipulators).
01363  *
01364  * Revision 1.38  2002/11/27 14:08:06  meichel
01365  * Adapted module dcmimgle to use of new header file ofstdinc.h
01366  *
01367  * Revision 1.37  2002/06/19 08:12:01  meichel
01368  * Added typecasts to avoid ambiguity with built-in functions on gcc 3.2
01369  *
01370  * Revision 1.36  2001/06/01 15:49:46  meichel
01371  * Updated copyright header
01372  *
01373  * Revision 1.35  2000/05/03 09:46:28  joergr
01374  * Removed most informational and some warning messages from release built
01375  * (#ifndef DEBUG).
01376  *
01377  * Revision 1.34  2000/04/28 12:32:31  joergr
01378  * DebugLevel - global for the module - now derived from OFGlobal (MF-safe).
01379  *
01380  * Revision 1.33  2000/04/27 13:08:40  joergr
01381  * Dcmimgle library code now consistently uses ofConsole for error output.
01382  *
01383  * Revision 1.32  2000/03/08 16:24:20  meichel
01384  * Updated copyright header.
01385  *
01386  * Revision 1.31  2000/03/07 16:15:12  joergr
01387  * Added explicit type casts to make Sun CC 2.0.1 happy.
01388  *
01389  * Revision 1.30  2000/03/06 18:19:36  joergr
01390  * Moved get-method to base class, renamed method and made method virtual to
01391  * avoid hiding of methods (reported by Sun CC 4.2).
01392  *
01393  * Revision 1.29  2000/03/03 14:09:13  meichel
01394  * Implemented library support for redirecting error messages into memory
01395  *   instead of printing them to stdout/stderr for GUI applications.
01396  *
01397  * Revision 1.28  2000/02/01 10:52:37  meichel
01398  * Avoiding to include <stdlib.h> as extern "C" on Borland C++ Builder 4,
01399  *   workaround for bug in compiler header files.
01400  *
01401  * Revision 1.27  1999/10/11 20:14:14  joergr
01402  * Fixed bug in window() routine for cases where presentation LUT is active.
01403  *
01404  * Revision 1.26  1999/10/06 13:42:03  joergr
01405  * Added method to remove reference to (internally handled) pixel data.
01406  *
01407  * Revision 1.25  1999/09/17 12:40:45  joergr
01408  * Added/changed/completed DOC++ style comments in the header files.
01409  * Enhanced efficiency of some "for" loops.
01410  *
01411  * Revision 1.24  1999/09/10 08:45:19  joergr
01412  * Added support for CIELAB display function.
01413  *
01414  * Revision 1.23  1999/08/25 16:41:53  joergr
01415  * Added new feature: Allow clipping region to be outside the image
01416  * (overlapping).
01417  *
01418  * Revision 1.22  1999/08/17 10:26:08  joergr
01419  * Commented unused parameter names to avoid compiler warnings.
01420  *
01421  * Revision 1.21  1999/07/23 14:08:44  joergr
01422  * Changed implementation/interpretation of windows center/width (according to
01423  * new letter ballot of supplement 33).
01424  * Enhanced handling of corrupted pixel data (wrong length).
01425  *
01426  * Revision 1.20  1999/05/03 15:43:21  joergr
01427  * Replaced method applyOptimizationLUT by its contents (method body) to avoid
01428  * warnings (and possible errors) on Sun CC 2.0.1 :-/
01429  *
01430  * Revision 1.18  1999/04/30 16:10:50  meichel
01431  * Minor code purifications to keep IBM xlC quiet
01432  *
01433  * Revision 1.17  1999/04/29 16:46:46  meichel
01434  * Minor code purifications to keep DEC cxx 6 quiet.
01435  *
01436  * Revision 1.16  1999/04/29 09:38:34  joergr
01437  * Changed position of "#ifdef" to avoid compiler warnings.
01438  *
01439  * Revision 1.15  1999/04/29 09:20:01  joergr
01440  * Removed color related image files from public toolkit part.
01441  *
01442  * Revision 1.14  1999/04/28 18:56:07  joergr
01443  * Removed support for pastel color output from public DCMTK part.
01444  *
01445  * Revision 1.13  1999/04/28 14:51:44  joergr
01446  * Added experimental support to create grayscale images with more than 256
01447  * shades of gray to be displayed on a consumer monitor (use pastel colors).
01448  * Introduced new scheme for the debug level variable: now each level can be
01449  * set separately (there is no "include" relationship).
01450  *
01451  * Revision 1.12  1999/03/24 17:20:14  joergr
01452  * Added/Modified comments and formatting.
01453  *
01454  * Revision 1.11  1999/03/02 12:03:52  joergr
01455  * Corrected bug in output routine of monochrome pixel data (wrong scaling when
01456  * Barten transformation and windowing are active).
01457  *
01458  * Revision 1.10  1999/02/28 16:41:01  joergr
01459  * Corrected bug: the output bits for bitmaps shutters were inverted (this was
01460  * done due to an error in the used test images).
01461  *
01462  * Revision 1.9  1999/02/11 16:40:19  joergr
01463  * Added routine to check whether particular grayscale values are unused in
01464  * the output data.
01465  * Removed two small memory leaks reported by dmalloc library.
01466  *
01467  * Revision 1.8  1999/02/05 16:44:52  joergr
01468  * Corrected calculation of DDL value for bitmaps shutters (overlays).
01469  *
01470  * Revision 1.7  1999/02/05 15:13:36  joergr
01471  * Added conversion P-Value to DDL when display function is absent.
01472  *
01473  * Revision 1.6  1999/02/03 17:32:43  joergr
01474  * Added optimization LUT to transform pixel data.
01475  * Added support for calibration according to Barten transformation (incl.
01476  * a DISPLAY file describing the monitor characteristic).
01477  *
01478  * Revision 1.5  1999/01/20 15:11:05  joergr
01479  * Replaced invocation of getCount() by member variable Count where possible.
01480  * Added new output method to fill external memory buffer with rendered pixel
01481  * data.
01482  * Added new overlay plane mode for bitmap shutters.
01483  * Added optimization to modality and VOI transformation (using additional
01484  * LUTs).
01485  *
01486  * Revision 1.4  1998/12/23 12:40:01  joergr
01487  * Removed unused parameter (BitsPerSample).
01488  *
01489  * Revision 1.3  1998/12/22 14:32:49  joergr
01490  * Improved implementation of presentation LUT application (and other gray
01491  * scale transformations). Tested with ECR test images from David Clunie.
01492  *
01493  * Revision 1.2  1998/12/14 17:25:55  joergr
01494  * Added support for correct scaling of input/output values for grayscale
01495  * transformations.
01496  *
01497  * Revision 1.1  1998/11/27 15:29:53  joergr
01498  * Added copyright message.
01499  * Introduced global debug level for dcmimage module to control error output.
01500  * Corrected bug in VOI LUT transformation method.
01501  * Changed behaviour: now window width of 0 is valid and negative width
01502  * is invalid.
01503  *
01504  * Revision 1.6  1998/07/01 08:39:24  joergr
01505  * Minor changes to avoid compiler warnings (gcc 2.8.1 with additional
01506  * options), e.g. add copy constructors.
01507  *
01508  * Revision 1.5  1998/05/11 14:53:22  joergr
01509  * Added CVS/RCS header to each file.
01510  *
01511  *
01512  */


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