diff options
| author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-02-02 17:13:01 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2020-02-02 17:13:01 +0100 | 
| commit | ffa8801644a7d53cc1c785e3450f794c07a14eb0 (patch) | |
| tree | 8d72a18a9a08b9151d12badcb1c78ce06a059f62 /backend/genesys/image.cpp | |
| parent | 1687222e1b9e74c89cafbb5910e72d8ec7bfd40f (diff) | |
New upstream version 1.0.29upstream/1.0.29
Diffstat (limited to 'backend/genesys/image.cpp')
| -rw-r--r-- | backend/genesys/image.cpp | 204 | 
1 files changed, 204 insertions, 0 deletions
| diff --git a/backend/genesys/image.cpp b/backend/genesys/image.cpp new file mode 100644 index 0000000..7d386c6 --- /dev/null +++ b/backend/genesys/image.cpp @@ -0,0 +1,204 @@ +/* sane - Scanner Access Now Easy. + +   Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + +   This file is part of the SANE package. + +   This program is free software; you can redistribute it and/or +   modify it under the terms of the GNU General Public License as +   published by the Free Software Foundation; either version 2 of the +   License, or (at your option) any later version. + +   This program is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, +   MA 02111-1307, USA. + +   As a special exception, the authors of SANE give permission for +   additional uses of the libraries contained in this release of SANE. + +   The exception is that, if you link a SANE library with other files +   to produce an executable, this does not by itself cause the +   resulting executable to be covered by the GNU General Public +   License.  Your use of that executable is in no way restricted on +   account of linking the SANE library code into it. + +   This exception does not, however, invalidate any other reasons why +   the executable file might be covered by the GNU General Public +   License. + +   If you submit changes to SANE to the maintainers to be included in +   a subsequent release, you agree by submitting the changes that +   those changes may be distributed with this exception intact. + +   If you write modifications of your own for SANE, it is your choice +   whether to permit this exception to apply to your modifications. +   If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "image.h" + +#include <array> + +namespace genesys { + +Image::Image() = default; + +Image::Image(std::size_t width, std::size_t height, PixelFormat format) : +    width_{width}, +    height_{height}, +    format_{format}, +    row_bytes_{get_pixel_row_bytes(format_, width_)} +{ +    data_.resize(get_row_bytes() * height); +} + +std::uint8_t* Image::get_row_ptr(std::size_t y) +{ +    return data_.data() + row_bytes_ * y; +} + +const std::uint8_t* Image::get_row_ptr(std::size_t y) const +{ +    return data_.data() + row_bytes_ * y; +} + +Pixel Image::get_pixel(std::size_t x, std::size_t y) const +{ +    return get_pixel_from_row(get_row_ptr(y), x, format_); +} + +void Image::set_pixel(std::size_t x, std::size_t y, const Pixel& pixel) +{ +    set_pixel_to_row(get_row_ptr(y), x, pixel, format_); +} + +RawPixel Image::get_raw_pixel(std::size_t x, std::size_t y) const +{ +    return get_raw_pixel_from_row(get_row_ptr(y), x, format_); +} + +std::uint16_t Image::get_raw_channel(std::size_t x, std::size_t y, unsigned channel) const +{ +    return get_raw_channel_from_row(get_row_ptr(y), x, channel, format_); +} + +void Image::set_raw_pixel(std::size_t x, std::size_t y, const RawPixel& pixel) +{ +    set_raw_pixel_to_row(get_row_ptr(y), x, pixel, format_); +} + +void Image::resize(std::size_t width, std::size_t height, PixelFormat format) +{ +    width_ = width; +    height_ = height; +    format_ = format; +    row_bytes_ = get_pixel_row_bytes(format_, width_); +    data_.resize(get_row_bytes() * height); +} + +template<PixelFormat SrcFormat, PixelFormat DstFormat> +void convert_pixel_row_impl2(const std::uint8_t* in_data, std::uint8_t* out_data, +                             std::size_t count) +{ +    for (std::size_t i = 0; i < count; ++i) { +        Pixel pixel = get_pixel_from_row(in_data, i, SrcFormat); +        set_pixel_to_row(out_data, i, pixel, DstFormat); +    } +} + +template<PixelFormat SrcFormat> +void convert_pixel_row_impl(const std::uint8_t* in_data, std::uint8_t* out_data, +                            PixelFormat out_format, std::size_t count) +{ +    switch (out_format) { +        case PixelFormat::I1: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::I1>(in_data, out_data, count); +            return; +        } +        case PixelFormat::RGB111: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB111>(in_data, out_data, count); +            return; +        } +        case PixelFormat::I8: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::I8>(in_data, out_data, count); +            return; +        } +        case PixelFormat::RGB888: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB888>(in_data, out_data, count); +            return; +        } +        case PixelFormat::BGR888: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::BGR888>(in_data, out_data, count); +            return; +        } +        case PixelFormat::I16: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::I16>(in_data, out_data, count); +            return; +        } +        case PixelFormat::RGB161616: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB161616>(in_data, out_data, count); +            return; +        } +        case PixelFormat::BGR161616: { +            convert_pixel_row_impl2<SrcFormat, PixelFormat::BGR161616>(in_data, out_data, count); +            return; +        } +        default: +            throw SaneException("Unknown pixel format %d", static_cast<unsigned>(out_format)); +    } +} +void convert_pixel_row_format(const std::uint8_t* in_data, PixelFormat in_format, +                              std::uint8_t* out_data, PixelFormat out_format, std::size_t count) +{ +    if (in_format == out_format) { +        std::memcpy(out_data, in_data, get_pixel_row_bytes(in_format, count)); +        return; +    } + +    switch (in_format) { +        case PixelFormat::I1: { +            convert_pixel_row_impl<PixelFormat::I1>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::RGB111: { +            convert_pixel_row_impl<PixelFormat::RGB111>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::I8: { +            convert_pixel_row_impl<PixelFormat::I8>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::RGB888: { +            convert_pixel_row_impl<PixelFormat::RGB888>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::BGR888: { +            convert_pixel_row_impl<PixelFormat::BGR888>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::I16: { +            convert_pixel_row_impl<PixelFormat::I16>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::RGB161616: { +            convert_pixel_row_impl<PixelFormat::RGB161616>(in_data, out_data, out_format, count); +            return; +        } +        case PixelFormat::BGR161616: { +            convert_pixel_row_impl<PixelFormat::BGR161616>(in_data, out_data, out_format, count); +            return; +        } +        default: +            throw SaneException("Unknown pixel format %d", static_cast<unsigned>(in_format)); +    } +} + +} // namespace genesys | 
