Mercurial > hg > orthanc
annotate OrthancServer/DicomIntegerPixelAccessor.cpp @ 58:6da7fc87efaa orthanc-renaming
renaming cont
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Sun, 16 Sep 2012 09:24:13 +0200 |
parents | 4bc019d2f969 |
children | a70bb32802ae |
rev | line source |
---|---|
0 | 1 /** |
50 | 2 * Palanthir - A Lightweight, RESTful DICOM Store |
0 | 3 * Copyright (C) 2012 Medical Physics Department, CHU of Liege, |
4 * Belgium | |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation, either version 3 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 **/ | |
19 | |
20 | |
21 #include "DicomIntegerPixelAccessor.h" | |
22 | |
6 | 23 #ifndef NOMINMAX |
2 | 24 #define NOMINMAX |
6 | 25 #endif |
26 | |
50 | 27 #include "../Core/PalanthirException.h" |
0 | 28 #include "FromDcmtkBridge.h" |
29 #include <boost/lexical_cast.hpp> | |
2 | 30 #include <limits> |
0 | 31 |
50 | 32 namespace Palanthir |
0 | 33 { |
34 DicomIntegerPixelAccessor::DicomIntegerPixelAccessor(const DicomMap& values, | |
35 const void* pixelData, | |
36 size_t size) : | |
37 pixelData_(pixelData), | |
38 size_(size) | |
39 { | |
40 unsigned int bitsAllocated; | |
41 unsigned int bitsStored; | |
42 unsigned int highBit; | |
43 unsigned int pixelRepresentation; | |
44 | |
45 try | |
46 { | |
47 width_ = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "Columns").AsString()); | |
48 height_ = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "Rows").AsString()); | |
49 samplesPerPixel_ = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "SamplesPerPixel").AsString()); | |
50 bitsAllocated = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "BitsAllocated").AsString()); | |
51 bitsStored = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "BitsStored").AsString()); | |
52 highBit = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "HighBit").AsString()); | |
53 pixelRepresentation = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "PixelRepresentation").AsString()); | |
54 } | |
55 catch (boost::bad_lexical_cast) | |
56 { | |
50 | 57 throw PalanthirException(ErrorCode_NotImplemented); |
0 | 58 } |
59 | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
60 frame_ = 0; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
61 try |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
62 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
63 numberOfFrames_ = boost::lexical_cast<unsigned int>(FromDcmtkBridge::GetValue(values, "NumberOfFrames").AsString()); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
64 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
65 catch (PalanthirException) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
66 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
67 // If the tag "NumberOfFrames" is absent, assume there is a single frame |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
68 numberOfFrames_ = 1; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
69 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
70 catch (boost::bad_lexical_cast) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
71 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
72 throw PalanthirException(ErrorCode_NotImplemented); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
73 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
74 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
75 if ((bitsAllocated != 8 && bitsAllocated != 16 && |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
76 bitsAllocated != 24 && bitsAllocated != 32) || |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
77 numberOfFrames_ == 0) |
0 | 78 { |
50 | 79 throw PalanthirException(ErrorCode_NotImplemented); |
0 | 80 } |
81 | |
82 if (bitsAllocated > 32 || | |
83 bitsStored >= 32) | |
84 { | |
85 // Not available, as the accessor internally uses int32_t values | |
50 | 86 throw PalanthirException(ErrorCode_NotImplemented); |
0 | 87 } |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
88 |
0 | 89 if (samplesPerPixel_ != 1) |
90 { | |
50 | 91 throw PalanthirException(ErrorCode_NotImplemented); |
0 | 92 } |
93 | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
94 if (width_ * height_ * bitsAllocated / 8 * numberOfFrames_ != size) |
0 | 95 { |
50 | 96 throw PalanthirException(ErrorCode_NotImplemented); |
0 | 97 } |
98 | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
99 /*printf("%d %d %d %d %d %d %d %d\n", width_, height_, samplesPerPixel_, bitsAllocated, |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
100 bitsStored, highBit, pixelRepresentation, numberOfFrames_);*/ |
0 | 101 |
102 bytesPerPixel_ = bitsAllocated / 8; | |
103 shift_ = highBit + 1 - bitsStored; | |
104 | |
105 if (pixelRepresentation) | |
106 { | |
107 mask_ = (1 << (bitsStored - 1)) - 1; | |
108 signMask_ = (1 << (bitsStored - 1)); | |
109 } | |
110 else | |
111 { | |
112 mask_ = (1 << bitsStored) - 1; | |
113 signMask_ = 0; | |
114 } | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
115 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
116 rowOffset_ = width_ * bytesPerPixel_; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
117 frameOffset_ = height_ * width_ * bytesPerPixel_; |
0 | 118 } |
119 | |
120 | |
121 void DicomIntegerPixelAccessor::GetExtremeValues(int32_t& min, | |
122 int32_t& max) const | |
123 { | |
124 if (height_ == 0 || width_ == 0) | |
125 { | |
126 min = max = 0; | |
127 return; | |
128 } | |
129 | |
130 min = std::numeric_limits<int32_t>::max(); | |
131 max = std::numeric_limits<int32_t>::min(); | |
132 | |
133 for (unsigned int y = 0; y < height_; y++) | |
134 { | |
135 for (unsigned int x = 0; x < width_; x++) | |
136 { | |
137 int32_t v = GetValue(x, y); | |
138 if (v < min) | |
139 min = v; | |
140 if (v > max) | |
141 max = v; | |
142 } | |
143 } | |
144 } | |
145 | |
146 | |
147 int32_t DicomIntegerPixelAccessor::GetValue(unsigned int x, unsigned int y) const | |
148 { | |
149 assert(x < width_ && y < height_); | |
150 | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
151 const uint8_t* pixel = reinterpret_cast<const uint8_t*>(pixelData_) + |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
152 y * rowOffset_ + x * bytesPerPixel_ + frame_ * frameOffset_; |
0 | 153 |
154 int32_t v; | |
155 v = pixel[0]; | |
156 if (bytesPerPixel_ >= 2) | |
157 v = v + (static_cast<int32_t>(pixel[1]) << 8); | |
158 if (bytesPerPixel_ >= 3) | |
159 v = v + (static_cast<int32_t>(pixel[2]) << 16); | |
160 if (bytesPerPixel_ >= 4) | |
161 v = v + (static_cast<int32_t>(pixel[3]) << 24); | |
162 | |
163 v = (v >> shift_) & mask_; | |
164 | |
165 if (v & signMask_) | |
166 { | |
167 // Signed value: Not implemented yet | |
50 | 168 //throw PalanthirException(ErrorCode_NotImplemented); |
0 | 169 v = 0; |
170 } | |
171 | |
172 return v; | |
173 } | |
53
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
174 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
175 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
176 void DicomIntegerPixelAccessor::SetCurrentFrame(unsigned int frame) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
177 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
178 if (frame >= numberOfFrames_) |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
179 { |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
180 throw PalanthirException(ErrorCode_ParameterOutOfRange); |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
181 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
182 |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
183 frame_ = frame; |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
184 } |
293038baf8f1
access to multi-frame images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
50
diff
changeset
|
185 |
0 | 186 } |