diff options
Diffstat (limited to 'frontend/scanimage.c')
-rw-r--r-- | frontend/scanimage.c | 184 |
1 files changed, 106 insertions, 78 deletions
diff --git a/frontend/scanimage.c b/frontend/scanimage.c index 3902092..901a7c8 100644 --- a/frontend/scanimage.c +++ b/frontend/scanimage.c @@ -20,8 +20,8 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ #ifdef _AIX # include "../include/lalloca.h" /* MUST come first for AIX! */ @@ -73,6 +73,7 @@ typedef struct int height; int x; int y; + int num_channels; } Image; @@ -440,88 +441,108 @@ print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *o break; case SANE_CONSTRAINT_RANGE: - if (opt->type == SANE_TYPE_INT) - { - if (!strcmp (opt->name, "x")) - { - printf ("%d..%d", - opt->constraint.range->min, - opt->constraint.range->max - tl_x); - } - else if (!strcmp (opt->name, "y")) - { - printf ("%d..%d", - opt->constraint.range->min, - opt->constraint.range->max - tl_y); - } - else - { - printf ("%d..%d", - opt->constraint.range->min, - opt->constraint.range->max); - } - print_unit (opt->unit); - if (opt->size > (SANE_Int) sizeof (SANE_Word)) - fputs (",...", stdout); - if (opt->constraint.range->quant) - printf (" (in steps of %d)", opt->constraint.range->quant); - } - else - { - if (!strcmp (opt->name, "x")) - { - printf ("%g..%g", - SANE_UNFIX (opt->constraint.range->min), - SANE_UNFIX (opt->constraint.range->max - tl_x)); - } - else if (!strcmp (opt->name, "y")) - { - printf ("%g..%g", - SANE_UNFIX (opt->constraint.range->min), - SANE_UNFIX (opt->constraint.range->max - tl_y)); - } - else - { - printf ("%g..%g", - SANE_UNFIX (opt->constraint.range->min), - SANE_UNFIX (opt->constraint.range->max)); - } - print_unit (opt->unit); - if (opt->size > (SANE_Int) sizeof (SANE_Word)) - fputs (",...", stdout); - if (opt->constraint.range->quant) - printf (" (in steps of %g)", - SANE_UNFIX (opt->constraint.range->quant)); - } - break; + // Check for no range - some buggy backends can miss this out. + if (!opt->constraint.range) + { + fputs ("{no_range}", stdout); + } + else + { + if (opt->type == SANE_TYPE_INT) + { + if (!strcmp (opt->name, "x")) + { + printf ("%d..%d", opt->constraint.range->min, + opt->constraint.range->max - tl_x); + } + else if (!strcmp (opt->name, "y")) + { + printf ("%d..%d", opt->constraint.range->min, + opt->constraint.range->max - tl_y); + } + else + { + printf ("%d..%d", opt->constraint.range->min, + opt->constraint.range->max); + } + print_unit (opt->unit); + if (opt->size > (SANE_Int) sizeof(SANE_Word)) + fputs (",...", stdout); + if (opt->constraint.range->quant) + printf (" (in steps of %d)", opt->constraint.range->quant); + } + else + { + if (!strcmp (opt->name, "x")) + { + printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min), + SANE_UNFIX(opt->constraint.range->max - tl_x)); + } + else if (!strcmp (opt->name, "y")) + { + printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min), + SANE_UNFIX(opt->constraint.range->max - tl_y)); + } + else + { + printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min), + SANE_UNFIX(opt->constraint.range->max)); + } + print_unit (opt->unit); + if (opt->size > (SANE_Int) sizeof(SANE_Word)) + fputs (",...", stdout); + if (opt->constraint.range->quant) + printf (" (in steps of %g)", + SANE_UNFIX(opt->constraint.range->quant)); + } + } + break; case SANE_CONSTRAINT_WORD_LIST: - for (i = 0; i < opt->constraint.word_list[0]; ++i) - { - if (not_first) - fputc ('|', stdout); + // Check no words in list or no list - - some buggy backends can miss this out. + // Note the check on < 1 as SANE_Int is signed. + if (!opt->constraint.word_list || (opt->constraint.word_list[0] < 1)) + { + fputs ("{no_wordlist}", stdout); + } + else + { + for (i = 0; i < opt->constraint.word_list[0]; ++i) + { + if (not_first) + fputc ('|', stdout); - not_first = SANE_TRUE; + not_first = SANE_TRUE; + + if (opt->type == SANE_TYPE_INT) + printf ("%d", opt->constraint.word_list[i + 1]); + else + printf ("%g", SANE_UNFIX(opt->constraint.word_list[i + 1])); + } + } - if (opt->type == SANE_TYPE_INT) - printf ("%d", opt->constraint.word_list[i + 1]); - else - printf ("%g", SANE_UNFIX (opt->constraint.word_list[i + 1])); - } print_unit (opt->unit); if (opt->size > (SANE_Int) sizeof (SANE_Word)) fputs (",...", stdout); break; case SANE_CONSTRAINT_STRING_LIST: - for (i = 0; opt->constraint.string_list[i]; ++i) - { - if (i > 0) - fputc ('|', stdout); + // Check for missing strings - some buggy backends can miss this out. + if (!opt->constraint.string_list || !opt->constraint.string_list[0]) + { + fputs ("{no_stringlist}", stdout); + } + else + { + for (i = 0; opt->constraint.string_list[i]; ++i) + { + if (i > 0) + fputc ('|', stdout); - fputs (opt->constraint.string_list[i], stdout); - } - break; + fputs (opt->constraint.string_list[i], stdout); + } + } + break; } } @@ -1124,6 +1145,8 @@ process_backend_option (SANE_Handle device, int optnum, const char *optarg) return; } set_option (device, optnum, valuep); + if (opt->type == SANE_TYPE_STRING && valuep) + free(valuep); } static void @@ -1285,10 +1308,10 @@ advance (Image * image) size_t old_size = 0, new_size; if (image->data) - old_size = image->height * image->width; + old_size = image->height * image->width * image->num_channels; image->height += STRIP_HEIGHT; - new_size = image->height * image->width; + new_size = image->height * image->width * image->num_channels; if (image->data) image->data = realloc (image->data, new_size); @@ -1312,7 +1335,7 @@ scan_it (FILE *ofp) SANE_Byte min = 0xff, max = 0; SANE_Parameters parm; SANE_Status status; - Image image = { 0, 0, 0, 0, 0 }; + Image image = { 0, 0, 0, 0, 0, 0 }; static const char *format_name[] = { "gray", "RGB", "red", "green", "blue" }; @@ -1382,6 +1405,7 @@ scan_it (FILE *ofp) if (first_frame) { + image.num_channels = 1; switch (parm.format) { case SANE_FRAME_RED: @@ -1390,6 +1414,7 @@ scan_it (FILE *ofp) assert (parm.depth == 8); must_buffer = 1; offset = parm.format - SANE_FRAME_RED; + image.num_channels = 3; break; case SANE_FRAME_RGB: @@ -1517,6 +1542,7 @@ scan_it (FILE *ofp) case SANE_FRAME_RED: case SANE_FRAME_GREEN: case SANE_FRAME_BLUE: + image.num_channels = 3; for (i = 0; i < len; ++i) { image.data[offset + 3 * i] = buffer[i]; @@ -1530,6 +1556,7 @@ scan_it (FILE *ofp) break; case SANE_FRAME_RGB: + image.num_channels = 1; for (i = 0; i < len; ++i) { image.data[offset + i] = buffer[i]; @@ -1543,6 +1570,7 @@ scan_it (FILE *ofp) break; case SANE_FRAME_GRAY: + image.num_channels = 1; for (i = 0; i < len; ++i) { image.data[offset + i] = buffer[i]; @@ -1725,7 +1753,7 @@ scan_it (FILE *ofp) } #endif - fwrite (image.data, 1, image.height * image.width, ofp); + fwrite (image.data, 1, image.height * image.width * image.num_channels, ofp); } #ifdef HAVE_LIBPNG if(output_format == OUTPUT_PNG) @@ -1800,7 +1828,7 @@ test_it (void) int i, len; SANE_Parameters parm; SANE_Status status; - Image image = { 0, 0, 0, 0, 0 }; + Image image = { 0, 0, 0, 0, 0, 0 }; static const char *format_name[] = { "gray", "RGB", "red", "green", "blue" }; |