diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 2 | ||||
-rw-r--r-- | src/xsane-back-gtk.c | 31 | ||||
-rw-r--r-- | src/xsane-batch-scan.c | 5 | ||||
-rw-r--r-- | src/xsane-fixedtext.h | 2 | ||||
-rw-r--r-- | src/xsane-front-gtk.c | 39 | ||||
-rw-r--r-- | src/xsane-preferences.c | 4 | ||||
-rw-r--r-- | src/xsane-preferences.h | 2 | ||||
-rw-r--r-- | src/xsane-preview.c | 15 | ||||
-rw-r--r-- | src/xsane-save.c | 720 | ||||
-rw-r--r-- | src/xsane-save.h | 4 | ||||
-rw-r--r-- | src/xsane-scan.c | 80 | ||||
-rw-r--r-- | src/xsane-text.h | 1 | ||||
-rw-r--r-- | src/xsane-viewer.c | 5 | ||||
-rw-r--r-- | src/xsane.c | 251 | ||||
-rw-r--r-- | src/xsane.h | 8 |
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; |