kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-debug-tiff' into 'master'
genesys: Use TIFF files for debugging See merge request sane-project/backends!464merge-requests/244/head
commit
d680724f9e
|
@ -581,7 +581,7 @@ libsane_genesys_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
|
||||||
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la \
|
libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la \
|
||||||
../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \
|
../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo \
|
||||||
../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo \
|
../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo \
|
||||||
$(MATH_LIB) $(USB_LIBS) $(RESMGR_LIBS)
|
$(MATH_LIB) $(TIFF_LIBS) $(USB_LIBS) $(RESMGR_LIBS)
|
||||||
EXTRA_DIST += genesys.conf.in
|
EXTRA_DIST += genesys.conf.in
|
||||||
|
|
||||||
libgphoto2_i_la_SOURCES = gphoto2.c gphoto2.h
|
libgphoto2_i_la_SOURCES = gphoto2.c gphoto2.h
|
||||||
|
|
|
@ -1300,9 +1300,9 @@ void scanner_search_strip(Genesys_Device& dev, bool forward, bool black)
|
||||||
unsigned pass = 0;
|
unsigned pass = 0;
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[80];
|
char title[80];
|
||||||
std::sprintf(title, "gl_search_strip_%s_%s%02d.pnm",
|
std::sprintf(title, "gl_search_strip_%s_%s%02d.tiff",
|
||||||
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
|
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
|
||||||
sanei_genesys_write_pnm_file(title, image);
|
write_tiff_file(title, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop until strip is found or maximum pass number done
|
// loop until strip is found or maximum pass number done
|
||||||
|
@ -1322,10 +1322,10 @@ void scanner_search_strip(Genesys_Device& dev, bool forward, bool black)
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[80];
|
char title[80];
|
||||||
std::sprintf(title, "gl_search_strip_%s_%s%02d.pnm",
|
std::sprintf(title, "gl_search_strip_%s_%s%02d.tiff",
|
||||||
black ? "black" : "white",
|
black ? "black" : "white",
|
||||||
forward ? "fwd" : "bwd", static_cast<int>(pass));
|
forward ? "fwd" : "bwd", static_cast<int>(pass));
|
||||||
sanei_genesys_write_pnm_file(title, image);
|
write_tiff_file(title, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned white_level = 90;
|
unsigned white_level = 90;
|
||||||
|
@ -1607,9 +1607,9 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[40];
|
char fn[40];
|
||||||
std::snprintf(fn, 40, "gl843_bottom_offset_%03d_%03d_%03d.pnm",
|
std::snprintf(fn, 40, "gl843_bottom_offset_%03d_%03d_%03d.tiff",
|
||||||
bottom[0], bottom[1], bottom[2]);
|
bottom[0], bottom[1], bottom[2]);
|
||||||
sanei_genesys_write_pnm_file(fn, first_line);
|
write_tiff_file(fn, first_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned ch = 0; ch < 3; ch++) {
|
for (unsigned ch = 0; ch < 3; ch++) {
|
||||||
|
@ -1717,9 +1717,8 @@ void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& senso
|
||||||
sanei_genesys_write_file("gl_offset_all_desc.txt",
|
sanei_genesys_write_file("gl_offset_all_desc.txt",
|
||||||
reinterpret_cast<const std::uint8_t*>(debug_image_info.data()),
|
reinterpret_cast<const std::uint8_t*>(debug_image_info.data()),
|
||||||
debug_image_info.size());
|
debug_image_info.size());
|
||||||
sanei_genesys_write_pnm_file("gl_offset_all.pnm",
|
write_tiff_file("gl_offset_all.tiff", debug_image.data(), session.params.depth, channels,
|
||||||
debug_image.data(), session.params.depth, channels, output_pixels,
|
output_pixels, debug_image_lines);
|
||||||
debug_image_lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__,
|
DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__,
|
||||||
|
@ -1905,7 +1904,7 @@ void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor&
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
sanei_genesys_write_pnm_file("gl_coarse_gain.pnm", image);
|
write_tiff_file("gl_coarse_gain.tiff", image);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned ch = 0; ch < channels; ch++) {
|
for (unsigned ch = 0; ch < channels; ch++) {
|
||||||
|
@ -2163,8 +2162,8 @@ SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[30];
|
char fn[30];
|
||||||
std::snprintf(fn, 30, "gl_led_%02d.pnm", i_test);
|
std::snprintf(fn, 30, "gl_led_%02d.tiff", i_test);
|
||||||
sanei_genesys_write_pnm_file(fn, image);
|
write_tiff_file(fn, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
int avg[3];
|
int avg[3];
|
||||||
|
@ -2459,11 +2458,9 @@ static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_
|
||||||
0.5f);
|
0.5f);
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
sanei_genesys_write_pnm_file16((log_filename_prefix + "_shading.pnm").c_str(),
|
write_tiff_file(log_filename_prefix + "_shading.tiff", calibration_data.data(), 16,
|
||||||
calibration_data.data(),
|
|
||||||
channels, pixels_per_line, dev->calib_session.params.lines);
|
channels, pixels_per_line, dev->calib_session.params.lines);
|
||||||
sanei_genesys_write_pnm_file16((log_filename_prefix + "_average.pnm").c_str(),
|
write_tiff_file(log_filename_prefix + "_average.tiff", out_average_data.data(), 16,
|
||||||
out_average_data.data(),
|
|
||||||
channels, out_pixels_per_line, 1);
|
channels, out_pixels_per_line, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2672,11 +2669,11 @@ static void genesys_dark_white_shading_calibration(Genesys_Device* dev,
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
if (dev->model->is_cis) {
|
if (dev->model->is_cis) {
|
||||||
sanei_genesys_write_pnm_file("gl_black_white_shading.pnm", calibration_data.data(),
|
write_tiff_file("gl_black_white_shading.tiff", calibration_data.data(),
|
||||||
16, 1, pixels_per_line*channels,
|
16, 1, pixels_per_line*channels,
|
||||||
dev->calib_session.params.lines);
|
dev->calib_session.params.lines);
|
||||||
} else {
|
} else {
|
||||||
sanei_genesys_write_pnm_file("gl_black_white_shading.pnm", calibration_data.data(),
|
write_tiff_file("gl_black_white_shading.tiff", calibration_data.data(),
|
||||||
16, channels, pixels_per_line,
|
16, channels, pixels_per_line,
|
||||||
dev->calib_session.params.lines);
|
dev->calib_session.params.lines);
|
||||||
}
|
}
|
||||||
|
@ -2750,10 +2747,10 @@ static void genesys_dark_white_shading_calibration(Genesys_Device* dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
sanei_genesys_write_pnm_file16("gl_white_average.pnm", dev->white_average_data.data(),
|
write_tiff_file("gl_white_average.tiff", dev->white_average_data.data(), 16, channels,
|
||||||
channels, out_pixels_per_line, 1);
|
out_pixels_per_line, 1);
|
||||||
sanei_genesys_write_pnm_file16("gl_dark_average.pnm", dev->dark_average_data.data(),
|
write_tiff_file("gl_dark_average.tiff", dev->dark_average_data.data(), 16, channels,
|
||||||
channels, out_pixels_per_line, 1);
|
out_pixels_per_line, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3929,12 +3926,10 @@ static void genesys_warmup_lamp(Genesys_Device* dev)
|
||||||
second_average /= total_pixels;
|
second_average /= total_pixels;
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
sanei_genesys_write_pnm_file("gl_warmup1.pnm", first_line.data(),
|
write_tiff_file("gl_warmup1.tiff", first_line.data(), dev->session.params.depth,
|
||||||
dev->session.params.depth, channels,
|
channels, total_size / (lines * channels), lines);
|
||||||
total_size / (lines * channels), lines);
|
write_tiff_file("gl_warmup2.tiff", second_line.data(), dev->session.params.depth,
|
||||||
sanei_genesys_write_pnm_file("gl_warmup2.pnm", second_line.data(),
|
channels, total_size / (lines * channels), lines);
|
||||||
dev->session.params.depth, channels,
|
|
||||||
total_size / (lines * channels), lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG(DBG_info, "%s: average 1 = %.2f, average 2 = %.2f\n", __func__, first_average,
|
DBG(DBG_info, "%s: average 1 = %.2f, average 2 = %.2f\n", __func__, first_average,
|
||||||
|
|
|
@ -1167,7 +1167,7 @@ void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor,
|
||||||
scanner_stop_action(*dev);
|
scanner_stop_action(*dev);
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
sanei_genesys_write_pnm_file("gl124_movetocalarea.pnm", image);
|
write_tiff_file("gl124_movetocalarea.tiff", image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2004,8 +2004,8 @@ SensorExposure CommandSetGl646::led_calibration(Genesys_Device* dev, const Genes
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[30];
|
char fn[30];
|
||||||
std::snprintf(fn, 30, "gl646_led_%02d.pnm", turn);
|
std::snprintf(fn, 30, "gl646_led_%02d.tiff", turn);
|
||||||
sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, pixels, 1);
|
write_tiff_file(fn, line.data(), 16, channels, pixels, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptable = true;
|
acceptable = true;
|
||||||
|
@ -2171,8 +2171,8 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor&
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[30];
|
char title[30];
|
||||||
std::snprintf(title, 30, "gl646_offset%03d.pnm", static_cast<int>(bottom));
|
std::snprintf(title, 30, "gl646_offset%03d.tiff", static_cast<int>(bottom));
|
||||||
sanei_genesys_write_pnm_file (title, line.data(), 8, channels, pixels, lines);
|
write_tiff_file(title, line.data(), 8, channels, pixels, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
min = 0;
|
min = 0;
|
||||||
|
@ -2277,8 +2277,8 @@ void CommandSetGl646::offset_calibration(Genesys_Device* dev, const Genesys_Sens
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[30];
|
char title[30];
|
||||||
std::snprintf(title, 30, "gl646_offset%03d.pnm", bottom);
|
std::snprintf(title, 30, "gl646_offset%03d.tiff", bottom);
|
||||||
sanei_genesys_write_pnm_file(title, first_line.data(), 8, channels, pixels, lines);
|
write_tiff_file(title, first_line.data(), 8, channels, pixels, lines);
|
||||||
}
|
}
|
||||||
bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels);
|
bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels);
|
||||||
DBG(DBG_info, "%s: bottom avg=%d\n", __func__, bottomavg);
|
DBG(DBG_info, "%s: bottom avg=%d\n", __func__, bottomavg);
|
||||||
|
@ -2293,8 +2293,8 @@ void CommandSetGl646::offset_calibration(Genesys_Device* dev, const Genesys_Sens
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[30];
|
char title[30];
|
||||||
std::snprintf(title, 30, "gl646_offset%03d.pnm", top);
|
std::snprintf(title, 30, "gl646_offset%03d.tiff", top);
|
||||||
sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels, pixels, lines);
|
write_tiff_file(title, second_line.data(), 8, channels, pixels, lines);
|
||||||
}
|
}
|
||||||
topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
|
topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
|
||||||
DBG(DBG_info, "%s: top avg=%d\n", __func__, topavg);
|
DBG(DBG_info, "%s: top avg=%d\n", __func__, topavg);
|
||||||
|
@ -2320,8 +2320,8 @@ void CommandSetGl646::offset_calibration(Genesys_Device* dev, const Genesys_Sens
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char title[30];
|
char title[30];
|
||||||
std::snprintf(title, 30, "gl646_offset%03d.pnm", dev->frontend.get_offset(1));
|
std::snprintf(title, 30, "gl646_offset%03d.tiff", dev->frontend.get_offset(1));
|
||||||
sanei_genesys_write_pnm_file(title, second_line.data(), 8, channels, pixels, lines);
|
write_tiff_file(title, second_line.data(), 8, channels, pixels, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
|
avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels);
|
||||||
|
@ -2432,8 +2432,8 @@ void CommandSetGl646::coarse_gain_calibration(Genesys_Device* dev, const Genesys
|
||||||
simple_scan(dev, calib_sensor, session, false, line, "coarse_gain_calibration");
|
simple_scan(dev, calib_sensor, session, false, line, "coarse_gain_calibration");
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
std::sprintf(title, "gl646_gain%02d.pnm", pass);
|
std::sprintf(title, "gl646_gain%02d.tiff", pass);
|
||||||
sanei_genesys_write_pnm_file(title, line.data(), 8, channels, pixels, lines);
|
write_tiff_file(title, line.data(), 8, channels, pixels, lines);
|
||||||
}
|
}
|
||||||
pass++;
|
pass++;
|
||||||
|
|
||||||
|
|
|
@ -1745,8 +1745,8 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor&
|
||||||
scanner_stop_action(*dev);
|
scanner_stop_action(*dev);
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[30];
|
char fn[30];
|
||||||
std::snprintf(fn, 30, "gl841_offset_%02d.pnm", turn);
|
std::snprintf(fn, 30, "gl841_offset_%02d.tiff", turn);
|
||||||
sanei_genesys_write_pnm_file(fn, line.data(), 8, 3, num_pixels, 1);
|
write_tiff_file(fn, line.data(), 8, 3, num_pixels, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for minimal value */
|
/* search for minimal value */
|
||||||
|
@ -1888,8 +1888,8 @@ void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sens
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[30];
|
char fn[30];
|
||||||
std::snprintf(fn, 30, "gl841_offset1_%02d.pnm", turn);
|
std::snprintf(fn, 30, "gl841_offset1_%02d.tiff", turn);
|
||||||
sanei_genesys_write_pnm_file(fn, first_line);
|
write_tiff_file(fn, first_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptable = true;
|
acceptable = true;
|
||||||
|
@ -1983,8 +1983,8 @@ void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sens
|
||||||
|
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
char fn[30];
|
char fn[30];
|
||||||
std::snprintf(fn, 30, "gl841_offset2_%02d.pnm", turn);
|
std::snprintf(fn, 30, "gl841_offset2_%02d.tiff", turn);
|
||||||
sanei_genesys_write_pnm_file(fn, second_line);
|
write_tiff_file(fn, second_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptable = true;
|
acceptable = true;
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
|
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_TIFFIO_H)
|
||||||
|
#include <tiffio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace genesys {
|
namespace genesys {
|
||||||
|
@ -201,4 +205,68 @@ void convert_pixel_row_format(const std::uint8_t* in_data, PixelFormat in_format
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_tiff_file(const std::string& filename, const void* data, int depth, int channels,
|
||||||
|
int pixels_per_line, int lines)
|
||||||
|
{
|
||||||
|
DBG_HELPER_ARGS(dbg, "depth=%d, channels=%d, ppl=%d, lines=%d", depth, channels,
|
||||||
|
pixels_per_line, lines);
|
||||||
|
#if defined(HAVE_TIFFIO_H)
|
||||||
|
auto image = TIFFOpen(filename.c_str(), "w");
|
||||||
|
if (!image) {
|
||||||
|
dbg.log(DBG_error, "Could not save debug image");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, pixels_per_line);
|
||||||
|
TIFFSetField(image, TIFFTAG_IMAGELENGTH, lines);
|
||||||
|
TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, depth);
|
||||||
|
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, channels);
|
||||||
|
if (channels > 1) {
|
||||||
|
TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||||
|
} else {
|
||||||
|
TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||||
|
}
|
||||||
|
TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||||
|
TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||||
|
|
||||||
|
std::size_t bytes_per_line = (pixels_per_line * channels * depth + 7) / 8;
|
||||||
|
const std::uint8_t* data_ptr = reinterpret_cast<const std::uint8_t*>(data);
|
||||||
|
|
||||||
|
// we don't need to handle endian because libtiff will handle that
|
||||||
|
for (int iline = 0; iline < lines; ++iline) {
|
||||||
|
const auto* line_data = data_ptr + bytes_per_line;
|
||||||
|
TIFFWriteScanline(image, const_cast<std::uint8_t*>(line_data), iline, 0);
|
||||||
|
}
|
||||||
|
TIFFClose(image);
|
||||||
|
|
||||||
|
#else
|
||||||
|
dbg.log(DBG_error, "Backend has been built without TIFF library support. "
|
||||||
|
"Debug images will not be saved");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_supported_write_tiff_file_image_format(PixelFormat format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case PixelFormat::I1:
|
||||||
|
case PixelFormat::RGB111:
|
||||||
|
case PixelFormat::I8:
|
||||||
|
case PixelFormat::RGB888:
|
||||||
|
case PixelFormat::I16:
|
||||||
|
case PixelFormat::RGB161616:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_tiff_file(const std::string& filename, const Image& image)
|
||||||
|
{
|
||||||
|
if (!is_supported_write_tiff_file_image_format(image.get_format())) {
|
||||||
|
throw SaneException("Unsupported format %d", static_cast<unsigned>(image.get_format()));
|
||||||
|
}
|
||||||
|
|
||||||
|
write_tiff_file(filename, image.get_row_ptr(0), get_pixel_format_depth(image.get_format()),
|
||||||
|
get_pixel_channels(image.get_format()), image.get_width(), image.get_height());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace genesys
|
} // namespace genesys
|
||||||
|
|
|
@ -82,6 +82,11 @@ private:
|
||||||
void convert_pixel_row_format(const std::uint8_t* in_data, PixelFormat in_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);
|
std::uint8_t* out_data, PixelFormat out_format, std::size_t count);
|
||||||
|
|
||||||
|
void write_tiff_file(const std::string& filename, const void* data, int depth,
|
||||||
|
int channels, int pixels_per_line, int lines);
|
||||||
|
|
||||||
|
void write_tiff_file(const std::string& filename, const Image& image);
|
||||||
|
|
||||||
} // namespace genesys
|
} // namespace genesys
|
||||||
|
|
||||||
#endif // ifndef BACKEND_GENESYS_IMAGE_H
|
#endif // ifndef BACKEND_GENESYS_IMAGE_H
|
||||||
|
|
|
@ -837,10 +837,8 @@ ImagePipelineNodeDebug::~ImagePipelineNodeDebug()
|
||||||
|
|
||||||
auto format = get_format();
|
auto format = get_format();
|
||||||
buffer_.linearize();
|
buffer_.linearize();
|
||||||
sanei_genesys_write_pnm_file(path_.c_str(), buffer_.get_front_row_ptr(),
|
write_tiff_file(path_, buffer_.get_front_row_ptr(), get_pixel_format_depth(format),
|
||||||
get_pixel_format_depth(format),
|
get_pixel_channels(format), get_width(), buffer_.height());
|
||||||
get_pixel_channels(format),
|
|
||||||
get_width(), buffer_.height());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,116 +106,6 @@ void sanei_genesys_write_file(const char* filename, const std::uint8_t* data, st
|
||||||
std::fclose(out);
|
std::fclose(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write data to a pnm file (e.g. calibration). For debugging only
|
|
||||||
// data is RGB or grey, with little endian byte order
|
|
||||||
void sanei_genesys_write_pnm_file(const char* filename, const std::uint8_t* data, int depth,
|
|
||||||
int channels, int pixels_per_line, int lines)
|
|
||||||
{
|
|
||||||
DBG_HELPER_ARGS(dbg, "depth=%d, channels=%d, ppl=%d, lines=%d", depth, channels,
|
|
||||||
pixels_per_line, lines);
|
|
||||||
int count;
|
|
||||||
|
|
||||||
std::FILE* out = std::fopen(filename, "w");
|
|
||||||
if (!out)
|
|
||||||
{
|
|
||||||
throw SaneException("could not open %s for writing: %s\n", filename, strerror(errno));
|
|
||||||
}
|
|
||||||
if(depth==1)
|
|
||||||
{
|
|
||||||
fprintf (out, "P4\n%d\n%d\n", pixels_per_line, lines);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::fprintf(out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6', pixels_per_line, lines,
|
|
||||||
static_cast<int>(std::pow(static_cast<double>(2),
|
|
||||||
static_cast<double>(depth - 1))));
|
|
||||||
}
|
|
||||||
if (channels == 3)
|
|
||||||
{
|
|
||||||
for (count = 0; count < (pixels_per_line * lines * 3); count++)
|
|
||||||
{
|
|
||||||
if (depth == 16)
|
|
||||||
fputc (*(data + 1), out);
|
|
||||||
fputc (*(data++), out);
|
|
||||||
if (depth == 16)
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (depth==1)
|
|
||||||
{
|
|
||||||
pixels_per_line/=8;
|
|
||||||
}
|
|
||||||
for (count = 0; count < (pixels_per_line * lines); count++)
|
|
||||||
{
|
|
||||||
switch (depth)
|
|
||||||
{
|
|
||||||
case 8:
|
|
||||||
fputc (*(data + count), out);
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
fputc (*(data + 1), out);
|
|
||||||
fputc (*(data), out);
|
|
||||||
data += 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fputc(data[count], out);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::fclose(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sanei_genesys_write_pnm_file16(const char* filename, const uint16_t* data, unsigned channels,
|
|
||||||
unsigned pixels_per_line, unsigned lines)
|
|
||||||
{
|
|
||||||
DBG_HELPER_ARGS(dbg, "channels=%d, ppl=%d, lines=%d", channels,
|
|
||||||
pixels_per_line, lines);
|
|
||||||
|
|
||||||
std::FILE* out = std::fopen(filename, "w");
|
|
||||||
if (!out) {
|
|
||||||
throw SaneException("could not open %s for writing: %s\n", filename, strerror(errno));
|
|
||||||
}
|
|
||||||
std::fprintf(out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6',
|
|
||||||
pixels_per_line, lines, 256 * 256 - 1);
|
|
||||||
|
|
||||||
for (unsigned count = 0; count < (pixels_per_line * lines * channels); count++) {
|
|
||||||
fputc(*data >> 8, out);
|
|
||||||
fputc(*data & 0xff, out);
|
|
||||||
data++;
|
|
||||||
}
|
|
||||||
std::fclose(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_supported_write_pnm_file_image_format(PixelFormat format)
|
|
||||||
{
|
|
||||||
switch (format) {
|
|
||||||
case PixelFormat::I1:
|
|
||||||
case PixelFormat::RGB111:
|
|
||||||
case PixelFormat::I8:
|
|
||||||
case PixelFormat::RGB888:
|
|
||||||
case PixelFormat::I16:
|
|
||||||
case PixelFormat::RGB161616:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sanei_genesys_write_pnm_file(const char* filename, const Image& image)
|
|
||||||
{
|
|
||||||
if (!is_supported_write_pnm_file_image_format(image.get_format())) {
|
|
||||||
throw SaneException("Unsupported format %d", static_cast<unsigned>(image.get_format()));
|
|
||||||
}
|
|
||||||
|
|
||||||
sanei_genesys_write_pnm_file(filename, image.get_row_ptr(0),
|
|
||||||
get_pixel_format_depth(image.get_format()),
|
|
||||||
get_pixel_channels(image.get_format()),
|
|
||||||
image.get_width(), image.get_height());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* Read and write RAM, registers and AFE */
|
/* Read and write RAM, registers and AFE */
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
@ -1103,7 +993,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_0_from_usb.pnm");
|
"_0_from_usb.tiff");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output_width = session.output_segment_pixel_group_count * session.segment_count;
|
auto output_width = session.output_segment_pixel_group_count * session.segment_count;
|
||||||
|
@ -1114,7 +1004,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_1_after_desegment.pnm");
|
"_1_after_desegment.tiff");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;
|
auto read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;
|
||||||
|
@ -1125,7 +1015,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_0_from_usb.pnm");
|
"_0_from_usb.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,7 +1034,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_2_after_swap.pnm");
|
"_2_after_swap.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1045,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_3_after_invert.pnm");
|
"_3_after_invert.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1165,7 +1055,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_4_after_merge_mono.pnm");
|
"_4_after_merge_mono.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1180,7 +1070,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_5_after_format.pnm");
|
"_5_after_format.tiff");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.max_color_shift_lines > 0 && session.params.channels == 3) {
|
if (session.max_color_shift_lines > 0 && session.params.channels == 3) {
|
||||||
|
@ -1192,7 +1082,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_6_after_color_unshift.pnm");
|
"_6_after_color_unshift.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,7 +1094,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_7_after_x_unstagger.pnm");
|
"_7_after_x_unstagger.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,7 +1104,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_8_after_y_unstagger.pnm");
|
"_8_after_y_unstagger.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1230,7 +1120,7 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
||||||
if (dbg_log_image_data()) {
|
if (dbg_log_image_data()) {
|
||||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||||
std::to_string(s_pipeline_index) +
|
std::to_string(s_pipeline_index) +
|
||||||
"_9_after_calibrate.pnm");
|
"_9_after_calibrate.tiff");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,14 +329,6 @@ void scanner_send_slope_table(Genesys_Device* dev, const Genesys_Sensor& sensor,
|
||||||
extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data,
|
extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data,
|
||||||
std::size_t length);
|
std::size_t length);
|
||||||
|
|
||||||
extern void sanei_genesys_write_pnm_file(const char* filename, const std::uint8_t* data, int depth,
|
|
||||||
int channels, int pixels_per_line, int lines);
|
|
||||||
|
|
||||||
void sanei_genesys_write_pnm_file(const char* filename, const Image& image);
|
|
||||||
|
|
||||||
extern void sanei_genesys_write_pnm_file16(const char* filename, const uint16_t *data, unsigned channels,
|
|
||||||
unsigned pixels_per_line, unsigned lines);
|
|
||||||
|
|
||||||
void wait_until_buffer_non_empty(Genesys_Device* dev, bool check_status_twice = false);
|
void wait_until_buffer_non_empty(Genesys_Device* dev, bool check_status_twice = false);
|
||||||
|
|
||||||
extern void sanei_genesys_read_data_from_scanner(Genesys_Device* dev, uint8_t* data, size_t size);
|
extern void sanei_genesys_read_data_from_scanner(Genesys_Device* dev, uint8_t* data, size_t size);
|
||||||
|
|
|
@ -11,7 +11,7 @@ TEST_LDADD = \
|
||||||
../../../lib/liblib.la \
|
../../../lib/liblib.la \
|
||||||
../../../backend/libgenesys.la \
|
../../../backend/libgenesys.la \
|
||||||
../../../backend/sane_strstatus.lo \
|
../../../backend/sane_strstatus.lo \
|
||||||
$(MATH_LIB) $(USB_LIBS) $(XML_LIBS) $(PTHREAD_LIBS)
|
$(MATH_LIB) $(TIFF_LIBS) $(USB_LIBS) $(XML_LIBS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
check_PROGRAMS = genesys_unit_tests genesys_session_config_tests
|
check_PROGRAMS = genesys_unit_tests genesys_session_config_tests
|
||||||
TESTS = genesys_unit_tests
|
TESTS = genesys_unit_tests
|
||||||
|
|
Ładowanie…
Reference in New Issue