dirotat.h

00001 /*
00002  *
00003  *  Copyright (C) 1996-2005, OFFIS
00004  *
00005  *  This software and supporting documentation were developed by
00006  *
00007  *    Kuratorium OFFIS e.V.
00008  *    Healthcare Information and Communication Systems
00009  *    Escherweg 2
00010  *    D-26121 Oldenburg, Germany
00011  *
00012  *  THIS SOFTWARE IS MADE AVAILABLE,  AS IS,  AND OFFIS MAKES NO  WARRANTY
00013  *  REGARDING  THE  SOFTWARE,  ITS  PERFORMANCE,  ITS  MERCHANTABILITY  OR
00014  *  FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES  OR
00015  *  ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
00016  *  PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
00017  *
00018  *  Module:  dcmimgle
00019  *
00020  *  Author:  Joerg Riesmeier
00021  *
00022  *  Purpose: DicomRotateTemplate (Header)
00023  *
00024  *  Last Update:      $Author: meichel $
00025  *  Update Date:      $Date: 2005/12/08 16:48:08 $
00026  *  CVS/RCS Revision: $Revision: 1.16 $
00027  *  Status:           $State: Exp $
00028  *
00029  *  CVS/RCS Log at end of file
00030  *
00031  */
00032 
00033 
00034 #ifndef DIROTAT_H
00035 #define DIROTAT_H
00036 
00037 #include "dcmtk/config/osconfig.h"
00038 #include "dcmtk/ofstd/ofcast.h"
00039 #include "dcmtk/dcmdata/dctypes.h"
00040 
00041 #include "dcmtk/dcmimgle/dipixel.h"
00042 #include "dcmtk/dcmimgle/ditranst.h"
00043 
00044 
00045 /*---------------------*
00046  *  class declaration  *
00047  *---------------------*/
00048 
00052 template<class T>
00053 class DiRotateTemplate
00054   : public DiTransTemplate<T>
00055 {
00056 
00057  public:
00058 
00070     DiRotateTemplate(DiPixel *pixel,
00071                      const Uint16 src_cols,
00072                      const Uint16 src_rows,
00073                      const Uint16 dest_cols,
00074                      const Uint16 dest_rows,
00075                      const Uint32 frames,
00076                      const int degree)
00077       : DiTransTemplate<T>(0, src_cols, src_rows, dest_cols, dest_rows, frames)
00078     {
00079         if (pixel != NULL)
00080         {
00081             this->Planes = pixel->getPlanes();
00082             if ((pixel->getCount() > 0) && (this->Planes > 0) &&
00083                 (pixel->getCount() == OFstatic_cast(unsigned long, src_cols) * OFstatic_cast(unsigned long, src_rows) * frames))
00084             {
00085                 if (degree == 90)
00086                     rotateRight(OFstatic_cast(T **, pixel->getDataArrayPtr()));
00087                 else if (degree == 180)
00088                     rotateTopDown(OFstatic_cast(T **, pixel->getDataArrayPtr()));
00089                 else if (degree == 270)
00090                     rotateLeft(OFstatic_cast(T **, pixel->getDataArrayPtr()));
00091             } else {
00092                 if (DicomImageClass::checkDebugLevel(DicomImageClass::DL_Warnings))
00093                 {
00094                    ofConsole.lockCerr() << "WARNING: could not rotate image ... corrupted data." << endl;
00095                    ofConsole.unlockCerr();
00096                 }
00097             }
00098         }
00099     }
00100 
00111     DiRotateTemplate(const int planes,
00112                      const Uint16 src_cols,
00113                      const Uint16 src_rows,
00114                      const Uint16 dest_cols,
00115                      const Uint16 dest_rows,
00116                      const Uint32 frames)
00117       : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames)
00118     {
00119     }
00120 
00123     virtual ~DiRotateTemplate()
00124     {
00125     }
00126 
00133     inline void rotateData(const T *src[],
00134                            T *dest[],
00135                            const int degree)
00136     {
00137         if (degree == 90)
00138             rotateRight(src, dest);
00139         else if (degree == 180)
00140             rotateTopDown(src, dest);
00141         else if (degree == 270)
00142             rotateLeft(src, dest);
00143         else
00144             copyPixel(src, dest);
00145     }
00146 
00147 
00148  protected:
00149 
00155     inline void rotateLeft(const T *src[],
00156                            T *dest[])
00157     {
00158         if ((src != NULL) && (dest != NULL))
00159         {
00160             register Uint16 x;
00161             register Uint16 y;
00162             register const T *p;
00163             register T *q;
00164             register T *r;
00165             const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00166             for (int j = 0; j < this->Planes; ++j)
00167             {
00168                 p = src[j];
00169                 r = dest[j];
00170                 for (unsigned long f = this->Frames; f != 0; --f)
00171                 {
00172                     r += count;
00173                     for (x = this->Dest_X; x != 0; --x)
00174                     {
00175                         q = r - x;
00176                         for (y = this->Dest_Y; y != 0; --y)
00177                         {
00178                             *q = *p++;
00179                             q -= this->Dest_X;
00180                         }
00181                     }
00182                 }
00183             }
00184         }
00185     }
00186 
00192     inline void rotateRight(const T *src[],
00193                             T *dest[])
00194     {
00195         if ((src != NULL) && (dest != NULL))
00196         {
00197             register Uint16 x;
00198             register Uint16 y;
00199             register const T *p;
00200             register T *q;
00201             register T *r;
00202             const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00203             for (int j = 0; j < this->Planes; ++j)
00204             {
00205                 p = src[j];
00206                 r = dest[j];
00207                 for (unsigned long f = this->Frames; f != 0; --f)
00208                 {
00209                     for (x = this->Dest_X; x != 0; --x)
00210                     {
00211                         q = r + x - 1;
00212                         for (y = this->Dest_Y; y != 0; --y)
00213                         {
00214                             *q = *p++;
00215                             q += this->Dest_X;
00216                         }
00217                     }
00218                     r += count;
00219                 }
00220             }
00221         }
00222     }
00223 
00229     inline void rotateTopDown(const T *src[],
00230                               T *dest[])
00231     {
00232         if ((src != NULL) && (dest != NULL))
00233         {
00234             register unsigned long i;
00235             register const T *p;
00236             register T *q;
00237             const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00238             for (int j = 0; j < this->Planes; ++j)
00239             {
00240                 p = src[j];
00241                 q = dest[j];
00242                 for (unsigned long f = this->Frames; f != 0; --f)
00243                 {
00244                     q += count;
00245                     for (i = count; i != 0; --i)
00246                         *--q = *p++;
00247                     q += count;
00248                 }
00249             }
00250         }
00251     }
00252 
00253  private:
00254 
00259     inline void rotateLeft(T *data[])
00260     {
00261         const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00262         T *temp = new T[count];
00263         if (temp != NULL)
00264         {
00265             register Uint16 x;
00266             register Uint16 y;
00267             register const T *p;
00268             register T *q;
00269             register T *r;
00270             for (int j = 0; j < this->Planes; ++j)
00271             {
00272                 r = data[j];
00273                 for (unsigned long f = this->Frames; f != 0; --f)
00274                 {
00275                     OFBitmanipTemplate<T>::copyMem(OFstatic_cast(const T *, r), temp, count);  // create temporary copy of current frame
00276                     p = temp;
00277                     r += count;
00278                     for (x = this->Dest_X; x != 0; --x)
00279                     {
00280                         q = r - x;
00281                         for (y = this->Dest_Y; y != 0; --y)
00282                         {
00283                             *q = *p++;
00284                             q -= this->Dest_X;
00285                         }
00286                     }
00287                 }
00288             }
00289             delete[] temp;
00290         }
00291     }
00292 
00297     inline void rotateRight(T *data[])
00298     {
00299         const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00300         T *temp = new T[count];
00301         if (temp != NULL)
00302         {
00303             register Uint16 x;
00304             register Uint16 y;
00305             register const T *p;
00306             register T *q;
00307             register T *r;
00308             for (int j = 0; j < this->Planes; ++j)
00309             {
00310                 r = data[j];
00311                 for (unsigned long f = this->Frames; f != 0; --f)
00312                 {
00313                     OFBitmanipTemplate<T>::copyMem(OFstatic_cast(const T *, r), temp, count);  // create temporary copy of current frame
00314                     p = temp;
00315                     for (x = this->Dest_X; x != 0; --x)
00316                     {
00317                         q = r + x - 1;
00318                         for (y = this->Dest_Y; y != 0; --y)
00319                         {
00320                             *q = *p++;
00321                             q += this->Dest_X;
00322                         }
00323                     }
00324                     r += count;
00325                 }
00326             }
00327             delete[] temp;
00328         }
00329     }
00330 
00335     inline void rotateTopDown(T *data[])
00336     {
00337         register unsigned long i;
00338         register T *p;
00339         register T *q;
00340         register T t;
00341         T *s;
00342         const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y);
00343         for (int j = 0; j < this->Planes; ++j)
00344         {
00345             s = data[j];
00346             for (unsigned long f = this->Frames; f != 0; --f)
00347             {
00348                 p = s;
00349                 q = s + count;
00350                 for (i = count / 2; i != 0; --i)
00351                 {
00352                     t = *p;
00353                     *p++ = *--q;
00354                     *q = t;
00355                 }
00356                 s += count;
00357             }
00358         }
00359     }
00360 };
00361 
00362 
00363 #endif
00364 
00365 
00366 /*
00367  *
00368  * CVS/RCS Log:
00369  * $Log: dirotat.h,v $
00370  * Revision 1.16  2005/12/08 16:48:08  meichel
00371  * Changed include path schema for all DCMTK header files
00372  *
00373  * Revision 1.15  2005/06/15 08:23:54  joergr
00374  * Fixed bug which prevented rotateTopDown() from rotating multi-frame images
00375  * correctly (only the first frame was actually rotated).
00376  *
00377  * Revision 1.14  2004/04/21 10:00:36  meichel
00378  * Minor modifications for compilation with gcc 3.4.0
00379  *
00380  * Revision 1.13  2004/02/06 11:07:50  joergr
00381  * Distinguish more clearly between const and non-const access to pixel data.
00382  *
00383  * Revision 1.12  2003/12/23 15:53:22  joergr
00384  * Replaced post-increment/decrement operators by pre-increment/decrement
00385  * operators where appropriate (e.g. 'i++' by '++i').
00386  *
00387  * Revision 1.11  2003/12/09 10:14:54  joergr
00388  * Adapted type casts to new-style typecast operators defined in ofcast.h.
00389  * Removed leading underscore characters from preprocessor symbols (reserved
00390  * symbols). Updated copyright header.
00391  *
00392  * Revision 1.10  2001/06/01 15:49:50  meichel
00393  * Updated copyright header
00394  *
00395  * Revision 1.9  2000/09/12 10:04:45  joergr
00396  * Corrected bug: wrong parameter for attribute search routine led to crashes
00397  * when multiple pixel data attributes were contained in the dataset (e.g.
00398  * IconImageSequence). Added new checking routines to avoid crashes when
00399  * processing corrupted image data.
00400  *
00401  * Revision 1.8  2000/03/08 16:24:24  meichel
00402  * Updated copyright header.
00403  *
00404  * Revision 1.7  2000/03/02 12:51:37  joergr
00405  * Rewrote variable initialization in class contructors to avoid warnings
00406  * reported on Irix.
00407  *
00408  * Revision 1.6  1999/09/17 13:07:20  joergr
00409  * Added/changed/completed DOC++ style comments in the header files.
00410  * Enhanced efficiency of some "for" loops.
00411  *
00412  * Revision 1.5  1999/03/24 17:17:20  joergr
00413  * Removed debug code.
00414  * Added/Modified comments and formatting.
00415  *
00416  * Revision 1.4  1999/01/20 15:12:47  joergr
00417  * Added debug code to measure time of some routines.
00418  *
00419  * Revision 1.3  1998/12/16 16:38:49  joergr
00420  * Added additional case to copy pixels.
00421  *
00422  * Revision 1.2  1998/12/14 17:30:49  joergr
00423  * Added (missing) implementation of methods to rotate images/frames without
00424  * creating a new DicomImage.
00425  *
00426  * Revision 1.1  1998/11/27 14:57:46  joergr
00427  * Added copyright message.
00428  * Added methods and classes for flipping and rotating, changed for
00429  * scaling and clipping.
00430  *
00431  *
00432  */


Generated on 20 Dec 2005 for OFFIS DCMTK Version 3.5.4 by Doxygen 1.4.5