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 */