From ad38bc6ecb80ddeb562841b33258dd53659b1da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 24 Aug 2020 18:44:51 +0200 Subject: New upstream version 1.0.31 --- backend/genesys/image_pipeline.h | 134 +++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 56 deletions(-) (limited to 'backend/genesys/image_pipeline.h') diff --git a/backend/genesys/image_pipeline.h b/backend/genesys/image_pipeline.h index 2986837..d4aef49 100644 --- a/backend/genesys/image_pipeline.h +++ b/backend/genesys/image_pipeline.h @@ -75,18 +75,6 @@ public: virtual bool get_next_row_data(std::uint8_t* out_data) = 0; }; -class ImagePipelineNodeBytesSource : public ImagePipelineNode -{ -public: - std::size_t remaining_bytes() const { return remaining_bytes_; } - void set_remaining_bytes(std::size_t bytes) { remaining_bytes_ = bytes; } - - std::size_t consume_remaining_bytes(std::size_t bytes); - -private: - std::size_t remaining_bytes_ = 0; -}; - // A pipeline node that produces data from a callable class ImagePipelineNodeCallableSource : public ImagePipelineNode { @@ -118,7 +106,7 @@ private: }; // A pipeline node that produces data from a callable requesting fixed-size chunks. -class ImagePipelineNodeBufferedCallableSource : public ImagePipelineNodeBytesSource +class ImagePipelineNodeBufferedCallableSource : public ImagePipelineNode { public: using ProducerCallback = std::function; @@ -135,8 +123,9 @@ public: bool get_next_row_data(std::uint8_t* out_data) override; - std::size_t buffer_size() const { return buffer_.size(); } - std::size_t buffer_available() const { return buffer_.available(); } + std::size_t remaining_bytes() const { return buffer_.remaining_size(); } + void set_remaining_bytes(std::size_t bytes) { buffer_.set_remaining_size(bytes); } + void set_last_read_multiple(std::size_t bytes) { buffer_.set_last_read_multiple(bytes); } private: ProducerCallback producer_; @@ -150,39 +139,8 @@ private: ImageBuffer buffer_; }; -class ImagePipelineNodeBufferedGenesysUsb : public ImagePipelineNodeBytesSource -{ -public: - using ProducerCallback = std::function; - - ImagePipelineNodeBufferedGenesysUsb(std::size_t width, std::size_t height, - PixelFormat format, std::size_t total_size, - const FakeBufferModel& buffer_model, - ProducerCallback producer); - - std::size_t get_width() const override { return width_; } - std::size_t get_height() const override { return height_; } - PixelFormat get_format() const override { return format_; } - - bool eof() const override { return eof_; } - - bool get_next_row_data(std::uint8_t* out_data) override; - - std::size_t buffer_available() const { return buffer_.available(); } - -private: - ProducerCallback producer_; - std::size_t width_ = 0; - std::size_t height_ = 0; - PixelFormat format_ = PixelFormat::UNKNOWN; - - bool eof_ = false; - - ImageBufferGenesysUsb buffer_; -}; - // A pipeline node that produces data from the given array. -class ImagePipelineNodeArraySource : public ImagePipelineNodeBytesSource +class ImagePipelineNodeArraySource : public ImagePipelineNode { public: ImagePipelineNodeArraySource(std::size_t width, std::size_t height, PixelFormat format, @@ -302,7 +260,7 @@ public: std::size_t pixels_per_chunk); }; -// A pipeline that swaps bytes in 16-bit components on big-endian systems +// A pipeline that swaps bytes in 16-bit components and does nothing otherwise. class ImagePipelineNodeSwap16BitEndian : public ImagePipelineNode { public: @@ -321,6 +279,23 @@ private: bool needs_swapping_ = false; }; +class ImagePipelineNodeInvert : public ImagePipelineNode +{ +public: + ImagePipelineNodeInvert(ImagePipelineNode& source); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; +}; + // A pipeline node that merges 3 mono lines into a color channel class ImagePipelineNodeMergeMonoLines : public ImagePipelineNode { @@ -377,7 +352,7 @@ public: unsigned shift_r, unsigned shift_g, unsigned shift_b); std::size_t get_width() const override { return source_.get_width(); } - std::size_t get_height() const override { return source_.get_height() - extra_height_; } + std::size_t get_height() const override { return height_; } PixelFormat get_format() const override { return source_.get_format(); } bool eof() const override { return source_.eof(); } @@ -387,23 +362,23 @@ public: private: ImagePipelineNode& source_; std::size_t extra_height_ = 0; + std::size_t height_ = 0; std::array channel_shifts_; RowBuffer buffer_; }; -// A pipeline node that shifts pixels across lines by the given offsets (performs unstaggering) +// A pipeline node that shifts pixels across lines by the given offsets (performs vertical +// unstaggering) class ImagePipelineNodePixelShiftLines : public ImagePipelineNode { public: - constexpr static std::size_t MAX_SHIFTS = 2; - ImagePipelineNodePixelShiftLines(ImagePipelineNode& source, const std::vector& shifts); std::size_t get_width() const override { return source_.get_width(); } - std::size_t get_height() const override { return source_.get_height() - extra_height_; } + std::size_t get_height() const override { return height_; } PixelFormat get_format() const override { return source_.get_format(); } bool eof() const override { return source_.eof(); } @@ -413,12 +388,44 @@ public: private: ImagePipelineNode& source_; std::size_t extra_height_ = 0; + std::size_t height_ = 0; std::vector pixel_shifts_; RowBuffer buffer_; }; +// A pipeline node that shifts pixels across columns by the given offsets. Each row is divided +// into pixel groups of shifts.size() pixels. For each output group starting at position xgroup, +// the i-th pixel will be set to the input pixel at position xgroup + shifts[i]. +class ImagePipelineNodePixelShiftColumns : public ImagePipelineNode +{ +public: + ImagePipelineNodePixelShiftColumns(ImagePipelineNode& source, + const std::vector& shifts); + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t width_ = 0; + std::size_t extra_width_ = 0; + + std::vector pixel_shifts_; + + std::vector temp_buffer_; +}; + +// exposed for tests +std::size_t compute_pixel_shift_extra_width(std::size_t source_width, + const std::vector& shifts); + // A pipeline node that extracts a sub-image from the image. Padding and cropping is done as needed. // The class can't pad to the left of the image currently, as only positive offsets are accepted. class ImagePipelineNodeExtract : public ImagePipelineNode @@ -476,7 +483,7 @@ class ImagePipelineNodeCalibrate : public ImagePipelineNode public: ImagePipelineNodeCalibrate(ImagePipelineNode& source, const std::vector& bottom, - const std::vector& top); + const std::vector& top, std::size_t x_start); std::size_t get_width() const override { return source_.get_width(); } std::size_t get_height() const override { return source_.get_height(); } @@ -517,6 +524,19 @@ class ImagePipelineStack { public: ImagePipelineStack() {} + ImagePipelineStack(ImagePipelineStack&& other) + { + clear(); + nodes_ = std::move(other.nodes_); + } + + ImagePipelineStack& operator=(ImagePipelineStack&& other) + { + clear(); + nodes_ = std::move(other.nodes_); + return *this; + } + ~ImagePipelineStack() { clear(); } std::size_t get_input_width() const; @@ -536,20 +556,22 @@ public: void clear(); template - void push_first_node(Args&&... args) + Node& push_first_node(Args&&... args) { if (!nodes_.empty()) { throw SaneException("Trying to append first node when there are existing nodes"); } nodes_.emplace_back(std::unique_ptr(new Node(std::forward(args)...))); + return static_cast(*nodes_.back()); } template - void push_node(Args&&... args) + Node& push_node(Args&&... args) { ensure_node_exists(); nodes_.emplace_back(std::unique_ptr(new Node(*nodes_.back(), std::forward(args)...))); + return static_cast(*nodes_.back()); } bool get_next_row_data(std::uint8_t* out_data) -- cgit v1.2.3