/* * #%L * OME-FILES C++ library for image IO. * Copyright © 2015 Open Microscopy Environment: * - Massachusetts Institute of Technology * - National Institutes of Health * - University of Dundee * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of any organization. * #L% */ #include #include #include #include #include #include #include #include using ome::files::PixelBuffer; using ome::files::PixelBufferBase; using ome::files::PixelProperties; using ome::files::VariantPixelBuffer; using ome::xml::model::enums::DimensionOrder; using ome::xml::model::enums::PixelType; namespace { void createPixelBuffer() { /* create-example-start */ // Language type for FLOAT pixel data typedef PixelProperties::std_type float_pixel_type; // Create PixelBuffer for floating point data // X=512 Y=512 Z=16 T=1 C=3 S/z/t/c=1 PixelBuffer buffer (boost::extents[512][512][16][1][3][1][1][1][1], PixelType::FLOAT); /* create-example-end */ /* at-example-start */ // Set all pixel values for Z=2 and C=1 to 0.5 // 9D index, default values to zero if unused PixelBuffer::indices_type idx; // Set Z and C indices idx[ome::files::DIM_SPATIAL_Z] = 2; idx[ome::files::DIM_CHANNEL] = 1; idx[ome::files::DIM_TEMPORAL_T] = idx[ome::files::DIM_SUBCHANNEL] = idx[ome::files::DIM_MODULO_Z] = idx[ome::files::DIM_MODULO_T] = idx[ome::files::DIM_MODULO_C] = 0; for (uint16_t x = 0; x < 512; ++x) { idx[ome::files::DIM_SPATIAL_X] = x; for (uint16_t y = 0; y < 512; ++y) { idx[ome::files::DIM_SPATIAL_Y] = y; buffer.at(idx) = 0.5f; } } /* at-example-end */ } void createPixelBufferOrdered() { /* create-ordered-example-start */ // Language type for UINT16 pixel data typedef PixelProperties::std_type uint16_pixel_type; // Storage order is XYSCTZctz; subchannels are not interleaved // ("planar") after XY; lowercase letters are unused Modulo // dimensions PixelBufferBase::storage_order_type order1 (PixelBufferBase::make_storage_order(DimensionOrder::XYCTZ, false)); // Create PixelBuffer for unsigned 16-bit data with specified // storage order // X=512 Y=512 Z=16 T=1 C=3 S/z/t/c=1 PixelBuffer buffer1 (boost::extents[512][512][16][1][3][1][1][1][1], PixelType::UINT16, ome::files::ENDIAN_NATIVE, order1); // Language type for INT8 pixel data typedef PixelProperties::std_type int8_pixel_type; // Storage order is SXYZCTzct; subchannels are interleaved // ("chunky") before XY; lowercase letters are unused Modulo // dimensions PixelBufferBase::storage_order_type order2 (PixelBufferBase::make_storage_order(DimensionOrder::XYZCT, true)); // Create PixelBuffer for signed 8-bit RGB data with specified storage // order // X=1024 Y=1024 Z=1 T=1 C=1 S=3 z/t/c=1 PixelBuffer buffer2 (boost::extents[1024][1024][1][1][1][3][1][1][1], PixelType::INT8, ome::files::ENDIAN_NATIVE, order2); /* create-ordered-example-end */ } void reorderPixelBuffer() { /* reorder-example-start */ // Language type for FLOAT pixel data typedef PixelProperties::std_type float_pixel_type; // Storage order is XYSZCTzct; subchannels are not interleaved // ("planar") after XY; lowercase letters are unused Modulo // dimensions PixelBufferBase::storage_order_type planar_order (PixelBufferBase::make_storage_order(DimensionOrder::XYZCT, false)); // Storage order is SXYZCTzct; subchannels are interleaved // ("chunky" or "contiguous") before XY; lowercase letters are // unused Modulo dimensions PixelBufferBase::storage_order_type contiguous_order (PixelBufferBase::make_storage_order(DimensionOrder::XYZCT, true)); // Create PixelBuffer for float data with planar order // X=512 Y=512 Z=16 T=1 C=3 S/z/t/c=1 PixelBuffer planar_buffer (boost::extents[512][512][16][1][3][1][1][1][1], PixelType::FLOAT, ome::files::ENDIAN_NATIVE, planar_order); // Create PixelBuffer for float data with contiguous order // X=512 Y=512 Z=16 T=1 C=3 S/z/t/c=1 PixelBuffer contiguous_buffer (boost::extents[512][512][16][1][3][1][1][1][1], PixelType::FLOAT, ome::files::ENDIAN_NATIVE, contiguous_order); // Transfer the pixel data from the planar buffer to the // contiguous buffer; the pixel data will be reordered // appropriately during the transfer. contiguous_buffer = planar_buffer; /* reorder-example-end */ } /* visitor-example-start */ // Visitor to compute min and max pixel value for pixel buffer of // any pixel type // The static_visitor specialization is the required return type of // the operator() methods and boost::apply_visitor() struct MinMaxVisitor : public boost::static_visitor> { // The min and max values will be returned in a pair. double is // used since it can contain the value for any pixel type typedef std::pair result_type; // Get min and max for any non-complex pixel type template result_type operator() (const T& v) { typedef typename T::element_type::value_type value_type; value_type *min = std::min_element(v->data(), v->data() + v->num_elements()); value_type *max = std::max_element(v->data(), v->data() + v->num_elements()); return result_type(static_cast(*min), static_cast(*max)); } // Less than comparison for real part of complex numbers template static bool complex_real_less(const T& lhs, const T& rhs) { return std::real(lhs) < std::real(rhs); } // Greater than comparison for real part of complex numbers template static bool complex_real_greater(const T& lhs, const T& rhs) { return std::real(lhs) > std::real(rhs); } // Get min and max for complex pixel types (COMPLEXFLOAT and // COMPLEXDOUBLE) // This is the same as for simple pixel types, except for the // addition of custom comparison functions and conversion of the // result to the real part. template typename boost::enable_if_c< boost::is_complex::value, result_type >::type operator() (const std::shared_ptr>& v) { typedef T value_type; value_type *min = std::min_element(v->data(), v->data() + v->num_elements(), complex_real_less); value_type *max = std::max_element(v->data(), v->data() + v->num_elements(), complex_real_greater); return result_type(static_cast(std::real(*min)), static_cast(std::real(*max))); } }; void applyVariant() { // Make variant buffer (int32, 16×16 single plane) VariantPixelBuffer variant(boost::extents[16][16][1][1][1][1][1][1][1], PixelType::INT32); // Get buffer size VariantPixelBuffer::size_type size = variant.num_elements(); // Create sample random-ish data std::vector vec; for (VariantPixelBuffer::size_type i = 0; i < size; ++i) { int32_t val = static_cast(i + 42); vec.push_back(val); } std::random_shuffle(vec.begin(), vec.end()); // Assign sample data to buffer. variant.assign(vec.begin(), vec.end()); // Create and apply visitor MinMaxVisitor visitor; MinMaxVisitor::result_type result = boost::apply_visitor(visitor, variant.vbuffer()); std::cout << "Min is " << result.first << ", max is " << result.second << '\n'; } /* visitor-example-end */ } int main() { // This is the default, but needs setting manually on Windows. ome::common::setLogLevel(ome::logging::trivial::warning); try { createPixelBuffer(); createPixelBufferOrdered(); reorderPixelBuffer(); applyVariant(); } catch (const std::exception& e) { std::cerr << "Caught exception: " << e.what() << '\n'; std::exit(1); } catch (...) { std::cerr << "Caught unknown exception\n"; std::exit(1); } }