summaryrefslogtreecommitdiff
path: root/frontend/scanimage.c
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/scanimage.c')
-rw-r--r--frontend/scanimage.c184
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" };