Mercurial > hg > orthanc
changeset 797:37adac56017a
ImageAccessor abstraction
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 May 2014 12:47:26 +0200 |
parents | e7b1ca0f1e04 |
children | e1d27ee2114a |
files | Core/Enumerations.h Core/FileFormats/PngReader.cpp Core/FileFormats/PngReader.h Core/OrthancException.cpp OrthancCppClient/Instance.cpp UnitTestsSources/Png.cpp |
diffstat | 6 files changed, 164 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- 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 }; /**
--- 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<png_bytep> rows(height_); - for (size_t i = 0; i < height_; i++) + std::vector<png_bytep> 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<const uint8_t*>(buffer_) + y * pitch_; + } + else + { + return NULL; + } + } + + + void* ImageAccessor::GetRow(unsigned int y) + { + if (readOnly_) + { + throw OrthancException(ErrorCode_ReadOnly); + } + + if (buffer_ != NULL) + { + return reinterpret_cast<uint8_t*>(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<void*>(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); + } } }
--- 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<uint8_t> 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<uint8_t> data_; + + void CheckHeader(const void* header); + + void Read(PngRabi& rabi); + + public: + PngReader(); void ReadFromFile(const char* filename);
--- 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 "???";
--- 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()
--- 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<uint16_t*>((uint8_t*) r.GetBuffer() + y * r.GetPitch()); - ASSERT_EQ(p, r.GetBuffer(y)); + const uint16_t *p = reinterpret_cast<const uint16_t*>((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<uint16_t*>((uint8_t*) r2.GetBuffer() + y * r2.GetPitch()); - ASSERT_EQ(p, r2.GetBuffer(y)); + const uint16_t *p = reinterpret_cast<const uint16_t*>((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);