Mercurial > hg > orthanc-stone
view Framework/Oracle/GetOrthancWebViewerJpegCommand.cpp @ 1013:53cc787bd7bc toa2019092301
- Added an optimized ProjectPoint2 to CoordinateSystem3D. It has *not* replaced
the ProjectPoint method because more tests need to be written.
- ProjectPointOntoPlane2 is a faster version of
GeometryToolbox::ProjectPointOntoPlane. Same remark as above.
- DicomStructureSet.cpp now uses this optimized call.
author | Benjamin Golinvaux <bgo@osimis.io> |
---|---|
date | Mon, 23 Sep 2019 15:18:33 +0200 |
parents | a7351ad54960 |
children | 81b29bc7c3d4 2d8ab34c8c91 |
line wrap: on
line source
/** * Stone of Orthanc * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2019 Osimis S.A., Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "GetOrthancWebViewerJpegCommand.h" #include "../Toolbox/LinearAlgebra.h" #include <Core/Images/Image.h> #include <Core/Images/ImageProcessing.h> #include <Core/Images/JpegReader.h> #include <Core/OrthancException.h> #include <Core/Toolbox.h> #include <json/reader.h> #include <json/value.h> namespace OrthancStone { GetOrthancWebViewerJpegCommand::SuccessMessage::SuccessMessage(const GetOrthancWebViewerJpegCommand& command, Orthanc::ImageAccessor* image) : // Takes ownership OriginMessage(command), image_(image) { if (image == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } } GetOrthancWebViewerJpegCommand::GetOrthancWebViewerJpegCommand() : frame_(0), quality_(95), timeout_(600), expectedFormat_(Orthanc::PixelFormat_Grayscale8) { } void GetOrthancWebViewerJpegCommand::SetQuality(unsigned int quality) { if (quality <= 0 || quality > 100) { throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } else { quality_ = quality; } } std::string GetOrthancWebViewerJpegCommand::GetUri() const { return ("/web-viewer/instances/jpeg" + boost::lexical_cast<std::string>(quality_) + "-" + instanceId_ + "_" + boost::lexical_cast<std::string>(frame_)); } void GetOrthancWebViewerJpegCommand::ProcessHttpAnswer(IMessageEmitter& emitter, const IObserver& receiver, const std::string& answer) const { // This code comes from older "OrthancSlicesLoader::ParseSliceImageJpeg()" Json::Value encoded; { Json::Reader reader; if (!reader.parse(answer, encoded)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } } if (encoded.type() != Json::objectValue || !encoded.isMember("Orthanc") || encoded["Orthanc"].type() != Json::objectValue) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } const Json::Value& info = encoded["Orthanc"]; if (!info.isMember("PixelData") || !info.isMember("Stretched") || !info.isMember("Compression") || info["Compression"].type() != Json::stringValue || info["PixelData"].type() != Json::stringValue || info["Stretched"].type() != Json::booleanValue || info["Compression"].asString() != "Jpeg") { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } bool isSigned = false; bool isStretched = info["Stretched"].asBool(); if (info.isMember("IsSigned")) { if (info["IsSigned"].type() != Json::booleanValue) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } else { isSigned = info["IsSigned"].asBool(); } } std::auto_ptr<Orthanc::ImageAccessor> reader; { std::string jpeg; Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString()); reader.reset(new Orthanc::JpegReader); dynamic_cast<Orthanc::JpegReader&>(*reader).ReadFromMemory(jpeg); } if (reader->GetFormat() == Orthanc::PixelFormat_RGB24) // This is a color image { if (expectedFormat_ != Orthanc::PixelFormat_RGB24) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } if (isSigned || isStretched) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } else { SuccessMessage message(*this, reader.release()); emitter.EmitMessage(receiver, message); return; } } if (reader->GetFormat() != Orthanc::PixelFormat_Grayscale8) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } if (!isStretched) { if (expectedFormat_ != reader->GetFormat()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } else { SuccessMessage message(*this, reader.release()); emitter.EmitMessage(receiver, message); return; } } int32_t stretchLow = 0; int32_t stretchHigh = 0; if (!info.isMember("StretchLow") || !info.isMember("StretchHigh") || info["StretchLow"].type() != Json::intValue || info["StretchHigh"].type() != Json::intValue) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } stretchLow = info["StretchLow"].asInt(); stretchHigh = info["StretchHigh"].asInt(); if (stretchLow < -32768 || stretchHigh > 65535 || (stretchLow < 0 && stretchHigh > 32767)) { // This range cannot be represented with a uint16_t or an int16_t throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } // Decode a grayscale JPEG 8bpp image coming from the Web viewer std::auto_ptr<Orthanc::ImageAccessor> image (new Orthanc::Image(expectedFormat_, reader->GetWidth(), reader->GetHeight(), false)); Orthanc::ImageProcessing::Convert(*image, *reader); reader.reset(); float scaling = static_cast<float>(stretchHigh - stretchLow) / 255.0f; if (!LinearAlgebra::IsCloseToZero(scaling)) { float offset = static_cast<float>(stretchLow) / scaling; Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling, true); } SuccessMessage message(*this, image.release()); emitter.EmitMessage(receiver, message); } }