Mercurial > hg > orthanc
changeset 1916:5bcf721bde4f
IImageWriter
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 09 Feb 2016 15:26:37 +0100 |
parents | 7454019be8f3 |
children | 7db4b909bec3 |
files | Core/Images/IImageWriter.h Core/Images/ImageAccessor.cpp Core/Images/JpegWriter.cpp Core/Images/JpegWriter.h Core/Images/PngWriter.cpp Core/Images/PngWriter.h Plugins/Engine/OrthancPlugins.cpp UnitTestsSources/ImageTests.cpp |
diffstat | 8 files changed, 173 insertions(+), 101 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/Images/IImageWriter.h Tue Feb 09 15:26:37 2016 +0100 @@ -0,0 +1,83 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 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 General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "ImageAccessor.h" +#include "../Toolbox.h" + +#include <boost/noncopyable.hpp> + +namespace Orthanc +{ + class IImageWriter : public boost::noncopyable + { + protected: + virtual void WriteToMemoryInternal(std::string& compressed, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) = 0; + + virtual void WriteToFileInternal(const std::string& path, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) + { + std::string compressed; + WriteToMemoryInternal(compressed, width, height, pitch, format, buffer); + Toolbox::WriteFile(compressed, path); + } + + public: + virtual ~IImageWriter() + { + } + + virtual void WriteToMemory(std::string& compressed, + const ImageAccessor& accessor) + { + WriteToMemoryInternal(compressed, accessor.GetWidth(), accessor.GetHeight(), + accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); + } + + virtual void WriteToFile(const std::string& path, + const ImageAccessor& accessor) + { + WriteToFileInternal(path, accessor.GetWidth(), accessor.GetHeight(), + accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); + } + }; +}
--- a/Core/Images/ImageAccessor.cpp Tue Feb 09 14:50:29 2016 +0100 +++ b/Core/Images/ImageAccessor.cpp Tue Feb 09 15:26:37 2016 +0100 @@ -176,7 +176,10 @@ pitch_ = pitch; buffer_ = const_cast<void*>(buffer); - assert(GetBytesPerPixel() * width_ <= pitch_); + if (GetBytesPerPixel() * width_ > pitch_) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } } @@ -193,7 +196,10 @@ pitch_ = pitch; buffer_ = buffer; - assert(GetBytesPerPixel() * width_ <= pitch_); + if (GetBytesPerPixel() * width_ > pitch_) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } }
--- a/Core/Images/JpegWriter.cpp Tue Feb 09 14:50:29 2016 +0100 +++ b/Core/Images/JpegWriter.cpp Tue Feb 09 15:26:37 2016 +0100 @@ -111,14 +111,15 @@ } - void JpegWriter::WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer) + void JpegWriter::WriteToFileInternal(const std::string& filename, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) { - FILE* fp = fopen(filename, "wb"); + // TODO This will not work on Windows system if the path contains non-ASCII characters + FILE* fp = fopen(filename.c_str(), "wb"); if (fp == NULL) { throw OrthancException(ErrorCode_FullStorage); @@ -156,12 +157,12 @@ } - void JpegWriter::WriteToMemory(std::string& jpeg, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer) + void JpegWriter::WriteToMemoryInternal(std::string& jpeg, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) { std::vector<uint8_t*> lines; GetLines(lines, height, pitch, format, buffer);
--- a/Core/Images/JpegWriter.h Tue Feb 09 14:50:29 2016 +0100 +++ b/Core/Images/JpegWriter.h Tue Feb 09 15:26:37 2016 +0100 @@ -32,16 +32,27 @@ #pragma once -#include "ImageAccessor.h" - -#include <string> -#include <stdint.h> -#include <boost/noncopyable.hpp> +#include "IImageWriter.h" namespace Orthanc { - class JpegWriter : public boost::noncopyable + class JpegWriter : public IImageWriter { + protected: + virtual void WriteToFileInternal(const std::string& filename, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer); + + virtual void WriteToMemoryInternal(std::string& jpeg, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer); + private: uint8_t quality_; @@ -56,33 +67,5 @@ { return quality_; } - - void WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer); - - void WriteToMemory(std::string& jpeg, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer); - - void WriteToFile(const char* filename, - const ImageAccessor& accessor) - { - WriteToFile(filename, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } - - void WriteToMemory(std::string& jpeg, - const ImageAccessor& accessor) - { - WriteToMemory(jpeg, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } }; }
--- a/Core/Images/PngWriter.cpp Tue Feb 09 14:50:29 2016 +0100 +++ b/Core/Images/PngWriter.cpp Tue Feb 09 15:26:37 2016 +0100 @@ -202,16 +202,17 @@ } - void PngWriter::WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer) + void PngWriter::WriteToFileInternal(const std::string& filename, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) { Prepare(width, height, pitch, format, buffer); - FILE* fp = fopen(filename, "wb"); + // TODO This will not work on Windows system if the path contains non-ASCII characters + FILE* fp = fopen(filename.c_str(), "wb"); if (!fp) { throw OrthancException(ErrorCode_CannotWriteFile); @@ -232,7 +233,6 @@ - static void MemoryCallback(png_structp png_ptr, png_bytep data, png_size_t size) @@ -243,12 +243,12 @@ - void PngWriter::WriteToMemory(std::string& png, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer) + void PngWriter::WriteToMemoryInternal(std::string& png, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer) { ChunkedBuffer chunks;
--- a/Core/Images/PngWriter.h Tue Feb 09 14:50:29 2016 +0100 +++ b/Core/Images/PngWriter.h Tue Feb 09 15:26:37 2016 +0100 @@ -32,16 +32,29 @@ #pragma once -#include "ImageAccessor.h" +#include "IImageWriter.h" -#include <boost/noncopyable.hpp> #include <boost/shared_ptr.hpp> -#include <string> namespace Orthanc { - class PngWriter : public boost::noncopyable + class PngWriter : public IImageWriter { + protected: + virtual void WriteToFileInternal(const std::string& filename, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer); + + virtual void WriteToMemoryInternal(std::string& png, + unsigned int width, + unsigned int height, + unsigned int pitch, + PixelFormat format, + const void* buffer); + private: struct PImpl; boost::shared_ptr<PImpl> pimpl_; @@ -61,33 +74,5 @@ PngWriter(); ~PngWriter(); - - void WriteToFile(const char* filename, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer); - - void WriteToMemory(std::string& png, - unsigned int width, - unsigned int height, - unsigned int pitch, - PixelFormat format, - const void* buffer); - - void WriteToFile(const char* filename, - const ImageAccessor& accessor) - { - WriteToFile(filename, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } - - void WriteToMemory(std::string& png, - const ImageAccessor& accessor) - { - WriteToMemory(png, accessor.GetWidth(), accessor.GetHeight(), - accessor.GetPitch(), accessor.GetFormat(), accessor.GetConstBuffer()); - } }; }
--- a/Plugins/Engine/OrthancPlugins.cpp Tue Feb 09 14:50:29 2016 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Tue Feb 09 15:26:37 2016 +0100 @@ -1328,12 +1328,15 @@ std::string compressed; + ImageAccessor accessor; + accessor.AssignReadOnly(Plugins::Convert(p.pixelFormat), p.width, p.height, p.pitch, p.buffer); + switch (p.imageFormat) { case OrthancPluginImageFormat_Png: { PngWriter writer; - writer.WriteToMemory(compressed, p.width, p.height, p.pitch, Plugins::Convert(p.pixelFormat), p.buffer); + writer.WriteToMemory(compressed, accessor); break; } @@ -1341,7 +1344,7 @@ { JpegWriter writer; writer.SetQuality(p.quality); - writer.WriteToMemory(compressed, p.width, p.height, p.pitch, Plugins::Convert(p.pixelFormat), p.buffer); + writer.WriteToMemory(compressed, accessor); break; }
--- a/UnitTestsSources/ImageTests.cpp Tue Feb 09 14:50:29 2016 +0100 +++ b/UnitTestsSources/ImageTests.cpp Tue Feb 09 15:26:37 2016 +0100 @@ -66,7 +66,10 @@ } } - w.WriteToFile("UnitTestsResults/ColorPattern.png", width, height, pitch, Orthanc::PixelFormat_RGB24, &image[0]); + Orthanc::ImageAccessor accessor; + accessor.AssignReadOnly(Orthanc::PixelFormat_RGB24, width, height, pitch, &image[0]); + + w.WriteToFile("UnitTestsResults/ColorPattern.png", accessor); std::string f, md5; Orthanc::Toolbox::ReadFile(f, "UnitTestsResults/ColorPattern.png"); @@ -91,7 +94,10 @@ } } - w.WriteToFile("UnitTestsResults/Gray8Pattern.png", width, height, pitch, Orthanc::PixelFormat_Grayscale8, &image[0]); + Orthanc::ImageAccessor accessor; + accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale8, width, height, pitch, &image[0]); + + w.WriteToFile("UnitTestsResults/Gray8Pattern.png", accessor); std::string f, md5; Orthanc::Toolbox::ReadFile(f, "UnitTestsResults/Gray8Pattern.png"); @@ -118,7 +124,9 @@ } } - w.WriteToFile("UnitTestsResults/Gray16Pattern.png", width, height, pitch, Orthanc::PixelFormat_Grayscale16, &image[0]); + Orthanc::ImageAccessor accessor; + accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale16, width, height, pitch, &image[0]); + w.WriteToFile("UnitTestsResults/Gray16Pattern.png", accessor); std::string f, md5; Orthanc::Toolbox::ReadFile(f, "UnitTestsResults/Gray16Pattern.png"); @@ -145,8 +153,11 @@ } } + Orthanc::ImageAccessor accessor; + accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale16, width, height, pitch, &image[0]); + std::string s; - w.WriteToMemory(s, width, height, pitch, Orthanc::PixelFormat_Grayscale16, &image[0]); + w.WriteToMemory(s, accessor); { Orthanc::PngReader r;