kopia lustrzana https://gitlab.com/sane-project/backends
genesys: Swap 16-bit pixel endian on big endian machines
rodzic
cae3015b66
commit
0b1bfa3f12
|
@ -45,25 +45,6 @@
|
|||
* Conversion filters for genesys backend
|
||||
*/
|
||||
|
||||
#if defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN)
|
||||
static void FUNC_NAME(genesys_reorder_components_endian) (uint8_t* src_data, uint8_t* dst_data,
|
||||
unsigned int lines, unsigned int pixels,
|
||||
unsigned int channels)
|
||||
{
|
||||
DBG_HELPER(dbg);
|
||||
unsigned int c;
|
||||
uint8_t *src = src_data;
|
||||
uint8_t *dst = dst_data;
|
||||
|
||||
for(c = 0; c < lines * pixels * channels; c++) {
|
||||
*dst++ = src[1];
|
||||
*dst++ = src[0];
|
||||
src += 2;
|
||||
}
|
||||
}
|
||||
#endif /*defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN)*/
|
||||
|
||||
|
||||
static void FUNC_NAME(genesys_reverse_ccd) (uint8_t* src_data, uint8_t* dst_data,
|
||||
unsigned int lines, unsigned int components_per_line,
|
||||
unsigned int *ccd_shift, unsigned int component_count)
|
||||
|
|
|
@ -210,6 +210,29 @@ ImagePipelineNodeDeinterleaveLines::ImagePipelineNodeDeinterleaveLines(
|
|||
interleaved_lines, pixels_per_chunk)
|
||||
{}
|
||||
|
||||
ImagePipelineNodeSwap16BitEndian::ImagePipelineNodeSwap16BitEndian(ImagePipelineNode& source) :
|
||||
source_(source),
|
||||
needs_swapping_{false}
|
||||
{
|
||||
if (get_pixel_format_depth(source_.get_format()) == 16) {
|
||||
needs_swapping_ = true;
|
||||
} else {
|
||||
DBG(DBG_info, "%s: this pipeline node does nothing for non 16-bit formats", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void ImagePipelineNodeSwap16BitEndian::get_next_row_data(std::uint8_t* out_data)
|
||||
{
|
||||
source_.get_next_row_data(out_data);
|
||||
if (needs_swapping_) {
|
||||
std::size_t pixels = get_row_bytes() / 2;
|
||||
for (std::size_t i = 0; i < pixels; ++i) {
|
||||
std::swap(*out_data, *(out_data + 1));
|
||||
out_data += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImagePipelineNodeMergeMonoLines::ImagePipelineNodeMergeMonoLines(ImagePipelineNode& source,
|
||||
ColorOrder color_order) :
|
||||
source_(source),
|
||||
|
|
|
@ -248,6 +248,23 @@ public:
|
|||
std::size_t pixels_per_chunk);
|
||||
};
|
||||
|
||||
// A pipeline that swaps bytes in 16-bit components on big-endian systems
|
||||
class ImagePipelineNodeSwap16BitEndian : public ImagePipelineNode
|
||||
{
|
||||
public:
|
||||
ImagePipelineNodeSwap16BitEndian(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(); }
|
||||
|
||||
void get_next_row_data(std::uint8_t* out_data) override;
|
||||
|
||||
private:
|
||||
ImagePipelineNode& source_;
|
||||
bool needs_swapping_ = false;
|
||||
};
|
||||
|
||||
// A pipeline node that merges 3 mono lines into a color channel
|
||||
class ImagePipelineNodeMergeMonoLines : public ImagePipelineNode
|
||||
{
|
||||
|
|
|
@ -1501,6 +1501,12 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
|||
get_fake_usb_buffer_model(session), read_data_from_usb);
|
||||
}
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (get_pixel_format_depth(format) == 16) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dev->model->is_cis && session.params.channels == 3) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ void test_node_desegment_1_line()
|
|||
ASSERT_EQ(out_data, expected_data);
|
||||
}
|
||||
|
||||
void test_node_deinterleave_lines()
|
||||
void test_node_deinterleave_lines_i8()
|
||||
{
|
||||
using Data = std::vector<std::uint8_t>;
|
||||
|
||||
|
@ -203,6 +203,67 @@ void test_node_deinterleave_lines()
|
|||
ASSERT_EQ(out_data, expected_data);
|
||||
}
|
||||
|
||||
void test_node_deinterleave_lines_rgb888()
|
||||
{
|
||||
using Data = std::vector<std::uint8_t>;
|
||||
|
||||
Data in_data = {
|
||||
1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21,
|
||||
4, 5, 6, 10, 11, 12, 16, 17, 18, 22, 23, 24,
|
||||
};
|
||||
|
||||
ImagePipelineStack stack;
|
||||
stack.push_first_node<ImagePipelineNodeArraySource>(4, 2, PixelFormat::RGB888,
|
||||
std::move(in_data));
|
||||
stack.push_node<ImagePipelineNodeDeinterleaveLines>(2, 1);
|
||||
|
||||
ASSERT_EQ(stack.get_output_width(), 8u);
|
||||
ASSERT_EQ(stack.get_output_height(), 1u);
|
||||
ASSERT_EQ(stack.get_output_row_bytes(), 24u);
|
||||
ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888);
|
||||
|
||||
auto out_data = stack.get_all_data();
|
||||
|
||||
Data expected_data;
|
||||
expected_data.resize(24, 0);
|
||||
std::iota(expected_data.begin(), expected_data.end(), 1); // will fill with 1, 2, 3, ..., 20
|
||||
|
||||
ASSERT_EQ(out_data, expected_data);
|
||||
}
|
||||
|
||||
void test_node_swap_16bit_endian()
|
||||
{
|
||||
using Data = std::vector<std::uint8_t>;
|
||||
|
||||
Data in_data = {
|
||||
0x10, 0x20, 0x30, 0x11, 0x21, 0x31,
|
||||
0x12, 0x22, 0x32, 0x13, 0x23, 0x33,
|
||||
0x14, 0x24, 0x34, 0x15, 0x25, 0x35,
|
||||
0x16, 0x26, 0x36, 0x17, 0x27, 0x37,
|
||||
};
|
||||
|
||||
ImagePipelineStack stack;
|
||||
stack.push_first_node<ImagePipelineNodeArraySource>(4, 1, PixelFormat::RGB161616,
|
||||
std::move(in_data));
|
||||
stack.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
|
||||
ASSERT_EQ(stack.get_output_width(), 4u);
|
||||
ASSERT_EQ(stack.get_output_height(), 1u);
|
||||
ASSERT_EQ(stack.get_output_row_bytes(), 24u);
|
||||
ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB161616);
|
||||
|
||||
auto out_data = stack.get_all_data();
|
||||
|
||||
Data expected_data = {
|
||||
0x20, 0x10, 0x11, 0x30, 0x31, 0x21,
|
||||
0x22, 0x12, 0x13, 0x32, 0x33, 0x23,
|
||||
0x24, 0x14, 0x15, 0x34, 0x35, 0x25,
|
||||
0x26, 0x16, 0x17, 0x36, 0x37, 0x27,
|
||||
};
|
||||
|
||||
ASSERT_EQ(out_data, expected_data);
|
||||
}
|
||||
|
||||
void test_node_merge_mono_lines()
|
||||
{
|
||||
using Data = std::vector<std::uint8_t>;
|
||||
|
@ -335,7 +396,9 @@ void test_image_pipeline()
|
|||
test_node_buffered_callable_source();
|
||||
test_node_format_convert();
|
||||
test_node_desegment_1_line();
|
||||
test_node_deinterleave_lines();
|
||||
test_node_deinterleave_lines_i8();
|
||||
test_node_deinterleave_lines_rgb888();
|
||||
test_node_swap_16bit_endian();
|
||||
test_node_merge_mono_lines();
|
||||
test_node_split_mono_lines();
|
||||
test_node_component_shift_lines();
|
||||
|
|
Ładowanie…
Reference in New Issue