# HG changeset patch # User Sebastien Jodogne # Date 1399373246 -7200 # Node ID 37adac56017af2d95c1abf461c36fe9a4114f790 # Parent e7b1ca0f1e04b2d1be54d5b6dd8e453d5271961c ImageAccessor abstraction diff -r e7b1ca0f1e04 -r 37adac56017a Core/Enumerations.h --- a/Core/Enumerations.h Tue May 06 12:09:11 2014 +0200 +++ b/Core/Enumerations.h Tue May 06 12:47:26 2014 +0200 @@ -68,7 +68,8 @@ ErrorCode_IncompatibleDatabaseVersion, ErrorCode_FullStorage, ErrorCode_CorruptedFile, - ErrorCode_InexistentTag + ErrorCode_InexistentTag, + ErrorCode_ReadOnly }; /** diff -r e7b1ca0f1e04 -r 37adac56017a Core/FileFormats/PngReader.cpp --- a/Core/FileFormats/PngReader.cpp Tue May 06 12:09:11 2014 +0200 +++ b/Core/FileFormats/PngReader.cpp Tue May 06 12:47:26 2014 +0200 @@ -131,10 +131,6 @@ PngReader::PngReader() { - width_ = 0; - height_ = 0; - pitch_ = 0; - format_ = PixelFormat_Grayscale8; } void PngReader::Read(PngRabi& rabi) @@ -152,18 +148,18 @@ &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); - width_ = width; - height_ = height; + PixelFormat format; + unsigned int pitch; if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 8) { - format_ = PixelFormat_Grayscale8; - pitch_ = width_; + format = PixelFormat_Grayscale8; + pitch = width; } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16) { - format_ = PixelFormat_Grayscale16; - pitch_ = 2 * width_; + format = PixelFormat_Grayscale16; + pitch = 2 * width; if (Toolbox::DetectEndianness() == Endianness_Little) { @@ -172,31 +168,34 @@ } else if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8) { - format_ = PixelFormat_Grayscale8; - pitch_ = 3 * width_; + format = PixelFormat_RGB24; + pitch = 3 * width; } else { throw OrthancException(ErrorCode_NotImplemented); } - buffer_.resize(height_ * pitch_); + data_.resize(height * pitch); - if (height_ == 0 || width_ == 0) + if (height == 0 || width == 0) { // Empty image, we are done + AssignEmpty(format); return; } - + png_read_update_info(rabi.png_, rabi.info_); - std::vector rows(height_); - for (size_t i = 0; i < height_; i++) + std::vector rows(height); + for (size_t i = 0; i < height; i++) { - rows[i] = &buffer_[0] + i * pitch_; + rows[i] = &data_[0] + i * pitch; } png_read_image(rabi.png_, &rows[0]); + + AssignReadOnly(format, width, height, pitch, &data_[0]); } void PngReader::ReadFromFile(const char* filename) @@ -225,6 +224,89 @@ } + void* ImageAccessor::GetBuffer() + { + if (readOnly_) + { + throw OrthancException(ErrorCode_ReadOnly); + } + + return buffer_; + } + + + const void* ImageAccessor::GetConstRow(unsigned int y) const + { + if (buffer_ != NULL) + { + return reinterpret_cast(buffer_) + y * pitch_; + } + else + { + return NULL; + } + } + + + void* ImageAccessor::GetRow(unsigned int y) + { + if (readOnly_) + { + throw OrthancException(ErrorCode_ReadOnly); + } + + if (buffer_ != NULL) + { + return reinterpret_cast(buffer_) + y * pitch_; + } + else + { + return NULL; + } + } + + + void ImageAccessor::AssignEmpty(PixelFormat format) + { + readOnly_ = false; + format_ = format; + width_ = 0; + height_ = 0; + pitch_ = 0; + buffer_ = NULL; + } + + + void ImageAccessor::AssignReadOnly(PixelFormat format, + unsigned int width, + unsigned int height, + unsigned int pitch, + const void *buffer) + { + readOnly_ = true; + format_ = format; + width_ = width; + height_ = height; + pitch_ = pitch; + buffer_ = const_cast(buffer); + } + + + void ImageAccessor::AssignWritable(PixelFormat format, + unsigned int width, + unsigned int height, + unsigned int pitch, + void *buffer) + { + readOnly_ = false; + format_ = format; + width_ = width; + height_ = height; + pitch_ = pitch; + buffer_ = buffer; + } + + namespace { @@ -298,8 +380,12 @@ void PngReader::ReadFromMemory(const std::string& buffer) { if (buffer.size() != 0) + { ReadFromMemory(&buffer[0], buffer.size()); + } else + { ReadFromMemory(NULL, 0); + } } } diff -r e7b1ca0f1e04 -r 37adac56017a Core/FileFormats/PngReader.h --- a/Core/FileFormats/PngReader.h Tue May 06 12:09:11 2014 +0200 +++ b/Core/FileFormats/PngReader.h Tue May 06 12:47:26 2014 +0200 @@ -40,23 +40,26 @@ namespace Orthanc { - class PngReader + class ImageAccessor { private: - struct PngRabi; - + bool readOnly_; PixelFormat format_; unsigned int width_; unsigned int height_; unsigned int pitch_; - std::vector buffer_; - - void CheckHeader(const void* header); - - void Read(PngRabi& rabi); + void *buffer_; public: - PngReader(); + ImageAccessor() + { + AssignEmpty(PixelFormat_Grayscale8); + } + + bool IsReadOnly() const + { + return readOnly_; + } PixelFormat GetFormat() const { @@ -78,21 +81,46 @@ return pitch_; } - const void* GetBuffer() const + const void* GetConstBuffer() const { - if (buffer_.size() > 0) - return &buffer_[0]; - else - return NULL; + return buffer_; } - const void* GetBuffer(unsigned int y) const - { - if (buffer_.size() > 0) - return &buffer_[y * pitch_]; - else - return NULL; - } + void* GetBuffer(); + + const void* GetConstRow(unsigned int y) const; + + void* GetRow(unsigned int y); + + void AssignEmpty(PixelFormat format); + + void AssignReadOnly(PixelFormat format, + unsigned int width, + unsigned int height, + unsigned int pitch, + const void *buffer); + + void AssignWritable(PixelFormat format, + unsigned int width, + unsigned int height, + unsigned int pitch, + void *buffer); + }; + + + class PngReader : public ImageAccessor + { + private: + struct PngRabi; + + std::vector data_; + + void CheckHeader(const void* header); + + void Read(PngRabi& rabi); + + public: + PngReader(); void ReadFromFile(const char* filename); diff -r e7b1ca0f1e04 -r 37adac56017a Core/OrthancException.cpp --- a/Core/OrthancException.cpp Tue May 06 12:09:11 2014 +0200 +++ b/Core/OrthancException.cpp Tue May 06 12:47:26 2014 +0200 @@ -111,6 +111,9 @@ case ErrorCode_InexistentTag: return "Inexistent tag"; + case ErrorCode_ReadOnly: + return "Cannot modify a read-only data structure"; + case ErrorCode_Custom: default: return "???"; diff -r e7b1ca0f1e04 -r 37adac56017a OrthancCppClient/Instance.cpp --- a/OrthancCppClient/Instance.cpp Tue May 06 12:09:11 2014 +0200 +++ b/OrthancCppClient/Instance.cpp Tue May 06 12:47:26 2014 +0200 @@ -178,13 +178,13 @@ const void* Instance::GetBuffer() { DownloadImage(); - return reader_->GetBuffer(); + return reader_->GetConstBuffer(); } const void* Instance::GetBuffer(unsigned int y) { DownloadImage(); - return reader_->GetBuffer(y); + return reader_->GetConstRow(y); } void Instance::DiscardImage() diff -r e7b1ca0f1e04 -r 37adac56017a UnitTestsSources/Png.cpp --- a/UnitTestsSources/Png.cpp Tue May 06 12:09:11 2014 +0200 +++ b/UnitTestsSources/Png.cpp Tue May 06 12:47:26 2014 +0200 @@ -119,8 +119,8 @@ v = 0; for (int y = 0; y < height; y++) { - uint16_t *p = reinterpret_cast((uint8_t*) r.GetBuffer() + y * r.GetPitch()); - ASSERT_EQ(p, r.GetBuffer(y)); + const uint16_t *p = reinterpret_cast((const uint8_t*) r.GetConstBuffer() + y * r.GetPitch()); + ASSERT_EQ(p, r.GetConstRow(y)); for (int x = 0; x < width; x++, p++, v++) { ASSERT_EQ(*p, v); @@ -142,8 +142,8 @@ v = 0; for (int y = 0; y < height; y++) { - uint16_t *p = reinterpret_cast((uint8_t*) r2.GetBuffer() + y * r2.GetPitch()); - ASSERT_EQ(p, r2.GetBuffer(y)); + const uint16_t *p = reinterpret_cast((const uint8_t*) r2.GetConstBuffer() + y * r2.GetPitch()); + ASSERT_EQ(p, r2.GetConstRow(y)); for (int x = 0; x < width; x++, p++, v++) { ASSERT_EQ(*p, v);