OFFIS DCMTK  Version 3.6.0
diybrpxt.h
1 /*
2  *
3  * Copyright (C) 1998-2011, OFFIS e.V.
4  * All rights reserved. See COPYRIGHT file for details.
5  *
6  * This software and supporting documentation were developed by
7  *
8  * OFFIS e.V.
9  * R&D Division Health
10  * Escherweg 2
11  * D-26121 Oldenburg, Germany
12  *
13  *
14  * Module: dcmimage
15  *
16  * Author: Joerg Riesmeier
17  *
18  * Purpose: DicomYBRPixelTemplate (Header)
19  *
20  * Last Update: $Author: joergr $
21  * Update Date: $Date: 2011-11-17 16:13:14 $
22  * CVS/RCS Revision: $Revision: 1.20 $
23  * Status: $State: Exp $
24  *
25  * CVS/RCS Log at end of file
26  *
27  */
28 
29 
30 #ifndef DIYBRPXT_H
31 #define DIYBRPXT_H
32 
33 #include "dcmtk/config/osconfig.h"
34 
35 #include "dcmtk/dcmimage/dicopxt.h"
36 #include "dcmtk/dcmimgle/diinpx.h" /* gcc 3.4 needs this */
37 
38 
39 /*---------------------*
40  * class declaration *
41  *---------------------*/
42 
45 template<class T1, class T2>
47  : public DiColorPixelTemplate<T2>
48 {
49 
50  public:
51 
62  const DiInputPixel *pixel,
63  EI_Status &status,
64  const unsigned long planeSize,
65  const int bits,
66  const OFBool rgb)
67  : DiColorPixelTemplate<T2>(docu, pixel, 3, status)
68  {
69  if ((pixel != NULL) && (this->Count > 0) && (status == EIS_Normal))
70  convert(OFstatic_cast(const T1 *, pixel->getData()) + pixel->getPixelStart(), planeSize, bits, rgb);
71  }
72 
76  {
77  }
78 
79 
80  private:
81 
89  void convert(const T1 *pixel,
90  const unsigned long planeSize,
91  const int bits,
92  const OFBool rgb)
93  {
94  if (this->Init(pixel))
95  {
96  const T1 offset = OFstatic_cast(T1, DicomImageClass::maxval(bits - 1));
97  // use the number of input pixels derived from the length of the 'PixelData'
98  // attribute), but not more than the size of the intermediate buffer
99  const unsigned long count = (this->InputCount < this->Count) ? this->InputCount : this->Count;
100  if (rgb) /* convert to RGB model */
101  {
102  register T2 *r = this->Data[0];
103  register T2 *g = this->Data[1];
104  register T2 *b = this->Data[2];
105  const T2 maxvalue = OFstatic_cast(T2, DicomImageClass::maxval(bits));
107  if (bits == 8 && !rep.isSigned()) // only for unsigned 8 bit
108  {
109  Sint16 rcr_tab[256];
110  Sint16 gcb_tab[256];
111  Sint16 gcr_tab[256];
112  Sint16 bcb_tab[256];
113  const double r_const = 0.7010 * OFstatic_cast(double, maxvalue);
114  const double g_const = 0.5291 * OFstatic_cast(double, maxvalue);
115  const double b_const = 0.8859 * OFstatic_cast(double, maxvalue);
116  register unsigned long l;
117  for (l = 0; l < 256; ++l)
118  {
119  rcr_tab[l] = OFstatic_cast(Sint16, 1.4020 * OFstatic_cast(double, l) - r_const);
120  gcb_tab[l] = OFstatic_cast(Sint16, 0.3441 * OFstatic_cast(double, l));
121  gcr_tab[l] = OFstatic_cast(Sint16, 0.7141 * OFstatic_cast(double, l) - g_const);
122  bcb_tab[l] = OFstatic_cast(Sint16, 1.7720 * OFstatic_cast(double, l) - b_const);
123  }
124  register Sint32 sr;
125  register Sint32 sg;
126  register Sint32 sb;
127  if (this->PlanarConfiguration)
128  {
129 /*
130  register const T1 *y = pixel;
131  register const T1 *cb = y + this->InputCount;
132  register const T1 *cr = cb + this->InputCount;
133  for (i = count; i != 0; --i, ++y, ++cb, ++cr)
134  {
135  sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[*cr]);
136  sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[*cb]) - OFstatic_cast(Sint32, gcr_tab[*cr]);
137  sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[*cb]);
138  *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
139  *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
140  *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
141  }
142 */
143  register const T1 *y = pixel;
144  register const T1 *cb = y + planeSize;
145  register const T1 *cr = cb + planeSize;
146  register unsigned long i = count;
147  while (i != 0)
148  {
149  /* convert a single frame */
150  for (l = planeSize; (l != 0) && (i != 0); --l, --i, ++y, ++cb, ++cr)
151  {
152  sr = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, *cr)]);
153  sg = OFstatic_cast(Sint32, *y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, *cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, *cr)]);
154  sb = OFstatic_cast(Sint32, *y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, *cb)]);
155  *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
156  *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
157  *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
158  }
159  /* jump to next frame start (skip 2 planes) */
160  y += 2 * planeSize;
161  cb += 2 * planeSize;
162  cr += 2 * planeSize;
163  }
164  }
165  else
166  {
167  register const T1 *p = pixel;
168  register T1 y;
169  register T1 cb;
170  register T1 cr;
171  register unsigned long i;
172  for (i = count; i != 0; --i)
173  {
174  y = *(p++);
175  cb = *(p++);
176  cr = *(p++);
177  sr = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, rcr_tab[OFstatic_cast(Uint32, cr)]);
178  sg = OFstatic_cast(Sint32, y) - OFstatic_cast(Sint32, gcb_tab[OFstatic_cast(Uint32, cb)]) - OFstatic_cast(Sint32, gcr_tab[OFstatic_cast(Uint32, cr)]);
179  sb = OFstatic_cast(Sint32, y) + OFstatic_cast(Sint32, bcb_tab[OFstatic_cast(Uint32, cb)]);
180  *(r++) = (sr < 0) ? 0 : (sr > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sr);
181  *(g++) = (sg < 0) ? 0 : (sg > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sg);
182  *(b++) = (sb < 0) ? 0 : (sb > OFstatic_cast(Sint32, maxvalue)) ? maxvalue : OFstatic_cast(T2, sb);
183  }
184  }
185  }
186  else
187  {
188  if (this->PlanarConfiguration)
189  {
190 /*
191  register const T1 *y = pixel;
192  register const T1 *cb = y + this->InputCount;
193  register const T1 *cr = cb + this->InputCount;
194  for (i = count; i != 0; --i)
195  convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
196  removeSign(*(cr++), offset), maxvalue);
197 */
198  register unsigned long l;
199  register unsigned long i = count;
200  register const T1 *y = pixel;
201  register const T1 *cb = y + planeSize;
202  register const T1 *cr = cb + planeSize;
203  while (i != 0)
204  {
205  /* convert a single frame */
206  for (l = planeSize; (l != 0) && (i != 0); --l, --i)
207  {
208  convertValue(*(r++), *(g++), *(b++), removeSign(*(y++), offset), removeSign(*(cb++), offset),
209  removeSign(*(cr++), offset), maxvalue);
210  }
211  /* jump to next frame start (skip 2 planes) */
212  y += 2 * planeSize;
213  cb += 2 * planeSize;
214  cr += 2 * planeSize;
215  }
216  }
217  else
218  {
219  register const T1 *p = pixel;
220  register T2 y;
221  register T2 cb;
222  register T2 cr;
223  register unsigned long i;
224  for (i = count; i != 0; --i)
225  {
226  y = removeSign(*(p++), offset);
227  cb = removeSign(*(p++), offset);
228  cr = removeSign(*(p++), offset);
229  convertValue(*(r++), *(g++), *(b++), y, cb, cr, maxvalue);
230  }
231  }
232  }
233  } else { /* retain YCbCr model */
234  register const T1 *p = pixel;
235  if (this->PlanarConfiguration)
236  {
237 /*
238  register T2 *q;
239  // number of pixels to be skipped (only applicable if 'PixelData' contains more
240  // pixels than expected)
241  const unsigned long skip = (this->InputCount > this->Count) ? (this->InputCount - this->Count) : 0;
242  for (int j = 0; j < 3; ++j)
243  {
244  q = this->Data[j];
245  for (i = count; i != 0; --i)
246  *(q++) = removeSign(*(p++), offset);
247  // skip to beginning of next plane
248  p += skip;
249  }
250 */
251  register unsigned long l;
252  register unsigned long i = 0;
253  while (i < count)
254  {
255  /* store current pixel index */
256  const unsigned long iStart = i;
257  for (int j = 0; j < 3; ++j)
258  {
259  /* convert a single plane */
260  for (l = planeSize, i = iStart; (l != 0) && (i < count); --l, ++i)
261  this->Data[j][i] = removeSign(*(p++), offset);
262  }
263  }
264  }
265  else
266  {
267  register int j;
268  register unsigned long i;
269  for (i = 0; i < count; ++i) /* for all pixel ... */
270  for (j = 0; j < 3; ++j)
271  this->Data[j][i] = removeSign(*(p++), offset); /* ... copy planes */
272  }
273  }
274  }
275  }
276 
279  inline void convertValue(T2 &red, T2 &green, T2 &blue, const T2 y, const T2 cb, const T2 cr, const T2 maxvalue)
280  {
281  double dr = OFstatic_cast(double, y) + 1.4020 * OFstatic_cast(double, cr) - 0.7010 * OFstatic_cast(double, maxvalue);
282  double dg = OFstatic_cast(double, y) - 0.3441 * OFstatic_cast(double, cb) - 0.7141 * OFstatic_cast(double, cr) + 0.5291 * OFstatic_cast(double, maxvalue);
283  double db = OFstatic_cast(double, y) + 1.7720 * OFstatic_cast(double, cb) - 0.8859 * OFstatic_cast(double, maxvalue);
284  red = (dr < 0.0) ? 0 : (dr > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, dr);
285  green = (dg < 0.0) ? 0 : (dg > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, dg);
286  blue = (db < 0.0) ? 0 : (db > OFstatic_cast(double, maxvalue)) ? maxvalue : OFstatic_cast(T2, db);
287  }
288 };
289 
290 
291 #endif
292 
293 
294 /*
295  *
296  * CVS/RCS Log:
297  * $Log: diybrpxt.h,v $
298  * Revision 1.20 2011-11-17 16:13:14 joergr
299  * Minor fixes to keep XCode 4.2 on Mac OS X Lion (clang compiler) quiet.
300  *
301  * Revision 1.19 2010-10-14 13:16:30 joergr
302  * Updated copyright header. Added reference to COPYRIGHT file.
303  *
304  * Revision 1.18 2010-03-01 09:08:46 uli
305  * Removed some unnecessary include directives in the headers.
306  *
307  * Revision 1.17 2005-12-08 16:02:01 meichel
308  * Changed include path schema for all DCMTK header files
309  *
310  * Revision 1.16 2004/04/21 10:00:31 meichel
311  * Minor modifications for compilation with gcc 3.4.0
312  *
313  * Revision 1.15 2004/02/06 11:16:35 joergr
314  * Added typecast to array indexes to avoid warning messages on MacOS X 10.3
315  * with gcc 3.3.
316  *
317  * Revision 1.14 2003/12/23 12:30:34 joergr
318  * Adapted type casts to new-style typecast operators defined in ofcast.h.
319  * Removed leading underscore characters from preprocessor symbols (reserved
320  * symbols). Updated copyright header.
321  * Replaced post-increment/decrement operators by pre-increment/decrement
322  * operators where appropriate (e.g. 'i++' by '++i').
323  *
324  * Revision 1.13 2002/06/26 16:20:19 joergr
325  * Enhanced handling of corrupted pixel data and/or length.
326  * Corrected decoding of multi-frame, planar images.
327  *
328  * Revision 1.12 2001/11/09 16:47:03 joergr
329  * Removed 'inline' specifier from certain methods.
330  *
331  * Revision 1.11 2001/09/28 13:55:41 joergr
332  * Added new flag (CIF_KeepYCbCrColorModel) which avoids conversion of YCbCr
333  * color models to RGB.
334  *
335  * Revision 1.10 2001/06/01 15:49:32 meichel
336  * Updated copyright header
337  *
338  * Revision 1.9 2000/04/27 13:15:15 joergr
339  * Dcmimage library code now consistently uses ofConsole for error output.
340  *
341  * Revision 1.8 2000/03/08 16:21:54 meichel
342  * Updated copyright header.
343  *
344  * Revision 1.7 1999/09/17 14:03:46 joergr
345  * Enhanced efficiency of some "for" loops.
346  *
347  * Revision 1.6 1999/04/28 12:52:04 joergr
348  * Corrected some typos, comments and formatting.
349  *
350  * Revision 1.5 1999/02/03 16:55:29 joergr
351  * Moved global functions maxval() and determineRepresentation() to class
352  * DicomImageClass (as static methods).
353  *
354  * Revision 1.4 1999/01/20 14:47:20 joergr
355  * Replaced invocation of getCount() by member variable Count where possible.
356  *
357  * Revision 1.3 1998/11/27 14:18:56 joergr
358  * Added copyright message.
359  *
360  * Revision 1.2 1998/05/11 14:53:32 joergr
361  * Added CVS/RCS header to each file.
362  *
363  *
364  */


Generated on Thu Dec 20 2012 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.8.2