ome-files  0.5.0
PixelBuffer.h
1 /*
2  * #%L
3  * OME-FILES C++ library for image IO.
4  * Copyright © 2006 - 2015 Open Microscopy Environment:
5  * - Massachusetts Institute of Technology
6  * - National Institutes of Health
7  * - University of Dundee
8  * - Board of Regents of the University of Wisconsin-Madison
9  * - Glencoe Software, Inc.
10  * %%
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  * The views and conclusions contained in the software and documentation are
33  * those of the authors and should not be interpreted as representing official
34  * policies, either expressed or implied, of any organization.
35  * #L%
36  */
37 
38 #ifndef OME_FILES_PIXELBUFFER_H
39 #define OME_FILES_PIXELBUFFER_H
40 
41 #include <array>
42 #include <cstdint>
43 #include <istream>
44 #include <limits>
45 #include <memory>
46 #include <ostream>
47 #include <stdexcept>
48 #include <string>
49 
50 // Disable expensive bounds checking
51 #define BOOST_DISABLE_ASSERTS 1
52 #include <boost/multi_array.hpp>
53 
54 #include <ome/files/PixelProperties.h>
55 
56 #include <ome/common/variant.h>
57 
58 #include <ome/xml/model/enums/DimensionOrder.h>
59 
60 namespace ome
61 {
62  namespace files
63  {
64 
79  {
89  };
90 
104  {
105  public:
107  static const uint16_t dimensions = 9;
108 
110  typedef boost::multi_array_types::size_type size_type;
111 
113  typedef boost::multi_array_types::index index;
114 
116  typedef std::array<boost::multi_array_types::index,
118 
120  typedef boost::general_storage_order<dimensions> storage_order_type;
121 
123  typedef boost::detail::multi_array::extent_gen<dimensions> range_type;
124 
125  protected:
135  pixeltype(pixeltype),
136  endiantype(endiantype)
137  {}
138 
139  public:
142  {}
143 
150  pixelType() const
151  {
152  return pixeltype;
153  }
154 
160  EndianType
161  endianType() const
162  {
163  return endiantype;
164  }
165 
178  static storage_order_type
180  bool interleaved);
181 
190  static storage_order_type
192 
193  private:
195  const ::ome::xml::model::enums::PixelType pixeltype;
196 
199  };
200 
234  template<typename T>
236  {
237  public:
239  typedef T value_type;
240 
246  typedef boost::multi_array_ref<value_type, dimensions> array_ref_type;
247 
252  typedef boost::multi_array<value_type, dimensions> array_type;
253 
260  explicit PixelBuffer():
261  PixelBufferBase(::ome::xml::model::enums::PixelType::UINT8, ENDIAN_NATIVE),
262  multiarray(std::shared_ptr<array_type>(new array_type(boost::extents[1][1][1][1][1][1][1][1][1],
264  {}
265 
277  template<class ExtentList>
278  explicit
279  PixelBuffer(const ExtentList& extents,
284  multiarray(std::shared_ptr<array_type>(new array_type(extents, storage)))
285  {}
286 
301  template<class ExtentList>
302  explicit
303  PixelBuffer(value_type *pixeldata,
304  const ExtentList& extents,
309  multiarray(std::shared_ptr<array_ref_type>(new array_ref_type(pixeldata, extents, storage)))
310  {}
311 
323  explicit
324  PixelBuffer(const range_type& range,
329  multiarray(std::shared_ptr<array_type>(new array_type(range, storage)))
330  {}
331 
346  explicit
347  PixelBuffer(value_type *pixeldata,
348  const range_type& range,
353  multiarray(std::shared_ptr<array_ref_type>(new array_ref_type(pixeldata, range, storage)))
354  {}
355 
364  explicit
365  PixelBuffer(const PixelBuffer& buffer):
366  PixelBufferBase(buffer),
367  multiarray(buffer.multiarray)
368  {}
369 
371  virtual ~PixelBuffer()
372  {}
373 
380  array_ref_type&
381  array();
382 
389  const array_ref_type&
390  array() const;
391 
400  value_type *
402  {
403  return array().data();
404  }
405 
414  const value_type *
415  data() const
416  {
417  return array().data();
418  }
419 
430  bool
431  valid() const
432  {
433  bool is_valid = true;
434 
435  try
436  {
437  array();
438  }
439  catch (const std::runtime_error&)
440  {
441  is_valid = false;
442  }
443 
444  return is_valid;
445  }
446 
454  bool
455  managed() const
456  {
457  return (boost::get<std::shared_ptr<array_type>>(&multiarray) != nullptr);
458  }
459 
465  size_type
466  num_elements() const
467  {
468  return array().num_elements();
469  }
470 
476  size_type
478  {
479  return array().num_dimensions();
480  }
481 
489  const size_type *
490  shape() const
491  {
492  return array().shape();
493  }
494 
502  const boost::multi_array_types::index *
503  strides() const
504  {
505  return array().strides();
506  }
507 
516  const boost::multi_array_types::index *
517  index_bases() const
518  {
519  return array().index_bases();
520  }
521 
532  const value_type *
533  origin() const
534  {
535  return array().origin();
536  }
537 
543  const storage_order_type&
545  {
546  return array().storage_order();
547  }
548 
559  PixelBuffer&
560  operator = (const PixelBuffer& rhs)
561  {
562  array() = rhs.array();
563  return *this;
564  }
565 
576  PixelBuffer&
577  operator = (const array_ref_type& rhs)
578  {
579  array() = rhs;
580  return *this;
581  }
582 
589  bool
590  operator == (const PixelBuffer& rhs) const
591  {
592  return array() == rhs.array();
593  }
594 
601  bool
602  operator == (const array_ref_type& rhs) const
603  {
604  return array() == rhs;
605  }
606 
613  bool
614  operator != (const PixelBuffer& rhs) const
615  {
616  return array() != rhs.array();
617  }
618 
625  bool
626  operator != (const array_ref_type& rhs) const
627  {
628  return array() != rhs;
629  }
630 
637  bool
638  operator < (const PixelBuffer& rhs) const
639  {
640  return array() < rhs.array();
641  }
642 
649  bool
650  operator < (const array_ref_type& rhs) const
651  {
652  return array() < rhs;
653  }
654 
661  bool
662  operator <= (const PixelBuffer& rhs) const
663  {
664  return array() <= rhs.array();
665  }
666 
673  bool
674  operator <= (const array_ref_type& rhs) const
675  {
676  return array() <= rhs;
677  }
678 
685  bool
686  operator > (const PixelBuffer& rhs) const
687  {
688  return array() > rhs.array();
689  }
690 
697  bool
698  operator > (const array_ref_type& rhs) const
699  {
700  return array() > rhs;
701  }
702 
709  bool
710  operator >= (const PixelBuffer& rhs) const
711  {
712  return array() >= rhs.array();
713  }
714 
721  bool
722  operator >= (const array_ref_type& rhs) const
723  {
724  return array() >= rhs;
725  }
726 
735  template <typename InputIterator>
736  void
737  assign(InputIterator begin,
738  InputIterator end)
739  {
740  array().assign(begin, end);
741  }
742 
753  value_type&
754  at(const indices_type& indices)
755  {
756  return array()(indices);
757  }
758 
769  const value_type&
770  at(const indices_type& indices) const
771  {
772  return array()(indices);
773  }
774 
785  template<class charT, class traits>
786  inline void
787  read(std::basic_istream<charT,traits>& stream)
788  {
789  stream.read(reinterpret_cast<char *>(data()),
790  static_cast<std::streamsize>(num_elements() * sizeof(value_type)));
791  }
792 
803  template<class charT, class traits>
804  inline void
805  write(std::basic_ostream<charT,traits>& stream) const
806  {
807  stream.write(reinterpret_cast<const char *>(data()),
808  static_cast<std::streamsize>(num_elements() * sizeof(value_type)));
809  }
810 
811  private:
827  boost::variant<std::shared_ptr<array_type>,
828  std::shared_ptr<array_ref_type>> multiarray;
829  };
830 
831  namespace detail
832  {
833 
835  template<typename T>
836  struct PixelBufferArrayVisitor : public boost::static_visitor<typename PixelBuffer<T>::array_ref_type *>
837  {
844  template <typename U>
846  operator() (U& v) const
847  {
848  if (!v)
849  throw std::runtime_error("Null array type");
850  return v.get();
851  }
852  };
853 
855  template<typename T>
856  struct PixelBufferConstArrayVisitor : public boost::static_visitor<const typename PixelBuffer<T>::array_ref_type *>
857  {
864  template <typename U>
865  const typename PixelBuffer<T>::array_ref_type *
866  operator() (U& v) const
867  {
868  if (!v)
869  throw std::runtime_error("Null array type");
870  return v.get();
871  }
872  };
873 
874  }
875 
876  template<typename T>
879  {
881  return *(boost::apply_visitor(v, multiarray));
882  }
883 
884  template<typename T>
885  const typename PixelBuffer<T>::array_ref_type&
887  {
889  return *(boost::apply_visitor(v, multiarray));
890  }
891 
892  }
893 }
894 
895 namespace std
896 {
897 
905  template<typename T, class charT, class traits>
906  inline std::basic_istream<charT,traits>&
907  operator>> (std::basic_istream<charT,traits>& is,
909  {
910  buf.read(is);
911  return is;
912  }
913 
921  template<typename T, class charT, class traits>
922  inline std::basic_ostream<charT,traits>&
923  operator<< (std::basic_ostream<charT,traits>& os,
924  const ::ome::files::PixelBuffer<T>& buf)
925  {
926  buf.write(os);
927  return os;
928  }
929 
930 }
931 
932 #endif // OME_FILES_PIXELBUFFER_H
933 
934 /*
935  * Local Variables:
936  * mode:C++
937  * End:
938  */
const value_type * origin() const
Get the origin of the array.
Definition: PixelBuffer.h:533
boost::multi_array_ref< value_type, dimensions > array_ref_type
Type for multi-dimensional pixel array view referencing external data.
Definition: PixelBuffer.h:246
size_type num_dimensions() const
Get the number of dimensions in the multi-dimensional array.
Definition: PixelBuffer.h:477
Buffer for a specific pixel type.
Definition: PixelBuffer.h:235
PixelBuffer(value_type *pixeldata, const range_type &range, ::ome::xml::model::enums::PixelType pixeltype=::ome::xml::model::enums::PixelType::UINT8, EndianType endiantype=ENDIAN_NATIVE, const storage_order_type &storage=PixelBufferBase::default_storage_order())
Construct from ranges (external storage).
Definition: PixelBuffer.h:347
void assign(InputIterator begin, InputIterator end)
Assign pixel values.
Definition: PixelBuffer.h:737
virtual ~PixelBuffer()
Destructor.
Definition: PixelBuffer.h:371
Spatial y dimension (Y).
Definition: PixelBuffer.h:81
value_type * data()
Get the raw data.
Definition: PixelBuffer.h:401
boost::variant< std::shared_ptr< array_type >, std::shared_ptr< array_ref_type > > multiarray
Multi-dimensional pixel array.
Definition: PixelBuffer.h:828
STL namespace.
boost::multi_array_types::index index
Index type.
Definition: PixelBuffer.h:113
Base class for all PixelBuffer types.
Definition: PixelBuffer.h:103
Logical subdivision of the temporal t dimension (t).
Definition: PixelBuffer.h:87
value_type & at(const indices_type &indices)
Get the pixel value at an index.
Definition: PixelBuffer.h:754
PixelBufferBase(::ome::xml::model::enums::PixelType pixeltype, EndianType endiantype)
Constructor.
Definition: PixelBuffer.h:133
const boost::multi_array_types::index * index_bases() const
Get the index bases of the multi-dimensional array.
Definition: PixelBuffer.h:517
Logical subdivision of the logical channel dimension (c).
Definition: PixelBuffer.h:88
Spatial x dimension (X).
Definition: PixelBuffer.h:80
::ome::xml::model::enums::PixelType pixelType() const
Get the pixel type in use.
Definition: PixelBuffer.h:150
Open Microscopy Environment C++.
boost::general_storage_order< dimensions > storage_order_type
Storage ordering type for controlling pixel memory layout.
Definition: PixelBuffer.h:120
Native endian.
Definition: Types.h:71
Find a PixelBuffer data array of a specific pixel type.
Definition: PixelBuffer.h:836
static storage_order_type make_storage_order(ome::xml::model::enums::DimensionOrder order, bool interleaved)
Generate storage ordering for a given dimension order.
Definition: PixelBuffer.cpp:54
const value_type & at(const indices_type &indices) const
Get the pixel value at an index.
Definition: PixelBuffer.h:770
PixelBuffer(const range_type &range, ::ome::xml::model::enums::PixelType pixeltype=::ome::xml::model::enums::PixelType::UINT8, EndianType endiantype=ENDIAN_NATIVE, const storage_order_type &storage=PixelBufferBase::default_storage_order())
Construct from ranges (internal storage).
Definition: PixelBuffer.h:324
virtual ~PixelBufferBase()
Destructor.
Definition: PixelBuffer.h:141
EndianType
Endianness.
Definition: Types.h:67
const boost::multi_array_types::index * strides() const
Get the strides of the multi-dimensional array.
Definition: PixelBuffer.h:503
const size_type * shape() const
Get the shape of the multi-dimensional array.
Definition: PixelBuffer.h:490
void write(std::basic_ostream< charT, traits > &stream) const
Write raw pixel data to a stream in physical storage order.
Definition: PixelBuffer.h:805
bool managed() const
Check if the buffer is internally managed.
Definition: PixelBuffer.h:455
EndianType endianType() const
Get the endian type in use.
Definition: PixelBuffer.h:161
size_type num_elements() const
Get the number of pixel elements in the multi-dimensional array.
Definition: PixelBuffer.h:466
void read(std::basic_istream< charT, traits > &stream)
Read raw pixel data from a stream in physical storage order.
Definition: PixelBuffer.h:787
Temporal t dimension (T).
Definition: PixelBuffer.h:83
Dimensions
Dimensions.
Definition: PixelBuffer.h:78
Find a PixelBuffer data array of a specific pixel type.
Definition: PixelBuffer.h:856
PixelBuffer(const ExtentList &extents, ::ome::xml::model::enums::PixelType pixeltype=::ome::xml::model::enums::PixelType::UINT8, EndianType endiantype=ENDIAN_NATIVE, const storage_order_type &storage=PixelBufferBase::default_storage_order())
Construct from extents (internal storage).
Definition: PixelBuffer.h:279
boost::detail::multi_array::extent_gen< dimensions > range_type
Extent range type.
Definition: PixelBuffer.h:123
boost::multi_array_types::size_type size_type
Size type.
Definition: PixelBuffer.h:110
PixelBuffer(const PixelBuffer &buffer)
Copy constructor.
Definition: PixelBuffer.h:365
array_ref_type & array()
Get the pixel data.
Definition: PixelBuffer.h:878
const ::ome::xml::model::enums::PixelType pixeltype
Pixel type stored in this buffer.
Definition: PixelBuffer.h:195
static const uint16_t dimensions
Total number of supported dimensions.
Definition: PixelBuffer.h:107
PixelBuffer()
Default constructor.
Definition: PixelBuffer.h:260
Spatial z dimension (Z).
Definition: PixelBuffer.h:82
boost::multi_array< value_type, dimensions > array_type
Type for multi-dimensional pixel array view.
Definition: PixelBuffer.h:252
static storage_order_type default_storage_order()
Generate default storage ordering.
Definition: PixelBuffer.cpp:133
const EndianType endiantype
Endian type stored in this buffer.
Definition: PixelBuffer.h:198
std::array< boost::multi_array_types::index, PixelBufferBase::dimensions > indices_type
Type used to index all dimensions in public interfaces.
Definition: PixelBuffer.h:117
Logical subdivision of the spatial z dimension (z).
Definition: PixelBuffer.h:86
PixelBuffer(value_type *pixeldata, const ExtentList &extents, ::ome::xml::model::enums::PixelType pixeltype=::ome::xml::model::enums::PixelType::UINT8, EndianType endiantype=ENDIAN_NATIVE, const storage_order_type &storage=PixelBufferBase::default_storage_order())
Construct from extents (external storage).
Definition: PixelBuffer.h:303
Logical channel (typically detectors of specific wavelengths) (C).
Definition: PixelBuffer.h:84
const value_type * data() const
Get the raw data.
Definition: PixelBuffer.h:415
const storage_order_type & storage_order() const
Get the array storage order.
Definition: PixelBuffer.h:544
T value_type
Pixel value type.
Definition: PixelBuffer.h:239
bool valid() const
Check the buffer validity.
Definition: PixelBuffer.h:431
Logical sub-channel (typically used for RGB channel sub-components) (S).
Definition: PixelBuffer.h:85