Program Listing for File MechEyeFrame.hpp

Return to documentation for file (D:\projects\eye\src\api\include\MechEyeFrame.hpp)

/*******************************************************************************
 *BSD 3-Clause License
 *
 *Copyright (c) 2016-2022, Mech-Mind Robotics
 *All rights reserved.
 *
 *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.
 *
 *3. Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 *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 HOLDER 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.
 ******************************************************************************/

#pragma once
#include <stdint.h>
#include <memory>
#include <vector>
#include <stdexcept>
#include "api_global.h"
#include "MechEyeDataType.h"

namespace mmind {
namespace api {

template <typename ElementType>
class Frame;

struct ElementDepth
{
    float d;
};

struct ElementColor
{
    uint8_t b;
    uint8_t g;
    uint8_t r;
};

struct ElementPointXYZ
{
    float x;
    float y;
    float z;
};

struct ElementPointXYZBGR
{
    uint8_t b;
    uint8_t g;
    uint8_t r;
    float x;
    float y;
    float z;
};

typedef Frame<ElementColor> ColorMap;

typedef Frame<ElementDepth> DepthMap;

typedef Frame<ElementPointXYZ> PointXYZMap;

typedef Frame<ElementPointXYZBGR> PointXYZBGRMap;

template <typename ElementType>
class Frame
{
public:
    Frame() : _width(0), _height(0), _pData(nullptr) {}
    ~Frame() {}

    inline uint32_t width() const { return _width; }

    inline uint32_t height() const { return _height; }

    inline bool empty() const { return !_pData; }

    inline const ElementType* data() const { return _pData.get(); }

    inline ElementType* data()
    {
        return const_cast<ElementType*>(static_cast<const Frame<ElementType>&>(*this).data());
    }

    inline const ElementType& operator[](std::size_t n) const
    {
        if (n >= _height * _width || !_pData)
            throw std::out_of_range("invalid subscript");
        ElementType* data = _pData.get();
        return data[n];
    }

    inline ElementType& operator[](std::size_t n)
    {
        return const_cast<ElementType&>(static_cast<const Frame<ElementType>&>(*this)[n]);
    }

    const ElementType& at(uint32_t row, uint32_t col) const
    {
        if (row >= _height || col >= _width || !_pData)
            throw std::out_of_range("invalid subscript");
        ElementType* data = _pData.get();
        return data[row * _width + col];
    }

    ElementType& at(uint32_t row, uint32_t col)
    {
        return const_cast<ElementType&>(static_cast<const Frame<ElementType>&>(*this).at(row, col));
    }

    void resize(uint32_t width, uint32_t height)
    {
        if (_width == width && _height == height)
            return;

        _width = width;
        _height = height;
        _pData.reset(new ElementType[_width * _height], [](ElementType* p) { delete[] p; });
    }

    void release()
    {
        _pData.reset();
        _width = 0;
        _height = 0;
    }

private:
    uint32_t _width;
    uint32_t _height;
    std::shared_ptr<ElementType> _pData;
};
} // namespace api
} // namespace mmind