Mercurial > hg > orthanc-webviewer
changeset 79:abdde1dfb3eb
use sdk 0.9.4
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 25 Sep 2015 12:32:37 +0200 |
parents | d6da56f86e5a |
children | 83496e713a8e |
files | CMakeLists.txt Orthanc/Core/Toolbox.cpp Orthanc/Core/Toolbox.h Orthanc/Plugins/Samples/Common/ExportedSymbols.list Orthanc/Resources/CMake/Compiler.cmake Plugin/Cache/CacheScheduler.cpp Plugin/JpegWriter.cpp Plugin/JpegWriter.h Plugin/ParsedDicomImage.cpp Plugin/ParsedDicomImage.h Plugin/Plugin.cpp Plugin/SeriesInformationAdapter.cpp Plugin/ViewerToolbox.cpp Plugin/ViewerToolbox.h Resources/SyncOrthancFolder.py UnitTestsSources/UnitTestsMain.cpp |
diffstat | 16 files changed, 218 insertions(+), 485 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Fri Sep 25 11:29:17 2015 +0200 +++ b/CMakeLists.txt Fri Sep 25 12:32:37 2015 +0200 @@ -32,7 +32,6 @@ set(USE_SYSTEM_GDCM ON CACHE BOOL "Use the system version of Grassroot DICOM (GDCM)") set(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test") set(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp") -set(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of zlib") set(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite") set(USE_SYSTEM_ORTHANC_SDK ON CACHE BOOL "Use the system version of the Orthanc plugin SDK") @@ -116,13 +115,8 @@ list(APPEND AUTOGENERATED_SOURCES ${AUTOGENERATED_DIR}/Version.rc) endif() -if (CMAKE_COMPILER_IS_GNUCXX) - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/Orthanc/Plugins/Samples/Common/VersionScript.map -Wl,--no-undefined") -endif() - if (APPLE) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework CoreFoundation") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -framework CoreFoundation") endif() add_definitions( @@ -134,22 +128,16 @@ set(CORE_SOURCES ${BOOST_SOURCES} ${SQLITE_SOURCES} - ${LIBJPEG_SOURCES} - ${ZLIB_SOURCES} - ${LIBPNG_SOURCES} ${JSONCPP_SOURCES} # Sources inherited from Orthanc core ${CMAKE_SOURCE_DIR}/Orthanc/Core/ChunkedBuffer.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/Enumerations.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/FileStorage/FilesystemStorage.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/ImageFormats/ImageAccessor.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/ImageFormats/ImageBuffer.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/ImageFormats/ImageProcessing.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/ImageFormats/PngReader.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/ImageFormats/PngWriter.cpp + ${CMAKE_SOURCE_DIR}/Orthanc/Core/Images/ImageAccessor.cpp + ${CMAKE_SOURCE_DIR}/Orthanc/Core/Images/ImageBuffer.cpp + ${CMAKE_SOURCE_DIR}/Orthanc/Core/Images/ImageProcessing.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/MultiThreading/SharedMessageQueue.cpp - ${CMAKE_SOURCE_DIR}/Orthanc/Core/OrthancException.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/SQLite/Connection.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/SQLite/FunctionContext.cpp ${CMAKE_SOURCE_DIR}/Orthanc/Core/SQLite/Statement.cpp @@ -162,7 +150,6 @@ ${CMAKE_SOURCE_DIR}/Plugin/Cache/CacheManager.cpp ${CMAKE_SOURCE_DIR}/Plugin/Cache/CacheScheduler.cpp - ${CMAKE_SOURCE_DIR}/Plugin/JpegWriter.cpp ${CMAKE_SOURCE_DIR}/Plugin/ViewerToolbox.cpp ${CMAKE_SOURCE_DIR}/Plugin/SeriesVolumeSorter.cpp ${CMAKE_SOURCE_DIR}/Plugin/ViewerPrefetchPolicy.cpp
--- a/Orthanc/Core/Toolbox.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Orthanc/Core/Toolbox.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -527,6 +527,29 @@ { result = base64_decode(data); } + + +# if BOOST_HAS_REGEX == 1 + void Toolbox::DecodeDataUriScheme(std::string& mime, + std::string& content, + const std::string& source) + { + boost::regex pattern("data:([^;]+);base64,([a-zA-Z0-9=+/]*)", + boost::regex::icase /* case insensitive search */); + + boost::cmatch what; + if (regex_match(source.c_str(), what, pattern)) + { + mime = what[1]; + DecodeBase64(content, what[2]); + } + else + { + throw OrthancException(ErrorCode_BadFileFormat); + } + } +# endif + #endif @@ -1009,28 +1032,6 @@ } -#if BOOST_HAS_REGEX == 1 - void Toolbox::DecodeDataUriScheme(std::string& mime, - std::string& content, - const std::string& source) - { - boost::regex pattern("data:([^;]+);base64,([a-zA-Z0-9=+/]*)", - boost::regex::icase /* case insensitive search */); - - boost::cmatch what; - if (regex_match(source.c_str(), what, pattern)) - { - mime = what[1]; - DecodeBase64(content, what[2]); - } - else - { - throw OrthancException(ErrorCode_BadFileFormat); - } - } -#endif - - void Toolbox::MakeDirectory(const std::string& path) { if (boost::filesystem::exists(path))
--- a/Orthanc/Core/Toolbox.h Fri Sep 25 11:29:17 2015 +0200 +++ b/Orthanc/Core/Toolbox.h Fri Sep 25 12:32:37 2015 +0200 @@ -117,6 +117,12 @@ void EncodeBase64(std::string& result, const std::string& data); + +# if BOOST_HAS_REGEX == 1 + void DecodeDataUriScheme(std::string& mime, + std::string& content, + const std::string& source); +# endif #endif std::string GetPathToExecutable(); @@ -153,12 +159,6 @@ const std::string& source, char separator); -#if BOOST_HAS_REGEX == 1 - void DecodeDataUriScheme(std::string& mime, - std::string& content, - const std::string& source); -#endif - void MakeDirectory(const std::string& path); bool IsExistingFile(const std::string& path);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Orthanc/Plugins/Samples/Common/ExportedSymbols.list Fri Sep 25 12:32:37 2015 +0200 @@ -0,0 +1,7 @@ +# This is the list of the symbols that must be exported by Orthanc +# plugins, if targeting OS X + +_OrthancPluginInitialize +_OrthancPluginFinalize +_OrthancPluginGetName +_OrthancPluginGetVersion
--- a/Orthanc/Resources/CMake/Compiler.cmake Fri Sep 25 11:29:17 2015 +0200 +++ b/Orthanc/Resources/CMake/Compiler.cmake Fri Sep 25 12:32:37 2015 +0200 @@ -50,7 +50,7 @@ ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${CMAKE_SOURCE_DIR}/Plugins/Samples/Common/VersionScript.map") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--version-script=${ORTHANC_ROOT}/Plugins/Samples/Common/VersionScript.map") # Remove the "-rdynamic" option # http://www.mail-archive.com/cmake@cmake.org/msg08837.html @@ -108,7 +108,7 @@ endif() elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${CMAKE_SOURCE_DIR}/Plugins/Samples/Common/ExportedSymbols.list") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${ORTHANC_ROOT}/Plugins/Samples/Common/ExportedSymbols.list") add_definitions( -D_XOPEN_SOURCE=1
--- a/Plugin/Cache/CacheScheduler.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/Cache/CacheScheduler.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -265,7 +265,8 @@ BundleSchedulers::iterator it = bundles_.find(bundleIndex); if (it == bundles_.end()) { - throw Orthanc::OrthancException("No factory associated with this bundle"); + // No factory associated with this bundle + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); } return *(it->second);
--- a/Plugin/JpegWriter.cpp Fri Sep 25 11:29:17 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,246 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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 "JpegWriter.h" - -#include "../Orthanc/Core/OrthancException.h" - -#include <jpeglib.h> -#include <setjmp.h> -#include <stdio.h> -#include <vector> -#include <string.h> -#include <stdlib.h> - -namespace OrthancPlugins -{ - namespace - { - class ErrorManager - { - private: - struct jpeg_error_mgr pub; /* "public" fields */ - jmp_buf setjmp_buffer; /* for return to caller */ - std::string message; - - static void OutputMessage(j_common_ptr cinfo) - { - char message[JMSG_LENGTH_MAX]; - (*cinfo->err->format_message) (cinfo, message); - - ErrorManager* that = reinterpret_cast<ErrorManager*>(cinfo->err); - that->message = std::string(message); - } - - - static void ErrorExit(j_common_ptr cinfo) - { - (*cinfo->err->output_message) (cinfo); - - ErrorManager* that = reinterpret_cast<ErrorManager*>(cinfo->err); - longjmp(that->setjmp_buffer, 1); - } - - - public: - ErrorManager() - { - memset(&pub, 0, sizeof(struct jpeg_error_mgr)); - memset(&setjmp_buffer, 0, sizeof(jmp_buf)); - - jpeg_std_error(&pub); - pub.error_exit = ErrorExit; - pub.output_message = OutputMessage; - } - - struct jpeg_error_mgr* GetPublic() - { - return &pub; - } - - jmp_buf& GetJumpBuffer() - { - return setjmp_buffer; - } - - const std::string& GetMessage() const - { - return message; - } - }; - } - - - static void GetLines(std::vector<uint8_t*>& lines, - unsigned int height, - unsigned int pitch, - Orthanc::PixelFormat format, - const void* buffer) - { - if (format != Orthanc::PixelFormat_Grayscale8 && - format != Orthanc::PixelFormat_RGB24) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - lines.resize(height); - - uint8_t* base = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(buffer)); - for (unsigned int y = 0; y < height; y++) - { - lines[y] = base + static_cast<intptr_t>(y) * static_cast<intptr_t>(pitch); - } - } - - - static void Compress(struct jpeg_compress_struct& cinfo, - std::vector<uint8_t*>& lines, - unsigned int width, - unsigned int height, - Orthanc::PixelFormat format, - int quality) - { - cinfo.image_width = width; - cinfo.image_height = height; - - switch (format) - { - case Orthanc::PixelFormat_Grayscale8: - cinfo.input_components = 1; - cinfo.in_color_space = JCS_GRAYSCALE; - break; - - case Orthanc::PixelFormat_RGB24: - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; - break; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE); - jpeg_start_compress(&cinfo, TRUE); - jpeg_write_scanlines(&cinfo, &lines[0], height); - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - } - - - void JpegWriter::SetQuality(uint8_t quality) - { - if (quality <= 0 || quality > 100) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - quality_ = quality; - } - - - void JpegWriter::WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - Orthanc::PixelFormat format, - const void* buffer) - { - FILE* fp = fopen(filename, "wb"); - if (fp == NULL) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_FullStorage); - } - - std::vector<uint8_t*> lines; - GetLines(lines, height, pitch, format, buffer); - - struct jpeg_compress_struct cinfo; - memset(&cinfo, 0, sizeof(struct jpeg_compress_struct)); - - ErrorManager jerr; - cinfo.err = jerr.GetPublic(); - - if (setjmp(jerr.GetJumpBuffer())) - { - /* If we get here, the JPEG code has signaled an error. - * We need to clean up the JPEG object, close the input file, and return. - */ - jpeg_destroy_compress(&cinfo); - fclose(fp); - throw Orthanc::OrthancException("Error during JPEG encoding: " + jerr.GetMessage()); - } - - // Do not allocate data on the stack below this line! - - jpeg_create_compress(&cinfo); - jpeg_stdio_dest(&cinfo, fp); - Compress(cinfo, lines, width, height, format, quality_); - - // Everything went fine, "setjmp()" didn't get called - - fclose(fp); - } - - - void JpegWriter::WriteToMemory(std::string& jpeg, - unsigned int width, - unsigned int height, - unsigned int pitch, - Orthanc::PixelFormat format, - const void* buffer) - { - std::vector<uint8_t*> lines; - GetLines(lines, height, pitch, format, buffer); - - struct jpeg_compress_struct cinfo; - memset(&cinfo, 0, sizeof(struct jpeg_compress_struct)); - - ErrorManager jerr; - - unsigned char* data = NULL; - unsigned long size; - - if (setjmp(jerr.GetJumpBuffer())) - { - jpeg_destroy_compress(&cinfo); - - if (data != NULL) - { - free(data); - } - - throw Orthanc::OrthancException("Error during JPEG encoding: " + jerr.GetMessage()); - } - - // Do not allocate data on the stack below this line! - - jpeg_create_compress(&cinfo); - cinfo.err = jerr.GetPublic(); - jpeg_mem_dest(&cinfo, &data, &size); - - Compress(cinfo, lines, width, height, format, quality_); - - // Everything went fine, "setjmp()" didn't get called - - jpeg.assign(reinterpret_cast<const char*>(data), size); - free(data); - } -}
--- a/Plugin/JpegWriter.h Fri Sep 25 11:29:17 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/** - * Orthanc - A Lightweight, RESTful DICOM Store - * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, 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/>. - **/ - - -#pragma once - -#include "../Orthanc/Core/ImageFormats/ImageAccessor.h" - -#include <string> -#include <stdint.h> - -namespace OrthancPlugins -{ - class JpegWriter - { - private: - int quality_; - - public: - JpegWriter() : quality_(90) - { - } - - void SetQuality(uint8_t quality); - - uint8_t GetQuality() const - { - return quality_; - } - - void WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - Orthanc::PixelFormat format, - const void* buffer); - - void WriteToMemory(std::string& jpeg, - unsigned int width, - unsigned int height, - unsigned int pitch, - Orthanc::PixelFormat format, - const void* buffer); - - void WriteToFile(const char* filename, - const Orthanc::ImageAccessor& accessor) - { - WriteToFile(filename, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } - - void WriteToMemory(std::string& jpeg, - const Orthanc::ImageAccessor& accessor) - { - WriteToMemory(jpeg, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } - }; -}
--- a/Plugin/ParsedDicomImage.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/ParsedDicomImage.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -22,10 +22,8 @@ #include "../Orthanc/Core/OrthancException.h" #include "../Orthanc/Core/Toolbox.h" -#include "../Orthanc/Core/ImageFormats/ImageProcessing.h" -#include "../Orthanc/Core/ImageFormats/ImageBuffer.h" -#include "../Orthanc/Core/ImageFormats/PngReader.h" -#include "JpegWriter.h" +#include "../Orthanc/Core/Images/ImageProcessing.h" +#include "../Orthanc/Core/Images/ImageBuffer.h" #include "ViewerToolbox.h" #include <gdcmImageReader.h> @@ -48,8 +46,7 @@ std::auto_ptr<gdcm::ImageChangePhotometricInterpretation> photometric_; std::auto_ptr<gdcm::ImageChangePlanarConfiguration> interleaved_; std::string decoded_; - Orthanc::PngReader png_; - bool insidePng_; + std::auto_ptr<ImageReader> png_; bool isDecoded_; bool DecodeUsingGdcm() @@ -151,8 +148,7 @@ { try { - png_.ReadFromMemory(png); - insidePng_ = true; + png_.reset(new ImageReader(context_, png, OrthancPluginImageFormat_Png)); return true; } catch (Orthanc::OrthancException&) @@ -198,12 +194,17 @@ const std::string& instanceId) : context_(context), instanceId_(instanceId), - insidePng_(false), isDecoded_(false) { } + OrthancPluginContext* GetContext() + { + return context_; + } + + const gdcm::DataSet& GetDataSet() const { return reader_.GetFile().GetDataSet(); @@ -235,7 +236,8 @@ reader_.SetStream(stream); if (!reader_.Read()) { - throw Orthanc::OrthancException("GDCM cannot extract an image from this DICOM instance"); + OrthancPluginLogError(context_, "GDCM cannot extract an image from this DICOM instance"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); } } @@ -247,10 +249,10 @@ return false; } - if (insidePng_) + if (png_.get() != NULL) { // The image was decoded using Orthanc's built-in REST API - accessor = png_; + accessor = png_->GetAccessor(); return true; } @@ -527,10 +529,7 @@ result["sizeInBytes"] = converted.GetSize(); std::string z; - if (!CompressUsingDeflate(z, converted.GetConstBuffer(), converted.GetSize(), compressionLevel)) - { - return false; - } + CompressUsingDeflate(z, pimpl_->GetContext(), converted.GetConstBuffer(), converted.GetSize()); result["Orthanc"]["PixelData"] = base64_encode(z); @@ -597,9 +596,8 @@ result["sizeInBytes"] = converted.GetSize(); std::string jpeg; - OrthancPlugins::JpegWriter writer; - writer.SetQuality(quality); - writer.WriteToMemory(jpeg, converted); + WriteJpegToMemory(jpeg, pimpl_->GetContext(), converted, quality); + result["Orthanc"]["PixelData"] = base64_encode(jpeg); return true; }
--- a/Plugin/ParsedDicomImage.h Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/ParsedDicomImage.h Fri Sep 25 12:32:37 2015 +0200 @@ -20,7 +20,7 @@ #pragma once -#include "../Orthanc/Core/ImageFormats/ImageAccessor.h" +#include "../Orthanc/Core/Images/ImageAccessor.h" #include <orthanc/OrthancCPlugin.h> #include <stdint.h>
--- a/Plugin/Plugin.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/Plugin.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -84,7 +84,6 @@ if (obj.get() != NULL) { const std::string& instanceId = dynamic_cast<DynamicString&>(*obj).GetValue(); - printf("[%s]\n", instanceId.c_str()); // On the reception of a new instance, precompute its spatial position cache->GetScheduler().Prefetch(OrthancPlugins::CacheBundle_InstanceInformation, instanceId);
--- a/Plugin/SeriesInformationAdapter.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/SeriesInformationAdapter.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -61,7 +61,8 @@ if (!cache_.Access(tmp, CacheBundle_InstanceInformation, instanceId)) { - throw Orthanc::OrthancException("The cache is corrupted. Delete it to reconstruct it."); + OrthancPluginLogError(context_, "The cache is corrupted. Delete it to reconstruct it."); + throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); } InstanceInformation instance(tmp);
--- a/Plugin/ViewerToolbox.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/ViewerToolbox.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -24,7 +24,6 @@ #include "../Orthanc/Core/Toolbox.h" #include <json/reader.h> -#include <zlib.h> #include <stdexcept> #include <boost/lexical_cast.hpp> #include <sys/stat.h> @@ -51,7 +50,7 @@ catch (std::bad_alloc&) { OrthancPluginFreeMemoryBuffer(context, &answer); - throw Orthanc::OrthancException("Not enough memory"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); } } @@ -127,41 +126,35 @@ } - bool CompressUsingDeflate(std::string& compressed, + void CompressUsingDeflate(std::string& compressed, + OrthancPluginContext* context, const void* uncompressed, - size_t uncompressedSize, - uint8_t compressionLevel) + size_t uncompressedSize) { - if (uncompressedSize == 0) + OrthancPluginMemoryBuffer tmp; + + OrthancPluginErrorCode code = OrthancPluginBufferCompression( + context, &tmp, uncompressed, uncompressedSize, + OrthancPluginCompressionType_Zlib, 0 /*compress*/); + + if (code != OrthancPluginErrorCode_Success) { - compressed.clear(); - return true; + throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); } - uLongf compressedSize = compressBound(uncompressedSize); - compressed.resize(compressedSize); - - int error = compress2 - (reinterpret_cast<uint8_t*>(&compressed[0]), - &compressedSize, - const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)), - uncompressedSize, - compressionLevel); + try + { + compressed.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); + } + catch (...) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); + } - if (error == Z_OK) - { - compressed.resize(compressedSize); - return true; - } - else - { - compressed.clear(); - return false; - } + OrthancPluginFreeMemoryBuffer(context, &tmp); } - const char* GetMimeType(const std::string& path) { size_t dot = path.find_last_of('.'); @@ -276,50 +269,116 @@ } - bool ReadFile(std::string& content, - const std::string& path) + OrthancPluginPixelFormat Convert(Orthanc::PixelFormat format) { - struct stat s; - if (stat(path.c_str(), &s) != 0 || - !(s.st_mode & S_IFREG)) + switch (format) + { + case Orthanc::PixelFormat_Grayscale16: + return OrthancPluginPixelFormat_Grayscale16; + + case Orthanc::PixelFormat_Grayscale8: + return OrthancPluginPixelFormat_Grayscale8; + + case Orthanc::PixelFormat_RGB24: + return OrthancPluginPixelFormat_RGB24; + + case Orthanc::PixelFormat_RGBA32: + return OrthancPluginPixelFormat_RGBA32; + + case Orthanc::PixelFormat_SignedGrayscale16: + return OrthancPluginPixelFormat_SignedGrayscale16; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) + { + switch (format) { - // Either the path does not exist, or it is not a regular file - return false; - } + case OrthancPluginPixelFormat_Grayscale16: + return Orthanc::PixelFormat_Grayscale16; + + case OrthancPluginPixelFormat_Grayscale8: + return Orthanc::PixelFormat_Grayscale8; + + case OrthancPluginPixelFormat_RGB24: + return Orthanc::PixelFormat_RGB24; + + case OrthancPluginPixelFormat_RGBA32: + return Orthanc::PixelFormat_RGBA32; + + case OrthancPluginPixelFormat_SignedGrayscale16: + return Orthanc::PixelFormat_SignedGrayscale16; - FILE* fp = fopen(path.c_str(), "rb"); - if (fp == NULL) + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + + void WriteJpegToMemory(std::string& result, + OrthancPluginContext* context, + const Orthanc::ImageAccessor& accessor, + uint8_t quality) + { + OrthancPluginMemoryBuffer tmp; + + OrthancPluginErrorCode code = OrthancPluginCompressJpegImage + (context, &tmp, Convert(accessor.GetFormat()), + accessor.GetWidth(), accessor.GetHeight(), accessor.GetPitch(), + accessor.GetBuffer(), quality); + + if (code != OrthancPluginErrorCode_Success) { - return false; + throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); } - long size; - - if (fseek(fp, 0, SEEK_END) == -1 || - (size = ftell(fp)) < 0) + try { - fclose(fp); - return false; + result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); + } + catch (...) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); } - content.resize(size); - - if (fseek(fp, 0, SEEK_SET) == -1) + OrthancPluginFreeMemoryBuffer(context, &tmp); + } + + + + ImageReader::ImageReader(OrthancPluginContext* context, + const std::string& image, + OrthancPluginImageFormat format) : context_(context) + { + image_ = OrthancPluginUncompressImage(context_, image.c_str(), image.size(), format); + + if (image_ == NULL) { - fclose(fp); - return false; + throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); } + } - bool ok = true; - if (size > 0 && - fread(&content[0], size, 1, fp) != 1) - { - ok = false; - } + ImageReader::~ImageReader() + { + OrthancPluginFreeImage(context_, image_); + } + - fclose(fp); + Orthanc::ImageAccessor ImageReader::GetAccessor() const + { + Orthanc::ImageAccessor accessor; - return ok; + accessor.AssignReadOnly(Convert(OrthancPluginGetImagePixelFormat(context_, image_)), + OrthancPluginGetImageWidth(context_, image_), + OrthancPluginGetImageHeight(context_, image_), + OrthancPluginGetImagePitch(context_, image_), + OrthancPluginGetImageBuffer(context_, image_)); + + return accessor; } }
--- a/Plugin/ViewerToolbox.h Fri Sep 25 11:29:17 2015 +0200 +++ b/Plugin/ViewerToolbox.h Fri Sep 25 12:32:37 2015 +0200 @@ -24,6 +24,8 @@ #include <json/value.h> #include <orthanc/OrthancCPlugin.h> +#include "../Orthanc/Core/Images/ImageAccessor.h" + namespace OrthancPlugins { enum CacheBundle @@ -45,10 +47,10 @@ const std::string& value, unsigned int expectedSize); - bool CompressUsingDeflate(std::string& compressed, + void CompressUsingDeflate(std::string& compressed, + OrthancPluginContext* context, const void* uncompressed, - size_t uncompressedSize, - uint8_t compressionLevel); + size_t uncompressedSize); const char* GetMimeType(const std::string& path); @@ -63,6 +65,30 @@ const std::string& key, int defaultValue); - bool ReadFile(std::string& content, - const std::string& path); + + + OrthancPluginPixelFormat Convert(Orthanc::PixelFormat format); + + Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format); + + void WriteJpegToMemory(std::string& result, + OrthancPluginContext* context, + const Orthanc::ImageAccessor& accessor, + uint8_t quality); + + class ImageReader + { + private: + OrthancPluginContext* context_; + OrthancPluginImage* image_; + + public: + ImageReader(OrthancPluginContext* context, + const std::string& image, + OrthancPluginImageFormat format); + + ~ImageReader(); + + Orthanc::ImageAccessor GetAccessor() const; + }; }
--- a/Resources/SyncOrthancFolder.py Fri Sep 25 11:29:17 2015 +0200 +++ b/Resources/SyncOrthancFolder.py Fri Sep 25 12:32:37 2015 +0200 @@ -56,11 +56,8 @@ 'Core/Toolbox.h', 'Core/Uuid.cpp', 'Core/Uuid.h', + 'Plugins/Samples/Common/ExportedSymbols.list', 'Plugins/Samples/Common/VersionScript.map', - 'Resources/EmbedResources.py', - 'Resources/MinGWToolchain.cmake', - 'Resources/MinGW-W64-Toolchain32.cmake', - 'Resources/MinGW-W64-Toolchain64.cmake', 'Resources/CMake/AutoGeneratedCode.cmake', 'Resources/CMake/BoostConfiguration.cmake', 'Resources/CMake/Compiler.cmake', @@ -68,9 +65,13 @@ 'Resources/CMake/GoogleTestConfiguration.cmake', 'Resources/CMake/JsonCppConfiguration.cmake', 'Resources/CMake/SQLiteConfiguration.cmake', - 'Resources/ThirdParty/base64/base64.h', + 'Resources/EmbedResources.py', + 'Resources/MinGW-W64-Toolchain32.cmake', + 'Resources/MinGW-W64-Toolchain64.cmake', + 'Resources/MinGWToolchain.cmake', + 'Resources/ThirdParty/VisualStudio/stdint.h', 'Resources/ThirdParty/base64/base64.cpp', - 'Resources/ThirdParty/VisualStudio/stdint.h', + 'Resources/ThirdParty/base64/base64.h', 'Resources/WindowsResources.py', 'Resources/WindowsResources.rc', ]
--- a/UnitTestsSources/UnitTestsMain.cpp Fri Sep 25 11:29:17 2015 +0200 +++ b/UnitTestsSources/UnitTestsMain.cpp Fri Sep 25 12:32:37 2015 +0200 @@ -26,13 +26,10 @@ #include "../Orthanc/Core/OrthancException.h" #include "../Orthanc/Core/Toolbox.h" -#include "../Orthanc/Core/ImageFormats/ImageBuffer.h" -#include "../Orthanc/Core/ImageFormats/PngWriter.h" #include "../Plugin/Cache/CacheManager.h" #include "../Plugin/Cache/CacheScheduler.h" #include "../Plugin/Cache/ICacheFactory.h" #include "../Plugin/Cache/ICacheFactory.h" -#include "../Plugin/JpegWriter.h" using namespace OrthancPlugins; @@ -189,29 +186,6 @@ -TEST(JpegWriter, Basic) -{ - Orthanc::ImageBuffer img(16, 16, Orthanc::PixelFormat_Grayscale8); - Orthanc::ImageAccessor accessor = img.GetAccessor(); - for (unsigned int y = 0, value = 0; y < img.GetHeight(); y++) - { - uint8_t* p = reinterpret_cast<uint8_t*>(accessor.GetRow(y)); - for (unsigned int x = 0; x < img.GetWidth(); x++, p++) - { - *p = value++; - } - } - - JpegWriter w; - w.WriteToFile("UnitTestsResults/hello.jpg", accessor); - - std::string s; - w.WriteToMemory(s, accessor); - Orthanc::Toolbox::WriteFile(s, "UnitTestsResults/hello2.jpg"); -} - - - int main(int argc, char **argv) { argc_ = argc;