summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMattia Rizzolo <mattia@mapreri.org>2014-10-03 14:05:09 +0000
committerMattia Rizzolo <mattia@mapreri.org>2014-10-03 14:05:09 +0000
commit6fceea28608be0fda32d94f59e1b1550774318a0 (patch)
tree9be4df525ab59533784ce0c8d441d61130b59e76 /src
parent817e6294b42b3e4435f1b99728afc1dca84a6445 (diff)
Imported Upstream version 0.98upstream/0.98
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/xsane-back-gtk.c31
-rw-r--r--src/xsane-batch-scan.c5
-rw-r--r--src/xsane-fixedtext.h2
-rw-r--r--src/xsane-front-gtk.c39
-rw-r--r--src/xsane-preferences.c4
-rw-r--r--src/xsane-preferences.h2
-rw-r--r--src/xsane-preview.c15
-rw-r--r--src/xsane-save.c720
-rw-r--r--src/xsane-save.h4
-rw-r--r--src/xsane-scan.c80
-rw-r--r--src/xsane-text.h1
-rw-r--r--src/xsane-viewer.c5
-rw-r--r--src/xsane.c251
-rw-r--r--src/xsane.h8
15 files changed, 911 insertions, 258 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 62916b7..8df620f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -31,7 +31,7 @@ INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include @INCLUDES@
-DEFS = @DEFS@ -DLOCALEDIR=$(datadir)/locale
+DEFS = @DEFS@ -DLOCALEDIR=$(datadir)/locale -DSANELOCALEDIR=$(sane_prefix)/share/locale
CPPFLAGS = @CPPFLAGS@ -DPATH_XSANE_DOC_DIR=$(xsanedocdir) -DPATH_SANE_DATA_DIR=$(sanedatadir)
CFLAGS = @CFLAGS@ @SANE_CFLAGS@ @GIMP_CFLAGS@ @GTK_CFLAGS@
LDFLAGS = @LDFLAGS@ @SANE_LDFLAGS@
diff --git a/src/xsane-back-gtk.c b/src/xsane-back-gtk.c
index 0aa382e..c4ddeef 100644
--- a/src/xsane-back-gtk.c
+++ b/src/xsane-back-gtk.c
@@ -183,7 +183,10 @@ SANE_Status xsane_control_option(SANE_Handle handle, SANE_Int option, SANE_Actio
if ((opt) && (!(opt->cap & SANE_CAP_SOFT_DETECT)))
{
DBG(DBG_warning, "WARNING: xsane_control_option(option = %d, action = %d): SANE_CAP_SOFT_DETECT is not set\n", option, action);
- return SANE_STATUS_GOOD;
+ if (option > 0) /* continue for option == 0, otherwise we can not read this option */
+ {
+ return SANE_STATUS_GOOD;
+ }
}
}
#endif
@@ -352,6 +355,14 @@ int xsane_back_gtk_make_path(size_t buf_size, char *buf, const char *prog_name,
buf[len++] = '_';
break;
+ case '*': /* "*" -> "_" */
+ buf[len++] = '_';
+ break;
+
+ case '?': /* "?" -> "_" */
+ buf[len++] = '_';
+ break;
+
#ifdef _WIN32
case ':': /* ":" -> "_" */
buf[len++] = '_';
@@ -881,7 +892,7 @@ static void xsane_back_gtk_filetype_callback(GtkWidget *widget, gpointer data)
{
if ( (!strcasecmp(extension, ".pnm")) || (!strcasecmp(extension, ".raw"))
|| (!strcasecmp(extension, ".png")) || (!strcasecmp(extension, ".ps"))
- || (!strcasecmp(extension, ".rgba"))
+ || (!strcasecmp(extension, ".pdf")) || (!strcasecmp(extension, ".rgba"))
|| (!strcasecmp(extension, ".tiff")) || (!strcasecmp(extension, ".tif"))
|| (!strcasecmp(extension, ".text")) || (!strcasecmp(extension, ".txt"))
|| (!strcasecmp(extension, ".jpg")) || (!strcasecmp(extension, ".jpeg"))
@@ -951,6 +962,12 @@ void xsane_back_gtk_filetype_menu_set_history(GtkWidget *xsane_filetype_option_m
select_item = filetype_nr;
}
+ filetype_nr++;
+ if ( (filetype) && (!strcasecmp(filetype, XSANE_FILETYPE_PDF)) )
+ {
+ select_item = filetype_nr;
+ }
+
#ifdef SUPPORT_RGBA
filetype_nr++;
if ( (filetype) && (!strcasecmp(filetype, XSANE_FILETYPE_RGBA)) )
@@ -1007,6 +1024,16 @@ GtkWidget *xsane_back_gtk_filetype_menu_new(char *filetype, GtkSignalFunc filety
}
#endif
+ xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF);
+ gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item);
+ g_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", filetype_callback, (void *) XSANE_FILETYPE_PDF);
+ gtk_widget_show(xsane_filetype_item);
+ filetype_nr++;
+ if ( (filetype) && (!strcasecmp(filetype, XSANE_FILETYPE_PDF)) )
+ {
+ select_item = filetype_nr;
+ }
+
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG);
diff --git a/src/xsane-batch-scan.c b/src/xsane-batch-scan.c
index bf5f57c..c7ae532 100644
--- a/src/xsane-batch-scan.c
+++ b/src/xsane-batch-scan.c
@@ -505,14 +505,11 @@ static void xsane_batch_scan_scan_list(void)
while (xsane.scanning)
{
-#if 0
+ /* we MUST call gtk_events_pending() or gdk_input_add will not work! */
if (gtk_events_pending())
{
gtk_main_iteration();
}
-#elseif
- gtk_main_iteration();
-#endif
}
if ( (xsane.status_of_last_scan != SANE_STATUS_GOOD) && (xsane.status_of_last_scan != SANE_STATUS_EOF) )
diff --git a/src/xsane-fixedtext.h b/src/xsane-fixedtext.h
index baa318b..d655d34 100644
--- a/src/xsane-fixedtext.h
+++ b/src/xsane-fixedtext.h
@@ -37,6 +37,7 @@
#define XSANE_FILETYPE_PNG ".png"
#define XSANE_FILETYPE_PNM ".pnm"
#define XSANE_FILETYPE_PS ".ps"
+#define XSANE_FILETYPE_PDF ".pdf"
#define XSANE_FILETYPE_RGBA ".rgba"
#define XSANE_FILETYPE_TEXT ".txt"
@@ -45,6 +46,7 @@
#define MENU_ITEM_FILETYPE_PNG "PNG"
#define MENU_ITEM_FILETYPE_PNM "PNM"
#define MENU_ITEM_FILETYPE_PS "PostScript"
+#define MENU_ITEM_FILETYPE_PDF "PDF"
#define MENU_ITEM_FILETYPE_RGBA "RGBA"
#define MENU_ITEM_FILETYPE_TEXT "TEXT"
diff --git a/src/xsane-front-gtk.c b/src/xsane-front-gtk.c
index 3695db8..2bf0fd9 100644
--- a/src/xsane-front-gtk.c
+++ b/src/xsane-front-gtk.c
@@ -45,7 +45,7 @@
int xsane_parse_options(char *options, char *argv[]);
void xsane_get_bounds(const SANE_Option_Descriptor *opt, double *minp, double *maxp);
double xsane_find_best_resolution(int well_known_option, double dpi);
-int xsane_set_resolution(int well_known_option, double resolution);
+double xsane_set_resolution(int well_known_option, double resolution);
void xsane_set_all_resolutions(void);
void xsane_define_maximum_output_size();
void xsane_close_dialog_callback(GtkWidget *widget, gpointer data);
@@ -292,7 +292,7 @@ double xsane_find_best_resolution(int well_known_option, double dpi)
/* ---------------------------------------------------------------------------------------------------------------------- */
-int xsane_set_resolution(int well_known_option, double resolution)
+double xsane_set_resolution(int well_known_option, double resolution)
{
const SANE_Option_Descriptor *opt;
double bestdpi;
@@ -304,12 +304,12 @@ int xsane_set_resolution(int well_known_option, double resolution)
if (!opt)
{
- return -1; /* option does not exits */
+ return -1.0; /* option does not exits */
}
if (!SANE_OPTION_IS_ACTIVE(opt->cap))
{
- return -1; /* option is not active */
+ return -1.0; /* option is not active */
}
bestdpi = xsane_find_best_resolution(well_known_option, resolution);
@@ -317,7 +317,7 @@ int xsane_set_resolution(int well_known_option, double resolution)
if (bestdpi < 0)
{
DBG(DBG_error, "set_resolution: %s\n", ERR_FAILED_SET_RESOLUTION);
- return -1;
+ return -1.0;
}
switch (opt->type)
@@ -332,14 +332,14 @@ int xsane_set_resolution(int well_known_option, double resolution)
default:
DBG(DBG_error, "set_resolution: %s %d\n", ERR_UNKNOWN_TYPE, opt->type);
- return 1; /* error */
+ return -1.0; /* error */
}
/* it makes problems to call xsane_back_gtk_set_option. This would allow a */
/* panel_rebuild that can mess up a lot at this place*/
xsane_control_option(xsane.dev, well_known_option, SANE_ACTION_SET_VALUE, &dpi, 0);
- return 0; /* everything is ok */
+ return (bestdpi); /* everything is ok */
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -347,18 +347,23 @@ int xsane_set_resolution(int well_known_option, double resolution)
void xsane_set_all_resolutions(void)
{
int printer_resolution;
+ double new_resolution;
DBG(DBG_proc, "xsane_set_all_resolutions\n");
- if (xsane_set_resolution(xsane.well_known.dpi_y, xsane.resolution_y)) /* set y resolution if possible */
+ new_resolution = xsane_set_resolution(xsane.well_known.dpi_y, xsane.resolution_y); /* set y resolution if possible */
+ if (new_resolution < 0) /* set y resolution not possible */
{
- xsane_set_resolution(xsane.well_known.dpi, xsane.resolution); /* set common resolution if necessary */
- xsane.resolution_x = xsane.resolution;
- xsane.resolution_y = xsane.resolution;
+ new_resolution = xsane_set_resolution(xsane.well_known.dpi, xsane.resolution); /* set common resolution if necessary */
+ xsane.resolution = new_resolution;
+ xsane.resolution_x = new_resolution;
+ xsane.resolution_y = new_resolution;
}
- else
+ else /* we were able to set y resolution */
{
- xsane_set_resolution(xsane.well_known.dpi_x, xsane.resolution_x); /* set x resolution if possible */
+ xsane.resolution_y = new_resolution;
+ new_resolution = xsane_set_resolution(xsane.well_known.dpi_x, xsane.resolution_x); /* set x resolution if possible */
+ xsane.resolution_x = new_resolution;
}
switch (xsane.param.format)
@@ -400,7 +405,7 @@ void xsane_define_maximum_output_size()
if ( (opt) && (opt->unit== SANE_UNIT_MM) )
{
- switch(xsane.xsane_mode)
+ switch(preferences.xsane_mode)
{
case XSANE_SAVE:
@@ -1333,7 +1338,7 @@ static void xsane_filetype_callback(GtkWidget *widget, gpointer data)
{
if ( (!strcasecmp(extension, ".pnm")) || (!strcasecmp(extension, ".raw"))
|| (!strcasecmp(extension, ".png")) || (!strcasecmp(extension, ".ps"))
- || (!strcasecmp(extension, ".rgba"))
+ || (!strcasecmp(extension, ".pdf")) || (!strcasecmp(extension, ".rgba"))
|| (!strcasecmp(extension, ".tiff")) || (!strcasecmp(extension, ".tif"))
|| (!strcasecmp(extension, ".text")) || (!strcasecmp(extension, ".txt"))
|| (!strcasecmp(extension, ".jpg")) || (!strcasecmp(extension, ".jpeg"))
@@ -1734,6 +1739,10 @@ int xsane_identify_output_format(char *filename, char *filetype, char **ext)
{
output_format = XSANE_PS;
}
+ else if (!strcasecmp(extension, "pdf"))
+ {
+ output_format = XSANE_PDF;
+ }
#ifdef HAVE_LIBTIFF
else if ( (!strcasecmp(extension, "tif")) || (!strcasecmp(extension, "tiff")) )
{
diff --git a/src/xsane-preferences.c b/src/xsane-preferences.c
index 83da4e5..b38cdbb 100644
--- a/src/xsane-preferences.c
+++ b/src/xsane-preferences.c
@@ -50,6 +50,7 @@
Preferences preferences =
{
0, /* xsane-version string */
+ XSANE_VIEWER, /* default xsane_mode viewer */
0, /* default path to temporary directory (not defined here) */
0, /* default working_directory */
0, /* no default filename */
@@ -138,6 +139,7 @@ Preferences preferences =
1, /* preselect_scanarea after preview scan */
1, /* auto_correct_colors after preview scan */
GTK_UPDATE_DISCONTINUOUS, /* update policy for gtk frontend sliders */
+ 0, /* medium_nr */
0, /* paper_orientation */
0, /* preset_area_definitions */
0, /* printernr */
@@ -155,6 +157,7 @@ static struct
desc[] =
{
{"xsane-version", xsane_rc_pref_string, POFFSET(xsane_version_str)},
+ {"xsane-mode", xsane_rc_pref_int, POFFSET(xsane_mode)},
{"tmp-path", xsane_rc_pref_string, POFFSET(tmp_path)},
{"working-directory", xsane_rc_pref_string, POFFSET(working_directory)},
{"filename", xsane_rc_pref_string, POFFSET(filename)},
@@ -243,6 +246,7 @@ desc[] =
{"preselect-scanarea", xsane_rc_pref_int, POFFSET(preselect_scanarea)},
{"auto-correct-colors", xsane_rc_pref_int, POFFSET(auto_correct_colors)},
{"gtk-update-policy", xsane_rc_pref_int, POFFSET(gtk_update_policy)},
+ {"medium-nr", xsane_rc_pref_int, POFFSET(medium_nr)},
{"paper-orientation", xsane_rc_pref_int, POFFSET(paper_orientation)},
{"preset-area-definitions", xsane_rc_pref_int, POFFSET(preset_area_definitions)},
{"printernr", xsane_rc_pref_int, POFFSET(printernr)},
diff --git a/src/xsane-preferences.h b/src/xsane-preferences.h
index e0b90c0..e59a66c 100644
--- a/src/xsane-preferences.h
+++ b/src/xsane-preferences.h
@@ -87,6 +87,7 @@ typedef struct
typedef struct
{
char *xsane_version_str; /* xsane-version string */
+ int xsane_mode; /* xsane_mode */
char *tmp_path; /* path to temporary directory */
char *working_directory; /* directory where xsane saves images etc */
char *filename; /* default filename */
@@ -182,6 +183,7 @@ typedef struct
int preselect_scanarea; /* automatic selection of scanarea after preview scan */
int auto_correct_colors; /* automatic color correction after preview scan */
int gtk_update_policy;
+ int medium_nr;
int paper_orientation; /* image position on printer and page orientation */
int printernr; /* number of printers */
diff --git a/src/xsane-preview.c b/src/xsane-preview.c
index 879bc99..5bd6457 100644
--- a/src/xsane-preview.c
+++ b/src/xsane-preview.c
@@ -815,7 +815,7 @@ static void preview_get_scale_device_to_image(Preview *p, float *xscalep, float
}
}
-#if 1
+ /* make sure pixels have square dimension */
if (xscale > yscale)
{
yscale = xscale;
@@ -824,7 +824,6 @@ static void preview_get_scale_device_to_image(Preview *p, float *xscalep, float
{
xscale = yscale;
}
-#endif
*xscalep = xscale;
*yscalep = yscale;
@@ -6757,10 +6756,6 @@ void preview_update_maximum_output_size(Preview *p)
{
float xxx = 0.0;
float yyy = 0.0;
- float dxmin = 0;
- float dymin = 0;
- float dxmax = 0;
- float dymax = 0;
int paper_orientation = 0;
@@ -6863,10 +6858,10 @@ void preview_update_maximum_output_size(Preview *p)
break;
}
- p->selection_maximum.coordinate[p->index_xmin] = p->selection.coordinate[p->index_xmin] + xxx *(-p->selection.coordinate[p->index_xmin] + p->selection.coordinate[p->index_xmax]) - p->maximum_output_width * xxx - dxmin;
- p->selection_maximum.coordinate[p->index_ymin] = p->selection.coordinate[p->index_ymin] + yyy *(-p->selection.coordinate[p->index_ymin] + p->selection.coordinate[p->index_ymax]) - p->maximum_output_height * yyy - dymin;
- p->selection_maximum.coordinate[p->index_xmax] = p->selection.coordinate[p->index_xmin] + xxx *(-p->selection.coordinate[p->index_xmin] + p->selection.coordinate[p->index_xmax]) + p->maximum_output_width * (1.0 - xxx) + dxmax;
- p->selection_maximum.coordinate[p->index_ymax] = p->selection.coordinate[p->index_ymin] + yyy *(-p->selection.coordinate[p->index_ymin] + p->selection.coordinate[p->index_ymax]) + p->maximum_output_height * (1.0 - yyy) + dymax;
+ p->selection_maximum.coordinate[p->index_xmin] = p->selection.coordinate[p->index_xmin] + xxx * (p->selection.coordinate[p->index_xmax] - p->selection.coordinate[p->index_xmin]) - p->maximum_output_width * xxx;
+ p->selection_maximum.coordinate[p->index_ymin] = p->selection.coordinate[p->index_ymin] + yyy * (p->selection.coordinate[p->index_ymax] - p->selection.coordinate[p->index_ymin]) - p->maximum_output_height * yyy;
+ p->selection_maximum.coordinate[p->index_xmax] = p->selection.coordinate[p->index_xmin] + xxx * (p->selection.coordinate[p->index_xmax] - p->selection.coordinate[p->index_xmin]) + p->maximum_output_width * (1.0 - xxx);
+ p->selection_maximum.coordinate[p->index_ymax] = p->selection.coordinate[p->index_ymin] + yyy * (p->selection.coordinate[p->index_ymax] - p->selection.coordinate[p->index_ymin]) + p->maximum_output_height * (1.0 - yyy);
if ( (p->selection.coordinate[p->index_xmin] < p->selection_maximum.coordinate[p->index_xmin]) ||
diff --git a/src/xsane-save.c b/src/xsane-save.c
index e9020e0..decd85a 100644
--- a/src/xsane-save.c
+++ b/src/xsane-save.c
@@ -25,6 +25,7 @@
#include "xsane.h"
#include "xsane-back-gtk.h"
#include "xsane-front-gtk.h"
+#include <time.h>
#include <sys/wait.h>
/* the following test is always false */
@@ -40,16 +41,16 @@
#include <jpeglib.h>
#endif
-#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
-#include <png.h>
#include <zlib.h>
#endif
+
+#ifdef HAVE_LIBPNG
+#include <png.h>
#endif
#ifdef HAVE_LIBTIFF
#include <tiffio.h>
-#include <time.h>
#endif
#ifdef HAVE_MMAP
@@ -2316,32 +2317,32 @@ static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
fprintf(outfile, "%%%%DocumentData: Clean7Bit\n");
+ fprintf(outfile, "%%%%LanguageLevel: 2\n");
fprintf(outfile, "%%%%Pages: 1\n");
fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n", box_left, box_bottom, box_right, box_top);
fprintf(outfile, "%%%%EndComments\n");
+ fprintf(outfile, "\n");
fprintf(outfile, "/origstate save def\n");
fprintf(outfile, "20 dict begin\n");
fprintf(outfile, "%%%%Page: 1 1\n");
if (depth == 1)
{
- fprintf(outfile, "/pix %d string def\n", (image_info->image_width+7)/8);
fprintf(outfile, "/grays %d string def\n", image_info->image_width);
fprintf(outfile, "/npixels 0 def\n");
fprintf(outfile, "/rgbindx 0 def\n");
}
- else
- {
- fprintf(outfile, "/pix %d string def\n", image_info->image_width);
- }
-
fprintf(outfile, "%d rotate\n", degree);
fprintf(outfile, "%d %d translate\n", position_left, position_bottom);
fprintf(outfile, "%f %f scale\n", width, height);
fprintf(outfile, "%d %d %d\n", image_info->image_width, image_info->image_height, depth);
fprintf(outfile, "[%d %d %d %d %d %d]\n", image_info->image_width, 0, 0, -image_info->image_height, 0, image_info->image_height);
- fprintf(outfile, "{currentfile pix readhexstring pop}\n");
+ fprintf(outfile, "currentfile\n");
+ fprintf(outfile, "/ASCII85Decode filter\n");
+#ifdef HAVE_LIBZ
+ fprintf(outfile, "/FlateDecode filter\n");
+#endif
if (image_info->colors == 3) /* what about RGBA here ? */
{
@@ -2357,16 +2358,228 @@ static void xsane_save_ps_create_header(FILE *outfile, Image_info *image_info,
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_bw(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+/* Utility function for the PostScript output */
+static int xsane_write_compressed_a85(FILE *outfile, unsigned char *line, int len, int finish)
{
- int x, y, count;
+ static unsigned char *cbuf = NULL;
+ static int cbuflen = 0;
+ static int linelen = 0;
+ int i, j;
+ int outlen;
+#ifdef HAVE_LIBZ
+ static int init = 0;
+ static z_stream s;
+ int ret;
+ int flush;
+#endif
+ static int a85count = 0;
+ static guint32 a85tuple = 0;
+ static unsigned char a85block[6] = {0, 0, 0, 0, 0, 0};
+ static int count = 0;
+
+ DBG(DBG_proc, "xsane_write_compressed_a85\n");
+
+#ifdef HAVE_LIBZ
+ if (linelen != len)
+ {
+ linelen = len;
+ if (cbuf != NULL)
+ {
+ free(cbuf);
+ }
+ /* buffer length = length + 0.1 * length + 12 (mandatory) */
+ cbuflen = len + len / 10 + 12;
+ cbuf = malloc(cbuflen);
+ }
+
+ if (cbuf == NULL)
+ {
+ DBG(DBG_error, "cbuf allocation failed\n");
+ return 1;
+ }
+
+ if (!init)
+ {
+ s.zalloc = Z_NULL;
+ s.zfree = Z_NULL;
+ s.opaque = Z_NULL;
+
+ ret = deflateInit(&s, Z_DEFAULT_COMPRESSION);
+
+ if (ret != Z_OK)
+ {
+ DBG(DBG_error, "deflateInit failed\n");
+ free(cbuf);
+ return 1;
+ }
+
+ init = 1;
+ }
+
+ s.avail_in = len;
+ s.next_in = line;
+
+ do
+ {
+ s.avail_out = cbuflen;
+ s.next_out = cbuf;
+
+ flush = (finish) ? Z_FINISH : Z_NO_FLUSH;
+
+ ret = deflate(&s, flush);
+
+ if (ret == Z_STREAM_ERROR)
+ {
+ DBG(DBG_error, "deflate failed\n");
+ free(cbuf);
+ return 1;
+ }
+
+ outlen = cbuflen - s.avail_out;
+#else
+ cbuf = line;
+ outlen = len;
+#endif /* HAVE_LIBZ */
+
+ /* ASCII85 (base 85) encoding */
+ for (i = 0; i < outlen; i++)
+ {
+ switch (a85count)
+ {
+ case 0:
+ a85tuple |= (cbuf[i] << 24);
+ a85count++;
+ break;
+
+ case 1:
+ a85tuple |= (cbuf[i] << 16);
+ a85count++;
+ break;
+
+ case 2:
+ a85tuple |= (cbuf[i] << 8);
+ a85count++;
+ break;
+
+ case 3:
+ a85tuple |= (cbuf[i] << 0);
+
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+
+ if (a85tuple == 0)
+ {
+ fprintf(outfile, "z");
+ count++;
+ }
+ else
+ {
+ /* The ASCII chars must be written in reverse order, hence -> a85block[4-j] */
+ for (j = 0; j < 5; j++)
+ {
+ a85block[4-j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+
+ for (j = 0; j < 5; j++)
+ {
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ }
+ }
+
+ a85count = 0;
+ a85tuple = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+#ifdef HAVE_LIBZ
+ } while (s.avail_out == 0);
+#endif
+
+ if (finish)
+ {
+ DBG(DBG_info, "finish\n");
+ if (a85count > 0)
+ {
+ a85count++;
+ for (j = 0; j <= a85count; j++)
+ {
+ a85block[j] = a85tuple % 85 + '!';
+ a85tuple /= 85;
+ }
+ /* Reverse order */
+ for (j--; j > 0; j--)
+ {
+ if (count == 40)
+ {
+ fprintf(outfile, "\n");
+ count = 0;
+ }
+ fprintf(outfile, "%c", a85block[j]);
+ count++;
+ }
+ }
+
+ /* ASCII85 EOD marker + newline*/
+ if (count + 2 > 40)
+ {
+ fprintf(outfile, "\n");
+ }
+ fprintf(outfile, "~>\n");
+#ifdef HAVE_LIBZ
+ deflateEnd(&s);
+ free(cbuf);
+ cbuf = NULL;
+ init = 0;
+#endif
+ a85tuple = 0;
+ a85count = 0;
+ cbuflen = 0;
+ linelen = 0;
+ count = 0;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+static int xsane_save_ps_pdf_bw(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+{
+ int x, y;
int bytes_per_line = (image_info->image_width+7)/8;
+ int ret;
+ unsigned char *line;
- DBG(DBG_proc, "xsane_save_ps_bw\n");
+ DBG(DBG_proc, "xsane_save_ps_pdf_bw\n");
*cancel_save = 0;
- count = 0;
+ line = (unsigned char *) malloc(bytes_per_line);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
for (y = 0; y < image_info->image_height; y++)
{
gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
@@ -2377,48 +2590,67 @@ static int xsane_save_ps_bw(FILE *outfile, FILE *imagefile, Image_info *image_in
for (x = 0; x < bytes_per_line; x++)
{
- fprintf(outfile, "%02x", (fgetc(imagefile) ^ 255));
- if (++count >= 40)
- {
- fprintf(outfile, "\n");
- count = 0;
- }
+ line[x] = fgetc(imagefile) ^ 255;
}
- fprintf(outfile, "\n");
+ ret = xsane_write_compressed_a85(outfile, line, bytes_per_line, (y == image_info->image_height - 1));
- if (ferror(outfile))
+ if ((ret != 0) || (ferror(outfile)))
{
char buf[255];
- snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, ERR_ZLIB);
+ }
+
DBG(DBG_error, "%s\n", buf);
xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
*cancel_save = 1;
+
break;
}
- count = 0;
if (*cancel_save)
{
break;
}
}
+ free(line);
+
return (*cancel_save);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+static int xsane_save_ps_pdf_gray(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
{
- int x, y, count;
+ int x, y;
+ int ret;
+ unsigned char *line;
- DBG(DBG_proc, "xsane_save_ps_gray\n");
+ DBG(DBG_proc, "xsane_save_ps_pdf_gray\n");
*cancel_save = 0;
- count = 0;
+ line = (unsigned char *) malloc(image_info->image_width);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
+
for (y = 0; y < image_info->image_height; y++)
{
if (image_info->depth > 8) /* reduce 16 bit images */
@@ -2428,67 +2660,81 @@ static int xsane_save_ps_gray(FILE *outfile, FILE *imagefile, Image_info *image_
for (x = 0; x < image_info->image_width; x++)
{
fread(&val, 2, 1, imagefile);
- fprintf(outfile, "%02x", val/256);
-
- if (++count >= 40)
- {
- fprintf(outfile, "\n");
- count = 0;
- }
+ line[x] = val/256;
}
}
else /* 8 bits/sample */
{
for (x = 0; x < image_info->image_width; x++)
{
- fprintf(outfile, "%02x", fgetc(imagefile));
- if (++count >= 40)
- {
- fprintf(outfile, "\n");
- count = 0;
- }
+ line[x] = fgetc(imagefile);
}
}
- fprintf(outfile, "\n");
+ ret = xsane_write_compressed_a85(outfile, line, image_info->image_width, (y == image_info->image_height - 1));
- if (ferror(outfile))
+ if ((ret != 0) || (ferror(outfile)))
{
char buf[255];
- snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s zlib error or memory allocation problem", ERR_DURING_SAVE);
+ }
+
DBG(DBG_error, "%s\n", buf);
xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
*cancel_save = 1;
+
break;
}
- count = 0;
gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
while (gtk_events_pending())
{
gtk_main_iteration();
}
+
if (*cancel_save)
{
break;
}
}
+ free(line);
+
return (*cancel_save);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-static int xsane_save_ps_color(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
+static int xsane_save_ps_pdf_color(FILE *outfile, FILE *imagefile, Image_info *image_info, GtkProgressBar *progress_bar, int *cancel_save)
{
- int x, y, count;
+ int x, y;
+ int ret;
+ unsigned char *line, *linep;
- DBG(DBG_proc, "xsane_save_ps_color\n");
+ DBG(DBG_proc, "xsane_save_ps_pdf_color\n");
*cancel_save = 0;
+
+ line = (unsigned char *) malloc(image_info->image_width * 3);
+
+ if (line == NULL)
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s malloc failed", ERR_DURING_SAVE);
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ return (*cancel_save);
+ }
- count = 0;
for (y = 0; y < image_info->image_height; y++)
{
gtk_progress_bar_update(progress_bar, (float) y / image_info->image_height);
@@ -2497,6 +2743,8 @@ static int xsane_save_ps_color(FILE *outfile, FILE *imagefile, Image_info *image
gtk_main_iteration();
}
+ linep = line;
+
if (image_info->depth > 8) /* reduce 16 bit images */
{
guint16 val;
@@ -2504,55 +2752,53 @@ static int xsane_save_ps_color(FILE *outfile, FILE *imagefile, Image_info *image
for (x = 0; x < image_info->image_width; x++)
{
fread(&val, 2, 1, imagefile);
- fprintf(outfile, "%02x", val/256);
+ *linep++ = val/256;
fread(&val, 2, 1, imagefile);
- fprintf(outfile, "%02x", val/256);
+ *linep++ = val/256;
fread(&val, 2, 1, imagefile);
- fprintf(outfile, "%02x", val/256);
-
- if (++count >= 10)
- {
- fprintf(outfile, "\n");
- count = 0;
- }
+ *linep++ = val/256;
}
}
else /* 8 bits/sample */
{
for (x = 0; x < image_info->image_width; x++)
{
- fprintf(outfile, "%02x", fgetc(imagefile));
- fprintf(outfile, "%02x", fgetc(imagefile));
- fprintf(outfile, "%02x", fgetc(imagefile));
-
- if (++count >= 10)
- {
- fprintf(outfile, "\n");
- count = 0;
- }
+ *linep++ = fgetc(imagefile);
+ *linep++ = fgetc(imagefile);
+ *linep++ = fgetc(imagefile);
}
}
- fprintf(outfile, "\n");
- if (ferror(outfile))
+ ret = xsane_write_compressed_a85(outfile, line, (image_info->image_width * 3), (y == image_info->image_height - 1));
+
+ if ((ret != 0) || (ferror(outfile)))
{
char buf[255];
- snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ if (ret == 0)
+ {
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf), "%s zlib error or memory allocation problem", ERR_DURING_SAVE);
+ }
+
DBG(DBG_error, "%s\n", buf);
xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
*cancel_save = 1;
+
break;
}
- count = 0;
-
if (*cancel_save)
{
break;
}
}
+ free(line);
+
return (*cancel_save);
}
@@ -2574,16 +2820,16 @@ int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float
{
if (image_info->depth == 1) /* lineart, halftone */
{
- xsane_save_ps_bw(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, progress_bar, cancel_save);
}
else /* grayscale */
{
- xsane_save_ps_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
}
}
else /* color RGB */
{
- xsane_save_ps_color(outfile, imagefile, image_info, progress_bar, cancel_save);
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, progress_bar, cancel_save);
}
fprintf(outfile, "\n");
@@ -2607,6 +2853,308 @@ int xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info, float
}
/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* The pdf_xref struct holds byte offsets from the beginning of the PDF
+ * file to each object of the PDF file -- used to build the xref table
+ */
+struct pdf_xref
+{
+ unsigned long obj5; /* obj 5 0 */
+ unsigned long obj6; /* obj 6 0 */
+ unsigned long obj7; /* obj 7 0 */
+ unsigned long xref; /* xref table */
+ unsigned long slen; /* length of image stream */
+ unsigned long slenp; /* position of image stream length */
+};
+
+static void xsane_save_pdf_create_header(FILE *outfile, Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin,
+ int paper_width, int paper_height,
+ int paper_orientation,
+ GtkProgressBar *progress_bar, struct pdf_xref *xref)
+{
+ int position_left, position_bottom, box_left, box_bottom, box_right, box_top, depth;
+ int left, bottom;
+ float rad;
+
+ DBG(DBG_proc, "xsane_save_pdf_create_header\n");
+
+ switch (paper_orientation)
+ {
+ default:
+ case 0: /* top left portrait */
+ left = 0.0;
+ bottom = paper_height - height;
+ break;
+
+ case 1: /* top right portrait */
+ left = paper_width - width;
+ bottom = paper_height - height;
+ break;
+
+ case 2: /* bottom right portrait */
+ left = paper_width - width;
+ bottom = 0.0;
+ break;
+
+ case 3: /* bottom left portrait */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 4: /* center portrait */
+ left = paper_width / 2.0 - width / 2.0;
+ bottom = paper_height / 2.0 - height / 2.0;
+ break;
+
+
+ case 8: /* top left landscape */
+ left = 0.0;
+ bottom = paper_width - height;
+ break;
+
+ case 9: /* top right landscape */
+ left = paper_height - width;
+ bottom = paper_width - height;
+ break;
+
+ case 10: /* bottom right landscape */
+ left = paper_height - width;
+ bottom = 0.0;
+ break;
+
+ case 11: /* bottom left landscape */
+ left = 0.0;
+ bottom = 0.0;
+ break;
+
+ case 12: /* center landscape */
+ left = paper_height / 2.0 - width / 2.0;
+ bottom = paper_width / 2.0 - height / 2.0;
+ break;
+ }
+
+
+ if (paper_orientation >= 8) /* rotate with 90 degrees - landscape mode */
+ {
+ rad = -M_PI_2; /* pi / 2 */
+ position_left = left + paper_bottom_margin;
+ position_bottom = bottom - paper_width - paper_left_margin;
+ box_left = paper_width - paper_left_margin - bottom - height;
+ box_bottom = left + paper_bottom_margin;
+ box_right = box_left + ceil(height);
+ box_top = box_bottom + ceil(width);
+ }
+ else /* do not rotate, portrait mode */
+ {
+ rad = 0;
+ position_left = left + paper_left_margin;
+ position_bottom = bottom + paper_bottom_margin;
+ box_left = left + paper_left_margin;
+ box_bottom = bottom + paper_bottom_margin;
+ box_right = box_left + ceil(width);
+ box_top = box_bottom + ceil(height);
+ }
+
+ depth = image_info->depth;
+
+ if (depth > 8)
+ {
+ depth = 8;
+ }
+
+ fprintf(outfile, "%%PDF-1.4\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "1 0 obj\n");
+ fprintf(outfile, " << /Type /Catalog\n");
+ fprintf(outfile, " /Outlines 2 0 R\n");
+ fprintf(outfile, " /Pages 3 0 R\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "2 0 obj\n");
+ fprintf(outfile, " << /Type /Outlines\n");
+ fprintf(outfile, " /Count 0\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "3 0 obj\n");
+ fprintf(outfile, " << /Type /Pages\n");
+ fprintf(outfile, " /Kids [4 0 R]\n");
+ fprintf(outfile, " /Count 1\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+ fprintf(outfile, "4 0 obj\n");
+ fprintf(outfile, " << /Type /Page\n");
+ fprintf(outfile, " /Parent 3 0 R\n");
+ fprintf(outfile, " /MediaBox [%d %d %d %d]\n", box_left, box_bottom, box_right, box_top);
+ fprintf(outfile, " /Contents 5 0 R\n");
+ fprintf(outfile, " /Resources << /ProcSet 6 0 R >>\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 5, for xref */
+ xref->obj5 = ftell(outfile);
+
+ fprintf(outfile, "5 0 obj\n");
+ fprintf(outfile, " << /Length >>\n");
+
+ /* Position of the stream length, to be written later on */
+ xref->slenp = ftell(outfile) - 15;
+
+ fprintf(outfile, "stream\n");
+
+ /* Start of the stream data */
+ xref->slen = ftell(outfile);
+
+ fprintf(outfile, "q\n");
+ fprintf(outfile, "1 0 0 1 %d %d cm\n", position_left, position_bottom); /* translate */
+ fprintf(outfile, "%f %f -%f %f 0 0 cm\n", cos(rad), sin(rad), sin(rad), cos(rad)); /* rotate */
+ fprintf(outfile, "%f 0 0 %f 0 0 cm\n", width, height); /* scale */
+ fprintf(outfile, "BI\n");
+ fprintf(outfile, " /W %d\n", image_info->image_width);
+ fprintf(outfile, " /H %d\n", image_info->image_height);
+
+ if (image_info->colors == 3) /* what about RGBA here ? */
+ {
+ fprintf(outfile, " /CS /RGB\n");
+ fprintf(outfile, " /BPC %d\n", depth);
+ }
+ else if (image_info->depth == 1) /* BW */
+ {
+ fprintf(outfile, " /CS /G\n");
+ fprintf(outfile, " /BPC 1\n");
+ }
+ else /* gray */
+ {
+ fprintf(outfile, " /CS /G\n");
+ fprintf(outfile, " /BPC 8\n");
+ }
+
+#ifdef HAVE_LIBZ
+ fprintf(outfile, " /F [/A85 /FlateDecode]\n");
+#else
+ fprintf(outfile, " /F /A85\n");
+#endif
+ fprintf(outfile, "ID\n");
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+int xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info, float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperheight, int paperwidth, int paper_orientation,
+ GtkProgressBar *progress_bar, int *cancel_save)
+{
+ struct tm *t;
+ time_t tt;
+ struct pdf_xref xref;
+
+ DBG(DBG_proc, "xsane_save_pdf\n");
+
+ *cancel_save = 0;
+
+ xsane_save_pdf_create_header(outfile, image_info, width, height,
+ paper_left_margin, paper_bottom_margin, paperheight, paperwidth, paper_orientation,
+ progress_bar, &xref);
+
+ if (image_info->colors == 1) /* lineart, halftone, grayscale */
+ {
+ if (image_info->depth == 1) /* lineart, halftone */
+ {
+ xsane_save_ps_pdf_bw(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ else /* grayscale */
+ {
+ xsane_save_ps_pdf_gray(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+ }
+ else /* color RGB */
+ {
+ xsane_save_ps_pdf_color(outfile, imagefile, image_info, progress_bar, cancel_save);
+ }
+
+ /* PDF trailer */
+ fprintf(outfile, "EI\n");
+ fprintf(outfile, "Q\n");
+
+ /* Go back and write the length of the stream */
+ xref.slen = ftell(outfile) - xref.slen - 1;
+ fseek(outfile, xref.slenp, SEEK_SET);
+ fprintf(outfile, "%lu", xref.slen);
+ fseek(outfile, 0L, SEEK_END);
+
+ fprintf(outfile, "endstream\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 6, for xref */
+ xref.obj6 = ftell(outfile);
+
+ fprintf(outfile, "6 0 obj\n");
+ fprintf(outfile, " [/PDF]\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of object 7, for xref */
+ xref.obj7 = ftell(outfile);
+
+ fprintf(outfile, "7 0 obj\n");
+ fprintf(outfile, " << /Title (XSane scanned image)\n");
+ fprintf(outfile, " /Creator (XSane version %s (sane %d.%d) - by Oliver Rauch)\n",
+ VERSION,
+ SANE_VERSION_MAJOR(xsane.sane_backend_versioncode),
+ SANE_VERSION_MINOR(xsane.sane_backend_versioncode));
+ fprintf(outfile, " /Producer (XSane %s)\n", VERSION);
+
+ tt = time(NULL);
+ t = gmtime(&tt);
+
+ fprintf(outfile, " /CreationDate (D:%04d%02d%02d%02d%02d%02d+00'00')\n",
+ 1900 + t->tm_year, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "endobj\n");
+ fprintf(outfile, "\n");
+
+ /* Offset of xref, for startxref below */
+ xref.xref = ftell(outfile);
+
+ fprintf(outfile, "xref\n");
+ fprintf(outfile, "0 8\n");
+ fprintf(outfile, "0000000000 65535 f \n");
+ fprintf(outfile, "0000000010 00000 n \n");
+ fprintf(outfile, "0000000094 00000 n \n");
+ fprintf(outfile, "0000000153 00000 n \n");
+ fprintf(outfile, "0000000229 00000 n \n");
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj5);
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj6);
+ fprintf(outfile, "%010lu 00000 n \n", xref.obj7);
+ fprintf(outfile, "\n");
+ fprintf(outfile, "trailer\n");
+ fprintf(outfile, " << /Size 8\n");
+ fprintf(outfile, " /Root 1 0 R\n");
+ fprintf(outfile, " /Info 7 0 R\n");
+ fprintf(outfile, " >>\n");
+ fprintf(outfile, "startxref\n");
+ fprintf(outfile, "%lu\n", xref.xref);
+ fprintf(outfile, "%%%%EOF\n");
+
+ if (ferror(outfile))
+ {
+ char buf[255];
+
+ snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno));
+ DBG(DBG_error, "%s\n", buf);
+ xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */);
+ *cancel_save = 1;
+ }
+
+ return (*cancel_save);
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
#ifdef HAVE_LIBJPEG
typedef struct
@@ -3804,6 +4352,26 @@ int xsane_save_image_as(char *output_filename, char *input_filename, int output_
}
break; /* switch format == XSANE_PS */
+ case XSANE_PDF: /* save PDF, use original size */
+ {
+ float imagewidth, imageheight;
+
+ imagewidth = 72.0 * image_info.image_width/image_info.resolution_x; /* width in 1/72 inch */
+ imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */
+
+ xsane_save_pdf(outfile, infile,
+ &image_info,
+ imagewidth, imageheight,
+ 0, /* paper_left_margin */
+ 0, /* paper_bottom_margin */
+ (int) imagewidth, /* paper_width */
+ (int) imageheight, /* paper_height */
+ 0 /* portrait top left */,
+ progress_bar,
+ cancel_save);
+ }
+ break; /* switch format == XSANE_PDF */
+
case XSANE_TEXT: /* save as text using ocr program like gocr/jocr */
{
xsane_save_image_as_text(output_filename, input_filename, progress_bar, cancel_save);
@@ -4139,7 +4707,7 @@ static void xsane_gimp_run(char *name, int nparams, GimpParam *param, int *nretu
run_mode = param[0].data.d_int32;
xsane.mode = XSANE_GIMP_EXTENSION;
- xsane.xsane_mode = XSANE_SAVE;
+ preferences.xsane_mode = XSANE_SAVE;
*nreturn_vals = 1;
*return_vals = values;
diff --git a/src/xsane-save.h b/src/xsane-save.h
index ae8e9a4..e2f1458 100644
--- a/src/xsane-save.h
+++ b/src/xsane-save.h
@@ -42,6 +42,10 @@ extern void xsane_save_ps(FILE *outfile, FILE *imagefile, Image_info *image_info
float width, float height,
int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
GtkProgressBar *progress_bar, int *cancel_save);
+extern void xsane_save_pdf(FILE *outfile, FILE *imagefile, Image_info *image_info,
+ float width, float height,
+ int paper_left_margin, int paper_bottom_margin, int paperwidth, int paperheight, int paper_orientation,
+ GtkProgressBar *progress_bar, int *cancel_save);
extern void xsane_save_jpeg(FILE *outfile, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save);
extern void xsane_save_tiff(const char *outfilename, FILE *imagefile, Image_info *image_info, int quality, GtkProgressBar *progress_bar, int *cancel_save);
extern void xsane_save_png(FILE *outfile, FILE *imagefile, Image_info *image_info, int compression, GtkProgressBar *progress_bar, int *cancel_save);
diff --git a/src/xsane-scan.c b/src/xsane-scan.c
index ee0542c..73953fe 100644
--- a/src/xsane-scan.c
+++ b/src/xsane-scan.c
@@ -82,9 +82,9 @@ static int xsane_generate_dummy_filename(int conversion_level)
}
if ( (xsane.mode == XSANE_GIMP_EXTENSION) ||
- (xsane.xsane_mode == XSANE_COPY) ||
- (xsane.xsane_mode == XSANE_VIEWER) ||
- ( (xsane.xsane_mode == XSANE_SAVE) &&
+ (preferences.xsane_mode == XSANE_COPY) ||
+ (preferences.xsane_mode == XSANE_VIEWER) ||
+ ( (preferences.xsane_mode == XSANE_SAVE) &&
(xsane.xsane_output_format != XSANE_PNM) &&
(xsane.xsane_output_format != XSANE_RGBA) ) )
{
@@ -99,14 +99,14 @@ static int xsane_generate_dummy_filename(int conversion_level)
return TRUE;
}
- else if (xsane.xsane_mode == XSANE_FAX) /* no conversion following, save directly to the selected filename */
+ else if (preferences.xsane_mode == XSANE_FAX) /* no conversion following, save directly to the selected filename */
{
xsane.dummy_filename = strdup(xsane.fax_filename);
DBG(DBG_info, "xsane.dummy_filename = %s\n", xsane.dummy_filename);
return FALSE;
}
- else if (xsane.xsane_mode == XSANE_MAIL) /* no conversion following, save directly to the selected filename */
+ else if (preferences.xsane_mode == XSANE_MAIL) /* no conversion following, save directly to the selected filename */
{
xsane.dummy_filename = strdup(xsane.mail_filename);
DBG(DBG_info, "xsane.dummy_filename = %s\n", xsane.dummy_filename);
@@ -1185,13 +1185,13 @@ void xsane_scan_done(SANE_Status status)
}
}
- if (xsane.xsane_mode == XSANE_VIEWER)
+ if (preferences.xsane_mode == XSANE_VIEWER)
{
xsane_viewer_new(xsane.dummy_filename, TRUE, NULL, VIEWER_FULL_MODIFICATION);
xsane.expand_lineart_to_grayscale = 0;
}
- if ((xsane.xsane_mode == XSANE_FAX) || (xsane.xsane_mode == XSANE_MAIL))
+ if ((preferences.xsane_mode == XSANE_FAX) || (preferences.xsane_mode == XSANE_MAIL))
{
xsane.expand_lineart_to_grayscale = 0;
}
@@ -1207,24 +1207,8 @@ void xsane_scan_done(SANE_Status status)
}
}
- if (xsane.xsane_mode == XSANE_SAVE)
+ if (preferences.xsane_mode == XSANE_SAVE)
{
- if (xsane.print_filenames) /* print created filenames to stdout? */
- {
- if (xsane.output_filename[0] != '/') /* relative path */
- {
- char pathname[512];
- getcwd(pathname, sizeof(pathname));
- printf("XSANE_IMAGE_FILENAME: %s/%s\n", pathname, xsane.output_filename);
- fflush(stdout);
- }
- else /* absolute path */
- {
- printf("XSANE_IMAGE_FILENAME: %s\n", xsane.output_filename);
- fflush(stdout);
- }
- }
-
if ( ( (xsane.xsane_output_format != XSANE_PNM) && /* these files do not need any transformation */
(xsane.xsane_output_format != XSANE_RGBA) ) ||
(xsane.mode == XSANE_GIMP_EXTENSION) )
@@ -1258,8 +1242,24 @@ void xsane_scan_done(SANE_Status status)
remove(xsane.dummy_filename);
}
+
+ if (xsane.print_filenames) /* print created filenames to stdout? */
+ {
+ if (xsane.output_filename[0] != '/') /* relative path */
+ {
+ char pathname[512];
+ getcwd(pathname, sizeof(pathname));
+ printf("XSANE_IMAGE_FILENAME: %s/%s\n", pathname, xsane.output_filename);
+ fflush(stdout);
+ }
+ else /* absolute path */
+ {
+ printf("XSANE_IMAGE_FILENAME: %s\n", xsane.output_filename);
+ fflush(stdout);
+ }
+ }
}
- else if (xsane.xsane_mode == XSANE_COPY)
+ else if (preferences.xsane_mode == XSANE_COPY)
{
FILE *outfile;
FILE *infile;
@@ -1378,7 +1378,7 @@ void xsane_scan_done(SANE_Status status)
}
}
- if ( (xsane.xsane_mode == XSANE_SAVE) && (xsane.mode == XSANE_STANDALONE) )
+ if ( (preferences.xsane_mode == XSANE_SAVE) && (xsane.mode == XSANE_STANDALONE) )
{
if (!xsane.force_filename) /* user filename selection active */
{
@@ -1395,7 +1395,7 @@ void xsane_scan_done(SANE_Status status)
xsane_update_counter_in_filename(&xsane.external_filename, TRUE, 1, 0);
}
}
- else if (xsane.xsane_mode == XSANE_FAX)
+ else if (preferences.xsane_mode == XSANE_FAX)
{
GtkWidget *list_item;
char *page;
@@ -1437,7 +1437,7 @@ void xsane_scan_done(SANE_Status status)
gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0);
}
#ifdef XSANE_ACTIVATE_MAIL
- else if (xsane.xsane_mode == XSANE_MAIL)
+ else if (preferences.xsane_mode == XSANE_MAIL)
{
GtkWidget *list_item;
char *page;
@@ -1628,9 +1628,9 @@ static void xsane_start_scan(void)
}
if ((xsane.param.depth == 1) && ((xsane.scan_rotation) ||
- (xsane.xsane_mode == XSANE_VIEWER) ||
- (xsane.xsane_mode == XSANE_FAX) ||
- (xsane.xsane_mode == XSANE_MAIL))
+ (preferences.xsane_mode == XSANE_VIEWER) ||
+ (preferences.xsane_mode == XSANE_FAX) ||
+ (preferences.xsane_mode == XSANE_MAIL))
) /* We want to do a transformation with a lineart scan */
/* or use the viewer to display a lineart scan, */
/* so we save it as grayscale */
@@ -1755,7 +1755,7 @@ void xsane_scan_dialog(void)
sane_get_parameters(xsane.dev, &xsane.param); /* update xsane.param */
- if ( (xsane.mode == XSANE_STANDALONE) && (xsane.xsane_mode == XSANE_SAVE) )
+ if ( (xsane.mode == XSANE_STANDALONE) && (preferences.xsane_mode == XSANE_SAVE) )
{
/* correct length of filename counter if it is shorter than minimum length */
if (!xsane.force_filename)
@@ -1776,7 +1776,7 @@ void xsane_scan_dialog(void)
{
char *extension;
- if ( (xsane.xsane_mode == XSANE_SAVE) && (preferences.overwrite_warning) ) /* test if filename already used */
+ if ( (preferences.xsane_mode == XSANE_SAVE) && (preferences.overwrite_warning) ) /* test if filename already used */
{
FILE *testfile;
@@ -1798,7 +1798,7 @@ void xsane_scan_dialog(void)
xsane.xsane_output_format = xsane_identify_output_format(xsane.output_filename, preferences.filetype, &extension);
- if (xsane.xsane_mode == XSANE_SAVE)
+ if (preferences.xsane_mode == XSANE_SAVE)
{
if (xsane.xsane_output_format == XSANE_UNKNOWN)
{
@@ -1863,7 +1863,7 @@ void xsane_scan_dialog(void)
}
#endif
- if (xsane.xsane_mode == XSANE_FAX)
+ if (preferences.xsane_mode == XSANE_FAX)
{
mkdir(preferences.fax_project, 7*64 + 0*8 + 0);
}
@@ -1953,7 +1953,7 @@ void xsane_scan_dialog(void)
xsane.gamma_data_green = malloc(gamma_green_size * sizeof(SANE_Int));
xsane.gamma_data_blue = malloc(gamma_blue_size * sizeof(SANE_Int));
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
gamma_red = xsane.gamma * xsane.gamma_red * preferences.printer[preferences.printernr]->gamma * preferences.printer[preferences.printernr]->gamma_red;
gamma_green = xsane.gamma * xsane.gamma_green * preferences.printer[preferences.printernr]->gamma * preferences.printer[preferences.printernr]->gamma_green;
@@ -2013,7 +2013,7 @@ void xsane_scan_dialog(void)
gamma_gray_size = opt->size / sizeof(opt->type);
gamma_gray_max = opt->constraint.range->max;
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
gamma = xsane.gamma * preferences.printer[preferences.printernr]->gamma;
}
@@ -2087,7 +2087,7 @@ static void xsane_create_internal_gamma_tables(void)
xsane.gamma_data_green = malloc(size * sizeof(SANE_Int));
xsane.gamma_data_blue = malloc(size * sizeof(SANE_Int));
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
gamma_red = xsane.gamma_red * preferences.printer[preferences.printernr]->gamma_red;
gamma_green = xsane.gamma_green * preferences.printer[preferences.printernr]->gamma_green;
@@ -2128,7 +2128,7 @@ static void xsane_create_internal_gamma_tables(void)
xsane.gamma_data_green = malloc(size * sizeof(SANE_Int));
xsane.gamma_data_blue = malloc(size * sizeof(SANE_Int));
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
gamma_red = xsane.gamma * xsane.gamma_red * preferences.printer[preferences.printernr]->gamma * preferences.printer[preferences.printernr]->gamma_red;
gamma_green = xsane.gamma * xsane.gamma_green * preferences.printer[preferences.printernr]->gamma * preferences.printer[preferences.printernr]->gamma_green;
@@ -2173,7 +2173,7 @@ static void xsane_create_internal_gamma_tables(void)
DBG(DBG_info, "creating xsane internal gray gamma table with size %d\n", size);
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
gamma = xsane.gamma * preferences.printer[preferences.printernr]->gamma;
}
diff --git a/src/xsane-text.h b/src/xsane-text.h
index c36a73a..3334f14 100644
--- a/src/xsane-text.h
+++ b/src/xsane-text.h
@@ -662,6 +662,7 @@
#define ERR_LIBTIFF _("LIBTIFF reports error")
#define ERR_LIBPNG _("LIBPNG reports error")
#define ERR_LIBJPEG _("LIBJPEG reports error")
+#define ERR_ZLIB _("ZLIB error or memory allocation problem")
#define ERR_UNKNOWN_TYPE _("unknown type")
#define ERR_UNKNOWN_CONSTRAINT_TYPE _("unknown constraint type")
#define ERR_OPTION_NAME_NULL _("Option has empty name (NULL).")
diff --git a/src/xsane-viewer.c b/src/xsane-viewer.c
index 9fcae69..6a58f8b 100644
--- a/src/xsane-viewer.c
+++ b/src/xsane-viewer.c
@@ -253,7 +253,6 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
char *inputfilename;
char windowname[256];
int output_format;
- char *filetype = NULL;
int abort = 0;
char buf[256];
@@ -282,7 +281,7 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_VIEWER_OUTPUT_FILENAME, xsane.device_text);
umask((mode_t) preferences.directory_umask); /* define new file permissions */
- abort = xsane_back_gtk_get_filename(windowname, outputfilename, sizeof(outputfilename), outputfilename, &filetype, TRUE, TRUE, FALSE, TRUE);
+ abort = xsane_back_gtk_get_filename(windowname, outputfilename, sizeof(outputfilename), outputfilename, &preferences.filetype, TRUE, TRUE, FALSE, TRUE);
umask(XSANE_DEFAULT_UMASK); /* define new file permissions */
if (abort)
@@ -321,7 +320,7 @@ static void xsane_viewer_save_callback(GtkWidget *window, gpointer data)
inputfilename = strdup(v->filename);
- output_format = xsane_identify_output_format(v->output_filename, filetype, 0);
+ output_format = xsane_identify_output_format(v->output_filename, preferences.filetype, 0);
if ((!v->allow_reduction_to_lineart) && (output_format == XSANE_PNM)) /* save PNM but do not reduce to lineart (if lineart) */
{
diff --git a/src/xsane.c b/src/xsane.c
index 9ef109f..d7cb4d0 100644
--- a/src/xsane.c
+++ b/src/xsane.c
@@ -328,7 +328,7 @@ static void xsane_set_modus_defaults(void)
{
DBG(DBG_proc, "xsane_set_modus_defaults\n");
- switch(xsane.xsane_mode)
+ switch(preferences.xsane_mode)
{
case XSANE_VIEWER:
xsane_define_maximum_output_size();
@@ -398,23 +398,23 @@ static void xsane_modus_callback(GtkWidget *xsane_parent, int *num)
{
DBG(DBG_proc, "xsane_modus_callback\n");
- xsane.xsane_mode = *num;
+ preferences.xsane_mode = *num;
xsane_set_modus_defaults(); /* set defaults and maximum output size */
xsane_refresh_dialog();
- if ((xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) || (xsane.xsane_mode == XSANE_COPY))
+ if ((preferences.xsane_mode == XSANE_SAVE) || (preferences.xsane_mode == XSANE_VIEWER) || (preferences.xsane_mode == XSANE_COPY))
{
gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE);
}
- if (xsane.xsane_mode != XSANE_FAX)
+ if (preferences.xsane_mode != XSANE_FAX)
{
xsane_fax_dialog_close();
}
#ifdef XSANE_ACTIVATE_MAIL
- if (xsane.xsane_mode != XSANE_MAIL)
+ if (preferences.xsane_mode != XSANE_MAIL)
{
if (xsane.mail_project_save)
{
@@ -1206,7 +1206,7 @@ static void xsane_scanmode_menu_callback(GtkWidget *widget, gpointer data)
opt = xsane_get_option_descriptor(xsane.dev, opt_num);
xsane_back_gtk_set_option(opt_num, menu_item->label, SANE_ACTION_SET_VALUE);
- if (xsane.xsane_mode == XSANE_COPY)
+ if (preferences.xsane_mode == XSANE_COPY)
{
switch (xsane.param.format)
{
@@ -1336,7 +1336,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_modus_option_menu, DESC_XSANE_MODE);
gtk_box_pack_end(GTK_BOX(xsane_hbox_xsane_modus), xsane_modus_option_menu, FALSE, FALSE, 2);
gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_modus_option_menu), xsane_modus_menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_modus_option_menu), xsane.xsane_mode);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_modus_option_menu), preferences.xsane_mode);
gtk_widget_show(xsane_modus_option_menu);
gtk_widget_show(xsane_hbox_xsane_modus);
@@ -1472,7 +1472,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_medium_option_menu, DESC_XSANE_MEDIUM);
gtk_box_pack_end(GTK_BOX(hbox), xsane_medium_option_menu, FALSE, FALSE, 2);
gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_medium_option_menu), xsane_medium_menu);
- gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_medium_option_menu), xsane.medium_nr);
+ gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_medium_option_menu), preferences.medium_nr);
gtk_widget_show(xsane_medium_option_menu);
gtk_widget_show(hbox);
@@ -1480,12 +1480,12 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
if (xsane.medium_calibration) /* are we running in medium calibration mode? */
{
- xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]);
+ xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
xsane_set_medium(NULL);
}
else
{
- xsane_set_medium(preferences.medium[xsane.medium_nr]);
+ xsane_set_medium(preferences.medium[preferences.medium_nr]);
}
}
else /* no medium selextion for lineart mode: use Full range gamma curve */
@@ -1495,7 +1495,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
}
- if (xsane.xsane_mode == XSANE_SAVE)
+ if (preferences.xsane_mode == XSANE_SAVE)
{
xsane.copy_number_entry = NULL;
@@ -1505,7 +1505,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
}
}
- if ( (xsane.xsane_mode == XSANE_SAVE) || (xsane.xsane_mode == XSANE_VIEWER) )
+ if ( (preferences.xsane_mode == XSANE_SAVE) || (preferences.xsane_mode == XSANE_VIEWER) )
{
/* resolution selection */
if (!xsane_resolution_widget_new(xsane_vbox_xsane_modus, xsane.well_known.dpi_x, &xsane.resolution_x, resolution_x_xpm,
@@ -1520,7 +1520,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
DESC_RESOLUTION, XSANE_GTK_NAME_RESOLUTION);
}
}
- else if (xsane.xsane_mode == XSANE_COPY)
+ else if (preferences.xsane_mode == XSANE_COPY)
{
GtkWidget *pixmapwidget, *hbox, *xsane_printer_option_menu, *xsane_printer_menu, *xsane_printer_item;
GdkBitmap *mask;
@@ -1677,7 +1677,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane.resolution, zoom_xpm, DESC_ZOOM);
}
}
- else if (xsane.xsane_mode == XSANE_FAX)
+ else if (preferences.xsane_mode == XSANE_FAX)
{
xsane.copy_number_entry = NULL;
@@ -1689,7 +1689,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */
xsane_fax_dialog();
}
#ifdef XSANE_ACTIVATE_MAIL
- else if (xsane.xsane_mode == XSANE_MAIL)
+ else if (preferences.xsane_mode == XSANE_MAIL)
{
xsane.copy_number_entry = NULL;
@@ -2042,11 +2042,6 @@ static int xsane_pref_restore(void)
preferences.fax_fine_option = strdup(FAXFINEOPT);
}
- if (!preferences.fax_viewer)
- {
- preferences.fax_viewer = strdup(FAXVIEWER);
- }
-
#ifdef XSANE_ACTIVATE_MAIL
if (!preferences.mail_smtp_server)
{
@@ -2519,13 +2514,13 @@ static gint xsane_medium_move_up_callback(GtkWidget *widget, GtkWidget *medium_w
preferences.medium[selection-1] = preferences.medium[selection];
preferences.medium[selection] = help_medium;
- if (xsane.medium_nr == selection)
+ if (preferences.medium_nr == selection)
{
- xsane.medium_nr--;
+ preferences.medium_nr--;
}
- else if (xsane.medium_nr == selection-1)
+ else if (preferences.medium_nr == selection-1)
{
- xsane.medium_nr++;
+ preferences.medium_nr++;
}
xsane_back_gtk_refresh_dialog(); /* brute-force: update menu */
@@ -2554,13 +2549,13 @@ static gint xsane_medium_move_down_callback(GtkWidget *widget, GtkWidget *medium
preferences.medium[selection] = preferences.medium[selection+1];
preferences.medium[selection+1] = help_medium;
- if (xsane.medium_nr == selection)
+ if (preferences.medium_nr == selection)
{
- xsane.medium_nr++;
+ preferences.medium_nr++;
}
- else if (xsane.medium_nr == selection+1)
+ else if (preferences.medium_nr == selection+1)
{
- xsane.medium_nr--;
+ preferences.medium_nr--;
}
xsane_back_gtk_refresh_dialog(); /* brute-force: update menu */
@@ -2683,7 +2678,7 @@ static gint xsane_medium_add_callback(GtkWidget *widget, GtkWidget *medium_widge
preferences.medium[selection]->negative = xsane.negative;
}
- xsane.medium_nr = selection; /* activate new created medium */
+ preferences.medium_nr = selection; /* activate new created medium */
xsane_back_gtk_refresh_dialog(); /* update menu */
xsane_enhancement_by_gamma(); /* update sliders */
@@ -2720,19 +2715,19 @@ static gint xsane_medium_delete_callback(GtkWidget *widget, GtkWidget *medium_wi
preferences.medium[i] = preferences.medium[i+1];
}
- if (xsane.medium_nr == selection)
+ if (preferences.medium_nr == selection)
{
- xsane.medium_nr--;
+ preferences.medium_nr--;
xsane.medium_changed = TRUE;
if (xsane.medium_calibration) /* are we running in medium calibration mode? */
{
- xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]);
+ xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
xsane_set_medium(NULL);
}
else
{
- xsane_set_medium(preferences.medium[xsane.medium_nr]);
+ xsane_set_medium(preferences.medium[preferences.medium_nr]);
}
xsane_enhancement_by_gamma(); /* update sliders */
@@ -2833,21 +2828,21 @@ static void xsane_set_medium_callback(GtkWidget *widget, gpointer data)
{
int medium_nr = (int) data;
- if (medium_nr != xsane.medium_nr)
+ if (medium_nr != preferences.medium_nr)
{
xsane.medium_changed = TRUE;
}
- xsane.medium_nr = medium_nr;
+ preferences.medium_nr = medium_nr;
if (xsane.medium_calibration) /* are we running in medium calibration mode? */
{
- xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]);
+ xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
xsane_set_medium(NULL);
}
else
{
- xsane_set_medium(preferences.medium[xsane.medium_nr]);
+ xsane_set_medium(preferences.medium[preferences.medium_nr]);
}
xsane_enhancement_by_gamma(); /* update sliders */
@@ -2930,7 +2925,7 @@ static void xsane_edit_medium_definition_callback(GtkWidget *widget, gpointer da
xsane.contrast_min = XSANE_MEDIUM_CALIB_CONTRAST_MIN;
xsane.contrast_max = XSANE_MEDIUM_CALIB_CONTRAST_MAX;
- xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]);
+ xsane_apply_medium_definition_as_enhancement(preferences.medium[preferences.medium_nr]);
xsane_set_medium(NULL);
}
else /* disable edit mode */
@@ -2947,7 +2942,7 @@ static void xsane_edit_medium_definition_callback(GtkWidget *widget, gpointer da
xsane.contrast_max = XSANE_CONTRAST_MAX;
xsane_apply_medium_definition_as_enhancement(preferences.medium[0]);
- xsane_set_medium(preferences.medium[xsane.medium_nr]);
+ xsane_set_medium(preferences.medium[preferences.medium_nr]);
}
xsane_enhancement_by_gamma(); /* update sliders */
@@ -3238,6 +3233,9 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data)
bufptr += strlen(bufptr);
#endif
+ sprintf(bufptr, "PDF, ");
+ bufptr += strlen(bufptr);
+
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
sprintf(bufptr, "PNG, ");
@@ -5010,7 +5008,6 @@ static void xsane_mail_dialog()
filetype_nr = -1;
select_item = 0;
-
#ifdef HAVE_LIBJPEG
filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG);
gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
@@ -5024,6 +5021,17 @@ static void xsane_mail_dialog()
#endif
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PDF);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PDF)) )
+ {
+ select_item = filetype_nr;
+ }
+
+
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG);
@@ -5038,6 +5046,16 @@ static void xsane_mail_dialog()
#endif
#endif
+ filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS);
+ gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item);
+ g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PS);
+ gtk_widget_show(filetype_item);
+ filetype_nr++;
+ if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PS)) )
+ {
+ select_item = filetype_nr;
+ }
+
#ifdef HAVE_LIBTIFF
filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF);
@@ -6184,6 +6202,7 @@ static void xsane_create_mail(int fd)
char *mail_text = NULL;
char *mail_text_pos = NULL;
char **attachment_filename = NULL;
+ char *mime_type = NULL;
char buf[256];
char filename[256];
char content_id[256];
@@ -6193,6 +6212,7 @@ static void xsane_create_mail(int fd)
int attachments = 0;
int use_attachment = 0;
int mail_text_size = 0;
+ int display_images_inline = FALSE;
DBG(DBG_proc, "xsane_create_mail\n");
@@ -6225,7 +6245,38 @@ static void xsane_create_mail(int fd)
}
}
- DBG(DBG_info, "reading list of attachments:\n");
+ if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PNG))
+ {
+ mime_type = "image/png";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG))
+ {
+ mime_type = "image/jpeg";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF))
+ {
+ mime_type = "image/tiff";
+ display_images_inline = TRUE;
+ }
+ else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PDF))
+ {
+ mime_type = "doc/pdf";
+ display_images_inline = FALSE;
+ }
+ else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PS))
+ {
+ mime_type = "doc/postscript";
+ display_images_inline = FALSE;
+ }
+ else
+ {
+ mime_type = "doc/unknown";
+ display_images_inline = FALSE;
+ }
+
+ DBG(DBG_info, "reading list of attachments:\n");
/* read list of attachments */
while (!feof(projectfile))
{
@@ -6296,7 +6347,12 @@ static void xsane_create_mail(int fd)
image_filename = attachment_filename[use_attachment++];
DBG(DBG_info, "inserting image cid for %s\n", image_filename);
snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
- snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+
+ /* doc files like ps and pdf can not be displayed inline in html mail */
+ if (display_images_inline)
+ {
+ snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+ }
write(fd, buf, strlen(buf));
}
else /* more images selected than available */
@@ -6320,7 +6376,12 @@ static void xsane_create_mail(int fd)
image_filename = attachment_filename[use_attachment++];
DBG(DBG_info, "appending image cid for %s\n", image_filename);
snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */
- snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+
+ /* doc files like ps and pdf can not be displayed inline in html mail */
+ if (display_images_inline)
+ {
+ snprintf(buf, sizeof(buf), "<p><img SRC=\"cid:%s\">\n", content_id);
+ }
write(fd, buf, strlen(buf));
}
@@ -6337,26 +6398,14 @@ static void xsane_create_mail(int fd)
if (attachment_file)
{
- DBG(DBG_info, "attaching png file \"%s\"\n", filename);
-
- if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PNG))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/png", attachment_file, image_filename);
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/jpeg", attachment_file, image_filename);
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/tiff", attachment_file, image_filename);
- }
+ DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.mail_filetype);
+ write_mail_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
remove(filename);
}
else /* could not open attachment file */
{
- DBG(DBG_error, "could not oppen attachment png file \"%s\"\n", filename);
+ DBG(DBG_error, "could not open attachment file \"%s\"\n", filename);
}
free(attachment_filename[i]);
@@ -6384,20 +6433,8 @@ static void xsane_create_mail(int fd)
if (attachment_file)
{
- DBG(DBG_info, "attaching png file \"%s\"\n", image_filename);
-
- if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_PNG))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/png", attachment_file, image_filename);
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/jpeg", attachment_file, image_filename);
- }
- else if (!strcmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF))
- {
- write_mail_attach_image(fd, boundary, content_id, "image/tiff", attachment_file, image_filename);
- }
+ DBG(DBG_info, "attaching file \"%s\" as \"%s\" with type %s\n", filename, image_filename, preferences.mail_filetype);
+ write_mail_attach_image(fd, boundary, content_id, mime_type, attachment_file, image_filename);
remove(filename);
}
@@ -7882,7 +7919,7 @@ static void xsane_device_dialog(void)
DBG(DBG_info, "Setting backend name \"%s\"\n", xsane.backend);
xsane.backend_translation = xsane.backend;
- bindtextdomain(xsane.backend_translation, STRINGIFY(LOCALEDIR)); /* set path for backend translation texts */
+ bindtextdomain(xsane.backend_translation, STRINGIFY(SANELOCALEDIR)); /* set path for backend translation texts */
#ifdef HAVE_GTK2
bind_textdomain_codeset(xsane.backend_translation, "UTF-8");
#endif
@@ -7906,7 +7943,7 @@ static void xsane_device_dialog(void)
DBG(DBG_info, "Setting general translation table \"sane-backends\" with localedir: %s\n", STRINGIFY(LOCALEDIR));
}
- bindtextdomain("sane-backends", STRINGIFY(LOCALEDIR)); /* set path for backend translation texts */
+ bindtextdomain("sane-backends", STRINGIFY(SANELOCALEDIR)); /* set path for backend translation texts */
#ifdef HAVE_GTK2
bind_textdomain_codeset(xsane.backend_translation, "UTF-8");
#endif
@@ -8548,10 +8585,10 @@ static void xsane_choose_device(void)
static void xsane_usage(void)
{
- printf("XSane %s %s\n", TEXT_VERSION, XSANE_VERSION);
- printf("%s %s\n\n", XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
- printf("%s %s %s\n\n", TEXT_USAGE, xsane.prog_name, TEXT_USAGE_OPTIONS);
- printf("%s\n\n", TEXT_HELP);
+ g_print("XSane %s %s\n", TEXT_VERSION, XSANE_VERSION);
+ g_print("%s %s\n\n", XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
+ g_print("%s %s %s\n\n", TEXT_USAGE, xsane.prog_name, TEXT_USAGE_OPTIONS);
+ g_print("%s\n\n", TEXT_HELP);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -8622,55 +8659,65 @@ static int xsane_init(int argc, char **argv)
/* then you get the error message when GIMP does */
/* query or tries to start the xsane plugin! */
#ifndef HAVE_ANY_GIMP
- printf("%s: %s\n", argv[0], ERR_GIMP_SUPPORT_MISSING);
+ g_print("%s: %s\n", argv[0], ERR_GIMP_SUPPORT_MISSING);
exit(0);
#endif
break;
case 'v': /* --version */
- printf("%s-%s %s %s\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
- printf(" %s %s\n", TEXT_EMAIL, XSANE_EMAIL);
- printf(" %s %s\n", TEXT_PACKAGE, XSANE_PACKAGE_VERSION);
- printf(" %s%d.%d.%d\n", TEXT_GTK_VERSION, GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
+ g_print("%s-%s %s %s\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
+ g_print(" %s %s\n", TEXT_EMAIL, XSANE_EMAIL);
+ g_print(" %s %s\n", TEXT_PACKAGE, XSANE_PACKAGE_VERSION);
+ g_print(" %s%d.%d.%d\n", TEXT_GTK_VERSION, GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
#ifdef HAVE_ANY_GIMP
- printf(" %s, %s%s\n", TEXT_WITH_GIMP_SUPPORT, TEXT_GIMP_VERSION, GIMP_VERSION);
+ g_print(" %s, %s%s\n", TEXT_WITH_GIMP_SUPPORT, TEXT_GIMP_VERSION, GIMP_VERSION);
#else
- printf(" %s\n", TEXT_WITHOUT_GIMP_SUPPORT);
+ g_print(" %s\n", TEXT_WITHOUT_GIMP_SUPPORT);
#endif
- printf(" %s ", TEXT_OUTPUT_FORMATS);
+ g_print(" %s ", TEXT_OUTPUT_FORMATS);
#ifdef HAVE_LIBJPEG
- printf("jpeg, ");
+ g_print("jpeg, ");
+#endif
+
+#ifdef HAVE_LIBZ
+ g_print("pdf(compr.), ");
+#else
+ g_print("pdf, ");
#endif
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
- printf("png, ");
+ g_print("png, ");
#endif
#endif
- printf("pnm, ");
- printf("ps");
+ g_print("pnm, ");
+#ifdef HAVE_LIBZ
+ g_print("ps(compr.)");
+#else
+ g_print("ps");
+#endif
#ifdef SUPPORT_RGBA
- printf(", rgba");
+ g_print(", rgba");
#endif
#ifdef HAVE_LIBTIFF
- printf(", tiff");
+ g_print(", tiff");
#endif
- printf(", txt");
+ g_print(", txt");
- printf("\n");
+ g_print("\n");
exit(0);
break;
case 'l': /* --license */
- printf("%s-%s %s %s\n\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
- printf("%s\n", TEXT_GPL);
+ g_print("%s-%s %s %s\n\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT);
+ g_print("%s\n", TEXT_GPL);
exit(0);
break;
@@ -8679,23 +8726,23 @@ static int xsane_init(int argc, char **argv)
break;
case 'V': /* --viewer, default */
- xsane.xsane_mode = XSANE_VIEWER;
+ preferences.xsane_mode = XSANE_VIEWER;
break;
case 's': /* --save */
- xsane.xsane_mode = XSANE_SAVE;
+ preferences.xsane_mode = XSANE_SAVE;
break;
case 'c': /* --copy */
- xsane.xsane_mode = XSANE_COPY;
+ preferences.xsane_mode = XSANE_COPY;
break;
case 'f': /* --fax */
- xsane.xsane_mode = XSANE_FAX;
+ preferences.xsane_mode = XSANE_FAX;
break;
case 'm': /* --mail */
- xsane.xsane_mode = XSANE_MAIL;
+ preferences.xsane_mode = XSANE_MAIL;
break;
case 'n': /* --No-mode-selection */
@@ -8962,7 +9009,7 @@ int main(int argc, char **argv)
xsane.main_window_fixed = -1; /* no command line option given, use preferences or fixed */
xsane.mode = XSANE_STANDALONE;
- xsane.xsane_mode = XSANE_VIEWER;
+ preferences.xsane_mode = XSANE_VIEWER;
xsane.lineart_mode = XSANE_LINEART_STANDARD;
xsane.xsane_output_format = XSANE_PNM;
xsane.mode_selection = 1; /* enable selection of xsane mode */
diff --git a/src/xsane.h b/src/xsane.h
index b54ee50..d26a89c 100644
--- a/src/xsane.h
+++ b/src/xsane.h
@@ -85,7 +85,7 @@
/* ---------------------------------------------------------------------------------------------------------------------- */
-#define XSANE_VERSION "0.97"
+#define XSANE_VERSION "0.98"
#define XSANE_AUTHOR "Oliver Rauch"
#define XSANE_COPYRIGHT "Oliver Rauch"
#define XSANE_DATE "1998-2005"
@@ -464,7 +464,6 @@ extern void xsane_batch_scan_add(void);
#define FAXPOSTSCRIPTOPT ""
#define FAXNORMALOPT "-l"
#define FAXFINEOPT "-m"
-#define FAXVIEWER "gv"
#define FAXCONVERTPSTOPNM "gs -dNOPAUSE -dBATCH -q -r204 -sDEVICE=pnm -sOutputFile="
#define MAILPROJECT "mailproject"
#define MAILCOMMAND "sendmail"
@@ -534,7 +533,7 @@ extern void xsane_batch_scan_add(void);
enum
{
XSANE_UNKNOWN, XSANE_PNM, XSANE_JPEG, XSANE_PNG, XSANE_PS, XSANE_TIFF, XSANE_RGBA,
- XSANE_RAW16, XSANE_PNM16, XSANE_TEXT
+ XSANE_RAW16, XSANE_PNM16, XSANE_TEXT, XSANE_PDF
};
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -685,7 +684,6 @@ typedef struct Xsane
Preview *preview;
int preview_gamma_size;
int mode;
- int medium_nr;
int main_window_fixed;
int mode_selection;
@@ -713,7 +711,7 @@ typedef struct Xsane
/* saving and transformation values: */
FILE *out;
- int xsane_mode;
+// int xsane_mode;
int xsane_output_format;
long header_size;
int expand_lineart_to_grayscale;