Mercurial > hg > orthanc-wsi
annotate Framework/Algorithms/ReconstructPyramidCommand.cpp @ 312:0683312e21ba
updated copyright, as Orthanc Team now replaces Osimis
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 30 May 2024 22:11:10 +0200 |
parents | 7020852a8fa9 |
children | 8ad12abde290 |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
312
0683312e21ba
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
309
diff
changeset
|
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
0683312e21ba
updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
309
diff
changeset
|
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium |
309
7020852a8fa9
updated year to 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium |
0 | 8 * |
9 * This program is free software: you can redistribute it and/or | |
10 * modify it under the terms of the GNU Affero General Public License | |
11 * as published by the Free Software Foundation, either version 3 of | |
12 * the License, or (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, but | |
15 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Affero General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Affero General Public License | |
20 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21 **/ | |
22 | |
23 | |
16
7a88c614be04
preparing for precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
24 #include "../PrecompiledHeadersWSI.h" |
0 | 25 #include "ReconstructPyramidCommand.h" |
26 | |
27 #include "../ImageToolbox.h" | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
28 |
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
29 #include <Compatibility.h> // For std::unique_ptr |
192 | 30 #include <Logging.h> |
31 #include <OrthancException.h> | |
32 #include <Images/Image.h> | |
229
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
33 #include <Images/ImageProcessing.h> |
0 | 34 |
35 #include <cassert> | |
36 | |
37 namespace OrthancWSI | |
38 { | |
39 Orthanc::ImageAccessor* ReconstructPyramidCommand::Explore(unsigned int level, | |
40 unsigned int offsetX, | |
41 unsigned int offsetY) | |
42 { | |
43 unsigned int zoom = 1 << level; | |
44 assert(x_ % zoom == 0 && y_ % zoom == 0); | |
45 unsigned int x = x_ / zoom + offsetX; | |
46 unsigned int y = y_ / zoom + offsetY; | |
47 | |
48 if (x >= target_.GetCountTilesX(level + shiftTargetLevel_) || | |
49 y >= target_.GetCountTilesY(level + shiftTargetLevel_)) | |
50 { | |
51 return NULL; | |
52 } | |
53 | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
54 std::unique_ptr<Orthanc::ImageAccessor> result; |
0 | 55 |
56 if (level == 0) | |
57 { | |
154 | 58 result.reset(new Orthanc::ImageAccessor); |
59 source_.GetDecodedTile(*result, x, y); | |
0 | 60 |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
61 ImageCompression compression; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
62 const std::string* rawTile = source_.GetRawTile(compression, x, y); |
0 | 63 |
64 if (rawTile != NULL) | |
65 { | |
66 // Simple transcoding | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
67 target_.WriteRawTile(*rawTile, compression, level + shiftTargetLevel_, x, y); |
0 | 68 } |
69 else | |
70 { | |
71 // Re-encoding the file | |
72 target_.EncodeTile(*result, level + shiftTargetLevel_, x, y); | |
73 } | |
74 } | |
75 else | |
76 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
77 std::unique_ptr<Orthanc::ImageAccessor> mosaic(ImageToolbox::Allocate(source_.GetPixelFormat(), |
0 | 78 2 * target_.GetTileWidth(), |
79 2 * target_.GetTileHeight())); | |
80 ImageToolbox::Set(*mosaic, | |
81 source_.GetParameters().GetBackgroundColorRed(), | |
82 source_.GetParameters().GetBackgroundColorGreen(), | |
83 source_.GetParameters().GetBackgroundColorBlue()); | |
84 | |
85 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
86 std::unique_ptr<Orthanc::ImageAccessor> subTile(Explore(level - 1, 2 * offsetX, 2 * offsetY)); |
0 | 87 if (subTile.get() != NULL) |
88 { | |
89 ImageToolbox::Embed(*mosaic, *subTile, 0, 0); | |
90 } | |
91 } | |
92 | |
93 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
94 std::unique_ptr<Orthanc::ImageAccessor> subTile(Explore(level - 1, 2 * offsetX + 1, 2 * offsetY)); |
0 | 95 if (subTile.get() != NULL) |
96 { | |
97 ImageToolbox::Embed(*mosaic, *subTile, target_.GetTileWidth(), 0); | |
98 } | |
99 } | |
100 | |
101 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
102 std::unique_ptr<Orthanc::ImageAccessor> subTile(Explore(level - 1, 2 * offsetX, 2 * offsetY + 1)); |
0 | 103 if (subTile.get() != NULL) |
104 { | |
105 ImageToolbox::Embed(*mosaic, *subTile, 0, target_.GetTileHeight()); | |
106 } | |
107 } | |
108 | |
109 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
110 std::unique_ptr<Orthanc::ImageAccessor> subTile(Explore(level - 1, 2 * offsetX + 1, 2 * offsetY + 1)); |
0 | 111 if (subTile.get() != NULL) |
112 { | |
113 ImageToolbox::Embed(*mosaic, *subTile, target_.GetTileWidth(), target_.GetTileHeight()); | |
114 } | |
115 } | |
116 | |
229
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
117 if (source_.GetParameters().IsSmoothEnabled()) |
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
118 { |
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
119 Orthanc::ImageProcessing::SmoothGaussian5x5(*mosaic, false /* don't use accurate rounding */); |
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
120 } |
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
121 |
d9bd12e3747a
use Orthanc::ImageProcessing::Halve() instead of ImageToolbox::Halve()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
122 result.reset(Orthanc::ImageProcessing::Halve(*mosaic, false /* don't force minimal pitch */)); |
0 | 123 |
124 target_.EncodeTile(*result, level + shiftTargetLevel_, x, y); | |
125 } | |
126 | |
127 return result.release(); | |
128 } | |
129 | |
130 | |
131 ReconstructPyramidCommand::ReconstructPyramidCommand(IPyramidWriter& target, | |
132 ITiledPyramid& source, | |
133 unsigned int upToLevel, | |
134 unsigned int x, | |
135 unsigned int y, | |
136 const DicomizerParameters& parameters) : | |
137 target_(target), | |
138 source_(source, 0, target.GetTileWidth(), target.GetTileHeight(), parameters), | |
139 upToLevel_(upToLevel), | |
140 x_(x), | |
141 y_(y), | |
142 shiftTargetLevel_(0) | |
143 { | |
144 unsigned int zoom = 1 << upToLevel; | |
145 if (x % zoom != 0 || | |
146 y % zoom != 0) | |
147 { | |
148 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
149 } | |
150 | |
151 if (target.GetPixelFormat() != source.GetPixelFormat()) | |
152 { | |
153 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); | |
154 } | |
155 } | |
156 | |
157 | |
158 bool ReconstructPyramidCommand::Execute() | |
159 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
160 std::unique_ptr<Orthanc::ImageAccessor> root(Explore(upToLevel_, 0, 0)); |
0 | 161 return true; |
162 } | |
163 | |
164 | |
236
b0ee417b667a
migrating new definitions in namespace Orthanc to namespace OrthancWSI
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
229
diff
changeset
|
165 void ReconstructPyramidCommand::PrepareBagOfTasks(BagOfTasks& tasks, |
0 | 166 IPyramidWriter& target, |
167 ITiledPyramid& source, | |
168 unsigned int countLevels, | |
169 unsigned int shiftTargetLevel, | |
170 const DicomizerParameters& parameters) | |
171 { | |
172 if (countLevels == 0) | |
173 { | |
174 return; | |
175 } | |
176 | |
177 if (shiftTargetLevel + countLevels > target.GetLevelCount()) | |
178 { | |
179 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
180 } | |
181 | |
182 const unsigned int targetCountTilesX = target.GetCountTilesX(shiftTargetLevel); | |
183 const unsigned int targetCountTilesY = target.GetCountTilesY(shiftTargetLevel); | |
184 const unsigned int step = 1 << (countLevels - 1); | |
185 | |
186 for (unsigned int y = 0; y < targetCountTilesY; y += step) | |
187 { | |
188 for (unsigned int x = 0; x < targetCountTilesX; x += step) | |
189 { | |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
192
diff
changeset
|
190 std::unique_ptr<ReconstructPyramidCommand> command; |
0 | 191 command.reset(new ReconstructPyramidCommand |
192 (target, source, countLevels - 1, x, y, parameters)); | |
193 command->SetShiftTargetLevel(shiftTargetLevel); | |
194 tasks.Push(command.release()); | |
195 } | |
196 } | |
197 } | |
198 } |