comparison ViewerPlugin/RawTile.cpp @ 260:35c241231af2 iiif

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 10 Jul 2023 08:31:50 +0200
parents
children c72fbdecdc38
comparison
equal deleted inserted replaced
259:3e511f10896c 260:35c241231af2
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium
6 * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
7 *
8 * This program is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU Affero General Public License
10 * as published by the Free Software Foundation, either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 **/
21
22
23 #include "../Framework/PrecompiledHeadersWSI.h"
24 #include "RawTile.h"
25
26 #include "../Framework/ImageToolbox.h"
27 #include "../Framework/Jpeg2000Reader.h"
28 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h"
29
30 #include <Compatibility.h> // For std::unique_ptr
31 #include <Images/JpegReader.h>
32 #include <Images/JpegWriter.h>
33 #include <Images/PngWriter.h>
34 #include <MultiThreading/Semaphore.h>
35 #include <OrthancException.h>
36
37
38 static std::unique_ptr<Orthanc::Semaphore> transcoderSemaphore_;
39
40 Orthanc::ImageAccessor* RawTile::DecodeInternal()
41 {
42 switch (compression_)
43 {
44 case OrthancWSI::ImageCompression_Jpeg:
45 {
46 std::unique_ptr<Orthanc::JpegReader> decoded(new Orthanc::JpegReader);
47 decoded->ReadFromMemory(tile_);
48 return decoded.release();
49 }
50
51 case OrthancWSI::ImageCompression_Jpeg2000:
52 {
53 std::unique_ptr<OrthancWSI::Jpeg2000Reader> decoded(new OrthancWSI::Jpeg2000Reader);
54 decoded->ReadFromMemory(tile_);
55
56 if (photometric_ == Orthanc::PhotometricInterpretation_YBR_ICT)
57 {
58 OrthancWSI::ImageToolbox::ConvertJpegYCbCrToRgb(*decoded);
59 }
60
61 return decoded.release();
62 }
63
64 case OrthancWSI::ImageCompression_None:
65 {
66 unsigned int bpp = Orthanc::GetBytesPerPixel(format_);
67 if (bpp * tileWidth_ * tileHeight_ != tile_.size())
68 {
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
70 }
71
72 std::unique_ptr<Orthanc::ImageAccessor> decoded(new Orthanc::ImageAccessor);
73 decoded->AssignReadOnly(format_, tileWidth_, tileHeight_, bpp * tileWidth_, tile_.c_str());
74
75 return decoded.release();
76 }
77
78 default:
79 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
80 }
81 }
82
83
84 void RawTile::EncodeInternal(std::string& encoded,
85 const Orthanc::ImageAccessor& decoded,
86 Orthanc::MimeType transcodingType)
87 {
88 switch (transcodingType)
89 {
90 case Orthanc::MimeType_Png:
91 {
92 Orthanc::PngWriter writer;
93 Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded);
94 break;
95 }
96
97 case Orthanc::MimeType_Jpeg:
98 {
99 Orthanc::JpegWriter writer;
100 Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded);
101 break;
102 }
103
104 default:
105 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
106 }
107 }
108
109
110 RawTile::RawTile(OrthancWSI::ITiledPyramid& pyramid,
111 unsigned int level,
112 unsigned int tileX,
113 unsigned int tileY) :
114 format_(pyramid.GetPixelFormat()),
115 tileWidth_(pyramid.GetTileWidth(level)),
116 tileHeight_(pyramid.GetTileHeight(level)),
117 photometric_(pyramid.GetPhotometricInterpretation())
118 {
119 if (!pyramid.ReadRawTile(tile_, compression_, level, tileX, tileY))
120 {
121 // Handling of missing tile (for sparse tiling): TODO parameter?
122 // AnswerSparseTile(output, tileWidth, tileHeight); return;
123 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
124 }
125 }
126
127
128 void RawTile::Answer(OrthancPluginRestOutput* output,
129 Orthanc::MimeType transcodingType)
130 {
131 if (compression_ == OrthancWSI::ImageCompression_Jpeg)
132 {
133 // The tile is already a JPEG image. In such a case, we can
134 // serve it as such, because any Web browser can handle JPEG.
135 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, tile_.c_str(),
136 tile_.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg));
137 }
138 else
139 {
140 // This is a lossless frame (coming from a JPEG2000 or an
141 // uncompressed DICOM instance), which is not a DICOM-JPEG
142 // instance. We need to decompress the raw tile, then transcode
143 // it to the PNG/JPEG, depending on the "transcodingType".
144
145 std::string transcoded;
146
147 {
148 // The semaphore is used to throttle the number of simultaneous computations
149 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_);
150
151 std::unique_ptr<Orthanc::ImageAccessor> decoded(DecodeInternal());
152 EncodeInternal(transcoded, *decoded, transcodingType);
153 }
154
155 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, transcoded.c_str(),
156 transcoded.size(), Orthanc::EnumerationToString(transcodingType));
157 }
158 }
159
160
161 Orthanc::ImageAccessor* RawTile::Decode()
162 {
163 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_);
164 return DecodeInternal();
165 }
166
167
168 void RawTile::Encode(std::string& encoded,
169 const Orthanc::ImageAccessor& decoded,
170 Orthanc::MimeType transcodingType)
171 {
172 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_);
173 EncodeInternal(encoded, decoded, transcodingType);
174 }
175
176
177 void RawTile::InitializeTranscoderSemaphore(unsigned int maxThreads)
178 {
179 transcoderSemaphore_.reset(new Orthanc::Semaphore(maxThreads));
180 }
181
182
183 void RawTile::FinalizeTranscoderSemaphore()
184 {
185 transcoderSemaphore_.reset(NULL);
186 }