comparison Framework/Outputs/PyramidWriterBase.cpp @ 0:4a7a53257c7d

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 22 Oct 2016 21:48:33 +0200
parents
children 7a88c614be04
comparison
equal deleted inserted replaced
-1:000000000000 0:4a7a53257c7d
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 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Affero General Public License
8 * as published by the Free Software Foundation, either version 3 of
9 * the 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 * Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20
21 #include "PyramidWriterBase.h"
22
23 #include "../ImageToolbox.h"
24 #include "../Orthanc/Core/OrthancException.h"
25 #include "../Orthanc/Core/Logging.h"
26
27 namespace OrthancWSI
28 {
29 PyramidWriterBase::Level PyramidWriterBase::GetLevel(unsigned int level) const
30 {
31 boost::mutex::scoped_lock lock(const_cast<PyramidWriterBase&>(*this).mutex_);
32
33 if (level >= levels_.size())
34 {
35 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
36 }
37 else
38 {
39 return levels_[level];
40 }
41 }
42
43
44 PyramidWriterBase::PyramidWriterBase(Orthanc::PixelFormat pixelFormat,
45 ImageCompression compression,
46 unsigned int tileWidth,
47 unsigned int tileHeight) :
48 pixelFormat_(pixelFormat),
49 compression_(compression),
50 tileWidth_(tileWidth),
51 tileHeight_(tileHeight),
52 jpegQuality_(90), // Default JPEG quality
53 first_(true)
54 {
55 }
56
57
58 void PyramidWriterBase::SetJpegQuality(int quality)
59 {
60 if (quality <= 0 || quality > 100)
61 {
62 LOG(ERROR) << "The JPEG quality must be in range [1;100], but " << quality << " is provided";
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
64 }
65
66 jpegQuality_ = quality;
67 }
68
69
70 void PyramidWriterBase::AddLevel(unsigned int width,
71 unsigned int height)
72 {
73 boost::mutex::scoped_lock lock(mutex_);
74
75 if (!first_)
76 {
77 LOG(ERROR) << "Cannot add pyramid levels after some tile has already been written";
78 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
79 }
80
81 if (!levels_.empty())
82 {
83 const Level& previous = levels_[levels_.size() - 1];
84
85 if (width >= previous.width_ ||
86 height >= previous.height_ ||
87 width == 0 ||
88 height == 0)
89 {
90 LOG(ERROR) << "Levels must have strictly decreasing sizes";
91 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
92 }
93 }
94
95 Level level;
96 level.z_ = levels_.size();
97 level.width_ = width;
98 level.height_ = height;
99 level.countTilesX_ = CeilingDivision(width, tileWidth_);
100 level.countTilesY_ = CeilingDivision(height, tileHeight_);
101 levels_.push_back(level);
102
103 AddLevelInternal(level);
104 }
105
106
107 unsigned int PyramidWriterBase::GetLevelCount() const
108 {
109 boost::mutex::scoped_lock lock(const_cast<PyramidWriterBase&>(*this).mutex_);
110 return levels_.size();
111 }
112
113
114 void PyramidWriterBase::WriteRawTile(const std::string& tile,
115 ImageCompression compression,
116 unsigned int z,
117 unsigned int x,
118 unsigned int y)
119 {
120 first_ = false;
121
122 const Level level = GetLevel(z);
123
124 if (compression != compression_)
125 {
126 std::string recoded;
127 ImageToolbox::ChangeTileCompression(recoded, tile, compression, compression_, jpegQuality_);
128 WriteRawTileInternal(recoded, level, x, y);
129 }
130 else
131 {
132 WriteRawTileInternal(tile, level, x, y);
133 }
134 }
135
136
137 void PyramidWriterBase::EncodeTile(const Orthanc::ImageAccessor& tile,
138 unsigned int z,
139 unsigned int x,
140 unsigned int y)
141 {
142 first_ = false;
143
144 const Level level = GetLevel(z);
145
146 std::string raw;
147 ImageToolbox::EncodeTile(raw, tile, compression_, jpegQuality_);
148 WriteRawTileInternal(raw, level, x, y);
149 }
150 }