2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
* PostScript file plugin
|
|
|
|
* PostScript writing and GhostScript interfacing code
|
1999-01-04 06:41:12 +08:00
|
|
|
* Copyright (C) 1997-98 Peter Kirchgessner
|
|
|
|
* (email: peter@kirchgessner.net, WWW: http://www.kirchgessner.net)
|
1997-11-25 06:05:25 +08:00
|
|
|
*
|
|
|
|
* Added controls for TextAlphaBits and GraphicsAlphaBits
|
|
|
|
* George White <aa056@chebucto.ns.ca>
|
|
|
|
*
|
2000-01-23 06:26:20 +08:00
|
|
|
* Added Ascii85 encoding
|
|
|
|
* Austin Donnelly <austin@gimp.org>
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
1997-11-25 06:05:25 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
1997-11-25 06:05:25 +08:00
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2018-07-12 05:27:07 +08:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
1997-11-25 06:05:25 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Event history:
|
|
|
|
* V 0.90, PK, 28-Mar-97: Creation.
|
|
|
|
* V 0.91, PK, 03-Apr-97: Clip everything outside BoundingBox.
|
|
|
|
* 24-Apr-97: Multi page read support.
|
|
|
|
* V 1.00, PK, 30-Apr-97: PDF support.
|
|
|
|
* V 1.01, PK, 05-Oct-97: Parse rc-file.
|
|
|
|
* V 1.02, GW, 09-Oct-97: Antialiasing support.
|
|
|
|
* PK, 11-Oct-97: No progress bars when running non-interactive.
|
|
|
|
* New procedure file_ps_load_setargs to set
|
|
|
|
* load-arguments non-interactively.
|
|
|
|
* If GS_OPTIONS are not set, use at least "-dSAFER"
|
1997-12-26 15:08:20 +08:00
|
|
|
* V 1.03, nn, 20-Dec-97: Initialize some variables
|
|
|
|
* V 1.04, PK, 20-Dec-97: Add Encapsulated PostScript output and preview
|
1999-01-04 06:41:12 +08:00
|
|
|
* V 1.05, PK, 21-Sep-98: Write b/w-images (indexed) using image-operator
|
|
|
|
* V 1.06, PK, 22-Dec-98: Fix problem with writing color PS files.
|
|
|
|
* Ghostview may hang when displaying the files.
|
1999-09-15 04:54:02 +08:00
|
|
|
* V 1.07, PK, 14-Sep-99: Add resolution to image
|
2000-01-23 06:26:20 +08:00
|
|
|
* V 1.08, PK, 16-Jan-2000: Add PostScript-Level 2 by Austin Donnelly
|
2000-03-11 01:27:25 +08:00
|
|
|
* V 1.09, PK, 15-Feb-2000: Force showpage on EPS-files
|
|
|
|
* Add "RunLength" compression
|
|
|
|
* Fix problem with "Level 2" toggle
|
2000-04-05 18:26:08 +08:00
|
|
|
* V 1.10, PK, 15-Mar-2000: For load EPSF, allow negative Bounding Box Values
|
2018-04-19 02:57:03 +08:00
|
|
|
* Save PS: don't start lines of image data with %%
|
2000-03-26 06:19:17 +08:00
|
|
|
* to prevent problems with stupid PostScript
|
|
|
|
* analyzer programs (Stanislav Brabec)
|
2000-04-05 18:26:08 +08:00
|
|
|
* Add BeginData/EndData comments
|
|
|
|
* Save PS: Set default rotation to 0
|
2000-08-21 07:26:11 +08:00
|
|
|
* V 1.11, PK, 20-Aug-2000: Fix problem with BoundingBox recognition
|
|
|
|
* for Mac files.
|
|
|
|
* Fix problem with loop when reading not all
|
|
|
|
* images of a multi page file.
|
2000-10-07 02:16:58 +08:00
|
|
|
* PK, 31-Aug-2000: Load PS: Add checks for space in filename.
|
2001-06-21 17:25:06 +08:00
|
|
|
* V 1.12 PK, 19-Jun-2001: Fix problem with command line switch --
|
|
|
|
* (reported by Ferenc Wagner)
|
2002-04-11 18:58:19 +08:00
|
|
|
* V 1.13 PK, 07-Apr-2002: Fix problem with DOS binary EPS files
|
2002-05-15 04:04:29 +08:00
|
|
|
* V 1.14 PK, 14-May-2002: Workaround EPS files of Adb. Ill. 8.0
|
2002-10-08 18:53:10 +08:00
|
|
|
* V 1.15 PK, 04-Oct-2002: Be more accurate with using BoundingBox
|
2004-01-26 07:46:24 +08:00
|
|
|
* V 1.16 PK, 22-Jan-2004: Don't use popen(), use g_spawn_async_with_pipes()
|
|
|
|
* or g_spawn_sync().
|
2004-09-19 18:54:48 +08:00
|
|
|
* V 1.17 PK, 19-Sep-2004: Fix problem with interpretation of bounding box
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
|
1999-05-30 00:35:47 +08:00
|
|
|
#include "config.h"
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2003-06-13 22:37:00 +08:00
|
|
|
#include <errno.h>
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2004-01-26 07:46:24 +08:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2005-03-04 23:12:29 +08:00
|
|
|
#include <glib/gstdio.h>
|
|
|
|
|
2000-01-08 23:23:28 +08:00
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include <libgimp/gimpui.h>
|
|
|
|
|
1999-05-30 00:35:47 +08:00
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
2012-01-22 12:26:08 +08:00
|
|
|
#include <ghostscript/ierrors.h>
|
|
|
|
#include <ghostscript/iapi.h>
|
|
|
|
#include <ghostscript/gdevdsp.h>
|
2004-01-26 07:46:24 +08:00
|
|
|
|
2008-12-04 00:07:32 +08:00
|
|
|
#define VERSIO 1.17
|
|
|
|
static const gchar dversio[] = "v1.17 19-Sep-2004";
|
2004-01-26 07:46:24 +08:00
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
#define LOAD_PS_PROC "file-ps-load"
|
|
|
|
#define LOAD_EPS_PROC "file-eps-load"
|
|
|
|
#define LOAD_PS_SETARGS_PROC "file-ps-load-setargs"
|
|
|
|
#define LOAD_PS_THUMB_PROC "file-ps-load-thumb"
|
|
|
|
#define SAVE_PS_PROC "file-ps-save"
|
|
|
|
#define SAVE_EPS_PROC "file-eps-save"
|
2008-08-11 18:06:13 +08:00
|
|
|
#define PLUG_IN_BINARY "file-ps"
|
2011-04-09 02:31:34 +08:00
|
|
|
#define PLUG_IN_ROLE "gimp-file-ps"
|
2005-08-15 18:30:39 +08:00
|
|
|
|
|
|
|
|
2014-02-22 16:40:49 +08:00
|
|
|
#define STR_LENGTH 64
|
|
|
|
#define MIN_RESOLUTION 5
|
|
|
|
#define MAX_RESOLUTION 8192
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Load info */
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-11-13 04:52:17 +08:00
|
|
|
guint resolution; /* resolution (dpi) at which to run ghostscript */
|
|
|
|
guint width, height; /* desired size (ghostscript may ignore this) */
|
|
|
|
gboolean use_bbox; /* 0: use width/height, 1: try to use BoundingBox */
|
|
|
|
gchar pages[STR_LENGTH]; /* Pages to load (eg.: 1,3,5-7) */
|
|
|
|
gint pnm_type; /* 4: pbm, 5: pgm, 6: ppm, 7: automatic */
|
|
|
|
gint textalpha; /* antialiasing: 1,2, or 4 TextAlphaBits */
|
|
|
|
gint graphicsalpha; /* antialiasing: 1,2, or 4 GraphicsAlphaBits */
|
1997-11-25 06:05:25 +08:00
|
|
|
} PSLoadVals;
|
|
|
|
|
|
|
|
static PSLoadVals plvals =
|
|
|
|
{
|
2004-11-19 05:36:10 +08:00
|
|
|
100, /* 100 dpi */
|
|
|
|
826, 1170, /* default width/height (A4) */
|
2007-11-13 04:52:17 +08:00
|
|
|
TRUE, /* try to use BoundingBox */
|
2004-11-19 05:36:10 +08:00
|
|
|
"1", /* pages to load */
|
2013-06-07 05:26:16 +08:00
|
|
|
6, /* use ppm (color) */
|
2018-04-19 02:57:03 +08:00
|
|
|
1, /* don't use text antialiasing */
|
|
|
|
1 /* don't use graphics antialiasing */
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2016-03-20 05:45:16 +08:00
|
|
|
/* Widgets for width and height of PostScript image to
|
2007-03-01 20:48:00 +08:00
|
|
|
* be loaded, so that they can be updated when desired resolution is
|
|
|
|
* changed
|
|
|
|
*/
|
2008-12-04 00:07:32 +08:00
|
|
|
static GtkWidget *ps_width_spinbutton;
|
|
|
|
static GtkWidget *ps_height_spinbutton;
|
2007-05-15 15:12:15 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Save info */
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-11-13 04:52:17 +08:00
|
|
|
gdouble width, height; /* Size of image */
|
|
|
|
gdouble x_offset, y_offset; /* Offset to image on page */
|
|
|
|
gboolean unit_mm; /* Unit of measure (0: inch, 1: mm) */
|
|
|
|
gboolean keep_ratio; /* Keep aspect ratio */
|
|
|
|
gint rotate; /* Rotation (0, 90, 180, 270) */
|
|
|
|
gint level; /* PostScript Level */
|
|
|
|
gboolean eps; /* Encapsulated PostScript flag */
|
|
|
|
gboolean preview; /* Preview Flag */
|
|
|
|
gint preview_size; /* Preview size */
|
1997-11-25 06:05:25 +08:00
|
|
|
} PSSaveVals;
|
|
|
|
|
|
|
|
static PSSaveVals psvals =
|
|
|
|
{
|
|
|
|
287.0, 200.0, /* Image size (A4) */
|
|
|
|
5.0, 5.0, /* Offset */
|
2007-11-13 04:52:17 +08:00
|
|
|
TRUE, /* Unit is mm */
|
|
|
|
TRUE, /* Keep edge ratio */
|
2000-04-05 18:26:08 +08:00
|
|
|
0, /* Rotate */
|
2000-01-23 06:26:20 +08:00
|
|
|
2, /* PostScript Level */
|
2007-11-13 04:52:17 +08:00
|
|
|
FALSE, /* Encapsulated PostScript flag */
|
|
|
|
FALSE, /* Preview flag */
|
1997-12-26 15:08:20 +08:00
|
|
|
256 /* Preview size */
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2008-12-04 00:07:32 +08:00
|
|
|
static const char hex[] = "0123456789abcdef";
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Declare some local functions.
|
|
|
|
*/
|
2014-10-27 01:54:42 +08:00
|
|
|
static void query (void);
|
|
|
|
static void run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals);
|
|
|
|
|
|
|
|
static gint32 load_image (const gchar *filename,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_image (GFile *file,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
|
|
|
|
static gboolean save_ps_header (GOutputStream *output,
|
|
|
|
GFile *file,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_ps_setup (GOutputStream *output,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint bpp,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_ps_trailer (GOutputStream *output,
|
|
|
|
GError **error);
|
|
|
|
|
|
|
|
static gboolean save_ps_preview (GOutputStream *output,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
|
|
|
|
static gboolean save_gray (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_bw (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_index (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
static gboolean save_rgb (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error);
|
|
|
|
|
|
|
|
static gboolean print (GOutputStream *output,
|
|
|
|
GError **error,
|
|
|
|
const gchar *format,
|
|
|
|
...) G_GNUC_PRINTF (3, 4);
|
|
|
|
|
|
|
|
static gint32 create_new_image (const gchar *filename,
|
|
|
|
guint pagenum,
|
|
|
|
guint width,
|
|
|
|
guint height,
|
|
|
|
GimpImageBaseType type,
|
|
|
|
gint32 *layer_ID);
|
|
|
|
|
|
|
|
static void check_load_vals (void);
|
|
|
|
static void check_save_vals (void);
|
|
|
|
|
|
|
|
static gint page_in_list (gchar *list,
|
|
|
|
guint pagenum);
|
|
|
|
|
|
|
|
static gint get_bbox (const gchar *filename,
|
|
|
|
gint *x0,
|
|
|
|
gint *y0,
|
|
|
|
gint *x1,
|
|
|
|
gint *y1);
|
|
|
|
|
|
|
|
static FILE * ps_open (const gchar *filename,
|
|
|
|
const PSLoadVals *loadopt,
|
|
|
|
gint *llx,
|
|
|
|
gint *lly,
|
|
|
|
gint *urx,
|
|
|
|
gint *ury,
|
|
|
|
gboolean *is_epsf);
|
|
|
|
|
|
|
|
static void ps_close (FILE *ifp);
|
|
|
|
|
|
|
|
static gboolean skip_ps (FILE *ifp);
|
|
|
|
|
|
|
|
static gint32 load_ps (const gchar *filename,
|
|
|
|
guint pagenum,
|
|
|
|
FILE *ifp,
|
|
|
|
gint llx,
|
|
|
|
gint lly,
|
|
|
|
gint urx,
|
|
|
|
gint ury);
|
|
|
|
|
|
|
|
static void dither_grey (const guchar *grey,
|
|
|
|
guchar *bw,
|
|
|
|
gint npix,
|
|
|
|
gint linecount);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* Dialog-handling */
|
1999-10-04 02:54:54 +08:00
|
|
|
|
2007-03-01 20:48:00 +08:00
|
|
|
static gint32 count_ps_pages (const gchar *filename);
|
2017-12-14 03:35:41 +08:00
|
|
|
static gboolean load_dialog (const gchar *filename);
|
2007-03-01 20:48:00 +08:00
|
|
|
static void load_pages_entry_callback (GtkWidget *widget,
|
|
|
|
gpointer data);
|
2007-05-15 15:12:15 +08:00
|
|
|
|
2007-03-01 20:48:00 +08:00
|
|
|
static gboolean resolution_change_callback (GtkAdjustment *adjustment,
|
|
|
|
gpointer data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2014-06-23 05:01:31 +08:00
|
|
|
GtkAdjustment *adjustment[4];
|
|
|
|
gint level;
|
1997-11-25 06:05:25 +08:00
|
|
|
} SaveDialogVals;
|
|
|
|
|
2004-05-20 01:53:21 +08:00
|
|
|
static gboolean save_dialog (void);
|
|
|
|
static void save_unit_toggle_update (GtkWidget *widget,
|
|
|
|
gpointer data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-05-16 20:26:20 +08:00
|
|
|
const GimpPlugInInfo PLUG_IN_INFO =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
NULL, /* init_proc */
|
|
|
|
NULL, /* quit_proc */
|
|
|
|
query, /* query_proc */
|
|
|
|
run, /* run_proc */
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* The run mode */
|
2001-12-19 08:13:16 +08:00
|
|
|
static GimpRunMode l_run_mode;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-27 20:28:46 +08:00
|
|
|
static void compress_packbits (int nin,
|
2000-03-11 01:27:25 +08:00
|
|
|
unsigned char *src,
|
2003-11-27 20:28:46 +08:00
|
|
|
int *nout,
|
2000-03-11 01:27:25 +08:00
|
|
|
unsigned char *dst);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-10-28 22:57:32 +08:00
|
|
|
static guint32 ascii85_buf = 0;
|
|
|
|
static gint ascii85_len = 0;
|
|
|
|
static gint ascii85_linewidth = 0;
|
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
static GimpPageSelectorTarget ps_pagemode = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
|
2000-01-23 06:26:20 +08:00
|
|
|
|
|
|
|
static void
|
|
|
|
ascii85_init (void)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
ascii85_len = 0;
|
2000-01-26 01:46:56 +08:00
|
|
|
ascii85_linewidth = 0;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
ascii85_flush (GOutputStream *output,
|
|
|
|
GError **error)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
gchar c[5];
|
|
|
|
gint i;
|
2000-01-26 01:46:56 +08:00
|
|
|
gboolean zero_case = (ascii85_buf == 0);
|
2014-10-27 01:54:42 +08:00
|
|
|
GString *string = g_string_new (NULL);
|
|
|
|
|
|
|
|
static gint max_linewidth = 75;
|
2000-01-23 06:26:20 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
for (i = 4; i >= 0; i--)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
c[i] = (ascii85_buf % 85) + '!';
|
|
|
|
ascii85_buf /= 85;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* check for special case: "!!!!!" becomes "z", but only if not
|
|
|
|
* at end of data. */
|
|
|
|
if (zero_case && (ascii85_len == 4))
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2000-03-26 06:19:17 +08:00
|
|
|
if (ascii85_linewidth >= max_linewidth)
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
g_string_append_c (string, '\n');
|
|
|
|
|
|
|
|
ascii85_linewidth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_append_c (string, 'z');
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
ascii85_linewidth++;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
for (i = 0; i < ascii85_len + 1; i++)
|
2000-03-26 06:19:17 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((ascii85_linewidth >= max_linewidth) && (c[i] != '%'))
|
|
|
|
{
|
|
|
|
g_string_append_c (string, '\n');
|
|
|
|
|
|
|
|
ascii85_linewidth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_append_c (string, c[i]);
|
|
|
|
|
|
|
|
ascii85_linewidth++;
|
2000-03-26 06:19:17 +08:00
|
|
|
}
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
ascii85_len = 0;
|
|
|
|
ascii85_buf = 0;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (string->len > 0 &&
|
|
|
|
! g_output_stream_write_all (output,
|
|
|
|
string->str, string->len, NULL,
|
|
|
|
NULL, error))
|
|
|
|
{
|
|
|
|
g_string_free (string, TRUE);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_free (string, TRUE);
|
|
|
|
|
|
|
|
return TRUE;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static inline gboolean
|
|
|
|
ascii85_out (GOutputStream *output,
|
|
|
|
guchar byte,
|
|
|
|
GError **error)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
if (ascii85_len == 4)
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! ascii85_flush (output, error))
|
|
|
|
return FALSE;
|
2000-01-23 06:26:20 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
ascii85_buf <<= 8;
|
|
|
|
ascii85_buf |= byte;
|
|
|
|
ascii85_len++;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
ascii85_nout (GOutputStream *output,
|
|
|
|
gint n,
|
|
|
|
guchar *uptr,
|
|
|
|
GError **error)
|
2000-03-11 01:27:25 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
while (n-- > 0)
|
|
|
|
{
|
|
|
|
if (! ascii85_out (output, *uptr, error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
uptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2000-03-11 01:27:25 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
ascii85_done (GOutputStream *output,
|
|
|
|
GError **error)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
if (ascii85_len)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
/* zero any unfilled buffer portion, then flush */
|
2014-10-27 01:54:42 +08:00
|
|
|
ascii85_buf <<= (8 * (4 - ascii85_len));
|
|
|
|
|
|
|
|
if (! ascii85_flush (output, error))
|
|
|
|
return FALSE;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "~>\n"))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
2000-01-23 06:26:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
static void
|
|
|
|
compress_packbits (int nin,
|
|
|
|
unsigned char *src,
|
|
|
|
int *nout,
|
|
|
|
unsigned char *dst)
|
|
|
|
|
2013-05-15 02:52:38 +08:00
|
|
|
{
|
|
|
|
unsigned char c;
|
2000-03-11 01:27:25 +08:00
|
|
|
int nrepeat, nliteral;
|
|
|
|
unsigned char *run_start;
|
|
|
|
unsigned char *start_dst = dst;
|
|
|
|
unsigned char *last_literal = NULL;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (nin <= 0) break;
|
|
|
|
|
|
|
|
run_start = src;
|
|
|
|
c = *run_start;
|
|
|
|
|
|
|
|
/* Search repeat bytes */
|
|
|
|
if ((nin > 1) && (c == src[1]))
|
|
|
|
{
|
|
|
|
nrepeat = 1;
|
|
|
|
nin -= 2;
|
|
|
|
src += 2;
|
|
|
|
while ((nin > 0) && (c == *src))
|
|
|
|
{
|
|
|
|
nrepeat++;
|
|
|
|
src++;
|
|
|
|
nin--;
|
|
|
|
if (nrepeat == 127) break; /* Maximum repeat */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add two-byte repeat to last literal run ? */
|
|
|
|
if ( (nrepeat == 1)
|
|
|
|
&& (last_literal != NULL) && (((*last_literal)+1)+2 <= 128))
|
|
|
|
{
|
|
|
|
*last_literal += 2;
|
|
|
|
*(dst++) = c;
|
|
|
|
*(dst++) = c;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add repeat run */
|
|
|
|
*(dst++) = (unsigned char)((-nrepeat) & 0xff);
|
|
|
|
*(dst++) = c;
|
|
|
|
last_literal = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Search literal bytes */
|
|
|
|
nliteral = 1;
|
|
|
|
nin--;
|
|
|
|
src++;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
if (nin <= 0) break;
|
|
|
|
|
|
|
|
if ((nin >= 2) && (src[0] == src[1])) /* A two byte repeat ? */
|
|
|
|
break;
|
|
|
|
|
|
|
|
nliteral++;
|
|
|
|
nin--;
|
|
|
|
src++;
|
|
|
|
if (nliteral == 128) break; /* Maximum literal run */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Could be added to last literal run ? */
|
|
|
|
if ((last_literal != NULL) && (((*last_literal)+1)+nliteral <= 128))
|
|
|
|
{
|
|
|
|
*last_literal += nliteral;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
last_literal = dst;
|
|
|
|
*(dst++) = (unsigned char)(nliteral-1);
|
|
|
|
}
|
|
|
|
while (nliteral-- > 0) *(dst++) = *(run_start++);
|
|
|
|
}
|
|
|
|
*nout = dst - start_dst;
|
|
|
|
}
|
|
|
|
|
2000-01-23 06:26:20 +08:00
|
|
|
|
2000-04-05 18:26:08 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
goffset eol;
|
|
|
|
goffset begin_data;
|
2000-04-05 18:26:08 +08:00
|
|
|
} PS_DATA_POS;
|
|
|
|
|
|
|
|
static PS_DATA_POS ps_data_pos = { 0, 0 };
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
ps_begin_data (GOutputStream *output,
|
|
|
|
GError **error)
|
2000-04-05 18:26:08 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
/* %%BeginData: 123456789012 ASCII Bytes */
|
|
|
|
if (! print (output, error, "%s", "%%BeginData: "))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ps_data_pos.eol = g_seekable_tell (G_SEEKABLE (output));
|
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
ps_data_pos.begin_data = g_seekable_tell (G_SEEKABLE (output));
|
|
|
|
|
|
|
|
return TRUE;
|
2000-04-05 18:26:08 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
ps_end_data (GOutputStream *output,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
goffset end_data;
|
|
|
|
gchar s[64];
|
2000-04-05 18:26:08 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((ps_data_pos.begin_data > 0) && (ps_data_pos.eol > 0))
|
|
|
|
{
|
|
|
|
end_data = g_seekable_tell (G_SEEKABLE (output));
|
2000-04-05 18:26:08 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (end_data > 0)
|
|
|
|
{
|
|
|
|
g_snprintf (s, sizeof (s),
|
|
|
|
"%ld ASCII Bytes", end_data - ps_data_pos.begin_data);
|
|
|
|
|
|
|
|
if (! g_seekable_seek (G_SEEKABLE (output),
|
|
|
|
ps_data_pos.eol - strlen (s), G_SEEK_SET,
|
|
|
|
NULL, error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (! print (output, error, "%s", s))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (! g_seekable_seek (G_SEEKABLE (output),
|
|
|
|
end_data, G_SEEK_SET,
|
|
|
|
NULL, error))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! print (output, error, "%s\n", "%%EndData"))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
2000-04-05 18:26:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
MAIN ()
|
|
|
|
|
|
|
|
static void
|
|
|
|
query (void)
|
|
|
|
{
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef load_args[] =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2009-01-20 04:11:36 +08:00
|
|
|
{ GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
|
2005-08-15 18:30:39 +08:00
|
|
|
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
|
|
|
|
{ GIMP_PDB_STRING, "raw-filename", "The name of the file to load" }
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef load_return_vals[] =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2004-11-19 03:00:02 +08:00
|
|
|
{ GIMP_PDB_IMAGE, "image", "Output image" }
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef set_load_args[] =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2018-04-26 02:31:11 +08:00
|
|
|
{ GIMP_PDB_INT32, "resolution", "Resolution to interpret image (dpi)" },
|
2005-08-15 18:30:39 +08:00
|
|
|
{ GIMP_PDB_INT32, "width", "Desired width" },
|
|
|
|
{ GIMP_PDB_INT32, "height", "Desired height" },
|
|
|
|
{ GIMP_PDB_INT32, "check-bbox", "0: Use width/height, 1: Use BoundingBox" },
|
|
|
|
{ GIMP_PDB_STRING, "pages", "Pages to load (e.g.: 1,3,5-7)" },
|
2013-06-07 05:26:16 +08:00
|
|
|
{ GIMP_PDB_INT32, "coloring", "4: b/w, 5: grey, 6: color image, 7: automatic" },
|
2007-05-29 23:29:37 +08:00
|
|
|
{ GIMP_PDB_INT32, "text-alpha-bits", "1, 2, or 4" },
|
|
|
|
{ GIMP_PDB_INT32, "graphic-alpha-bits", "1, 2, or 4" }
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef thumb_args[] =
|
2004-11-19 03:00:02 +08:00
|
|
|
{
|
|
|
|
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
|
2005-08-15 18:30:39 +08:00
|
|
|
{ GIMP_PDB_INT32, "thumb-size", "Preferred thumbnail size" }
|
2004-11-19 03:00:02 +08:00
|
|
|
};
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef thumb_return_vals[] =
|
2004-11-19 03:00:02 +08:00
|
|
|
{
|
|
|
|
{ GIMP_PDB_IMAGE, "image", "Output image" }
|
|
|
|
};
|
|
|
|
|
2006-05-16 20:26:20 +08:00
|
|
|
static const GimpParamDef save_args[] =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2009-01-20 04:11:36 +08:00
|
|
|
{ GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
|
2005-08-15 18:30:39 +08:00
|
|
|
{ GIMP_PDB_IMAGE, "image", "Input image" },
|
2016-02-16 09:35:43 +08:00
|
|
|
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to export" },
|
|
|
|
{ GIMP_PDB_STRING, "filename", "The name of the file to export the image in" },
|
|
|
|
{ GIMP_PDB_STRING, "raw-filename", "The name of the file to export the image in" },
|
2005-08-15 18:30:39 +08:00
|
|
|
{ GIMP_PDB_FLOAT, "width", "Width of the image in PostScript file (0: use input image size)" },
|
|
|
|
{ GIMP_PDB_FLOAT, "height", "Height of image in PostScript file (0: use input image size)" },
|
|
|
|
{ GIMP_PDB_FLOAT, "x-offset", "X-offset to image from lower left corner" },
|
|
|
|
{ GIMP_PDB_FLOAT, "y-offset", "Y-offset to image from lower left corner" },
|
|
|
|
{ GIMP_PDB_INT32, "unit", "Unit for width/height/offset. 0: inches, 1: millimeters" },
|
|
|
|
{ GIMP_PDB_INT32, "keep-ratio", "0: use width/height, 1: keep aspect ratio" },
|
|
|
|
{ GIMP_PDB_INT32, "rotation", "0, 90, 180, 270" },
|
|
|
|
{ GIMP_PDB_INT32, "eps-flag", "0: PostScript, 1: Encapsulated PostScript" },
|
|
|
|
{ GIMP_PDB_INT32, "preview", "0: no preview, >0: max. size of preview" },
|
|
|
|
{ GIMP_PDB_INT32, "level", "1: PostScript Level 1, 2: PostScript Level 2" }
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (LOAD_PS_PROC,
|
2004-05-14 08:01:11 +08:00
|
|
|
"load PostScript documents",
|
|
|
|
"load PostScript documents",
|
1999-09-15 04:54:02 +08:00
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
1997-11-25 06:05:25 +08:00
|
|
|
"Peter Kirchgessner",
|
1997-12-26 15:08:20 +08:00
|
|
|
dversio,
|
2004-05-14 08:01:11 +08:00
|
|
|
N_("PostScript document"),
|
1997-11-25 06:05:25 +08:00
|
|
|
NULL,
|
2000-08-22 09:26:57 +08:00
|
|
|
GIMP_PLUGIN,
|
2001-12-06 10:28:58 +08:00
|
|
|
G_N_ELEMENTS (load_args),
|
|
|
|
G_N_ELEMENTS (load_return_vals),
|
1997-11-25 06:05:25 +08:00
|
|
|
load_args, load_return_vals);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_file_handler_mime (LOAD_PS_PROC, "application/postscript");
|
|
|
|
gimp_register_magic_load_handler (LOAD_PS_PROC,
|
2006-05-08 20:23:32 +08:00
|
|
|
"ps",
|
|
|
|
"",
|
2004-05-14 08:01:11 +08:00
|
|
|
"0,string,%!,0,long,0xc5d0d3c6");
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (LOAD_EPS_PROC,
|
2004-05-14 08:01:11 +08:00
|
|
|
"load Encapsulated PostScript images",
|
|
|
|
"load Encapsulated PostScript images",
|
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
|
|
|
"Peter Kirchgessner",
|
|
|
|
dversio,
|
|
|
|
N_("Encapsulated PostScript image"),
|
|
|
|
NULL,
|
|
|
|
GIMP_PLUGIN,
|
|
|
|
G_N_ELEMENTS (load_args),
|
|
|
|
G_N_ELEMENTS (load_return_vals),
|
|
|
|
load_args, load_return_vals);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_file_handler_mime (LOAD_EPS_PROC, "image/x-eps");
|
|
|
|
gimp_register_magic_load_handler (LOAD_EPS_PROC,
|
2006-05-08 20:23:32 +08:00
|
|
|
"eps",
|
|
|
|
"",
|
2004-05-14 08:01:11 +08:00
|
|
|
"0,string,%!,0,long,0xc5d0d3c6");
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (LOAD_PS_SETARGS_PROC,
|
2006-08-29 21:32:22 +08:00
|
|
|
"set additional parameters for procedure file-ps-load",
|
|
|
|
"set additional parameters for procedure file-ps-load",
|
1999-09-15 04:54:02 +08:00
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
1997-11-25 06:05:25 +08:00
|
|
|
"Peter Kirchgessner",
|
1997-12-26 15:08:20 +08:00
|
|
|
dversio,
|
1997-11-25 06:05:25 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2000-08-22 09:26:57 +08:00
|
|
|
GIMP_PLUGIN,
|
2001-12-06 10:28:58 +08:00
|
|
|
G_N_ELEMENTS (set_load_args), 0,
|
1997-11-25 06:05:25 +08:00
|
|
|
set_load_args, NULL);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (LOAD_PS_THUMB_PROC,
|
2006-08-29 21:32:22 +08:00
|
|
|
"Loads a small preview from a PostScript or PDF document",
|
2004-11-19 03:00:02 +08:00
|
|
|
"",
|
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
|
|
|
"Peter Kirchgessner",
|
|
|
|
dversio,
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-11-19 03:00:02 +08:00
|
|
|
GIMP_PLUGIN,
|
|
|
|
G_N_ELEMENTS (thumb_args),
|
|
|
|
G_N_ELEMENTS (thumb_return_vals),
|
|
|
|
thumb_args, thumb_return_vals);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_thumbnail_loader (LOAD_PS_PROC, LOAD_PS_THUMB_PROC);
|
|
|
|
gimp_register_thumbnail_loader (LOAD_EPS_PROC, LOAD_PS_THUMB_PROC);
|
2005-07-03 03:58:49 +08:00
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (SAVE_PS_PROC,
|
2016-02-16 09:35:43 +08:00
|
|
|
"export image as PostScript document",
|
|
|
|
"PostScript exporting handles all image types except "
|
2005-08-15 18:30:39 +08:00
|
|
|
"those with alpha channels.",
|
2000-03-11 01:27:25 +08:00
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
1997-11-25 06:05:25 +08:00
|
|
|
"Peter Kirchgessner",
|
1997-12-26 15:08:20 +08:00
|
|
|
dversio,
|
2004-05-14 08:01:11 +08:00
|
|
|
N_("PostScript document"),
|
1999-10-04 02:54:54 +08:00
|
|
|
"RGB, GRAY, INDEXED",
|
2000-08-22 09:26:57 +08:00
|
|
|
GIMP_PLUGIN,
|
2001-12-06 10:28:58 +08:00
|
|
|
G_N_ELEMENTS (save_args), 0,
|
1997-11-25 06:05:25 +08:00
|
|
|
save_args, NULL);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_file_handler_mime (SAVE_PS_PROC, "application/postscript");
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_register_file_handler_uri (SAVE_PS_PROC);
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_save_handler (SAVE_PS_PROC, "ps", "");
|
2004-05-14 08:01:11 +08:00
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_install_procedure (SAVE_EPS_PROC,
|
2016-02-16 09:35:43 +08:00
|
|
|
"export image as Encapsulated PostScript image",
|
|
|
|
"PostScript exporting handles all image types except "
|
2005-08-15 18:30:39 +08:00
|
|
|
"those with alpha channels.",
|
2004-05-14 08:01:11 +08:00
|
|
|
"Peter Kirchgessner <peter@kirchgessner.net>",
|
|
|
|
"Peter Kirchgessner",
|
|
|
|
dversio,
|
|
|
|
N_("Encapsulated PostScript image"),
|
|
|
|
"RGB, GRAY, INDEXED",
|
|
|
|
GIMP_PLUGIN,
|
|
|
|
G_N_ELEMENTS (save_args), 0,
|
|
|
|
save_args, NULL);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_file_handler_mime (SAVE_EPS_PROC, "application/x-eps");
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_register_file_handler_uri (SAVE_EPS_PROC);
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_register_save_handler (SAVE_EPS_PROC, "eps", "");
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-09-15 04:54:02 +08:00
|
|
|
static void
|
|
|
|
ps_set_save_size (PSSaveVals *vals,
|
2000-01-26 01:46:56 +08:00
|
|
|
gint32 image_ID)
|
|
|
|
{
|
2000-02-08 04:35:13 +08:00
|
|
|
gdouble xres, yres, factor, iw, ih;
|
|
|
|
guint width, height;
|
|
|
|
GimpUnit unit;
|
1999-09-15 04:54:02 +08:00
|
|
|
|
|
|
|
gimp_image_get_resolution (image_ID, &xres, &yres);
|
2007-05-29 23:29:37 +08:00
|
|
|
|
2000-03-26 06:19:17 +08:00
|
|
|
if ((xres < 1e-5) || (yres < 1e-5))
|
2007-05-29 23:29:37 +08:00
|
|
|
xres = yres = 72.0;
|
|
|
|
|
1999-09-15 04:54:02 +08:00
|
|
|
/* Calculate size of image in inches */
|
2000-01-26 01:46:56 +08:00
|
|
|
width = gimp_image_width (image_ID);
|
1999-09-15 04:54:02 +08:00
|
|
|
height = gimp_image_height (image_ID);
|
2000-01-26 01:46:56 +08:00
|
|
|
iw = width / xres;
|
|
|
|
ih = height / yres;
|
|
|
|
|
|
|
|
unit = gimp_image_get_unit (image_ID);
|
|
|
|
factor = gimp_unit_get_factor (unit);
|
2007-11-13 04:52:17 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (factor == 0.0254 ||
|
|
|
|
factor == 0.254 ||
|
|
|
|
factor == 2.54 ||
|
|
|
|
factor == 25.4)
|
|
|
|
{
|
|
|
|
vals->unit_mm = TRUE;
|
|
|
|
}
|
|
|
|
|
1999-09-15 04:54:02 +08:00
|
|
|
if (vals->unit_mm)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
|
|
|
iw *= 25.4;
|
|
|
|
ih *= 25.4;
|
|
|
|
}
|
2007-11-13 04:52:17 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
vals->width = iw;
|
1999-09-15 04:54:02 +08:00
|
|
|
vals->height = ih;
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
2003-07-02 20:03:08 +08:00
|
|
|
run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2008-08-18 14:53:21 +08:00
|
|
|
static GimpParam values[2];
|
|
|
|
GimpRunMode run_mode;
|
|
|
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
|
|
|
gint32 image_ID = -1;
|
|
|
|
gint32 drawable_ID = -1;
|
|
|
|
gint32 orig_image_ID = -1;
|
|
|
|
GimpExportReturn export = GIMP_EXPORT_CANCEL;
|
|
|
|
GError *error = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
l_run_mode = run_mode = param[0].data.d_int32;
|
|
|
|
|
2003-03-26 00:38:19 +08:00
|
|
|
INIT_I18N ();
|
2013-05-13 20:31:35 +08:00
|
|
|
gegl_init (NULL, NULL);
|
2003-03-26 00:38:19 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
*nreturn_vals = 1;
|
2000-01-26 01:46:56 +08:00
|
|
|
*return_vals = values;
|
2004-11-19 03:00:02 +08:00
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2017-12-14 03:35:41 +08:00
|
|
|
if (strcmp (name, LOAD_PS_PROC) == 0 ||
|
|
|
|
strcmp (name, LOAD_EPS_PROC) == 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
switch (run_mode)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_INTERACTIVE:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Possibly retrieve data */
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_get_data (LOAD_PS_PROC, &plvals);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2017-12-14 03:35:41 +08:00
|
|
|
if (! load_dialog (param[1].data.d_string))
|
2006-05-08 20:23:32 +08:00
|
|
|
status = GIMP_PDB_CANCEL;
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_NONINTERACTIVE:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Make sure all the arguments are there! */
|
|
|
|
if (nparams != 3)
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
1997-11-25 06:05:25 +08:00
|
|
|
else /* Get additional interpretation arguments */
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_get_data (LOAD_PS_PROC, &plvals);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Possibly retrieve data */
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_get_data (LOAD_PS_PROC, &plvals);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
check_load_vals ();
|
2008-08-18 14:53:21 +08:00
|
|
|
image_ID = load_image (param[1].data.d_string, &error);
|
2006-05-08 20:23:32 +08:00
|
|
|
|
|
|
|
if (image_ID != -1)
|
|
|
|
{
|
|
|
|
*nreturn_vals = 2;
|
|
|
|
values[1].type = GIMP_PDB_IMAGE;
|
|
|
|
values[1].data.d_image = image_ID;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = GIMP_PDB_EXECUTION_ERROR;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Store plvals data */
|
2000-08-22 09:26:57 +08:00
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
2006-05-08 20:23:32 +08:00
|
|
|
gimp_set_data (LOAD_PS_PROC, &plvals, sizeof (PSLoadVals));
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2005-08-15 18:30:39 +08:00
|
|
|
else if (strcmp (name, LOAD_PS_THUMB_PROC) == 0)
|
2004-11-19 03:00:02 +08:00
|
|
|
{
|
|
|
|
if (nparams < 2)
|
|
|
|
{
|
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
gint size = param[1].data.d_int32;
|
2004-11-19 03:00:02 +08:00
|
|
|
|
|
|
|
/* We should look for an embedded preview but for now we
|
|
|
|
* just load the document at a small resolution and the
|
|
|
|
* first page only.
|
|
|
|
*/
|
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
plvals.resolution = size / 4;
|
2004-11-19 03:00:02 +08:00
|
|
|
plvals.width = size;
|
|
|
|
plvals.height = size;
|
2018-06-19 21:37:54 +08:00
|
|
|
strncpy (plvals.pages, "1", sizeof (plvals.pages) - 1);
|
2004-11-19 03:00:02 +08:00
|
|
|
|
|
|
|
check_load_vals ();
|
2008-08-18 14:53:21 +08:00
|
|
|
image_ID = load_image (param[0].data.d_string, &error);
|
2004-11-19 03:00:02 +08:00
|
|
|
|
|
|
|
if (image_ID != -1)
|
|
|
|
{
|
2006-05-08 20:23:32 +08:00
|
|
|
*nreturn_vals = 2;
|
|
|
|
values[1].type = GIMP_PDB_IMAGE;
|
|
|
|
values[1].data.d_image = image_ID;
|
2004-11-19 03:00:02 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = GIMP_PDB_EXECUTION_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-08-15 18:30:39 +08:00
|
|
|
else if (strcmp (name, SAVE_PS_PROC) == 0 ||
|
|
|
|
strcmp (name, SAVE_EPS_PROC) == 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2005-08-15 18:30:39 +08:00
|
|
|
psvals.eps = strcmp (name, SAVE_PS_PROC);
|
2004-05-14 08:01:11 +08:00
|
|
|
|
2007-11-13 04:52:17 +08:00
|
|
|
image_ID = orig_image_ID = param[1].data.d_int32;
|
1999-10-04 02:54:54 +08:00
|
|
|
drawable_ID = param[2].data.d_int32;
|
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
/* eventually export the image */
|
1999-10-04 02:54:54 +08:00
|
|
|
switch (run_mode)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
case GIMP_RUN_INTERACTIVE:
|
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
|
|
|
gimp_ui_init (PLUG_IN_BINARY, FALSE);
|
2013-11-10 07:18:48 +08:00
|
|
|
|
|
|
|
export = gimp_export_image (&image_ID, &drawable_ID,
|
|
|
|
psvals.eps ? "EPS" : "PostScript",
|
|
|
|
GIMP_EXPORT_CAN_HANDLE_RGB |
|
|
|
|
GIMP_EXPORT_CAN_HANDLE_GRAY |
|
|
|
|
GIMP_EXPORT_CAN_HANDLE_INDEXED);
|
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
if (export == GIMP_EXPORT_CANCEL)
|
|
|
|
{
|
|
|
|
values[0].data.d_status = GIMP_PDB_CANCEL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1999-10-04 02:54:54 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
switch (run_mode)
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_INTERACTIVE:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Possibly retrieve data */
|
2004-05-14 08:01:11 +08:00
|
|
|
gimp_get_data (name, &psvals);
|
1997-12-26 15:08:20 +08:00
|
|
|
|
1999-10-04 02:54:54 +08:00
|
|
|
ps_set_save_size (&psvals, orig_image_ID);
|
2001-05-22 08:36:38 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* First acquire information with a dialog */
|
|
|
|
if (! save_dialog ())
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_CANCEL;
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_NONINTERACTIVE:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Make sure all the arguments are there! */
|
2000-01-23 06:26:20 +08:00
|
|
|
if (nparams != 15)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
psvals.width = param[5].data.d_float;
|
|
|
|
psvals.height = param[6].data.d_float;
|
|
|
|
psvals.x_offset = param[7].data.d_float;
|
|
|
|
psvals.y_offset = param[8].data.d_float;
|
|
|
|
psvals.unit_mm = (param[9].data.d_int32 != 0);
|
|
|
|
psvals.keep_ratio = (param[10].data.d_int32 != 0);
|
|
|
|
psvals.rotate = param[11].data.d_int32;
|
2007-11-13 04:52:17 +08:00
|
|
|
psvals.eps = (param[12].data.d_int32 != 0);
|
2006-05-08 20:23:32 +08:00
|
|
|
psvals.preview = (param[13].data.d_int32 != 0);
|
|
|
|
psvals.preview_size = param[13].data.d_int32;
|
|
|
|
psvals.level = param[14].data.d_int32;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Possibly retrieve data */
|
2004-05-14 08:01:11 +08:00
|
|
|
gimp_get_data (name, &psvals);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
if ((psvals.width == 0.0) || (psvals.height == 0.0))
|
|
|
|
ps_set_save_size (&psvals, orig_image_ID);
|
|
|
|
|
|
|
|
check_save_vals ();
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (save_image (g_file_new_for_uri (param[3].data.d_string),
|
|
|
|
image_ID, drawable_ID,
|
2008-08-18 14:53:21 +08:00
|
|
|
&error))
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
/* Store psvals data */
|
|
|
|
gimp_set_data (name, &psvals, sizeof (PSSaveVals));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = GIMP_PDB_EXECUTION_ERROR;
|
|
|
|
}
|
|
|
|
}
|
1999-10-04 02:54:54 +08:00
|
|
|
|
2000-08-24 22:17:34 +08:00
|
|
|
if (export == GIMP_EXPORT_EXPORT)
|
2006-05-08 20:23:32 +08:00
|
|
|
gimp_image_delete (image_ID);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2005-08-15 18:30:39 +08:00
|
|
|
else if (strcmp (name, LOAD_PS_SETARGS_PROC) == 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
/* Make sure all the arguments are there! */
|
|
|
|
if (nparams != 8)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
plvals.resolution = param[0].data.d_int32;
|
|
|
|
plvals.width = param[1].data.d_int32;
|
|
|
|
plvals.height = param[2].data.d_int32;
|
|
|
|
plvals.use_bbox = param[3].data.d_int32;
|
|
|
|
if (param[4].data.d_string != NULL)
|
|
|
|
strncpy (plvals.pages, param[4].data.d_string,
|
|
|
|
sizeof (plvals.pages));
|
|
|
|
else
|
|
|
|
plvals.pages[0] = '\0';
|
|
|
|
plvals.pages[sizeof (plvals.pages) - 1] = '\0';
|
|
|
|
plvals.pnm_type = param[5].data.d_int32;
|
|
|
|
plvals.textalpha = param[6].data.d_int32;
|
|
|
|
plvals.graphicsalpha = param[7].data.d_int32;
|
|
|
|
check_load_vals ();
|
|
|
|
|
|
|
|
gimp_set_data (LOAD_PS_PROC, &plvals, sizeof (PSLoadVals));
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2008-08-18 14:53:21 +08:00
|
|
|
if (status != GIMP_PDB_SUCCESS && error)
|
|
|
|
{
|
|
|
|
*nreturn_vals = 2;
|
|
|
|
values[1].type = GIMP_PDB_STRING;
|
|
|
|
values[1].data.d_string = error->message;
|
|
|
|
}
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
values[0].data.d_status = status;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gint32
|
2008-08-18 14:53:21 +08:00
|
|
|
load_image (const gchar *filename,
|
|
|
|
GError **error)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
gint32 image_ID = 0;
|
|
|
|
gint32 *image_list, *nl;
|
|
|
|
guint page_count;
|
|
|
|
FILE *ifp;
|
|
|
|
gchar *temp;
|
|
|
|
gint llx, lly, urx, ury;
|
|
|
|
gint k, n_images, max_images, max_pagenum;
|
|
|
|
gboolean is_epsf;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#ifdef PS_DEBUG
|
2000-01-26 01:46:56 +08:00
|
|
|
g_print ("load_image:\n resolution = %d\n", plvals.resolution);
|
|
|
|
g_print (" %dx%d pixels\n", plvals.width, plvals.height);
|
|
|
|
g_print (" BoundingBox: %d\n", plvals.use_bbox);
|
2013-06-07 05:26:16 +08:00
|
|
|
g_print (" Coloring: %d\n", plvals.pnm_type);
|
2000-01-26 01:46:56 +08:00
|
|
|
g_print (" TextAlphaBits: %d\n", plvals.textalpha);
|
|
|
|
g_print (" GraphicsAlphaBits: %d\n", plvals.graphicsalpha);
|
1997-11-25 06:05:25 +08:00
|
|
|
#endif
|
|
|
|
|
2014-07-23 22:39:00 +08:00
|
|
|
gimp_progress_init_printf (_("Opening '%s'"),
|
|
|
|
gimp_filename_to_utf8 (filename));
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Try to see if PostScript file is available */
|
2005-03-04 23:12:29 +08:00
|
|
|
ifp = g_fopen (filename, "r");
|
2000-01-26 01:46:56 +08:00
|
|
|
if (ifp == NULL)
|
|
|
|
{
|
2008-08-18 14:53:21 +08:00
|
|
|
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
|
|
|
|
_("Could not open '%s' for reading: %s"),
|
|
|
|
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
2003-06-13 22:37:00 +08:00
|
|
|
return -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
fclose (ifp);
|
|
|
|
|
2012-01-22 12:26:08 +08:00
|
|
|
ifp = ps_open (filename, &plvals, &llx, &lly, &urx, &ury, &is_epsf);
|
2000-01-26 01:46:56 +08:00
|
|
|
if (!ifp)
|
|
|
|
{
|
2008-08-20 22:00:44 +08:00
|
|
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR,
|
2016-03-20 05:45:16 +08:00
|
|
|
_("Could not interpret PostScript file '%s'"),
|
2008-08-20 22:00:44 +08:00
|
|
|
gimp_filename_to_utf8 (filename));
|
2004-11-19 05:10:12 +08:00
|
|
|
return -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2001-12-06 10:28:58 +08:00
|
|
|
image_list = g_new (gint32, 10);
|
2000-01-26 01:46:56 +08:00
|
|
|
n_images = 0;
|
|
|
|
max_images = 10;
|
|
|
|
|
|
|
|
max_pagenum = 9999; /* Try to get the maximum pagenumber to read */
|
2004-11-19 05:10:12 +08:00
|
|
|
if (is_epsf)
|
|
|
|
max_pagenum = 1;
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (!page_in_list (plvals.pages, max_pagenum)) /* Is there a limit in list ? */
|
|
|
|
{
|
|
|
|
max_pagenum = -1;
|
|
|
|
for (temp = plvals.pages; *temp != '\0'; temp++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
if ((*temp < '0') || (*temp > '9'))
|
2004-11-19 05:10:12 +08:00
|
|
|
continue; /* Search next digit */
|
2006-05-08 20:23:32 +08:00
|
|
|
sscanf (temp, "%d", &k);
|
|
|
|
if (k > max_pagenum)
|
2004-11-19 05:10:12 +08:00
|
|
|
max_pagenum = k;
|
2006-05-08 20:23:32 +08:00
|
|
|
while ((*temp >= '0') && (*temp <= '9'))
|
2004-11-19 05:10:12 +08:00
|
|
|
temp++;
|
2006-05-08 20:23:32 +08:00
|
|
|
temp--;
|
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
|
|
|
|
if (max_pagenum < 1)
|
|
|
|
max_pagenum = 9999;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Load all images */
|
|
|
|
for (page_count = 1; page_count <= max_pagenum; page_count++)
|
|
|
|
{
|
|
|
|
if (page_in_list (plvals.pages, page_count))
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
image_ID = load_ps (filename, page_count, ifp, llx, lly, urx, ury);
|
|
|
|
if (image_ID == -1)
|
2004-11-19 05:10:12 +08:00
|
|
|
break;
|
2001-05-22 08:36:38 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
gimp_image_set_resolution (image_ID,
|
2014-10-27 01:54:42 +08:00
|
|
|
(gdouble) plvals.resolution,
|
|
|
|
(gdouble) plvals.resolution);
|
2006-05-08 20:23:32 +08:00
|
|
|
|
|
|
|
if (n_images == max_images)
|
|
|
|
{
|
|
|
|
nl = (gint32 *) g_realloc (image_list,
|
|
|
|
(max_images+10)*sizeof (gint32));
|
|
|
|
if (nl == NULL) break;
|
|
|
|
image_list = nl;
|
|
|
|
max_images += 10;
|
|
|
|
}
|
|
|
|
image_list[n_images++] = image_ID;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else /* Skip an image */
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
image_ID = -1;
|
2006-05-08 20:23:32 +08:00
|
|
|
if (! skip_ps (ifp))
|
2004-11-19 05:10:12 +08:00
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
|
2012-01-22 12:26:08 +08:00
|
|
|
ps_close (ifp);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
if (ps_pagemode == GIMP_PAGE_SELECTOR_TARGET_LAYERS)
|
|
|
|
{
|
|
|
|
for (k = 0; k < n_images; k++)
|
|
|
|
{
|
|
|
|
gchar *name;
|
|
|
|
|
|
|
|
if (k == 0)
|
|
|
|
{
|
|
|
|
image_ID = image_list[0];
|
|
|
|
|
|
|
|
name = g_strdup_printf (_("%s-pages"), filename);
|
|
|
|
gimp_image_set_filename (image_ID, name);
|
|
|
|
g_free (name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gint32 current_layer;
|
|
|
|
gint32 tmp_ID;
|
|
|
|
|
|
|
|
tmp_ID = gimp_image_get_active_drawable (image_list[k]);
|
|
|
|
|
2010-07-09 18:27:36 +08:00
|
|
|
name = gimp_item_get_name (tmp_ID);
|
2005-08-15 16:48:45 +08:00
|
|
|
|
|
|
|
current_layer = gimp_layer_new_from_drawable (tmp_ID, image_ID);
|
2010-07-09 18:27:36 +08:00
|
|
|
gimp_item_set_name (current_layer, name);
|
2010-09-06 17:40:46 +08:00
|
|
|
gimp_image_insert_layer (image_ID, current_layer, -1, -1);
|
2005-08-15 16:48:45 +08:00
|
|
|
gimp_image_delete (image_list[k]);
|
|
|
|
|
|
|
|
g_free (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_image_undo_enable (image_ID);
|
|
|
|
}
|
|
|
|
else
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2005-08-15 16:48:45 +08:00
|
|
|
/* Display images in reverse order.
|
|
|
|
* The last will be displayed by GIMP itself
|
|
|
|
*/
|
|
|
|
for (k = n_images - 1; k >= 0; k--)
|
|
|
|
{
|
|
|
|
gimp_image_undo_enable (image_list[k]);
|
|
|
|
gimp_image_clean_all (image_list[k]);
|
|
|
|
|
|
|
|
if (l_run_mode != GIMP_RUN_NONINTERACTIVE && k > 0)
|
|
|
|
gimp_display_new (image_list[k]);
|
|
|
|
}
|
|
|
|
|
|
|
|
image_ID = (n_images > 0) ? image_list[0] : -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free (image_list);
|
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
return image_ID;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_image (GFile *file,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
GOutputStream *output;
|
2018-11-27 19:27:20 +08:00
|
|
|
GCancellable *cancellable;
|
2014-10-27 01:54:42 +08:00
|
|
|
GimpImageType drawable_type;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
drawable_type = gimp_drawable_type (drawable_ID);
|
|
|
|
|
2016-02-16 09:35:43 +08:00
|
|
|
/* Make sure we're not exporting an image with an alpha channel */
|
1997-11-25 06:05:25 +08:00
|
|
|
if (gimp_drawable_has_alpha (drawable_ID))
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2008-08-20 22:00:44 +08:00
|
|
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
2016-02-16 09:35:43 +08:00
|
|
|
_("PostScript export cannot handle images with alpha channels"));
|
2000-01-26 01:46:56 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
switch (drawable_type)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_INDEXED_IMAGE:
|
|
|
|
case GIMP_GRAY_IMAGE:
|
|
|
|
case GIMP_RGB_IMAGE:
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
default:
|
2014-10-27 01:54:42 +08:00
|
|
|
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
|
|
|
_("Cannot operate on unknown image types."));
|
2004-11-19 05:10:12 +08:00
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2016-02-16 09:35:43 +08:00
|
|
|
gimp_progress_init_printf (_("Exporting '%s'"),
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_file_get_utf8_name (file));
|
2014-07-23 22:39:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
output = G_OUTPUT_STREAM (g_file_replace (file,
|
|
|
|
NULL, FALSE, G_FILE_CREATE_NONE,
|
|
|
|
NULL, error));
|
|
|
|
if (output)
|
|
|
|
{
|
|
|
|
GOutputStream *buffered;
|
|
|
|
|
|
|
|
buffered = g_buffered_output_stream_new (output);
|
|
|
|
g_object_unref (output);
|
|
|
|
|
|
|
|
output = buffered;
|
|
|
|
}
|
|
|
|
else
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
return FALSE;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_header (output, file, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2011-10-10 12:26:32 +08:00
|
|
|
switch (drawable_type)
|
|
|
|
{
|
|
|
|
case GIMP_INDEXED_IMAGE:
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_index (output, image_ID, drawable_ID, error))
|
|
|
|
goto fail;
|
2011-10-10 12:26:32 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-10-10 12:26:32 +08:00
|
|
|
case GIMP_GRAY_IMAGE:
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_gray (output, image_ID, drawable_ID, error))
|
|
|
|
goto fail;
|
2011-10-10 12:26:32 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-10-10 12:26:32 +08:00
|
|
|
case GIMP_RGB_IMAGE:
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_rgb (output, image_ID, drawable_ID, error))
|
|
|
|
goto fail;
|
2011-10-10 12:26:32 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-10-10 12:26:32 +08:00
|
|
|
default:
|
2014-10-27 01:54:42 +08:00
|
|
|
g_return_val_if_reached (FALSE);
|
2011-10-10 12:26:32 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_trailer (output, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! g_output_stream_close (output, NULL, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
g_object_unref (output);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
2018-11-27 19:27:20 +08:00
|
|
|
cancellable = g_cancellable_new ();
|
|
|
|
g_cancellable_cancel (cancellable);
|
|
|
|
g_output_stream_close (output, cancellable, NULL);
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
g_object_unref (output);
|
2018-11-27 19:27:20 +08:00
|
|
|
g_object_unref (cancellable);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Check (and correct) the load values plvals */
|
|
|
|
static void
|
|
|
|
check_load_vals (void)
|
|
|
|
{
|
2014-02-22 16:40:49 +08:00
|
|
|
if (plvals.resolution < MIN_RESOLUTION)
|
|
|
|
plvals.resolution = MIN_RESOLUTION;
|
|
|
|
else if (plvals.resolution > MAX_RESOLUTION)
|
|
|
|
plvals.resolution = MAX_RESOLUTION;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
if (plvals.width < 2)
|
|
|
|
plvals.width = 2;
|
|
|
|
if (plvals.height < 2)
|
|
|
|
plvals.height = 2;
|
1997-11-25 06:05:25 +08:00
|
|
|
plvals.use_bbox = (plvals.use_bbox != 0);
|
|
|
|
if (plvals.pages[0] == '\0')
|
2018-06-19 21:37:54 +08:00
|
|
|
strncpy (plvals.pages, "1-99", sizeof (plvals.pages) - 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
if ((plvals.pnm_type < 4) || (plvals.pnm_type > 7))
|
|
|
|
plvals.pnm_type = 6;
|
|
|
|
if ( (plvals.textalpha != 1) && (plvals.textalpha != 2)
|
|
|
|
&& (plvals.textalpha != 4))
|
|
|
|
plvals.textalpha = 1;
|
|
|
|
if ( (plvals.graphicsalpha != 1) && (plvals.graphicsalpha != 2)
|
|
|
|
&& (plvals.graphicsalpha != 4))
|
|
|
|
plvals.graphicsalpha = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Check (and correct) the save values psvals */
|
|
|
|
static void
|
|
|
|
check_save_vals (void)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
|
|
|
int i;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
i = psvals.rotate;
|
|
|
|
if ((i != 0) && (i != 90) && (i != 180) && (i != 270))
|
|
|
|
psvals.rotate = 90;
|
|
|
|
if (psvals.preview_size <= 0)
|
|
|
|
psvals.preview = FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if a page is in a given list */
|
|
|
|
static gint
|
2000-01-26 01:46:56 +08:00
|
|
|
page_in_list (gchar *list,
|
|
|
|
guint page_num)
|
|
|
|
{
|
|
|
|
char tmplist[STR_LENGTH], *c0, *c1;
|
|
|
|
int state, start_num, end_num;
|
1997-11-25 06:05:25 +08:00
|
|
|
#define READ_STARTNUM 0
|
|
|
|
#define READ_ENDNUM 1
|
|
|
|
#define CHK_LIST(a,b,c) {int low=(a),high=(b),swp; \
|
|
|
|
if ((low>0) && (high>0)) { \
|
|
|
|
if (low>high) {swp=low; low=high; high=swp;} \
|
|
|
|
if ((low<=(c))&&(high>=(c))) return (1); } }
|
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
if ((list == NULL) || (*list == '\0'))
|
|
|
|
return 1;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
strncpy (tmplist, list, STR_LENGTH);
|
|
|
|
tmplist[STR_LENGTH-1] = '\0';
|
|
|
|
|
|
|
|
c0 = c1 = tmplist;
|
|
|
|
while (*c1) /* Remove all whitespace and break on unsupported characters */
|
|
|
|
{
|
|
|
|
if ((*c1 >= '0') && (*c1 <= '9'))
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
*(c0++) = *c1;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else if ((*c1 == '-') || (*c1 == ','))
|
2013-01-27 23:52:38 +08:00
|
|
|
{ /* Try to remove double occurrences of these characters */
|
2006-05-08 20:23:32 +08:00
|
|
|
if (c0 == tmplist)
|
|
|
|
{
|
|
|
|
*(c0++) = *c1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*(c0-1) != *c1)
|
|
|
|
*(c0++) = *c1;
|
|
|
|
}
|
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
else
|
|
|
|
break;
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
c1++;
|
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
|
|
|
|
if (c0 == tmplist)
|
|
|
|
return 1;
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
*c0 = '\0';
|
|
|
|
|
|
|
|
/* Now we have a comma separated list like 1-4-1,-3,1- */
|
|
|
|
|
|
|
|
start_num = end_num = -1;
|
|
|
|
state = READ_STARTNUM;
|
|
|
|
for (c0 = tmplist; *c0 != '\0'; c0++)
|
|
|
|
{
|
|
|
|
switch (state)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
case READ_STARTNUM:
|
|
|
|
if (*c0 == ',')
|
|
|
|
{
|
|
|
|
if ((start_num > 0) && (start_num == (int)page_num))
|
2004-11-19 05:10:12 +08:00
|
|
|
return -1;
|
2006-05-08 20:23:32 +08:00
|
|
|
start_num = -1;
|
|
|
|
}
|
|
|
|
else if (*c0 == '-')
|
|
|
|
{
|
|
|
|
if (start_num < 0) start_num = 1;
|
|
|
|
state = READ_ENDNUM;
|
|
|
|
}
|
|
|
|
else /* '0' - '9' */
|
|
|
|
{
|
|
|
|
if (start_num < 0) start_num = 0;
|
|
|
|
start_num *= 10;
|
|
|
|
start_num += *c0 - '0';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case READ_ENDNUM:
|
|
|
|
if (*c0 == ',')
|
|
|
|
{
|
|
|
|
if (end_num < 0) end_num = 9999;
|
|
|
|
CHK_LIST (start_num, end_num, (int)page_num);
|
|
|
|
start_num = end_num = -1;
|
|
|
|
state = READ_STARTNUM;
|
|
|
|
}
|
|
|
|
else if (*c0 == '-')
|
|
|
|
{
|
|
|
|
CHK_LIST (start_num, end_num, (int)page_num);
|
|
|
|
start_num = end_num;
|
|
|
|
end_num = -1;
|
|
|
|
}
|
|
|
|
else /* '0' - '9' */
|
|
|
|
{
|
|
|
|
if (end_num < 0) end_num = 0;
|
|
|
|
end_num *= 10;
|
|
|
|
end_num += *c0 - '0';
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
if (state == READ_STARTNUM)
|
|
|
|
{
|
|
|
|
if (start_num > 0)
|
2006-05-08 20:23:32 +08:00
|
|
|
return (start_num == (int) page_num);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (end_num < 0) end_num = 9999;
|
|
|
|
CHK_LIST (start_num, end_num, (int)page_num);
|
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
|
|
|
|
return 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
#undef CHK_LIST
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-21 07:26:11 +08:00
|
|
|
/* A function like fgets, but treats single CR-character as line break. */
|
|
|
|
/* As a line break the newline-character is returned. */
|
|
|
|
static char *psfgets (char *s, int size, FILE *stream)
|
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
char *sptr = s;
|
2000-08-21 07:26:11 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
if (size <= 0)
|
|
|
|
return NULL;
|
2000-08-21 07:26:11 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
if (size == 1)
|
|
|
|
{
|
|
|
|
*s = '\0';
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = getc (stream);
|
|
|
|
if (c == EOF)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
/* At this point we have space in sptr for at least two characters */
|
|
|
|
if (c == '\n') /* Got end of line (UNIX line end) ? */
|
|
|
|
{
|
|
|
|
*(sptr++) = '\n';
|
|
|
|
break;
|
|
|
|
}
|
2018-05-13 00:13:12 +08:00
|
|
|
else if (c == '\r') /* Got a carriage return. Check next character */
|
2004-11-19 05:10:12 +08:00
|
|
|
{
|
|
|
|
c = getc (stream);
|
|
|
|
if ((c == EOF) || (c == '\n')) /* EOF or DOS line end ? */
|
|
|
|
{
|
|
|
|
*(sptr++) = '\n'; /* Return UNIX line end */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else /* Single carriage return. Return UNIX line end. */
|
|
|
|
{
|
|
|
|
ungetc (c, stream); /* Save the extra character */
|
|
|
|
*(sptr++) = '\n';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* no line end character */
|
|
|
|
{
|
|
|
|
*(sptr++) = (char)c;
|
|
|
|
size--;
|
|
|
|
}
|
|
|
|
if (size == 1)
|
|
|
|
break; /* Only space for the nul-character ? */
|
|
|
|
|
|
|
|
c = getc (stream);
|
|
|
|
if (c == EOF)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
*sptr = '\0';
|
|
|
|
|
|
|
|
return s;
|
2000-08-21 07:26:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Get the BoundingBox of a PostScript file. On success, 0 is returned. */
|
|
|
|
/* On failure, -1 is returned. */
|
|
|
|
static gint
|
2003-07-02 20:03:08 +08:00
|
|
|
get_bbox (const gchar *filename,
|
|
|
|
gint *x0,
|
|
|
|
gint *y0,
|
|
|
|
gint *x1,
|
|
|
|
gint *y1)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
|
|
|
char line[1024], *src;
|
|
|
|
FILE *ifp;
|
|
|
|
int retval = -1;
|
|
|
|
|
2005-03-05 02:31:43 +08:00
|
|
|
ifp = g_fopen (filename, "rb");
|
2004-11-19 05:10:12 +08:00
|
|
|
if (ifp == NULL)
|
|
|
|
return -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
2000-08-21 07:26:11 +08:00
|
|
|
if (psfgets (line, sizeof (line)-1, ifp) == NULL) break;
|
2000-01-26 01:46:56 +08:00
|
|
|
if ((line[0] != '%') || (line[1] != '%')) continue;
|
|
|
|
src = &(line[2]);
|
|
|
|
while ((*src == ' ') || (*src == '\t')) src++;
|
|
|
|
if (strncmp (src, "BoundingBox", 11) != 0) continue;
|
|
|
|
src += 11;
|
|
|
|
while ((*src == ' ') || (*src == '\t') || (*src == ':')) src++;
|
|
|
|
if (strncmp (src, "(atend)", 7) == 0) continue;
|
|
|
|
if (sscanf (src, "%d%d%d%d", x0, y0, x1, y1) == 4)
|
2006-05-08 20:23:32 +08:00
|
|
|
retval = 0;
|
2000-01-26 01:46:56 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
fclose (ifp);
|
2004-11-19 05:10:12 +08:00
|
|
|
|
|
|
|
return retval;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
static gchar *pnmfile;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Open the PostScript file. On failure, NULL is returned. */
|
|
|
|
/* The filepointer returned will give a PNM-file generated */
|
|
|
|
/* by the PostScript-interpreter. */
|
|
|
|
static FILE *
|
2003-07-02 20:03:08 +08:00
|
|
|
ps_open (const gchar *filename,
|
1997-11-25 06:05:25 +08:00
|
|
|
const PSLoadVals *loadopt,
|
2000-01-26 01:46:56 +08:00
|
|
|
gint *llx,
|
|
|
|
gint *lly,
|
|
|
|
gint *urx,
|
2000-03-11 01:27:25 +08:00
|
|
|
gint *ury,
|
2012-01-22 12:26:08 +08:00
|
|
|
gboolean *is_epsf)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
const gchar *driver;
|
|
|
|
GPtrArray *cmdA;
|
|
|
|
gchar **pcmdA;
|
|
|
|
FILE *fd_popen = NULL;
|
|
|
|
FILE *eps_file;
|
|
|
|
gint width, height;
|
|
|
|
gint resolution;
|
|
|
|
gint x0, y0, x1, y1;
|
|
|
|
gint offx = 0;
|
|
|
|
gint offy = 0;
|
|
|
|
gboolean is_pdf;
|
|
|
|
gboolean maybe_epsf = FALSE;
|
2012-01-22 12:26:08 +08:00
|
|
|
int code;
|
|
|
|
void *instance;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
resolution = loadopt->resolution;
|
|
|
|
*llx = *lly = 0;
|
|
|
|
width = loadopt->width;
|
|
|
|
height = loadopt->height;
|
2004-01-26 07:46:24 +08:00
|
|
|
*urx = width - 1;
|
|
|
|
*ury = height - 1;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-01-27 23:52:38 +08:00
|
|
|
/* Check if the file is a PDF. For PDF, we can't set geometry */
|
2007-05-29 23:29:37 +08:00
|
|
|
is_pdf = FALSE;
|
2004-01-26 07:46:24 +08:00
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
/* Check if it is a EPS-file */
|
2007-05-29 23:29:37 +08:00
|
|
|
*is_epsf = FALSE;
|
2004-01-26 07:46:24 +08:00
|
|
|
|
2005-03-04 23:12:29 +08:00
|
|
|
eps_file = g_fopen (filename, "rb");
|
2004-01-26 07:46:24 +08:00
|
|
|
|
|
|
|
if (eps_file != NULL)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
gchar hdr[512];
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2004-01-26 07:46:24 +08:00
|
|
|
fread (hdr, 1, sizeof(hdr), eps_file);
|
2000-01-26 01:46:56 +08:00
|
|
|
is_pdf = (strncmp (hdr, "%PDF", 4) == 0);
|
2000-03-11 01:27:25 +08:00
|
|
|
|
|
|
|
if (!is_pdf) /* Check for EPSF */
|
2004-01-26 07:46:24 +08:00
|
|
|
{
|
|
|
|
char *adobe, *epsf;
|
|
|
|
int ds = 0;
|
|
|
|
static unsigned char doseps[5] = { 0xc5, 0xd0, 0xd3, 0xc6, 0 };
|
|
|
|
|
|
|
|
hdr[sizeof(hdr)-1] = '\0';
|
|
|
|
adobe = strstr (hdr, "PS-Adobe-");
|
|
|
|
epsf = strstr (hdr, "EPSF-");
|
|
|
|
|
|
|
|
if ((adobe != NULL) && (epsf != NULL))
|
|
|
|
ds = epsf - adobe;
|
|
|
|
|
|
|
|
*is_epsf = ((ds >= 11) && (ds <= 15));
|
|
|
|
|
|
|
|
/* Illustrator uses negative values in BoundingBox without marking */
|
|
|
|
/* files as EPSF. Try to handle that. */
|
|
|
|
maybe_epsf =
|
|
|
|
(strstr (hdr, "%%Creator: Adobe Illustrator(R) 8.0") != 0);
|
|
|
|
|
|
|
|
/* Check DOS EPS binary file */
|
|
|
|
if ((!*is_epsf) && (strncmp (hdr, (char *)doseps, 4) == 0))
|
|
|
|
*is_epsf = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (eps_file);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((!is_pdf) && (loadopt->use_bbox)) /* Try the BoundingBox ? */
|
|
|
|
{
|
2000-03-26 06:19:17 +08:00
|
|
|
if (get_bbox (filename, &x0, &y0, &x1, &y1) == 0)
|
|
|
|
{
|
2002-05-15 04:04:29 +08:00
|
|
|
if (maybe_epsf && ((x0 < 0) || (y0 < 0)))
|
|
|
|
*is_epsf = 1;
|
|
|
|
|
2000-03-26 06:19:17 +08:00
|
|
|
if (*is_epsf) /* Handle negative BoundingBox for EPSF */
|
|
|
|
{
|
|
|
|
offx = -x0; x1 += offx; x0 += offx;
|
|
|
|
offy = -y0; y1 += offy; y0 += offy;
|
|
|
|
}
|
|
|
|
if ((x0 >= 0) && (y0 >= 0) && (x1 > x0) && (y1 > y0))
|
|
|
|
{
|
2002-10-08 18:53:10 +08:00
|
|
|
*llx = (int)((x0/72.0) * resolution + 0.0001);
|
|
|
|
*lly = (int)((y0/72.0) * resolution + 0.0001);
|
2004-09-19 18:54:48 +08:00
|
|
|
/* Use upper bbox values as image size */
|
|
|
|
width = (int)((x1/72.0) * resolution + 0.5);
|
|
|
|
height = (int)((y1/72.0) * resolution + 0.5);
|
|
|
|
/* Pixel coordinates must be one less */
|
|
|
|
*urx = width - 1;
|
|
|
|
*ury = height - 1;
|
|
|
|
if (*urx < *llx) *urx = *llx;
|
|
|
|
if (*ury < *lly) *ury = *lly;
|
2000-03-26 06:19:17 +08:00
|
|
|
}
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2004-01-26 07:46:24 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
switch (loadopt->pnm_type)
|
|
|
|
{
|
|
|
|
case 4:
|
|
|
|
driver = "pbmraw";
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
driver = "pgmraw";
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
driver = "pnmraw";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
driver = "ppmraw";
|
|
|
|
break;
|
|
|
|
}
|
1999-06-21 08:23:55 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* For instance, the Win32 port of ghostscript doesn't work correctly when
|
|
|
|
* using standard output as output file.
|
|
|
|
* Thus, use a real output file.
|
|
|
|
*/
|
2012-01-22 12:26:08 +08:00
|
|
|
pnmfile = gimp_temp_name ("pnm");
|
2003-03-22 09:12:48 +08:00
|
|
|
|
2004-01-26 07:46:24 +08:00
|
|
|
/* Build command array */
|
|
|
|
cmdA = g_ptr_array_new ();
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2012-01-22 12:26:08 +08:00
|
|
|
g_ptr_array_add (cmdA, g_strdup (g_get_prgname ()));
|
2004-01-26 07:46:24 +08:00
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-sDEVICE=%s", driver));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-r%d", resolution));
|
|
|
|
|
2005-04-21 18:46:52 +08:00
|
|
|
if (is_pdf)
|
|
|
|
{
|
|
|
|
/* Acrobat Reader honors CropBox over MediaBox, so let's match that
|
|
|
|
* behavior.
|
|
|
|
*/
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-dUseCropBox"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* For PDF, we can't set geometry */
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-g%dx%d", width, height));
|
|
|
|
}
|
2004-01-26 07:46:24 +08:00
|
|
|
|
|
|
|
/* Antialiasing not available for PBM-device */
|
|
|
|
if ((loadopt->pnm_type != 4) && (loadopt->textalpha != 1))
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-dTextAlphaBits=%d",
|
|
|
|
loadopt->textalpha));
|
|
|
|
if ((loadopt->pnm_type != 4) && (loadopt->graphicsalpha != 1))
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-dGraphicsAlphaBits=%d",
|
|
|
|
loadopt->graphicsalpha));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-q"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-dBATCH"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-dNOPAUSE"));
|
|
|
|
|
|
|
|
/* If no additional options specified, use at least -dSAFER */
|
2005-03-04 23:12:29 +08:00
|
|
|
if (g_getenv ("GS_OPTIONS") == NULL)
|
2004-01-26 07:46:24 +08:00
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-dSAFER"));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-01-26 07:46:24 +08:00
|
|
|
/* Output file name */
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("-sOutputFile=%s", pnmfile));
|
2000-03-26 06:19:17 +08:00
|
|
|
|
|
|
|
/* Offset command for gs to get image part with negative x/y-coord. */
|
|
|
|
if ((offx != 0) || (offy != 0))
|
2004-01-26 07:46:24 +08:00
|
|
|
{
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-c"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("%d", offx));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup_printf ("%d", offy));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("translate"));
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-01-26 07:46:24 +08:00
|
|
|
/* input file name */
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-f"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup (filename));
|
|
|
|
|
|
|
|
if (*is_epsf)
|
|
|
|
{
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-c"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("showpage"));
|
|
|
|
}
|
|
|
|
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("-c"));
|
|
|
|
g_ptr_array_add (cmdA, g_strdup ("quit"));
|
|
|
|
g_ptr_array_add (cmdA, NULL);
|
|
|
|
|
|
|
|
pcmdA = (gchar **) cmdA->pdata;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#ifdef PS_DEBUG
|
2004-01-26 07:46:24 +08:00
|
|
|
{
|
|
|
|
gchar **p = pcmdA;
|
2012-01-22 12:26:08 +08:00
|
|
|
g_print ("Passing args (argc=%d):\n", cmdA->len - 1);
|
2004-01-26 07:46:24 +08:00
|
|
|
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
g_print ("%s\n", *p);
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
#endif
|
1999-06-21 08:23:55 +08:00
|
|
|
|
2012-01-22 12:26:08 +08:00
|
|
|
code = gsapi_new_instance (&instance, NULL);
|
|
|
|
if (code == 0) {
|
|
|
|
code = gsapi_init_with_args (instance, cmdA->len - 1, pcmdA);
|
|
|
|
code = gsapi_exit (instance);
|
|
|
|
gsapi_delete_instance (instance);
|
|
|
|
}
|
2004-01-26 07:46:24 +08:00
|
|
|
|
|
|
|
/* Don't care about exit status of ghostscript. */
|
|
|
|
/* Just try to read what it wrote. */
|
2004-10-06 21:18:37 +08:00
|
|
|
|
2005-03-04 23:12:29 +08:00
|
|
|
fd_popen = g_fopen (pnmfile, "rb");
|
2004-01-26 07:46:24 +08:00
|
|
|
|
|
|
|
g_ptr_array_free (cmdA, FALSE);
|
|
|
|
g_strfreev (pcmdA);
|
|
|
|
|
|
|
|
return fd_popen;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Close the PNM-File of the PostScript interpreter */
|
|
|
|
static void
|
2012-01-22 12:26:08 +08:00
|
|
|
ps_close (FILE *ifp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-06-21 08:23:55 +08:00
|
|
|
/* If a real outputfile was used, close the file and remove it. */
|
2000-01-26 01:46:56 +08:00
|
|
|
fclose (ifp);
|
2005-03-04 23:12:29 +08:00
|
|
|
g_unlink (pnmfile);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read the header of a raw PNM-file and return type (4-6) or -1 on failure */
|
|
|
|
static gint
|
|
|
|
read_pnmraw_type (FILE *ifp,
|
2000-01-26 01:46:56 +08:00
|
|
|
gint *width,
|
|
|
|
gint *height,
|
|
|
|
gint *maxval)
|
|
|
|
{
|
2013-05-15 02:52:38 +08:00
|
|
|
int frst, scnd, thrd;
|
2007-05-29 23:29:37 +08:00
|
|
|
gint pnmtype;
|
|
|
|
gchar line[1024];
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* GhostScript may write some informational messages infront of the header. */
|
|
|
|
/* We are just looking at a Px\n in the input stream. */
|
|
|
|
frst = getc (ifp);
|
|
|
|
scnd = getc (ifp);
|
|
|
|
thrd = getc (ifp);
|
|
|
|
for (;;)
|
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
if (thrd == EOF) return -1;
|
2012-01-22 12:26:08 +08:00
|
|
|
#ifdef G_OS_WIN32
|
2000-01-26 01:46:56 +08:00
|
|
|
if (thrd == '\r') thrd = getc (ifp);
|
1999-05-02 00:10:36 +08:00
|
|
|
#endif
|
2000-01-26 01:46:56 +08:00
|
|
|
if ((thrd == '\n') && (frst == 'P') && (scnd >= '1') && (scnd <= '6'))
|
2006-05-08 20:23:32 +08:00
|
|
|
break;
|
2000-01-26 01:46:56 +08:00
|
|
|
frst = scnd;
|
|
|
|
scnd = thrd;
|
|
|
|
thrd = getc (ifp);
|
|
|
|
}
|
|
|
|
pnmtype = scnd - '0';
|
2018-04-19 02:57:03 +08:00
|
|
|
/* We don't use the ASCII-versions */
|
2004-11-19 05:10:12 +08:00
|
|
|
if ((pnmtype >= 1) && (pnmtype <= 3))
|
|
|
|
return -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* Read width/height */
|
|
|
|
for (;;)
|
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
if (fgets (line, sizeof (line)-1, ifp) == NULL)
|
|
|
|
return -1;
|
|
|
|
if (line[0] != '#')
|
|
|
|
break;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
if (sscanf (line, "%d%d", width, height) != 2)
|
|
|
|
return -1;
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
*maxval = 255;
|
|
|
|
|
|
|
|
if (pnmtype != 4) /* Read maxval */
|
|
|
|
{
|
|
|
|
for (;;)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
if (fgets (line, sizeof (line)-1, ifp) == NULL)
|
2004-11-19 05:10:12 +08:00
|
|
|
return -1;
|
2006-05-08 20:23:32 +08:00
|
|
|
if (line[0] != '#')
|
2004-11-19 05:10:12 +08:00
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
if (sscanf (line, "%d", maxval) != 1)
|
|
|
|
return -1;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
|
|
|
|
return pnmtype;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
|
|
|
|
static gint32
|
2003-11-27 20:28:46 +08:00
|
|
|
create_new_image (const gchar *filename,
|
|
|
|
guint pagenum,
|
|
|
|
guint width,
|
|
|
|
guint height,
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpImageBaseType type,
|
2013-05-13 20:31:35 +08:00
|
|
|
gint32 *layer_ID)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2003-11-27 20:28:46 +08:00
|
|
|
gint32 image_ID;
|
|
|
|
GimpImageType gdtype;
|
2005-08-15 16:48:45 +08:00
|
|
|
gchar *tmp;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-05-13 20:29:17 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case GIMP_GRAY:
|
|
|
|
gdtype = GIMP_GRAY_IMAGE;
|
|
|
|
break;
|
|
|
|
case GIMP_INDEXED:
|
|
|
|
gdtype = GIMP_INDEXED_IMAGE;
|
|
|
|
break;
|
|
|
|
case GIMP_RGB:
|
|
|
|
default:
|
|
|
|
gdtype = GIMP_RGB_IMAGE;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-05-14 16:09:06 +08:00
|
|
|
image_ID = gimp_image_new_with_precision (width, height, type,
|
Initial space invasion commit in GIMP
All babl formats now have a space equivalent to a color profile,
determining the format's primaries and TRCs. This commit makes GIMP
aware of this.
libgimp:
- enum GimpPrecision: rename GAMMA values to NON_LINEAR and keep GAMMA
as deprecated aliases, add PERCEPTUAL values so we now have LINEAR,
NON_LINEAR and PERCPTUAL for each encoding, matching the babl
encoding variants RGB, R'G'B' and R~G~B~.
- gimp_color_transform_can_gegl_copy() now returns TRUE if both
profiles can return a babl space, increasing the amount of fast babl
color conversions significantly.
- TODO: no solution yet for getting libgimp drawable proxy buffers in
the right format with space.
plug-ins:
- follow the GimpPrecision change.
- TODO: everything else unchanged and partly broken or sub-optimal,
like setting a new image's color profile too late.
app:
- add enum GimpTRCType { LINEAR, NON_LINEAR, PERCEPTUAL } as
replacement for all "linear" booleans.
- change gimp-babl functions to take babl spaces and GimpTRCType
parameters and support all sorts of new perceptual ~ formats.
- a lot of places changed in the early days of goat invasion didn't
take advantage of gimp-babl utility functions and constructed
formats manually. They all needed revisiting and many now use much
simpler code calling gimp-babl API.
- change gimp_babl_format_get_color_profile() to really extract a
newly allocated color profile from the format, and add
gimp_babl_get_builtin_color_profile() which does the same as
gimp_babl_format_get_color_profile() did before. Visited all callers
to decide whether they are looking for the format's actual profile,
or for one of the builtin profiles, simplifying code that only needs
builtin profiles.
- drawables have a new get_space_api(), get_linear() is now get_trc().
- images now have a "layer space" and an API to get it,
gimp_image_get_layer_format() returns formats in that space.
- an image's layer space is created from the image's color profile,
change gimpimage-color-profile to deal with that correctly
- change many babl_format() calls to babl_format_with_space() and take
the space from passed formats or drawables
- add function gimp_layer_fix_format_space() which replaces the
layer's buffer with one that has the image's layer format, but
doesn't change pixel values
- use gimp_layer_fix_format_space() to make sure layers loaded from
XCF and created by plug-ins have the right space when added to the
image, because it's impossible to always assign the right space upon
layer creation
- "assign color profile" and "discard color profile" now require use
of gimp_layer_fix_format_space() too because the profile is now
embedded in all formats via the space. Add
gimp_image_assign_color_profile() which does all that and call it
instead of a simple gimp_image_set_color_profile(), also from the
PDB set-color-profile functions, which are essentially "assign" and
"discard" calls.
- generally, make sure a new image's color profile is set before
adding layers to it, gimp_image_set_color_profile() is more than
before considered know-what-you-are-doing API.
- take special precaution in all places that call
gimp_drawable_convert_type(), we now must pass a new_profile from
all callers that convert layers within the same image (such as
image_convert_type, image_convert_precision), because the layer's
new space can't be determined from the image's layer format during
the call.
- change all "linear" properties to "trc", in all config objects like
for levels and curves, in the histogram, in the widgets. This results
in some GUI that now has three choices instead of two.
TODO: we might want to reduce that back to two later.
- keep "linear" boolean properties around as compat if needed for file
pasring, but always convert the parsed parsed boolean to
GimpTRCType.
- TODO: the image's "enable color management" switch is currently
broken, will fix that in another commit.
2018-07-21 20:23:01 +08:00
|
|
|
GIMP_PRECISION_U8_NON_LINEAR);
|
2005-08-15 16:48:45 +08:00
|
|
|
gimp_image_undo_disable (image_ID);
|
2003-11-27 20:28:46 +08:00
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
tmp = g_strdup_printf ("%s-%d", filename, pagenum);
|
|
|
|
gimp_image_set_filename (image_ID, tmp);
|
|
|
|
g_free (tmp);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
tmp = g_strdup_printf (_("Page %d"), pagenum);
|
|
|
|
*layer_ID = gimp_layer_new (image_ID, tmp, width, height,
|
2017-01-09 06:00:19 +08:00
|
|
|
gdtype,
|
2017-08-22 02:04:25 +08:00
|
|
|
100,
|
|
|
|
gimp_image_get_default_new_layer_mode (image_ID));
|
2005-08-15 16:48:45 +08:00
|
|
|
g_free (tmp);
|
|
|
|
|
2010-09-06 17:40:46 +08:00
|
|
|
gimp_image_insert_layer (image_ID, *layer_ID, -1, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2003-11-27 20:28:46 +08:00
|
|
|
return image_ID;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Skip PNM image generated from PostScript file. */
|
2004-11-19 05:10:12 +08:00
|
|
|
/* Return TRUE on success, FALSE otherwise. */
|
|
|
|
static gboolean
|
1997-11-25 06:05:25 +08:00
|
|
|
skip_ps (FILE *ifp)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2004-11-19 05:10:12 +08:00
|
|
|
guchar buf[8192];
|
|
|
|
gsize len;
|
|
|
|
gint pnmtype, width, height, maxval, bpl;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
pnmtype = read_pnmraw_type (ifp, &width, &height, &maxval);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (pnmtype == 4) /* Portable bitmap */
|
2004-11-19 05:10:12 +08:00
|
|
|
bpl = (width + 7) / 8;
|
2000-01-26 01:46:56 +08:00
|
|
|
else if (pnmtype == 5)
|
|
|
|
bpl = width;
|
|
|
|
else if (pnmtype == 6)
|
2004-11-19 05:10:12 +08:00
|
|
|
bpl = width * 3;
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2004-11-19 05:10:12 +08:00
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
len = bpl * height;
|
|
|
|
while (len)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2004-11-19 21:34:07 +08:00
|
|
|
gsize bytes = fread (buf, 1, MIN (len, sizeof (buf)), ifp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
if (bytes < MIN (len, sizeof (buf)))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
len -= bytes;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
return TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Load PNM image generated from PostScript file */
|
|
|
|
static gint32
|
2003-07-02 20:03:08 +08:00
|
|
|
load_ps (const gchar *filename,
|
|
|
|
guint pagenum,
|
|
|
|
FILE *ifp,
|
|
|
|
gint llx,
|
|
|
|
gint lly,
|
|
|
|
gint urx,
|
|
|
|
gint ury)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2013-05-15 02:52:38 +08:00
|
|
|
guchar *dest;
|
2000-01-26 01:46:56 +08:00
|
|
|
guchar *data, *bitline = NULL, *byteline = NULL, *byteptr, *temp;
|
|
|
|
guchar bit2byte[256*8];
|
|
|
|
int width, height, tile_height, scan_lines, total_scan_lines;
|
|
|
|
int image_width, image_height;
|
|
|
|
int skip_left, skip_bottom;
|
|
|
|
int i, j, pnmtype, maxval, bpp, nread;
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpImageBaseType imagetype;
|
2000-01-26 01:46:56 +08:00
|
|
|
gint32 layer_ID, image_ID;
|
2013-05-13 20:31:35 +08:00
|
|
|
GeglBuffer *buffer = NULL;
|
2000-01-26 01:46:56 +08:00
|
|
|
int err = 0, e;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
pnmtype = read_pnmraw_type (ifp, &width, &height, &maxval);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if ((width == urx+1) && (height == ury+1)) /* gs respected BoundingBox ? */
|
|
|
|
{
|
|
|
|
skip_left = llx; skip_bottom = lly;
|
|
|
|
image_width = width - skip_left;
|
|
|
|
image_height = height - skip_bottom;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
skip_left = skip_bottom = 0;
|
|
|
|
image_width = width;
|
|
|
|
image_height = height;
|
|
|
|
}
|
|
|
|
if (pnmtype == 4) /* Portable Bitmap */
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
imagetype = GIMP_INDEXED;
|
2000-01-26 01:46:56 +08:00
|
|
|
nread = (width+7)/8;
|
|
|
|
bpp = 1;
|
2007-05-29 23:29:37 +08:00
|
|
|
bitline = g_new (guchar, nread);
|
|
|
|
byteline = g_new (guchar, nread * 8);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* Get an array for mapping 8 bits in a byte to 8 bytes */
|
|
|
|
temp = bit2byte;
|
|
|
|
for (j = 0; j < 256; j++)
|
2006-05-08 20:23:32 +08:00
|
|
|
for (i = 7; i >= 0; i--)
|
|
|
|
*(temp++) = ((j & (1 << i)) != 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
else if (pnmtype == 5) /* Portable Greymap */
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
imagetype = GIMP_GRAY;
|
2000-01-26 01:46:56 +08:00
|
|
|
nread = width;
|
|
|
|
bpp = 1;
|
2007-05-29 23:29:37 +08:00
|
|
|
byteline = g_new (guchar, nread);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
else if (pnmtype == 6) /* Portable Pixmap */
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
imagetype = GIMP_RGB;
|
2000-01-26 01:46:56 +08:00
|
|
|
nread = width * 3;
|
|
|
|
bpp = 3;
|
2007-05-29 23:29:37 +08:00
|
|
|
byteline = g_new (guchar, nread);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2004-11-19 05:10:12 +08:00
|
|
|
else
|
|
|
|
return -1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
image_ID = create_new_image (filename, pagenum,
|
2006-05-08 20:23:32 +08:00
|
|
|
image_width, image_height, imagetype,
|
2013-05-13 20:31:35 +08:00
|
|
|
&layer_ID);
|
|
|
|
buffer = gimp_drawable_get_buffer (layer_ID);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
tile_height = gimp_tile_height ();
|
|
|
|
data = g_malloc (tile_height * image_width * bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
dest = data;
|
|
|
|
total_scan_lines = scan_lines = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (pnmtype == 4) /* Read bitimage ? Must be mapped to indexed */
|
2007-05-29 23:29:37 +08:00
|
|
|
{
|
|
|
|
const guchar BWColorMap[2*3] = { 255, 255, 255, 0, 0, 0 };
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
gimp_image_set_colormap (image_ID, BWColorMap, 2);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
e = (fread (bitline, 1, nread, ifp) != nread);
|
2013-05-13 20:31:35 +08:00
|
|
|
if (total_scan_lines >= image_height)
|
|
|
|
continue;
|
2007-05-29 23:29:37 +08:00
|
|
|
err |= e;
|
2013-05-13 20:31:35 +08:00
|
|
|
if (err)
|
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
j = width; /* Map 1 byte of bitimage to 8 bytes of indexed image */
|
|
|
|
temp = bitline;
|
|
|
|
byteptr = byteline;
|
|
|
|
while (j >= 8)
|
|
|
|
{
|
|
|
|
memcpy (byteptr, bit2byte + *(temp++)*8, 8);
|
|
|
|
byteptr += 8;
|
|
|
|
j -= 8;
|
|
|
|
}
|
|
|
|
if (j > 0)
|
|
|
|
memcpy (byteptr, bit2byte + *temp*8, j);
|
|
|
|
|
|
|
|
memcpy (dest, byteline+skip_left, image_width);
|
|
|
|
dest += image_width;
|
|
|
|
scan_lines++;
|
|
|
|
total_scan_lines++;
|
2006-05-08 20:23:32 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((scan_lines == tile_height) || ((i + 1) == image_height))
|
2007-05-29 23:29:37 +08:00
|
|
|
{
|
2013-05-13 20:31:35 +08:00
|
|
|
gegl_buffer_set (buffer,
|
|
|
|
GEGL_RECTANGLE (0, i-scan_lines+1,
|
|
|
|
image_width, scan_lines),
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
data,
|
|
|
|
GEGL_AUTO_ROWSTRIDE);
|
2007-05-29 23:29:37 +08:00
|
|
|
scan_lines = 0;
|
|
|
|
dest = data;
|
|
|
|
}
|
2013-05-13 20:31:35 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) (i + 1) / (gdouble) image_height);
|
2013-05-13 20:31:35 +08:00
|
|
|
|
|
|
|
if (err)
|
|
|
|
break;
|
2007-05-29 23:29:37 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
else /* Read gray/rgb-image */
|
|
|
|
{
|
|
|
|
for (i = 0; i < height; i++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
e = (fread (byteline, bpp, width, ifp) != width);
|
2013-05-13 20:31:35 +08:00
|
|
|
if (total_scan_lines >= image_height)
|
|
|
|
continue;
|
2006-05-08 20:23:32 +08:00
|
|
|
err |= e;
|
2013-05-13 20:31:35 +08:00
|
|
|
if (err)
|
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
|
|
|
|
memcpy (dest, byteline+skip_left*bpp, image_width*bpp);
|
|
|
|
dest += image_width*bpp;
|
|
|
|
scan_lines++;
|
|
|
|
total_scan_lines++;
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((scan_lines == tile_height) || ((i + 1) == image_height))
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2013-05-13 20:31:35 +08:00
|
|
|
gegl_buffer_set (buffer,
|
|
|
|
GEGL_RECTANGLE (0, i-scan_lines+1,
|
|
|
|
image_width, scan_lines),
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
data,
|
|
|
|
GEGL_AUTO_ROWSTRIDE);
|
2006-05-08 20:23:32 +08:00
|
|
|
scan_lines = 0;
|
|
|
|
dest = data;
|
|
|
|
}
|
2013-05-13 20:31:35 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) (i + 1) / (gdouble) image_height);
|
2013-05-13 20:31:35 +08:00
|
|
|
|
|
|
|
if (err)
|
|
|
|
break;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
g_free (data);
|
2007-05-29 23:29:37 +08:00
|
|
|
g_free (byteline);
|
|
|
|
g_free (bitline);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
if (err)
|
|
|
|
g_message ("EOF encountered on reading");
|
|
|
|
|
2013-05-13 20:31:35 +08:00
|
|
|
g_object_unref (buffer);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
return (err ? -1 : image_ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Write out the PostScript file header */
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_ps_header (GOutputStream *output,
|
|
|
|
GFile *file,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
gchar *basename = g_path_get_basename (gimp_file_get_utf8_name (file));
|
2004-08-09 06:26:17 +08:00
|
|
|
time_t cutime = time (NULL);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error,
|
|
|
|
"%%!PS-Adobe-3.0%s\n", psvals.eps ? " EPSF-3.0" : ""))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
2017-03-22 00:45:50 +08:00
|
|
|
"%%%%Creator: GIMP PostScript file plug-in V %4.2f "
|
2014-10-27 01:54:42 +08:00
|
|
|
"by Peter Kirchgessner\n", VERSIO))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"%%%%Title: %s\n"
|
|
|
|
"%%%%CreationDate: %s"
|
|
|
|
"%%%%DocumentData: Clean7Bit\n",
|
|
|
|
basename, ctime (&cutime)))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (psvals.eps || (psvals.level > 1))
|
|
|
|
if (! print (output, error,"%%%%LanguageLevel: 2\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%%%%Pages: 1\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
g_free (basename);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fail:
|
2004-08-09 06:26:17 +08:00
|
|
|
|
|
|
|
g_free (basename);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
return FALSE;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Write out transformation for image */
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_ps_setup (GOutputStream *output,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint bpp,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
gdouble x_offset, y_offset, x_size, y_size;
|
|
|
|
gdouble urx, ury;
|
|
|
|
gdouble width_inch, height_inch;
|
|
|
|
gdouble f1, f2, dx, dy;
|
|
|
|
gint xtrans, ytrans;
|
|
|
|
gint i_urx, i_ury;
|
|
|
|
gchar tmpbuf1[G_ASCII_DTOSTR_BUF_SIZE];
|
|
|
|
gchar tmpbuf2[G_ASCII_DTOSTR_BUF_SIZE];
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* initialize */
|
|
|
|
|
|
|
|
dx = 0.0;
|
|
|
|
dy = 0.0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
x_offset = psvals.x_offset;
|
|
|
|
y_offset = psvals.y_offset;
|
|
|
|
width_inch = fabs (psvals.width);
|
1997-11-25 06:05:25 +08:00
|
|
|
height_inch = fabs (psvals.height);
|
|
|
|
|
|
|
|
if (psvals.unit_mm)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
|
|
|
x_offset /= 25.4; y_offset /= 25.4;
|
|
|
|
width_inch /= 25.4; height_inch /= 25.4;
|
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (psvals.keep_ratio) /* Proportions to keep ? */
|
2000-01-26 01:46:56 +08:00
|
|
|
{ /* Fit the image into the allowed size */
|
|
|
|
f1 = width_inch / width;
|
|
|
|
f2 = height_inch / height;
|
|
|
|
if (f1 < f2)
|
2014-10-27 01:54:42 +08:00
|
|
|
height_inch = width_inch * (gdouble) height / (gdouble) width;
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
width_inch = fabs (height_inch) * (gdouble) width / (gdouble) height;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if ((psvals.rotate == 0) || (psvals.rotate == 180))
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
x_size = width_inch;
|
|
|
|
y_size = height_inch;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
y_size = width_inch;
|
|
|
|
x_size = height_inch;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-10-08 18:53:10 +08:00
|
|
|
/* Round up upper right corner only for non-integer values */
|
2014-10-27 01:54:42 +08:00
|
|
|
urx = (x_offset + x_size) * 72.0;
|
|
|
|
ury = (y_offset + y_size) * 72.0;
|
|
|
|
i_urx = (gint) urx;
|
|
|
|
i_ury = (gint) ury;
|
|
|
|
if (urx != (gdouble) i_urx) i_urx++; /* Check for non-integer value */
|
|
|
|
if (ury != (gdouble) i_ury) i_ury++;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"%%%%BoundingBox: %d %d %d %d\n"
|
|
|
|
"%%%%EndComments\n",
|
|
|
|
(gint) (x_offset * 72.0), (gint) (y_offset * 72.0), i_urx, i_ury))
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1997-12-26 15:08:20 +08:00
|
|
|
if (psvals.preview && (psvals.preview_size > 0))
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_preview (output, drawable_ID, error))
|
|
|
|
return FALSE;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-12-26 15:08:20 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error,
|
|
|
|
"%%%%BeginProlog\n"
|
|
|
|
"%% Use own dictionary to avoid conflicts\n"
|
|
|
|
"10 dict begin\n"
|
|
|
|
"%%%%EndProlog\n"
|
|
|
|
"%%%%Page: 1 1\n"
|
|
|
|
"%% Translate for offset\n"
|
|
|
|
"%s %s translate\n",
|
|
|
|
g_ascii_dtostr (tmpbuf1, sizeof (tmpbuf1), x_offset * 72.0),
|
|
|
|
g_ascii_dtostr (tmpbuf2, sizeof (tmpbuf2), y_offset * 72.0)))
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Calculate translation to startpoint of first scanline */
|
|
|
|
switch (psvals.rotate)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
case 0: dx = 0.0; dy = y_size * 72.0;
|
2000-01-26 01:46:56 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
case 90: dx = dy = 0.0;
|
2000-01-26 01:46:56 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
case 180: dx = x_size * 72.0; dy = 0.0;
|
2000-01-26 01:46:56 +08:00
|
|
|
break;
|
2014-10-27 01:54:42 +08:00
|
|
|
case 270: dx = x_size * 72.0; dy = y_size * 72.0;
|
2000-01-26 01:46:56 +08:00
|
|
|
break;
|
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if ((dx != 0.0) || (dy != 0.0))
|
2002-12-17 03:24:05 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error,
|
|
|
|
"%% Translate to begin of first scanline\n"
|
|
|
|
"%s %s translate\n",
|
|
|
|
g_ascii_dtostr (tmpbuf1, sizeof (tmpbuf1), dx),
|
|
|
|
g_ascii_dtostr (tmpbuf2, sizeof (tmpbuf2), dy)))
|
|
|
|
return FALSE;
|
2002-12-17 03:24:05 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
if (psvals.rotate)
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "%d rotate\n", (gint) psvals.rotate))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"%s %s scale\n",
|
|
|
|
g_ascii_dtostr (tmpbuf1, sizeof (tmpbuf1), 72.0 * width_inch),
|
|
|
|
g_ascii_dtostr (tmpbuf2, sizeof (tmpbuf2), -72.0 * height_inch)))
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Write the PostScript procedures to read the image */
|
2000-01-23 06:26:20 +08:00
|
|
|
if (psvals.level <= 1)
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"%% Variable to keep one line of raster data\n"))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (bpp == 1)
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"/scanline %d string def\n", (width + 7) / 8))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"/scanline %d %d mul string def\n", width, bpp / 8))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"%% Image geometry\n%d %d %d\n"
|
|
|
|
"%% Transformation matrix\n",
|
|
|
|
width, height, (bpp == 1) ? 1 : 8))
|
|
|
|
return FALSE;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
xtrans = ytrans = 0;
|
2014-10-27 01:54:42 +08:00
|
|
|
if (psvals.width < 0.0) { width = -width; xtrans = -width; }
|
1997-11-25 06:05:25 +08:00
|
|
|
if (psvals.height < 0.0) { height = -height; ytrans = -height; }
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error,
|
|
|
|
"[ %d 0 0 %d %d %d ]\n", width, height, xtrans, ytrans))
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
save_ps_trailer (GOutputStream *output,
|
|
|
|
GError **error)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
return print (output, error,
|
|
|
|
"%%%%Trailer\n"
|
|
|
|
"end\n%%%%EOF\n");
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2013-06-07 05:26:16 +08:00
|
|
|
/* Do a Floyd-Steinberg dithering on a grayscale scanline. */
|
1997-12-26 15:08:20 +08:00
|
|
|
/* linecount must keep the counter for the actual scanline (0, 1, 2, ...). */
|
|
|
|
/* If linecount is less than zero, all used memory is freed. */
|
|
|
|
|
|
|
|
static void
|
2006-08-29 21:32:22 +08:00
|
|
|
dither_grey (const guchar *grey,
|
|
|
|
guchar *bw,
|
|
|
|
gint npix,
|
|
|
|
gint linecount)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean do_init_arrays = TRUE;
|
|
|
|
static gint *fs_error = NULL;
|
|
|
|
static gint limit[1278];
|
|
|
|
static gint east_error[256];
|
|
|
|
static gint seast_error[256];
|
|
|
|
static gint south_error[256];
|
|
|
|
static gint swest_error[256];
|
2006-08-29 21:32:22 +08:00
|
|
|
|
2013-05-15 02:52:38 +08:00
|
|
|
const guchar *greyptr;
|
2014-10-27 01:54:42 +08:00
|
|
|
guchar *bwptr, mask;
|
|
|
|
gint *fse;
|
|
|
|
gint x, greyval, fse_inline;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
if (linecount <= 0)
|
|
|
|
{
|
2006-08-29 21:32:22 +08:00
|
|
|
g_free (fs_error);
|
|
|
|
|
|
|
|
if (linecount < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fs_error = g_new0 (gint, npix + 2);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* Initialize some arrays that speed up dithering */
|
|
|
|
if (do_init_arrays)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2006-08-29 21:32:22 +08:00
|
|
|
gint i;
|
|
|
|
|
|
|
|
do_init_arrays = FALSE;
|
|
|
|
|
|
|
|
for (i = 0, x = -511; x <= 766; i++, x++)
|
|
|
|
limit[i] = (x < 0) ? 0 : ((x > 255) ? 255 : x);
|
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
for (greyval = 0; greyval < 256; greyval++)
|
|
|
|
{
|
2006-08-29 21:32:22 +08:00
|
|
|
east_error[greyval] = (greyval < 128) ?
|
|
|
|
((greyval * 79) >> 8) : (((greyval - 255) * 79) >> 8);
|
|
|
|
seast_error[greyval] = (greyval < 128) ?
|
|
|
|
((greyval * 34) >> 8) : (((greyval - 255) * 34) >> 8);
|
|
|
|
south_error[greyval] = (greyval < 128) ?
|
|
|
|
((greyval * 56) >> 8) : (((greyval - 255) * 56) >> 8);
|
|
|
|
swest_error[greyval] = (greyval < 128) ?
|
|
|
|
((greyval * 12) >> 8) : (((greyval - 255) * 12) >> 8);
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2006-08-29 21:32:22 +08:00
|
|
|
g_return_if_fail (fs_error != NULL);
|
|
|
|
|
|
|
|
memset (bw, 0, (npix + 7) / 8); /* Initialize with white */
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
greyptr = grey;
|
|
|
|
bwptr = bw;
|
|
|
|
mask = 0x80;
|
2006-08-29 21:32:22 +08:00
|
|
|
|
|
|
|
fse_inline = fs_error[1];
|
|
|
|
|
|
|
|
for (x = 0, fse = fs_error + 1; x < npix; x++, fse++)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2006-08-29 21:32:22 +08:00
|
|
|
greyval =
|
|
|
|
limit[*(greyptr++) + fse_inline + 512]; /* 0 <= greyval <= 255 */
|
|
|
|
|
|
|
|
if (greyval < 128)
|
|
|
|
*bwptr |= mask; /* Set a black pixel */
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
/* Error distribution */
|
|
|
|
fse_inline = east_error[greyval] + fse[1];
|
|
|
|
fse[1] = seast_error[greyval];
|
|
|
|
fse[0] += south_error[greyval];
|
|
|
|
fse[-1] += swest_error[greyval];
|
|
|
|
|
|
|
|
mask >>= 1; /* Get mask for next b/w-pixel */
|
2006-08-29 21:32:22 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (!mask)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
mask = 0x80;
|
|
|
|
bwptr++;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-12-26 15:08:20 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 00:22:12 +08:00
|
|
|
/* Write a device independent screen preview */
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_ps_preview (GOutputStream *output,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2013-05-14 22:13:19 +08:00
|
|
|
GimpImageType drawable_type;
|
|
|
|
GeglBuffer *buffer = NULL;
|
|
|
|
const Babl *format;
|
2014-10-27 01:54:42 +08:00
|
|
|
gint bpp;
|
|
|
|
guchar *bwptr, *greyptr;
|
|
|
|
gint width, height, x, y, nbsl, out_count;
|
|
|
|
gint nchar_pl = 72, src_y;
|
|
|
|
gdouble f1, f2;
|
|
|
|
guchar *grey, *bw, *src_row, *src_ptr;
|
|
|
|
guchar *cmap;
|
|
|
|
gint ncols, cind;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
if (psvals.preview_size <= 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
return TRUE;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
|
|
cmap = NULL;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
drawable_type = gimp_drawable_type (drawable_ID);
|
|
|
|
switch (drawable_type)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2013-05-14 22:13:19 +08:00
|
|
|
case GIMP_GRAY_IMAGE:
|
|
|
|
format = babl_format ("Y' u8");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_INDEXED_IMAGE:
|
|
|
|
cmap = gimp_image_get_colormap (gimp_item_get_image (drawable_ID),
|
|
|
|
&ncols);
|
|
|
|
format = gimp_drawable_get_format (drawable_ID);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_RGB_IMAGE:
|
|
|
|
default:
|
|
|
|
format = babl_format ("R'G'B' u8");
|
|
|
|
break;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2013-05-14 22:13:19 +08:00
|
|
|
|
|
|
|
bpp = babl_format_get_bytes_per_pixel (format);
|
|
|
|
|
|
|
|
width = gegl_buffer_get_width (buffer);
|
|
|
|
height = gegl_buffer_get_height (buffer);
|
|
|
|
|
|
|
|
/* Calculate size of preview */
|
|
|
|
if ((width > psvals.preview_size) ||
|
|
|
|
(height > psvals.preview_size))
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
f1 = (gdouble) psvals.preview_size / (gdouble) width;
|
|
|
|
f2 = (gdouble) psvals.preview_size / (gdouble) height;
|
2007-05-29 23:29:37 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (f1 < f2)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
width = psvals.preview_size;
|
2013-05-14 22:13:19 +08:00
|
|
|
height *= f1;
|
|
|
|
if (height <= 0)
|
|
|
|
height = 1;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
height = psvals.preview_size;
|
2013-05-14 22:13:19 +08:00
|
|
|
width *= f1;
|
|
|
|
if (width <= 0)
|
|
|
|
width = 1;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
nbsl = (width + 7) / 8; /* Number of bytes per scanline in bitmap */
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
grey = g_new (guchar, width);
|
|
|
|
bw = g_new (guchar, nbsl);
|
2013-05-14 22:13:19 +08:00
|
|
|
src_row = g_new (guchar, gegl_buffer_get_width (buffer) * bpp);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error,
|
|
|
|
"%%%%BeginPreview: %d %d 1 %d\n",
|
|
|
|
width, height,
|
|
|
|
((nbsl * 2 + nchar_pl - 1) / nchar_pl) * height))
|
|
|
|
goto fail;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
2013-05-14 22:13:19 +08:00
|
|
|
/* Get a scanline from the input image and scale it to the desired
|
|
|
|
width */
|
|
|
|
src_y = (y * gegl_buffer_get_height (buffer)) / height;
|
|
|
|
gegl_buffer_get (buffer,
|
|
|
|
GEGL_RECTANGLE (0, src_y,
|
|
|
|
gegl_buffer_get_width (buffer), 1),
|
|
|
|
1.0, format, src_row,
|
|
|
|
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
greyptr = grey;
|
2013-05-14 22:13:19 +08:00
|
|
|
if (bpp == 3) /* RGB-image */
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{ /* Convert to grey */
|
2013-05-14 22:13:19 +08:00
|
|
|
src_ptr = src_row + ((x * gegl_buffer_get_width (buffer)) / width) * 3;
|
2006-05-08 20:23:32 +08:00
|
|
|
*(greyptr++) = (3*src_ptr[0] + 6*src_ptr[1] + src_ptr[2]) / 10;
|
|
|
|
}
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else if (cmap) /* Indexed image */
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
2013-05-14 22:13:19 +08:00
|
|
|
src_ptr = src_row + ((x * gegl_buffer_get_width (buffer)) / width);
|
2013-06-07 05:26:16 +08:00
|
|
|
cind = *src_ptr; /* Get color index and convert to grey */
|
2006-05-08 20:23:32 +08:00
|
|
|
src_ptr = (cind >= ncols) ? cmap : (cmap + 3*cind);
|
|
|
|
*(greyptr++) = (3*src_ptr[0] + 6*src_ptr[1] + src_ptr[2]) / 10;
|
|
|
|
}
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else /* Grey image */
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++)
|
2013-05-14 22:13:19 +08:00
|
|
|
*(greyptr++) = *(src_row + ((x * gegl_buffer_get_width (buffer)) / width));
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2013-06-07 05:26:16 +08:00
|
|
|
/* Now we have a grayscale line for the desired width. */
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Dither it to b/w */
|
|
|
|
dither_grey (grey, bw, width, y);
|
|
|
|
|
|
|
|
/* Write out the b/w line */
|
|
|
|
out_count = 0;
|
|
|
|
bwptr = bw;
|
|
|
|
for (x = 0; x < nbsl; x++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (out_count == 0)
|
|
|
|
if (! print (output, error, "%% "))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%02x", *(bwptr++)))
|
|
|
|
goto fail;
|
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
out_count += 2;
|
|
|
|
if (out_count >= nchar_pl)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
out_count = 0;
|
|
|
|
}
|
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2003-06-13 22:37:00 +08:00
|
|
|
if ((y % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) y / (gdouble) height);
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "%%%%EndPreview\n"))
|
|
|
|
goto fail;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
|
|
|
dither_grey (grey, bw, width, -1);
|
|
|
|
g_free (src_row);
|
|
|
|
g_free (bw);
|
|
|
|
g_free (grey);
|
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
g_object_unref (buffer);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
|
|
|
g_free (src_row);
|
|
|
|
g_free (bw);
|
|
|
|
g_free (grey);
|
|
|
|
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return FALSE;
|
1997-12-26 15:08:20 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_gray (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
GeglBuffer *buffer = NULL;
|
|
|
|
const Babl *format;
|
|
|
|
gint bpp;
|
|
|
|
gint height, width, i, j;
|
|
|
|
gint tile_height;
|
|
|
|
guchar *data;
|
|
|
|
guchar *src;
|
|
|
|
guchar *packb = NULL;
|
|
|
|
gboolean level2 = (psvals.level > 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 16:54:00 +08:00
|
|
|
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
|
|
format = babl_format ("Y' u8");
|
2014-10-27 01:54:42 +08:00
|
|
|
bpp = babl_format_get_bytes_per_pixel (format);
|
|
|
|
width = gegl_buffer_get_width (buffer);
|
2013-05-14 16:54:00 +08:00
|
|
|
height = gegl_buffer_get_height (buffer);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
tile_height = gimp_tile_height ();
|
|
|
|
|
|
|
|
/* allocate a buffer for retrieving information from the pixel region */
|
2013-05-14 16:54:00 +08:00
|
|
|
src = data = (guchar *) g_malloc (tile_height * width * bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Set up transformation in PostScript */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_setup (output, drawable_ID, width, height, 1 * 8, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Write read image procedure */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! level2)
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"{ currentfile scanline readhexstring pop }\n"))
|
|
|
|
goto fail;
|
|
|
|
}
|
2000-01-23 06:26:20 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"currentfile /ASCII85Decode filter /RunLengthDecode filter\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ascii85_init ();
|
|
|
|
|
|
|
|
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
|
|
|
|
packb = (guchar *) g_malloc ((width * 105) / 100 + 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! ps_begin_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "image\n"))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define GET_GRAY_TILE(begin) \
|
2014-10-27 01:54:42 +08:00
|
|
|
{ gint scan_lines; \
|
1997-11-25 06:05:25 +08:00
|
|
|
scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); \
|
2013-05-14 16:54:00 +08:00
|
|
|
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, i, width, scan_lines), \
|
|
|
|
1.0, format, begin, \
|
|
|
|
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); \
|
1997-11-25 06:05:25 +08:00
|
|
|
src = begin; }
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((i % tile_height) == 0)
|
|
|
|
GET_GRAY_TILE (data); /* Get more data */
|
|
|
|
|
|
|
|
if (! level2)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "%c", hex[(*src) >> 4]))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c", hex[(*(src++)) & 0x0f]))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (((j + 1) % 39) == 0)
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
gint nout;
|
2000-03-11 01:27:25 +08:00
|
|
|
|
|
|
|
compress_packbits (width, src, &nout, packb);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! ascii85_nout (output, nout, packb, error))
|
|
|
|
goto fail;
|
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
src += width;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2003-06-13 22:37:00 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) i / (gdouble) height);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
if (level2)
|
2003-06-13 22:37:00 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
/* Write EOD of RunLengthDecode filter */
|
|
|
|
if (! ascii85_out (output, 128, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! ascii85_done (output, error))
|
|
|
|
goto fail;
|
2003-06-13 22:37:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! ps_end_data (output, error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (! print (output, error, "showpage\n"))
|
|
|
|
goto fail;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
g_free (data);
|
2014-10-27 01:54:42 +08:00
|
|
|
g_free (packb);
|
|
|
|
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
fail:
|
|
|
|
|
|
|
|
g_free (data);
|
|
|
|
g_free (packb);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 16:54:00 +08:00
|
|
|
g_object_unref (buffer);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
return FALSE;
|
2004-11-19 05:10:12 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#undef GET_GRAY_TILE
|
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_bw (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
GeglBuffer *buffer = NULL;
|
|
|
|
const Babl *format;
|
|
|
|
gint bpp;
|
|
|
|
gint height, width, i, j;
|
|
|
|
gint ncols, nbsl, nwrite;
|
|
|
|
gint tile_height;
|
|
|
|
guchar *cmap, *ct;
|
|
|
|
guchar *data, *src;
|
|
|
|
guchar *packb = NULL;
|
|
|
|
guchar *scanline, *dst, mask;
|
|
|
|
guchar *hex_scanline;
|
|
|
|
gboolean level2 = (psvals.level > 1);
|
1999-01-04 06:41:12 +08:00
|
|
|
|
2004-11-02 20:00:25 +08:00
|
|
|
cmap = gimp_image_get_colormap (image_ID, &ncols);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
|
|
format = gimp_drawable_get_format (drawable_ID);
|
2014-10-27 01:54:42 +08:00
|
|
|
bpp = babl_format_get_bytes_per_pixel (format);
|
|
|
|
width = gegl_buffer_get_width (buffer);
|
2013-05-14 22:13:19 +08:00
|
|
|
height = gegl_buffer_get_height (buffer);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
tile_height = gimp_tile_height ();
|
|
|
|
|
|
|
|
/* allocate a buffer for retrieving information from the pixel region */
|
2013-05-14 22:13:19 +08:00
|
|
|
src = data = g_new (guchar, tile_height * width * bpp);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
nbsl = (width + 7) / 8;
|
|
|
|
|
|
|
|
scanline = g_new (guchar, nbsl + 1);
|
2003-07-03 21:26:06 +08:00
|
|
|
hex_scanline = g_new (guchar, (nbsl + 1) * 2);
|
1999-01-04 06:41:12 +08:00
|
|
|
|
|
|
|
/* Set up transformation in PostScript */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_setup (output, drawable_ID, width, height, 1, error))
|
|
|
|
goto fail;
|
1999-01-04 06:41:12 +08:00
|
|
|
|
|
|
|
/* Write read image procedure */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! level2)
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"{ currentfile scanline readhexstring pop }\n"))
|
|
|
|
goto fail;
|
|
|
|
}
|
2000-01-23 06:26:20 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"currentfile /ASCII85Decode filter /RunLengthDecode filter\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ascii85_init ();
|
|
|
|
|
|
|
|
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
|
|
|
|
packb = g_new (guchar, ((nbsl+1) * 105) / 100 + 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! ps_begin_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "image\n"))
|
|
|
|
goto fail;
|
1999-01-04 06:41:12 +08:00
|
|
|
|
|
|
|
#define GET_BW_TILE(begin) \
|
2014-10-27 01:54:42 +08:00
|
|
|
{ gint scan_lines; \
|
1999-01-04 06:41:12 +08:00
|
|
|
scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); \
|
2013-05-14 22:13:19 +08:00
|
|
|
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, i, width, scan_lines), \
|
|
|
|
1.0, format, begin, \
|
|
|
|
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); \
|
1999-01-04 06:41:12 +08:00
|
|
|
src = begin; }
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((i % tile_height) == 0)
|
|
|
|
GET_BW_TILE (data); /* Get more data */
|
|
|
|
|
2000-01-23 06:26:20 +08:00
|
|
|
dst = scanline;
|
2000-01-26 01:46:56 +08:00
|
|
|
memset (dst, 0, nbsl);
|
|
|
|
mask = 0x80;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Build a bitmap for a scanline */
|
|
|
|
for (j = 0; j < width; j++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
ct = cmap + *(src++)*3;
|
|
|
|
if (ct[0] || ct[1] || ct[2])
|
|
|
|
*dst |= mask;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (mask == 0x01)
|
|
|
|
{
|
|
|
|
mask = 0x80; dst++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mask >>= 1;
|
|
|
|
}
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! level2)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
/* Convert to hexstring */
|
|
|
|
for (j = 0; j < nbsl; j++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
hex_scanline[j * 2] = (guchar) hex[scanline[j] >> 4];
|
|
|
|
hex_scanline[j * 2 + 1] = (guchar) hex[scanline[j] & 0x0f];
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
/* Write out hexstring */
|
|
|
|
j = nbsl * 2;
|
|
|
|
dst = hex_scanline;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
while (j > 0)
|
|
|
|
{
|
|
|
|
nwrite = (j > 78) ? 78 : j;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! g_output_stream_write_all (output,
|
|
|
|
dst, nwrite, NULL,
|
|
|
|
NULL, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
j -= nwrite;
|
|
|
|
dst += nwrite;
|
|
|
|
}
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
gint nout;
|
2000-03-11 01:27:25 +08:00
|
|
|
|
|
|
|
compress_packbits (nbsl, scanline, &nout, packb);
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! ascii85_nout (output, nout, packb, error))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2003-06-13 22:37:00 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) i / (gdouble) height);
|
1999-01-04 06:41:12 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
if (level2)
|
2003-06-13 22:37:00 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
/* Write EOD of RunLengthDecode filter */
|
|
|
|
if (! ascii85_out (output, 128, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! ascii85_done (output, error))
|
|
|
|
goto fail;
|
2003-06-13 22:37:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! ps_end_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "showpage\n"))
|
|
|
|
goto fail;
|
1999-01-04 06:41:12 +08:00
|
|
|
|
|
|
|
g_free (hex_scanline);
|
|
|
|
g_free (scanline);
|
|
|
|
g_free (data);
|
2014-10-27 01:54:42 +08:00
|
|
|
g_free (packb);
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
|
|
|
g_free (hex_scanline);
|
|
|
|
g_free (scanline);
|
|
|
|
g_free (data);
|
|
|
|
g_free (packb);
|
1999-01-04 06:41:12 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
g_object_unref (buffer);
|
1999-01-04 06:41:12 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
return FALSE;
|
2004-11-19 05:10:12 +08:00
|
|
|
|
1999-01-04 06:41:12 +08:00
|
|
|
#undef GET_BW_TILE
|
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_index (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
GeglBuffer *buffer = NULL;
|
|
|
|
const Babl *format;
|
|
|
|
gint bpp;
|
|
|
|
gint height, width, i, j;
|
|
|
|
gint ncols, bw;
|
|
|
|
gint tile_height;
|
|
|
|
guchar *cmap, *cmap_start;
|
|
|
|
guchar *data, *src;
|
|
|
|
guchar *packb = NULL;
|
|
|
|
guchar *plane = NULL;
|
|
|
|
gchar coltab[256 * 6], *ct;
|
|
|
|
gboolean level2 = (psvals.level > 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-02 20:00:25 +08:00
|
|
|
cmap = cmap_start = gimp_image_get_colormap (image_ID, &ncols);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
ct = coltab;
|
1999-01-04 06:41:12 +08:00
|
|
|
bw = 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
for (j = 0; j < 256; j++)
|
|
|
|
{
|
2000-01-26 01:46:56 +08:00
|
|
|
if (j >= ncols)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2008-12-04 00:07:32 +08:00
|
|
|
memset (ct, 0, 6);
|
2006-05-08 20:23:32 +08:00
|
|
|
ct += 6;
|
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
bw &= ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0)) ||
|
|
|
|
((cmap[0] == 255) && (cmap[1] == 255) && (cmap[2] == 255));
|
|
|
|
|
|
|
|
*(ct++) = (guchar) hex[(*cmap) >> 4];
|
|
|
|
*(ct++) = (guchar) hex[(*(cmap++)) & 0x0f];
|
|
|
|
*(ct++) = (guchar) hex[(*cmap) >> 4];
|
|
|
|
*(ct++) = (guchar) hex[(*(cmap++)) & 0x0f];
|
|
|
|
*(ct++) = (guchar) hex[(*cmap) >> 4];
|
|
|
|
*(ct++) = (guchar) hex[(*(cmap++)) & 0x0f];
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
if (bw)
|
2014-10-27 01:54:42 +08:00
|
|
|
return save_bw (output, image_ID, drawable_ID, error);
|
1999-01-04 06:41:12 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
|
|
format = gimp_drawable_get_format (drawable_ID);
|
2014-10-27 01:54:42 +08:00
|
|
|
bpp = babl_format_get_bytes_per_pixel (format);
|
|
|
|
width = gegl_buffer_get_width (buffer);
|
2013-05-14 22:13:19 +08:00
|
|
|
height = gegl_buffer_get_height (buffer);
|
|
|
|
|
1999-01-04 06:41:12 +08:00
|
|
|
tile_height = gimp_tile_height ();
|
|
|
|
|
|
|
|
/* allocate a buffer for retrieving information from the pixel region */
|
2014-10-27 01:54:42 +08:00
|
|
|
src = data = (guchar *) g_malloc (tile_height * width * bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Set up transformation in PostScript */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_setup (output, drawable_ID, width, height, 3 * 8, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Write read image procedure */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! level2)
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"{ currentfile scanline readhexstring pop } false 3\n"))
|
|
|
|
goto fail;
|
|
|
|
}
|
2000-01-23 06:26:20 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"%% Strings to hold RGB-samples per scanline\n"
|
|
|
|
"/rstr %d string def\n"
|
|
|
|
"/gstr %d string def\n"
|
|
|
|
"/bstr %d string def\n",
|
|
|
|
width, width, width))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
rstr readstring pop}\n"
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
gstr readstring pop}\n"
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
bstr readstring pop}\n"
|
|
|
|
"true 3\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
|
|
|
|
packb = (guchar *) g_malloc ((width * 105) / 100 + 2);
|
|
|
|
plane = (guchar *) g_malloc (width);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! ps_begin_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "colorimage\n"))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define GET_INDEX_TILE(begin) \
|
2014-10-27 01:54:42 +08:00
|
|
|
{ gint scan_lines; \
|
1997-11-25 06:05:25 +08:00
|
|
|
scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); \
|
2013-05-14 22:13:19 +08:00
|
|
|
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, i, width, scan_lines), \
|
|
|
|
1.0, format, begin, \
|
|
|
|
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); \
|
1997-11-25 06:05:25 +08:00
|
|
|
src = begin; }
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
2000-01-23 06:26:20 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((i % tile_height) == 0)
|
|
|
|
GET_INDEX_TILE (data); /* Get more data */
|
|
|
|
|
|
|
|
if (! level2)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! g_output_stream_write_all (output,
|
|
|
|
coltab + (*(src++)) * 6, 6, NULL,
|
|
|
|
NULL, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (((j + 1) % 13) == 0)
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
gint rgb;
|
2000-03-11 01:27:25 +08:00
|
|
|
|
|
|
|
for (rgb = 0; rgb < 3; rgb++)
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
guchar *src_ptr = src;
|
|
|
|
guchar *plane_ptr = plane;
|
|
|
|
gint nout;
|
|
|
|
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
*(plane_ptr++) = cmap_start[3 * *(src_ptr++) + rgb];
|
|
|
|
|
|
|
|
compress_packbits (width, plane, &nout, packb);
|
|
|
|
|
|
|
|
ascii85_init ();
|
|
|
|
|
|
|
|
if (! ascii85_nout (output, nout, packb, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* Write EOD of RunLengthDecode filter */
|
|
|
|
if (! ascii85_out (output, 128, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! ascii85_done (output, error))
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
src += width;
|
|
|
|
}
|
2003-06-13 22:37:00 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) i / (gdouble) height);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! ps_end_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "showpage\n"))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
g_free (data);
|
2014-10-27 01:54:42 +08:00
|
|
|
g_free (packb);
|
|
|
|
g_free (plane);
|
|
|
|
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
fail:
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
g_free (data);
|
|
|
|
g_free (packb);
|
|
|
|
g_free (plane);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 22:13:19 +08:00
|
|
|
g_object_unref (buffer);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
return FALSE;
|
2004-11-19 05:10:12 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#undef GET_INDEX_TILE
|
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
save_rgb (GOutputStream *output,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID,
|
|
|
|
GError **error)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
GeglBuffer *buffer = NULL;
|
|
|
|
const Babl *format;
|
|
|
|
gint bpp;
|
|
|
|
gint height, width, tile_height;
|
|
|
|
gint i, j;
|
|
|
|
guchar *data, *src;
|
|
|
|
guchar *packb = NULL;
|
|
|
|
guchar *plane = NULL;
|
|
|
|
gboolean level2 = (psvals.level > 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 16:54:00 +08:00
|
|
|
buffer = gimp_drawable_get_buffer (drawable_ID);
|
|
|
|
format = babl_format ("R'G'B' u8");
|
2014-10-27 01:54:42 +08:00
|
|
|
bpp = babl_format_get_bytes_per_pixel (format);
|
|
|
|
width = gegl_buffer_get_width (buffer);
|
2013-05-14 16:54:00 +08:00
|
|
|
height = gegl_buffer_get_height (buffer);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
tile_height = gimp_tile_height ();
|
|
|
|
|
|
|
|
/* allocate a buffer for retrieving information from the pixel region */
|
2013-05-14 16:54:00 +08:00
|
|
|
src = data = g_new (guchar, tile_height * width * bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Set up transformation in PostScript */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! save_ps_setup (output, drawable_ID, width, height, 3 * 8, error))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Write read image procedure */
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! level2)
|
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"{ currentfile scanline readhexstring pop } false 3\n"))
|
|
|
|
goto fail;
|
|
|
|
}
|
2000-01-23 06:26:20 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
if (! print (output, error,
|
|
|
|
"%% Strings to hold RGB-samples per scanline\n"
|
|
|
|
"/rstr %d string def\n"
|
|
|
|
"/gstr %d string def\n"
|
|
|
|
"/bstr %d string def\n",
|
|
|
|
width, width, width))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error,
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
rstr readstring pop}\n"
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
gstr readstring pop}\n"
|
|
|
|
"{currentfile /ASCII85Decode filter /RunLengthDecode filter\
|
|
|
|
bstr readstring pop}\n"
|
|
|
|
"true 3\n"))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* Allocate buffer for packbits data. Worst case: Less than 1% increase */
|
|
|
|
packb = g_new (guchar, (width * 105) / 100 + 2);
|
|
|
|
plane = g_new (guchar, width);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! ps_begin_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "colorimage\n"))
|
|
|
|
goto fail;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define GET_RGB_TILE(begin) \
|
2014-10-27 01:54:42 +08:00
|
|
|
{ gint scan_lines; \
|
1997-11-25 06:05:25 +08:00
|
|
|
scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); \
|
2013-05-14 16:54:00 +08:00
|
|
|
gegl_buffer_get (buffer, GEGL_RECTANGLE (0, i, width, scan_lines), \
|
|
|
|
1.0, format, begin, \
|
|
|
|
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); \
|
1997-11-25 06:05:25 +08:00
|
|
|
src = begin; }
|
|
|
|
|
|
|
|
for (i = 0; i < height; i++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if ((i % tile_height) == 0)
|
|
|
|
GET_RGB_TILE (data); /* Get more data */
|
|
|
|
|
|
|
|
if (! level2)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*src) >> 4])) /* Red */
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*(src++)) & 0x0f]))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*src) >> 4])) /* Green */
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*(src++)) & 0x0f]))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*src) >> 4])) /* Blue */
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "%c",
|
|
|
|
hex[(*(src++)) & 0x0f]))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (((j+1) % 13) == 0)
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
if (! print (output, error, "\n"))
|
|
|
|
goto fail;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2014-10-27 01:54:42 +08:00
|
|
|
{
|
|
|
|
gint rgb;
|
2000-03-11 01:27:25 +08:00
|
|
|
|
|
|
|
for (rgb = 0; rgb < 3; rgb++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2014-10-27 01:54:42 +08:00
|
|
|
guchar *src_ptr = src + rgb;
|
|
|
|
guchar *plane_ptr = plane;
|
|
|
|
gint nout;
|
|
|
|
|
|
|
|
for (j = 0; j < width; j++)
|
|
|
|
{
|
|
|
|
*(plane_ptr++) = *src_ptr;
|
|
|
|
src_ptr += 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
compress_packbits (width, plane, &nout, packb);
|
|
|
|
|
|
|
|
ascii85_init ();
|
|
|
|
|
|
|
|
if (! ascii85_nout (output, nout, packb, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* Write EOD of RunLengthDecode filter */
|
|
|
|
if (! ascii85_out (output, 128, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! ascii85_done (output, error))
|
|
|
|
goto fail;
|
2000-03-11 01:27:25 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
src += 3 * width;
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
2003-06-13 22:37:00 +08:00
|
|
|
|
|
|
|
if ((i % 20) == 0)
|
2014-10-27 01:54:42 +08:00
|
|
|
gimp_progress_update ((gdouble) i / (gdouble) height);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2014-10-27 01:54:42 +08:00
|
|
|
|
2011-04-11 01:05:08 +08:00
|
|
|
gimp_progress_update (1.0);
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
if (! ps_end_data (output, error))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (! print (output, error, "showpage\n"))
|
|
|
|
goto fail;
|
2003-06-13 22:37:00 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
g_free (data);
|
|
|
|
g_free (packb);
|
|
|
|
g_free (plane);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2013-05-14 16:54:00 +08:00
|
|
|
g_object_unref (buffer);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-19 05:10:12 +08:00
|
|
|
return TRUE;
|
2014-10-27 01:54:42 +08:00
|
|
|
|
|
|
|
fail:
|
|
|
|
|
|
|
|
g_free (data);
|
|
|
|
g_free (packb);
|
|
|
|
g_free (plane);
|
|
|
|
|
|
|
|
g_object_unref (buffer);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#undef GET_RGB_TILE
|
|
|
|
}
|
|
|
|
|
2014-10-27 01:54:42 +08:00
|
|
|
static gboolean
|
|
|
|
print (GOutputStream *output,
|
|
|
|
GError **error,
|
|
|
|
const gchar *format,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
gboolean success;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
success = g_output_stream_vprintf (output, NULL, NULL,
|
|
|
|
error, format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Load interface functions */
|
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
static gint32
|
|
|
|
count_ps_pages (const gchar *filename)
|
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
FILE *psfile;
|
|
|
|
gchar *extension;
|
|
|
|
gchar buf[1024];
|
2005-08-15 16:48:45 +08:00
|
|
|
gint32 num_pages = 0;
|
|
|
|
gint32 showpage_count = 0;
|
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
extension = strrchr (filename, '.');
|
|
|
|
if (extension)
|
|
|
|
{
|
|
|
|
extension = g_ascii_strdown (extension + 1, -1);
|
|
|
|
|
|
|
|
if (strcmp (extension, "eps") == 0)
|
|
|
|
{
|
|
|
|
g_free (extension);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (extension);
|
|
|
|
}
|
2005-08-15 16:48:45 +08:00
|
|
|
|
|
|
|
psfile = g_fopen (filename, "r");
|
|
|
|
|
|
|
|
if (psfile == NULL)
|
|
|
|
{
|
|
|
|
g_message (_("Could not open '%s' for reading: %s"),
|
|
|
|
gimp_filename_to_utf8 (filename), g_strerror (errno));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (num_pages == 0 && !feof (psfile))
|
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
fgets (buf, sizeof (buf), psfile);
|
2005-08-15 16:48:45 +08:00
|
|
|
|
2007-05-29 23:29:37 +08:00
|
|
|
if (strncmp (buf + 2, "Pages:", 6) == 0)
|
|
|
|
sscanf (buf + strlen ("%%Pages:"), "%d", &num_pages);
|
|
|
|
else if (strncmp (buf, "showpage", 8) == 0)
|
2005-08-15 16:48:45 +08:00
|
|
|
showpage_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (feof (psfile) && num_pages < 1 && showpage_count > 0)
|
|
|
|
num_pages = showpage_count;
|
|
|
|
|
|
|
|
fclose (psfile);
|
|
|
|
|
|
|
|
return num_pages;
|
|
|
|
}
|
|
|
|
|
2004-05-20 01:53:21 +08:00
|
|
|
static gboolean
|
2017-12-14 03:35:41 +08:00
|
|
|
load_dialog (const gchar *filename)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2014-06-23 05:01:31 +08:00
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *main_vbox;
|
|
|
|
GtkWidget *hbox;
|
|
|
|
GtkWidget *frame;
|
|
|
|
GtkWidget *vbox;
|
2018-05-09 05:06:26 +08:00
|
|
|
GtkWidget *grid;
|
2014-06-23 05:01:31 +08:00
|
|
|
GtkWidget *spinbutton;
|
|
|
|
GtkAdjustment *adj;
|
|
|
|
GtkWidget *entry = NULL;
|
|
|
|
GtkWidget *target = NULL;
|
|
|
|
GtkWidget *toggle;
|
|
|
|
GtkWidget *selector = NULL;
|
|
|
|
gint32 page_count;
|
|
|
|
gchar *range = NULL;
|
|
|
|
gboolean run;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
page_count = count_ps_pages (filename);
|
|
|
|
|
2005-08-15 18:30:39 +08:00
|
|
|
gimp_ui_init (PLUG_IN_BINARY, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2011-04-09 02:31:34 +08:00
|
|
|
dialog = gimp_dialog_new (_("Import from PostScript"), PLUG_IN_ROLE,
|
2003-11-06 23:27:05 +08:00
|
|
|
NULL, 0,
|
2006-05-08 20:23:32 +08:00
|
|
|
gimp_standard_help_func, LOAD_PS_PROC,
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2017-02-12 23:18:24 +08:00
|
|
|
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
|
|
|
_("_Import"), GTK_RESPONSE_OK,
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2018-05-10 23:04:37 +08:00
|
|
|
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
|
2005-08-15 16:48:45 +08:00
|
|
|
GTK_RESPONSE_OK,
|
|
|
|
GTK_RESPONSE_CANCEL,
|
|
|
|
-1);
|
2005-02-09 04:40:33 +08:00
|
|
|
|
2007-05-15 15:12:15 +08:00
|
|
|
gimp_window_set_transient (GTK_WINDOW (dialog));
|
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
|
2009-07-16 00:57:12 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
|
|
|
main_vbox, TRUE, TRUE, 0);
|
2000-01-08 23:23:28 +08:00
|
|
|
gtk_widget_show (main_vbox);
|
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
if (page_count > 1)
|
|
|
|
{
|
|
|
|
selector = gimp_page_selector_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), selector, TRUE, TRUE, 0);
|
|
|
|
gimp_page_selector_set_n_pages (GIMP_PAGE_SELECTOR (selector),
|
2006-05-08 20:23:32 +08:00
|
|
|
page_count);
|
2005-08-15 16:48:45 +08:00
|
|
|
gimp_page_selector_set_target (GIMP_PAGE_SELECTOR (selector),
|
2006-05-08 20:23:32 +08:00
|
|
|
ps_pagemode);
|
2005-10-28 22:57:32 +08:00
|
|
|
|
2005-08-15 16:48:45 +08:00
|
|
|
gtk_widget_show (selector);
|
2005-10-28 22:57:32 +08:00
|
|
|
|
|
|
|
g_signal_connect_swapped (selector, "activate",
|
|
|
|
G_CALLBACK (gtk_window_activate_default),
|
|
|
|
dialog);
|
2005-08-15 16:48:45 +08:00
|
|
|
}
|
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
|
|
|
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
|
2000-01-08 23:23:28 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (hbox);
|
|
|
|
|
|
|
|
/* Rendering */
|
2004-05-20 01:53:21 +08:00
|
|
|
frame = gimp_frame_new (_("Rendering"));
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
|
|
|
|
|
|
|
/* Resolution/Width/Height/Pages labels */
|
2018-05-09 05:06:26 +08:00
|
|
|
grid = gtk_grid_new ();
|
|
|
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (grid);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
adj = gtk_adjustment_new (plvals.resolution,
|
|
|
|
MIN_RESOLUTION, MAX_RESOLUTION,
|
|
|
|
1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (adj, 1.0, 0);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
|
|
|
|
_("Resolution:"), 0.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2007-05-15 15:12:15 +08:00
|
|
|
|
2007-03-01 20:48:00 +08:00
|
|
|
g_signal_connect (adj, "value-changed",
|
|
|
|
G_CALLBACK (resolution_change_callback),
|
|
|
|
&plvals.resolution);
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (adj, "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_int_adjustment_update),
|
|
|
|
&plvals.resolution);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
adj = gtk_adjustment_new (plvals.width,
|
|
|
|
1, GIMP_MAX_IMAGE_SIZE,
|
|
|
|
1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
ps_width_spinbutton = gtk_spin_button_new (adj, 1.0, 0);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
|
|
|
|
_("_Width:"), 0.0, 0.5,
|
|
|
|
ps_width_spinbutton, 1);
|
2014-06-23 05:01:31 +08:00
|
|
|
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (adj, "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_int_adjustment_update),
|
|
|
|
&plvals.width);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
adj = gtk_adjustment_new (plvals.height,
|
|
|
|
1, GIMP_MAX_IMAGE_SIZE,
|
|
|
|
1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
ps_height_spinbutton = gtk_spin_button_new (adj, 1.0, 0);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 2,
|
|
|
|
_("_Height:"), 0.0, 0.5,
|
|
|
|
ps_height_spinbutton, 1);
|
2014-06-23 05:01:31 +08:00
|
|
|
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (adj, "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_int_adjustment_update),
|
|
|
|
&plvals.height);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2017-12-14 03:35:41 +08:00
|
|
|
if (page_count == 0)
|
2005-08-15 16:48:45 +08:00
|
|
|
{
|
|
|
|
entry = gtk_entry_new ();
|
|
|
|
gtk_widget_set_size_request (entry, 80, -1);
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (entry), plvals.pages);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 3,
|
|
|
|
_("Pages:"), 0.0, 0.5,
|
|
|
|
entry, 1);
|
2005-08-15 16:48:45 +08:00
|
|
|
|
|
|
|
g_signal_connect (entry, "changed",
|
|
|
|
G_CALLBACK (load_pages_entry_callback),
|
|
|
|
NULL);
|
|
|
|
gimp_help_set_help_data (GTK_WIDGET (entry),
|
|
|
|
_("Pages to load (e.g.: 1-4 or 1,3,5-7)"), NULL);
|
|
|
|
|
2011-03-17 21:31:39 +08:00
|
|
|
target = gtk_combo_box_text_new ();
|
|
|
|
gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (target),
|
|
|
|
GIMP_PAGE_SELECTOR_TARGET_LAYERS,
|
|
|
|
_("Layers"));
|
|
|
|
gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (target),
|
|
|
|
GIMP_PAGE_SELECTOR_TARGET_IMAGES,
|
|
|
|
_("Images"));
|
2005-08-15 16:48:45 +08:00
|
|
|
gtk_combo_box_set_active (GTK_COMBO_BOX (target), (int) ps_pagemode);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 4,
|
|
|
|
_("Open as"), 0.0, 0.5,
|
|
|
|
target, 1);
|
2005-08-15 16:48:45 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-08 23:23:28 +08:00
|
|
|
toggle = gtk_check_button_new_with_label (_("Try Bounding Box"));
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), plvals.use_bbox);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (toggle);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (toggle, "toggled",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_toggle_button_update),
|
|
|
|
&plvals.use_bbox);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
2013-06-07 05:26:16 +08:00
|
|
|
/* Coloring */
|
2003-11-15 02:05:39 +08:00
|
|
|
frame = gimp_int_radio_group_new (TRUE, _("Coloring"),
|
2006-05-08 20:23:32 +08:00
|
|
|
G_CALLBACK (gimp_radio_button_update),
|
|
|
|
&plvals.pnm_type, plvals.pnm_type,
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
_("B/W"), 4, NULL,
|
|
|
|
_("Gray"), 5, NULL,
|
|
|
|
_("Color"), 6, NULL,
|
|
|
|
_("Automatic"), 7, NULL,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
|
|
|
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
|
2000-01-08 23:23:28 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (hbox);
|
|
|
|
|
2004-06-22 03:15:08 +08:00
|
|
|
frame = gimp_int_radio_group_new (TRUE, _("Text antialiasing"),
|
2006-05-08 20:23:32 +08:00
|
|
|
G_CALLBACK (gimp_radio_button_update),
|
|
|
|
&plvals.textalpha, plvals.textalpha,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2011-11-17 06:13:03 +08:00
|
|
|
C_("antialiasing", "None"), 1, NULL,
|
|
|
|
_("Weak"), 2, NULL,
|
|
|
|
_("Strong"), 4, NULL,
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
2004-06-22 03:15:08 +08:00
|
|
|
frame = gimp_int_radio_group_new (TRUE, _("Graphic antialiasing"),
|
2006-05-08 20:23:32 +08:00
|
|
|
G_CALLBACK (gimp_radio_button_update),
|
|
|
|
&plvals.graphicsalpha, plvals.graphicsalpha,
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2011-11-17 06:13:03 +08:00
|
|
|
C_("antialiasing", "None"), 1, NULL,
|
|
|
|
_("Weak"), 2, NULL,
|
|
|
|
_("Strong"), 4, NULL,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
|
|
|
gtk_widget_show (dialog);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-12 02:11:56 +08:00
|
|
|
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-10-28 22:57:32 +08:00
|
|
|
if (selector)
|
2005-08-15 16:48:45 +08:00
|
|
|
{
|
|
|
|
range = gimp_page_selector_get_selected_range (GIMP_PAGE_SELECTOR (selector));
|
|
|
|
|
|
|
|
if (strlen (range) < 1)
|
|
|
|
{
|
|
|
|
gimp_page_selector_select_all (GIMP_PAGE_SELECTOR (selector));
|
|
|
|
range = gimp_page_selector_get_selected_range (GIMP_PAGE_SELECTOR (selector));
|
|
|
|
}
|
|
|
|
|
2018-10-22 21:41:18 +08:00
|
|
|
strncpy (plvals.pages, range, sizeof (plvals.pages) - 1);
|
2005-08-15 16:48:45 +08:00
|
|
|
plvals.pages[strlen (range)] = '\0';
|
|
|
|
|
|
|
|
ps_pagemode = gimp_page_selector_get_target (GIMP_PAGE_SELECTOR (selector));
|
|
|
|
}
|
2017-12-14 03:35:41 +08:00
|
|
|
else if (page_count == 0)
|
2005-08-15 16:48:45 +08:00
|
|
|
{
|
|
|
|
ps_pagemode = gtk_combo_box_get_active (GTK_COMBO_BOX (target));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-22 21:41:18 +08:00
|
|
|
strncpy (plvals.pages, "1", sizeof (plvals.pages) - 1);
|
2005-08-15 16:48:45 +08:00
|
|
|
ps_pagemode = GIMP_PAGE_SELECTOR_TARGET_IMAGES;
|
|
|
|
}
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_widget_destroy (dialog);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
return run;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2000-01-26 01:46:56 +08:00
|
|
|
load_pages_entry_callback (GtkWidget *widget,
|
2006-05-08 20:23:32 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2004-11-19 05:36:10 +08:00
|
|
|
gsize nelem = sizeof (plvals.pages);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
strncpy (plvals.pages, gtk_entry_get_text (GTK_ENTRY (widget)), nelem);
|
|
|
|
plvals.pages[nelem-1] = '\0';
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Save interface functions */
|
|
|
|
|
2004-05-20 01:53:21 +08:00
|
|
|
static gboolean
|
1997-11-25 06:05:25 +08:00
|
|
|
save_dialog (void)
|
|
|
|
{
|
|
|
|
SaveDialogVals *vals;
|
2014-06-23 05:01:31 +08:00
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *toggle;
|
|
|
|
GtkWidget *frame, *uframe;
|
|
|
|
GtkWidget *hbox, *vbox;
|
|
|
|
GtkWidget *main_vbox[2];
|
2018-05-09 05:06:26 +08:00
|
|
|
GtkWidget *grid;
|
2014-06-23 05:01:31 +08:00
|
|
|
GtkWidget *spinbutton;
|
|
|
|
GtkAdjustment *adj;
|
|
|
|
gint j;
|
|
|
|
gboolean run;
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2000-07-31 06:48:35 +08:00
|
|
|
vals = g_new (SaveDialogVals, 1);
|
2000-01-26 01:46:56 +08:00
|
|
|
vals->level = (psvals.level > 1);
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2009-07-21 20:10:29 +08:00
|
|
|
dialog = gimp_export_dialog_new (_("PostScript"), PLUG_IN_BINARY, SAVE_PS_PROC);
|
2005-09-10 02:38:00 +08:00
|
|
|
|
1997-12-26 15:08:20 +08:00
|
|
|
/* Main hbox */
|
2011-09-30 18:17:53 +08:00
|
|
|
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
|
2009-07-21 20:10:29 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
|
2009-07-16 00:57:12 +08:00
|
|
|
hbox, FALSE, FALSE, 0);
|
1997-12-26 15:08:20 +08:00
|
|
|
main_vbox[0] = main_vbox[1] = NULL;
|
|
|
|
|
2001-12-06 10:28:58 +08:00
|
|
|
for (j = 0; j < G_N_ELEMENTS (main_vbox); j++)
|
2000-01-08 23:23:28 +08:00
|
|
|
{
|
2011-09-30 18:17:53 +08:00
|
|
|
main_vbox[j] = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), main_vbox[j], FALSE, TRUE, 0);
|
|
|
|
gtk_widget_show (main_vbox[j]);
|
2000-01-08 23:23:28 +08:00
|
|
|
}
|
1997-12-26 15:08:20 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Image Size */
|
2004-05-20 01:53:21 +08:00
|
|
|
frame = gimp_frame_new (_("Image Size"));
|
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox[0]), frame, FALSE, TRUE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
|
|
|
|
|
|
|
/* Width/Height/X-/Y-offset labels */
|
2018-05-09 05:06:26 +08:00
|
|
|
grid = gtk_grid_new ();
|
|
|
|
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
|
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (grid);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
vals->adjustment[0] = gtk_adjustment_new (psvals.width,
|
|
|
|
1e-5, GIMP_MAX_IMAGE_SIZE, 1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (vals->adjustment[0], 1.0, 2);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
|
|
|
|
_("_Width:"), 0.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (vals->adjustment[0], "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_double_adjustment_update),
|
|
|
|
&psvals.width);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
vals->adjustment[1] = gtk_adjustment_new (psvals.height,
|
|
|
|
1e-5, GIMP_MAX_IMAGE_SIZE, 1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (vals->adjustment[1], 1.0, 2);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 1,
|
|
|
|
_("_Height:"), 0.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (vals->adjustment[1], "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_double_adjustment_update),
|
|
|
|
&psvals.height);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
vals->adjustment[2] = gtk_adjustment_new (psvals.x_offset,
|
|
|
|
0.0, GIMP_MAX_IMAGE_SIZE, 1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (vals->adjustment[2], 1.0, 2);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 2,
|
|
|
|
_("_X offset:"), 0.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (vals->adjustment[2], "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_double_adjustment_update),
|
|
|
|
&psvals.x_offset);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
vals->adjustment[3] = gtk_adjustment_new (psvals.y_offset,
|
|
|
|
0.0, GIMP_MAX_IMAGE_SIZE, 1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (vals->adjustment[3], 1.0, 2);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 3,
|
|
|
|
_("_Y offset:"), 0.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (vals->adjustment[3], "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_double_adjustment_update),
|
|
|
|
&psvals.y_offset);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-06-22 03:15:08 +08:00
|
|
|
toggle = gtk_check_button_new_with_mnemonic (_("_Keep aspect ratio"));
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), psvals.keep_ratio);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (toggle);
|
|
|
|
|
2001-12-31 08:21:10 +08:00
|
|
|
gimp_help_set_help_data (toggle,
|
2006-08-29 21:32:22 +08:00
|
|
|
_("When toggled, the resulting image will be "
|
|
|
|
"scaled to fit into the given size without "
|
|
|
|
"changing the aspect ratio."),
|
2006-05-08 20:23:32 +08:00
|
|
|
"#keep_aspect_ratio"),
|
2001-12-31 08:21:10 +08:00
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (toggle, "toggled",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_toggle_button_update),
|
|
|
|
&psvals.keep_ratio);
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Unit */
|
2003-11-15 02:05:39 +08:00
|
|
|
uframe = gimp_int_radio_group_new (TRUE, _("Unit"),
|
2006-05-08 20:23:32 +08:00
|
|
|
G_CALLBACK (save_unit_toggle_update),
|
|
|
|
vals, psvals.unit_mm,
|
2001-12-31 08:21:10 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
_("_Inch"), FALSE, NULL,
|
|
|
|
_("_Millimeter"), TRUE, NULL,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2001-12-31 08:21:10 +08:00
|
|
|
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox[0]), uframe, TRUE, TRUE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (uframe);
|
|
|
|
|
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
|
|
|
/* Rotation */
|
2003-11-15 02:05:39 +08:00
|
|
|
frame = gimp_int_radio_group_new (TRUE, _("Rotation"),
|
2006-05-08 20:23:32 +08:00
|
|
|
G_CALLBACK (gimp_radio_button_update),
|
|
|
|
&psvals.rotate, psvals.rotate,
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
"_0", 0, NULL,
|
|
|
|
"_90", 90, NULL,
|
|
|
|
"_180", 180, NULL,
|
|
|
|
"_270", 270, NULL,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-05-08 20:23:32 +08:00
|
|
|
NULL);
|
2001-12-31 08:21:10 +08:00
|
|
|
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox[1]), frame, TRUE, TRUE, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
1997-12-26 15:08:20 +08:00
|
|
|
/* Format */
|
2004-05-20 01:53:21 +08:00
|
|
|
frame = gimp_frame_new (_("Output"));
|
1997-12-26 15:08:20 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (main_vbox[1]), frame, TRUE, TRUE, 0);
|
2000-01-08 23:23:28 +08:00
|
|
|
|
2011-09-30 18:17:53 +08:00
|
|
|
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
1997-12-26 15:08:20 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
|
|
|
|
2004-06-22 03:15:08 +08:00
|
|
|
toggle = gtk_check_button_new_with_mnemonic (_("_PostScript level 2"));
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
2000-01-23 06:26:20 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), vals->level);
|
|
|
|
gtk_widget_show (toggle);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (toggle, "toggled",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_toggle_button_update),
|
|
|
|
&vals->level);
|
|
|
|
|
2003-01-19 22:40:56 +08:00
|
|
|
toggle = gtk_check_button_new_with_mnemonic (_("_Encapsulated PostScript"));
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), psvals.eps);
|
1997-12-26 15:08:20 +08:00
|
|
|
gtk_widget_show (toggle);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (toggle, "toggled",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_toggle_button_update),
|
|
|
|
&psvals.eps);
|
|
|
|
|
2003-01-19 22:40:56 +08:00
|
|
|
toggle = gtk_check_button_new_with_mnemonic (_("P_review"));
|
2004-05-20 01:53:21 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), psvals.preview);
|
1997-12-26 15:08:20 +08:00
|
|
|
gtk_widget_show (toggle);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (toggle, "toggled",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_toggle_button_update),
|
|
|
|
&psvals.preview);
|
|
|
|
|
1997-12-26 15:08:20 +08:00
|
|
|
/* Preview size label/entry */
|
2018-05-09 05:06:26 +08:00
|
|
|
grid = gtk_grid_new ();
|
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (grid);
|
1997-12-26 15:08:20 +08:00
|
|
|
|
2011-05-11 17:41:26 +08:00
|
|
|
g_object_bind_property (toggle, "active",
|
2018-05-09 05:06:26 +08:00
|
|
|
grid, "sensitive",
|
2011-05-11 17:41:26 +08:00
|
|
|
G_BINDING_SYNC_CREATE);
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2018-06-25 00:15:16 +08:00
|
|
|
adj = gtk_adjustment_new (psvals.preview_size,
|
|
|
|
0, 1024, 1, 10, 0);
|
2014-06-23 05:01:31 +08:00
|
|
|
spinbutton = gtk_spin_button_new (adj, 1.0, 0);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
2018-05-09 05:06:26 +08:00
|
|
|
gimp_grid_attach_aligned (GTK_GRID (grid), 0, 0,
|
|
|
|
_("Preview _size:"), 1.0, 0.5,
|
|
|
|
spinbutton, 1);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_widget_show (spinbutton);
|
1997-12-26 15:08:20 +08:00
|
|
|
|
2005-07-01 00:03:24 +08:00
|
|
|
g_signal_connect (adj, "value-changed",
|
2001-12-31 08:21:10 +08:00
|
|
|
G_CALLBACK (gimp_int_adjustment_update),
|
|
|
|
&psvals.preview_size);
|
|
|
|
|
1997-12-26 15:08:20 +08:00
|
|
|
gtk_widget_show (vbox);
|
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
|
|
|
gtk_widget_show (hbox);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_widget_show (dialog);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-12 02:11:56 +08:00
|
|
|
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
|
|
|
gtk_widget_destroy (dialog);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-03-11 01:27:25 +08:00
|
|
|
psvals.level = (vals->level) ? 2 : 1;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
g_free (vals);
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
return run;
|
2000-01-26 01:46:56 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2000-01-26 01:46:56 +08:00
|
|
|
save_unit_toggle_update (GtkWidget *widget,
|
2006-05-08 20:23:32 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2008-06-29 02:40:23 +08:00
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
|
2000-01-26 01:46:56 +08:00
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
SaveDialogVals *vals = (SaveDialogVals *) data;
|
|
|
|
gdouble factor;
|
|
|
|
gdouble value;
|
|
|
|
gint unit_mm;
|
|
|
|
gint i;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-31 08:21:10 +08:00
|
|
|
unit_mm = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
|
|
|
"gimp-item-data"));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
psvals.unit_mm = unit_mm;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
if (unit_mm)
|
2006-05-08 20:23:32 +08:00
|
|
|
factor = 25.4;
|
2000-01-26 01:46:56 +08:00
|
|
|
else
|
2006-05-08 20:23:32 +08:00
|
|
|
factor = 1.0 / 25.4;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
for (i = 0; i < 4; i++)
|
2006-05-08 20:23:32 +08:00
|
|
|
{
|
2014-06-23 05:01:31 +08:00
|
|
|
value = gtk_adjustment_get_value (vals->adjustment[i]) * factor;
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2014-06-23 05:01:31 +08:00
|
|
|
gtk_adjustment_set_value (vals->adjustment[i], value);
|
2006-05-08 20:23:32 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
2007-03-01 20:48:00 +08:00
|
|
|
|
|
|
|
static gboolean
|
|
|
|
resolution_change_callback (GtkAdjustment *adjustment,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2007-05-29 23:29:37 +08:00
|
|
|
guint *old_resolution = (guint *) data;
|
|
|
|
gdouble ratio;
|
2007-03-01 20:48:00 +08:00
|
|
|
|
|
|
|
if (*old_resolution)
|
2009-10-10 20:46:05 +08:00
|
|
|
ratio = (gdouble) gtk_adjustment_get_value (adjustment) / *old_resolution;
|
2007-03-01 20:48:00 +08:00
|
|
|
else
|
2007-05-29 23:29:37 +08:00
|
|
|
ratio = 1.0;
|
|
|
|
|
2007-03-01 20:48:00 +08:00
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (ps_width_spinbutton),
|
2008-06-29 02:40:23 +08:00
|
|
|
gtk_spin_button_get_value (GTK_SPIN_BUTTON (ps_width_spinbutton)) * ratio);
|
2007-03-01 20:48:00 +08:00
|
|
|
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (ps_height_spinbutton),
|
2008-06-29 02:40:23 +08:00
|
|
|
gtk_spin_button_get_value (GTK_SPIN_BUTTON (ps_height_spinbutton)) * ratio);
|
2007-05-15 15:12:15 +08:00
|
|
|
|
2007-03-01 20:48:00 +08:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
}
|