kopia lustrzana https://gitlab.com/sane-project/backends
add PNG format to scanimage
rodzic
348d59f859
commit
c83123ee46
13
acinclude.m4
13
acinclude.m4
|
@ -312,6 +312,19 @@ AC_DEFUN([SANE_CHECK_TIFF],
|
||||||
AC_SUBST(TIFF_LIBS)
|
AC_SUBST(TIFF_LIBS)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([SANE_CHECK_PNG],
|
||||||
|
[
|
||||||
|
AC_CHECK_LIB(png,png_init_io,
|
||||||
|
[
|
||||||
|
AC_CHECK_HEADER(png.h,
|
||||||
|
[sane_cv_use_libpng="yes"; PNG_LIBS="-lpng"],)
|
||||||
|
],)
|
||||||
|
if test "$sane_cv_use_libpng" = "yes" ; then
|
||||||
|
AC_DEFINE(HAVE_LIBPNG,1,[Define to 1 if you have the libpng library.])
|
||||||
|
fi
|
||||||
|
AC_SUBST(PNG_LIBS)
|
||||||
|
])
|
||||||
|
|
||||||
#
|
#
|
||||||
# Checks for pthread support
|
# Checks for pthread support
|
||||||
AC_DEFUN([SANE_CHECK_LOCKING],
|
AC_DEFUN([SANE_CHECK_LOCKING],
|
||||||
|
|
|
@ -122,6 +122,7 @@ AC_SUBST(SYSLOG_LIBS)
|
||||||
|
|
||||||
SANE_CHECK_JPEG
|
SANE_CHECK_JPEG
|
||||||
SANE_CHECK_TIFF
|
SANE_CHECK_TIFF
|
||||||
|
SANE_CHECK_PNG
|
||||||
SANE_CHECK_IEEE1284
|
SANE_CHECK_IEEE1284
|
||||||
SANE_CHECK_PTHREAD
|
SANE_CHECK_PTHREAD
|
||||||
SANE_CHECK_LOCKING
|
SANE_CHECK_LOCKING
|
||||||
|
|
|
@ -103,9 +103,9 @@ The
|
||||||
option selects how image data is written to standard output.
|
option selects how image data is written to standard output.
|
||||||
.I format
|
.I format
|
||||||
can be
|
can be
|
||||||
.B pnm
|
.B pnm tiff
|
||||||
or
|
or
|
||||||
.BR tiff.
|
.BR png.
|
||||||
If
|
If
|
||||||
.B \-\-format
|
.B \-\-format
|
||||||
is not used, PNM is written.
|
is not used, PNM is written.
|
||||||
|
|
|
@ -18,7 +18,7 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||||
|
|
||||||
scanimage_SOURCES = scanimage.c stiff.c stiff.h
|
scanimage_SOURCES = scanimage.c stiff.c stiff.h
|
||||||
scanimage_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \
|
scanimage_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \
|
||||||
../lib/libfelib.la
|
../lib/libfelib.la @PNG_LIBS@
|
||||||
|
|
||||||
saned_SOURCES = saned.c
|
saned_SOURCES = saned.c
|
||||||
saned_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \
|
saned_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \
|
||||||
|
|
|
@ -42,6 +42,10 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
#include <png.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../include/_stdint.h"
|
#include "../include/_stdint.h"
|
||||||
|
|
||||||
#include "../include/sane/sane.h"
|
#include "../include/sane/sane.h"
|
||||||
|
@ -104,6 +108,7 @@ static struct option basic_options[] = {
|
||||||
|
|
||||||
#define OUTPUT_PNM 0
|
#define OUTPUT_PNM 0
|
||||||
#define OUTPUT_TIFF 1
|
#define OUTPUT_TIFF 1
|
||||||
|
#define OUTPUT_PNG 2
|
||||||
|
|
||||||
#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbp"
|
#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbp"
|
||||||
#define STRIP_HEIGHT 256 /* # lines we increment image height */
|
#define STRIP_HEIGHT 256 /* # lines we increment image height */
|
||||||
|
@ -1153,6 +1158,47 @@ write_pnm_header (SANE_Frame format, int width, int height, int depth, FILE *ofp
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
static void
|
||||||
|
write_png_header (SANE_Frame format, int width, int height, int depth, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr)
|
||||||
|
{
|
||||||
|
int color_type;
|
||||||
|
|
||||||
|
*png_ptr = png_create_write_struct
|
||||||
|
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
if (!*png_ptr) {
|
||||||
|
fprintf(stderr, "png_create_write_struct failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*info_ptr = png_create_info_struct(*png_ptr);
|
||||||
|
if (!*info_ptr) {
|
||||||
|
fprintf(stderr, "png_create_info_struct failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
png_init_io(*png_ptr, ofp);
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case SANE_FRAME_RED:
|
||||||
|
case SANE_FRAME_GREEN:
|
||||||
|
case SANE_FRAME_BLUE:
|
||||||
|
case SANE_FRAME_RGB:
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
color_type = PNG_COLOR_TYPE_GRAY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_set_IHDR(*png_ptr, *info_ptr, width, height,
|
||||||
|
depth, color_type, PNG_INTERLACE_NONE,
|
||||||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||||
|
|
||||||
|
png_write_info(*png_ptr, *info_ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
advance (Image * image)
|
advance (Image * image)
|
||||||
{
|
{
|
||||||
|
@ -1196,6 +1242,12 @@ scan_it (FILE *ofp)
|
||||||
};
|
};
|
||||||
SANE_Word total_bytes = 0, expected_bytes;
|
SANE_Word total_bytes = 0, expected_bytes;
|
||||||
SANE_Int hang_over = -1;
|
SANE_Int hang_over = -1;
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
int pngrow = 0;
|
||||||
|
png_bytep pngbuf = NULL;
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -1269,21 +1321,34 @@ scan_it (FILE *ofp)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
switch(output_format)
|
||||||
if (output_format == OUTPUT_TIFF)
|
{
|
||||||
|
case OUTPUT_TIFF:
|
||||||
sanei_write_tiff_header (parm.format,
|
sanei_write_tiff_header (parm.format,
|
||||||
parm.pixels_per_line, parm.lines,
|
parm.pixels_per_line, parm.lines,
|
||||||
parm.depth, resolution_value,
|
parm.depth, resolution_value,
|
||||||
icc_profile, ofp);
|
icc_profile, ofp);
|
||||||
else
|
break;
|
||||||
|
case OUTPUT_PNM:
|
||||||
write_pnm_header (parm.format, parm.pixels_per_line,
|
write_pnm_header (parm.format, parm.pixels_per_line,
|
||||||
parm.lines, parm.depth, ofp);
|
parm.lines, parm.depth, ofp);
|
||||||
}
|
break;
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
case OUTPUT_PNG:
|
||||||
|
write_png_header (parm.format, parm.pixels_per_line,
|
||||||
|
parm.lines, parm.depth, ofp, &png_ptr, &info_ptr);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
if(output_format == OUTPUT_PNG)
|
||||||
|
pngbuf = malloc(parm.bytes_per_line);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (must_buffer)
|
if (must_buffer)
|
||||||
{
|
{
|
||||||
|
@ -1397,6 +1462,30 @@ scan_it (FILE *ofp)
|
||||||
}
|
}
|
||||||
else /* ! must_buffer */
|
else /* ! must_buffer */
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
if (output_format == OUTPUT_PNG)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int left = len;
|
||||||
|
while(pngrow + left >= parm.bytes_per_line)
|
||||||
|
{
|
||||||
|
memcpy(pngbuf + pngrow, buffer + i, parm.bytes_per_line - pngrow);
|
||||||
|
if(parm.depth == 1)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for(j = 0; j < parm.bytes_per_line; j++)
|
||||||
|
pngbuf[j] = ~pngbuf[j];
|
||||||
|
}
|
||||||
|
png_write_row(png_ptr, pngbuf);
|
||||||
|
i += parm.bytes_per_line - pngrow;
|
||||||
|
left -= parm.bytes_per_line - pngrow;
|
||||||
|
pngrow = 0;
|
||||||
|
}
|
||||||
|
memcpy(pngbuf + pngrow, buffer + i, left);
|
||||||
|
pngrow += left;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if ((output_format == OUTPUT_TIFF) || (parm.depth != 16))
|
if ((output_format == OUTPUT_TIFF) || (parm.depth != 16))
|
||||||
fwrite (buffer, 1, len, ofp);
|
fwrite (buffer, 1, len, ofp);
|
||||||
else
|
else
|
||||||
|
@ -1451,13 +1540,23 @@ scan_it (FILE *ofp)
|
||||||
{
|
{
|
||||||
image.height = image.y;
|
image.height = image.y;
|
||||||
|
|
||||||
if (output_format == OUTPUT_TIFF)
|
switch(output_format) {
|
||||||
|
case OUTPUT_TIFF:
|
||||||
sanei_write_tiff_header (parm.format, parm.pixels_per_line,
|
sanei_write_tiff_header (parm.format, parm.pixels_per_line,
|
||||||
image.height, parm.depth, resolution_value,
|
image.height, parm.depth, resolution_value,
|
||||||
icc_profile, ofp);
|
icc_profile, ofp);
|
||||||
else
|
break;
|
||||||
|
case OUTPUT_PNM:
|
||||||
write_pnm_header (parm.format, parm.pixels_per_line,
|
write_pnm_header (parm.format, parm.pixels_per_line,
|
||||||
image.height, parm.depth, ofp);
|
image.height, parm.depth, ofp);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
case OUTPUT_PNG:
|
||||||
|
write_png_header (parm.format, parm.pixels_per_line,
|
||||||
|
image.height, parm.depth, ofp, &png_ptr, &info_ptr);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(WORDS_BIGENDIAN)
|
#if !defined(WORDS_BIGENDIAN)
|
||||||
/* multibyte pnm file may need byte swap to LE */
|
/* multibyte pnm file may need byte swap to LE */
|
||||||
|
@ -1477,11 +1576,21 @@ scan_it (FILE *ofp)
|
||||||
|
|
||||||
fwrite (image.data, 1, image.height * image.width, ofp);
|
fwrite (image.data, 1, image.height * image.width, ofp);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
if(output_format == OUTPUT_PNG)
|
||||||
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* flush the output buffer */
|
/* flush the output buffer */
|
||||||
fflush( ofp );
|
fflush( ofp );
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
if(output_format == OUTPUT_PNG) {
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
free(pngbuf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (image.data)
|
if (image.data)
|
||||||
free (image.data);
|
free (image.data);
|
||||||
|
|
||||||
|
@ -1799,6 +1908,15 @@ main (int argc, char **argv)
|
||||||
case OPTION_FORMAT:
|
case OPTION_FORMAT:
|
||||||
if (strcmp (optarg, "tiff") == 0)
|
if (strcmp (optarg, "tiff") == 0)
|
||||||
output_format = OUTPUT_TIFF;
|
output_format = OUTPUT_TIFF;
|
||||||
|
else if (strcmp (optarg, "png") == 0)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
output_format = OUTPUT_PNG;
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "PNG support not compiled in\n");
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
output_format = OUTPUT_PNM;
|
output_format = OUTPUT_PNM;
|
||||||
break;
|
break;
|
||||||
|
@ -1937,7 +2055,7 @@ standard output.\n\
|
||||||
Parameters are separated by a blank from single-character options (e.g.\n\
|
Parameters are separated by a blank from single-character options (e.g.\n\
|
||||||
-d epson) and by a \"=\" from multi-character options (e.g. --device-name=epson).\n\
|
-d epson) and by a \"=\" from multi-character options (e.g. --device-name=epson).\n\
|
||||||
-d, --device-name=DEVICE use a given scanner device (e.g. hp:/dev/scanner)\n\
|
-d, --device-name=DEVICE use a given scanner device (e.g. hp:/dev/scanner)\n\
|
||||||
--format=pnm|tiff file format of output file\n\
|
--format=pnm|tiff|png file format of output file\n\
|
||||||
-i, --icc-profile=PROFILE include this ICC profile into TIFF file\n", prog_name);
|
-i, --icc-profile=PROFILE include this ICC profile into TIFF file\n", prog_name);
|
||||||
printf ("\
|
printf ("\
|
||||||
-L, --list-devices show available scanner devices\n\
|
-L, --list-devices show available scanner devices\n\
|
||||||
|
@ -1945,8 +2063,8 @@ Parameters are separated by a blank from single-character options (e.g.\n\
|
||||||
can be specified: %%d (device name), %%v (vendor),\n\
|
can be specified: %%d (device name), %%v (vendor),\n\
|
||||||
%%m (model), %%t (type), %%i (index number), and\n\
|
%%m (model), %%t (type), %%i (index number), and\n\
|
||||||
%%n (newline)\n\
|
%%n (newline)\n\
|
||||||
-b, --batch[=FORMAT] working in batch mode, FORMAT is `out%%d.pnm' or\n\
|
-b, --batch[=FORMAT] working in batch mode, FORMAT is `out%%d.pnm' `out%%d.tif' or\n\
|
||||||
`out%%d.tif' by default depending on --format\n");
|
`out%%d.png' by default depending on --format\n");
|
||||||
printf ("\
|
printf ("\
|
||||||
--batch-start=# page number to start naming files with\n\
|
--batch-start=# page number to start naming files with\n\
|
||||||
--batch-count=# how many pages to scan in batch mode\n\
|
--batch-count=# how many pages to scan in batch mode\n\
|
||||||
|
@ -2225,10 +2343,19 @@ List of available devices:", prog_name);
|
||||||
|
|
||||||
if (batch && NULL == format)
|
if (batch && NULL == format)
|
||||||
{
|
{
|
||||||
if (output_format == OUTPUT_TIFF)
|
switch(output_format) {
|
||||||
|
case OUTPUT_TIFF:
|
||||||
format = "out%d.tif";
|
format = "out%d.tif";
|
||||||
else
|
break;
|
||||||
|
case OUTPUT_PNM:
|
||||||
format = "out%d.pnm";
|
format = "out%d.pnm";
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_LIBPNG
|
||||||
|
case OUTPUT_PNG:
|
||||||
|
format = "out%d.png";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!batch)
|
if (!batch)
|
||||||
|
|
Ładowanie…
Reference in New Issue