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: DicomRotateTemplate (Header) 00019 * 00020 * Last Update: $Author: joergr $ 00021 * Update Date: $Date: 2010-10-14 13:16:27 $ 00022 * CVS/RCS Revision: $Revision: 1.21 $ 00023 * Status: $State: Exp $ 00024 * 00025 * CVS/RCS Log at end of file 00026 * 00027 */ 00028 00029 00030 #ifndef DIROTAT_H 00031 #define DIROTAT_H 00032 00033 #include "dcmtk/config/osconfig.h" 00034 #include "dcmtk/ofstd/ofcast.h" 00035 00036 #include "dcmtk/dcmimgle/dipixel.h" 00037 #include "dcmtk/dcmimgle/ditranst.h" 00038 00039 00040 /*---------------------* 00041 * class declaration * 00042 *---------------------*/ 00043 00047 template<class T> 00048 class DiRotateTemplate 00049 : public DiTransTemplate<T> 00050 { 00051 00052 public: 00053 00065 DiRotateTemplate(DiPixel *pixel, 00066 const Uint16 src_cols, 00067 const Uint16 src_rows, 00068 const Uint16 dest_cols, 00069 const Uint16 dest_rows, 00070 const Uint32 frames, 00071 const int degree) 00072 : DiTransTemplate<T>(0, src_cols, src_rows, dest_cols, dest_rows, frames) 00073 { 00074 if (pixel != NULL) 00075 { 00076 this->Planes = pixel->getPlanes(); 00077 if ((pixel->getCount() > 0) && (this->Planes > 0) && 00078 (pixel->getCount() == OFstatic_cast(unsigned long, src_cols) * OFstatic_cast(unsigned long, src_rows) * frames)) 00079 { 00080 if (degree == 90) 00081 rotateRight(OFstatic_cast(T **, pixel->getDataArrayPtr())); 00082 else if (degree == 180) 00083 rotateTopDown(OFstatic_cast(T **, pixel->getDataArrayPtr())); 00084 else if (degree == 270) 00085 rotateLeft(OFstatic_cast(T **, pixel->getDataArrayPtr())); 00086 } else { 00087 DCMIMGLE_WARN("could not rotate image ... corrupted data"); 00088 } 00089 } 00090 } 00091 00102 DiRotateTemplate(const int planes, 00103 const Uint16 src_cols, 00104 const Uint16 src_rows, 00105 const Uint16 dest_cols, 00106 const Uint16 dest_rows, 00107 const Uint32 frames) 00108 : DiTransTemplate<T>(planes, src_cols, src_rows, dest_cols, dest_rows, frames) 00109 { 00110 } 00111 00114 virtual ~DiRotateTemplate() 00115 { 00116 } 00117 00124 inline void rotateData(const T *src[], 00125 T *dest[], 00126 const int degree) 00127 { 00128 if (degree == 90) 00129 rotateRight(src, dest); 00130 else if (degree == 180) 00131 rotateTopDown(src, dest); 00132 else if (degree == 270) 00133 rotateLeft(src, dest); 00134 else 00135 copyPixel(src, dest); 00136 } 00137 00138 00139 protected: 00140 00146 inline void rotateLeft(const T *src[], 00147 T *dest[]) 00148 { 00149 if ((src != NULL) && (dest != NULL)) 00150 { 00151 register Uint16 x; 00152 register Uint16 y; 00153 register const T *p; 00154 register T *q; 00155 register T *r; 00156 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00157 for (int j = 0; j < this->Planes; ++j) 00158 { 00159 p = src[j]; 00160 r = dest[j]; 00161 for (unsigned long f = this->Frames; f != 0; --f) 00162 { 00163 r += count; 00164 for (x = this->Dest_X; x != 0; --x) 00165 { 00166 q = r - x; 00167 for (y = this->Dest_Y; y != 0; --y) 00168 { 00169 *q = *p++; 00170 q -= this->Dest_X; 00171 } 00172 } 00173 } 00174 } 00175 } 00176 } 00177 00183 inline void rotateRight(const T *src[], 00184 T *dest[]) 00185 { 00186 if ((src != NULL) && (dest != NULL)) 00187 { 00188 register Uint16 x; 00189 register Uint16 y; 00190 register const T *p; 00191 register T *q; 00192 register T *r; 00193 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00194 for (int j = 0; j < this->Planes; ++j) 00195 { 00196 p = src[j]; 00197 r = dest[j]; 00198 for (unsigned long f = this->Frames; f != 0; --f) 00199 { 00200 for (x = this->Dest_X; x != 0; --x) 00201 { 00202 q = r + x - 1; 00203 for (y = this->Dest_Y; y != 0; --y) 00204 { 00205 *q = *p++; 00206 q += this->Dest_X; 00207 } 00208 } 00209 r += count; 00210 } 00211 } 00212 } 00213 } 00214 00220 inline void rotateTopDown(const T *src[], 00221 T *dest[]) 00222 { 00223 if ((src != NULL) && (dest != NULL)) 00224 { 00225 register unsigned long i; 00226 register const T *p; 00227 register T *q; 00228 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00229 for (int j = 0; j < this->Planes; ++j) 00230 { 00231 p = src[j]; 00232 q = dest[j]; 00233 for (unsigned long f = this->Frames; f != 0; --f) 00234 { 00235 q += count; 00236 for (i = count; i != 0; --i) 00237 *--q = *p++; 00238 q += count; 00239 } 00240 } 00241 } 00242 } 00243 00244 private: 00245 00250 inline void rotateLeft(T *data[]) 00251 { 00252 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00253 T *temp = new T[count]; 00254 if (temp != NULL) 00255 { 00256 register Uint16 x; 00257 register Uint16 y; 00258 register const T *p; 00259 register T *q; 00260 register T *r; 00261 for (int j = 0; j < this->Planes; ++j) 00262 { 00263 r = data[j]; 00264 for (unsigned long f = this->Frames; f != 0; --f) 00265 { 00266 OFBitmanipTemplate<T>::copyMem(OFstatic_cast(const T *, r), temp, count); // create temporary copy of current frame 00267 p = temp; 00268 r += count; 00269 for (x = this->Dest_X; x != 0; --x) 00270 { 00271 q = r - x; 00272 for (y = this->Dest_Y; y != 0; --y) 00273 { 00274 *q = *p++; 00275 q -= this->Dest_X; 00276 } 00277 } 00278 } 00279 } 00280 delete[] temp; 00281 } 00282 } 00283 00288 inline void rotateRight(T *data[]) 00289 { 00290 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00291 T *temp = new T[count]; 00292 if (temp != NULL) 00293 { 00294 register Uint16 x; 00295 register Uint16 y; 00296 register const T *p; 00297 register T *q; 00298 register T *r; 00299 for (int j = 0; j < this->Planes; ++j) 00300 { 00301 r = data[j]; 00302 for (unsigned long f = this->Frames; f != 0; --f) 00303 { 00304 OFBitmanipTemplate<T>::copyMem(OFstatic_cast(const T *, r), temp, count); // create temporary copy of current frame 00305 p = temp; 00306 for (x = this->Dest_X; x != 0; --x) 00307 { 00308 q = r + x - 1; 00309 for (y = this->Dest_Y; y != 0; --y) 00310 { 00311 *q = *p++; 00312 q += this->Dest_X; 00313 } 00314 } 00315 r += count; 00316 } 00317 } 00318 delete[] temp; 00319 } 00320 } 00321 00326 inline void rotateTopDown(T *data[]) 00327 { 00328 register unsigned long i; 00329 register T *p; 00330 register T *q; 00331 register T t; 00332 T *s; 00333 const unsigned long count = OFstatic_cast(unsigned long, this->Dest_X) * OFstatic_cast(unsigned long, this->Dest_Y); 00334 for (int j = 0; j < this->Planes; ++j) 00335 { 00336 s = data[j]; 00337 for (unsigned long f = this->Frames; f != 0; --f) 00338 { 00339 p = s; 00340 q = s + count; 00341 for (i = count / 2; i != 0; --i) 00342 { 00343 t = *p; 00344 *p++ = *--q; 00345 *q = t; 00346 } 00347 s += count; 00348 } 00349 } 00350 } 00351 }; 00352 00353 00354 #endif 00355 00356 00357 /* 00358 * 00359 * CVS/RCS Log: 00360 * $Log: dirotat.h,v $ 00361 * Revision 1.21 2010-10-14 13:16:27 joergr 00362 * Updated copyright header. Added reference to COPYRIGHT file. 00363 * 00364 * Revision 1.20 2010-03-01 09:08:47 uli 00365 * Removed some unnecessary include directives in the headers. 00366 * 00367 * Revision 1.19 2009-10-28 14:38:17 joergr 00368 * Fixed minor issues in log output. 00369 * 00370 * Revision 1.18 2009-10-28 09:53:40 uli 00371 * Switched to logging mechanism provided by the "new" oflog module. 00372 * 00373 * Revision 1.17 2006-08-15 16:30:11 meichel 00374 * Updated the code in module dcmimgle to correctly compile when 00375 * all standard C++ classes remain in namespace std. 00376 * 00377 * Revision 1.16 2005/12/08 16:48:08 meichel 00378 * Changed include path schema for all DCMTK header files 00379 * 00380 * Revision 1.15 2005/06/15 08:23:54 joergr 00381 * Fixed bug which prevented rotateTopDown() from rotating multi-frame images 00382 * correctly (only the first frame was actually rotated). 00383 * 00384 * Revision 1.14 2004/04/21 10:00:36 meichel 00385 * Minor modifications for compilation with gcc 3.4.0 00386 * 00387 * Revision 1.13 2004/02/06 11:07:50 joergr 00388 * Distinguish more clearly between const and non-const access to pixel data. 00389 * 00390 * Revision 1.12 2003/12/23 15:53:22 joergr 00391 * Replaced post-increment/decrement operators by pre-increment/decrement 00392 * operators where appropriate (e.g. 'i++' by '++i'). 00393 * 00394 * Revision 1.11 2003/12/09 10:14:54 joergr 00395 * Adapted type casts to new-style typecast operators defined in ofcast.h. 00396 * Removed leading underscore characters from preprocessor symbols (reserved 00397 * symbols). Updated copyright header. 00398 * 00399 * Revision 1.10 2001/06/01 15:49:50 meichel 00400 * Updated copyright header 00401 * 00402 * Revision 1.9 2000/09/12 10:04:45 joergr 00403 * Corrected bug: wrong parameter for attribute search routine led to crashes 00404 * when multiple pixel data attributes were contained in the dataset (e.g. 00405 * IconImageSequence). Added new checking routines to avoid crashes when 00406 * processing corrupted image data. 00407 * 00408 * Revision 1.8 2000/03/08 16:24:24 meichel 00409 * Updated copyright header. 00410 * 00411 * Revision 1.7 2000/03/02 12:51:37 joergr 00412 * Rewrote variable initialization in class contructors to avoid warnings 00413 * reported on Irix. 00414 * 00415 * Revision 1.6 1999/09/17 13:07:20 joergr 00416 * Added/changed/completed DOC++ style comments in the header files. 00417 * Enhanced efficiency of some "for" loops. 00418 * 00419 * Revision 1.5 1999/03/24 17:17:20 joergr 00420 * Removed debug code. 00421 * Added/Modified comments and formatting. 00422 * 00423 * Revision 1.4 1999/01/20 15:12:47 joergr 00424 * Added debug code to measure time of some routines. 00425 * 00426 * Revision 1.3 1998/12/16 16:38:49 joergr 00427 * Added additional case to copy pixels. 00428 * 00429 * Revision 1.2 1998/12/14 17:30:49 joergr 00430 * Added (missing) implementation of methods to rotate images/frames without 00431 * creating a new DicomImage. 00432 * 00433 * Revision 1.1 1998/11/27 14:57:46 joergr 00434 * Added copyright message. 00435 * Added methods and classes for flipping and rotating, changed for 00436 * scaling and clipping. 00437 * 00438 * 00439 */