Commit 591b2d35 authored by Michael Natterer's avatar Michael Natterer 😴
Browse files

plug-ins: port file-ps' saving code to GIO

parent 8dae8029
......@@ -171,86 +171,101 @@ static const char hex[] = "0123456789abcdef";
/* Declare some local functions.
*/
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 gint save_image (const gchar *filename,
gint32 image_ID,
gint32 drawable_ID,
GError **error);
static gint save_gray (FILE *ofp,
gint32 image_ID,
gint32 drawable_ID);
static gint save_bw (FILE *ofp,
gint32 image_ID,
gint32 drawable_ID);
static gint save_index (FILE *ofp,
gint32 image_ID,
gint32 drawable_ID);
static gint save_rgb (FILE *ofp,
gint32 image_ID,
gint32 drawable_ID);
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 save_ps_header (FILE *ofp,
const gchar *filename);
static void save_ps_setup (FILE *ofp,
gint32 drawable_ID,
gint width,
gint height,
gint bpp);
static void save_ps_trailer (FILE *ofp);
static void save_ps_preview (FILE *ofp,
gint32 drawable_ID);
static void dither_grey (const guchar *grey,
guchar *bw,
gint npix,
gint linecount);
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);
/* Dialog-handling */
......@@ -301,87 +316,127 @@ static GimpPageSelectorTarget ps_pagemode = GIMP_PAGE_SELECTOR_TARGET_LAYERS;
static void
ascii85_init (void)
{
ascii85_len = 0;
ascii85_len = 0;
ascii85_linewidth = 0;
}
static void
ascii85_flush (FILE *ofp)
static gboolean
ascii85_flush (GOutputStream *output,
GError **error)
{
char c[5];
int i;
gchar c[5];
gint i;
gboolean zero_case = (ascii85_buf == 0);
static int max_linewidth = 75;
GString *string = g_string_new (NULL);
static gint max_linewidth = 75;
for (i=4; i >= 0; i--)
for (i = 4; i >= 0; i--)
{
c[i] = (ascii85_buf % 85) + '!';
ascii85_buf /= 85;
}
/* check for special case: "!!!!!" becomes "z", but only if not
* at end of data. */
if (zero_case && (ascii85_len == 4))
{
if (ascii85_linewidth >= max_linewidth)
{
putc ('\n', ofp);
ascii85_linewidth = 0;
}
putc ('z', ofp);
{
g_string_append_c (string, '\n');
ascii85_linewidth = 0;
}
g_string_append_c (string, 'z');
ascii85_linewidth++;
}
else
{
for (i=0; i < ascii85_len+1; i++)
{
if ((ascii85_linewidth >= max_linewidth) && (c[i] != '%'))
for (i = 0; i < ascii85_len + 1; i++)
{
putc ('\n', ofp);
ascii85_linewidth = 0;
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++;
}
putc (c[i], ofp);
ascii85_linewidth++;
}
}
ascii85_len = 0;
ascii85_buf = 0;
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;
}
static inline void
ascii85_out (unsigned char byte, FILE *ofp)
static inline gboolean
ascii85_out (GOutputStream *output,
guchar byte,
GError **error)
{
if (ascii85_len == 4)
ascii85_flush (ofp);
if (! ascii85_flush (output, error))
return FALSE;
ascii85_buf <<= 8;
ascii85_buf |= byte;
ascii85_len++;
return TRUE;
}
static void
ascii85_nout (int n, unsigned char *uptr, FILE *ofp)
static gboolean
ascii85_nout (GOutputStream *output,
gint n,
guchar *uptr,
GError **error)
{
while (n-- > 0)
{
ascii85_out (*uptr, ofp);
uptr++;
}
while (n-- > 0)
{
if (! ascii85_out (output, *uptr, error))
return FALSE;
uptr++;
}
return TRUE;
}
static void
ascii85_done (FILE *ofp)
static gboolean
ascii85_done (GOutputStream *output,
GError **error)
{
if (ascii85_len)
{
/* zero any unfilled buffer portion, then flush */
ascii85_buf <<= (8 * (4-ascii85_len));
ascii85_flush (ofp);
ascii85_buf <<= (8 * (4 - ascii85_len));
if (! ascii85_flush (output, error))
return FALSE;
}
putc ('~', ofp);
putc ('>', ofp);
putc ('\n', ofp);
if (! print (output, error, "~>\n"))
return FALSE;
return TRUE;
}
......@@ -471,46 +526,65 @@ compress_packbits (int nin,
typedef struct
{
long eol;
long begin_data;
goffset eol;
goffset begin_data;
} PS_DATA_POS;
static PS_DATA_POS ps_data_pos = { 0, 0 };
static void
ps_begin_data (FILE *ofp)
static gboolean
ps_begin_data (GOutputStream *output,
GError **error)
{
/* %%BeginData: 123456789012 ASCII Bytes */
fprintf (ofp, "%s", "%%BeginData: ");
fflush (ofp);
ps_data_pos.eol = ftell (ofp);
fprintf (ofp, "\n");
fflush (ofp);
ps_data_pos.begin_data = ftell (ofp);
/* %%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;
}
static void
ps_end_data (FILE *ofp)
static gboolean
ps_end_data (GOutputStream *output,
GError **error)
{
goffset end_data;
gchar s[64];
{long end_data;
char s[64];
if ((ps_data_pos.begin_data > 0) && (ps_data_pos.eol > 0))
{
end_data = g_seekable_tell (G_SEEKABLE (output));
if ((ps_data_pos.begin_data > 0) && (ps_data_pos.eol > 0))
{
fflush (ofp);
end_data = ftell (ofp);
if (end_data > 0)
{
sprintf (s, "%ld ASCII Bytes", end_data - ps_data_pos.begin_data);
if (fseek (ofp, ps_data_pos.eol - strlen (s), SEEK_SET) == 0)
{
fprintf (ofp, "%s", s);
fseek (ofp, 0, SEEK_END);
}
}
}
fprintf (ofp, "%s\n", "%%EndData");
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;
}
......@@ -676,6 +750,7 @@ query (void)
save_args, NULL);
gimp_register_file_handler_mime (SAVE_PS_PROC, "application/postscript");
gimp_register_file_handler_uri (SAVE_PS_PROC);
gimp_register_save_handler (SAVE_PS_PROC, "ps", "");
gimp_install_procedure (SAVE_EPS_PROC,
......@@ -692,6 +767,7 @@ query (void)
save_args, NULL);
gimp_register_file_handler_mime (SAVE_EPS_PROC, "application/x-eps");
gimp_register_file_handler_uri (SAVE_EPS_PROC);
gimp_register_save_handler (SAVE_EPS_PROC, "eps", "");
}
......@@ -931,7 +1007,9 @@ run (const gchar *name,
ps_set_save_size (&psvals, orig_image_ID);
check_save_vals ();
if (save_image (param[3].data.d_string, image_ID, drawable_ID,
if (save_image (g_file_new_for_uri (param[3].data.d_string),
image_ID, drawable_ID,
&error))
{
/* Store psvals data */
......@@ -1071,8 +1149,8 @@ load_image (const gchar *filename,
break;
gimp_image_set_resolution (image_ID,
(double) plvals.resolution,
(double) plvals.resolution);
(gdouble) plvals.resolution,
(gdouble) plvals.resolution);
if (n_images == max_images)
{
......@@ -1151,19 +1229,14 @@ load_image (const gchar *filename,
}
static gint
save_image (const gchar *filename,
gint32 image_ID,
gint32 drawable_ID,
GError **error)
static gboolean
save_image (GFile *file,
gint32 image_ID,
gint32 drawable_ID,
GError **error)
{
FILE* ofp;
GimpImageType drawable_type;
gint retval;
/* initialize */
retval = 0;
GOutputStream *output;
GimpImageType drawable_type;
drawable_type = gimp_drawable_type (drawable_ID);
......@@ -1181,48 +1254,73 @@ save_image (const gchar *filename,
case GIMP_GRAY_IMAGE:
case GIMP_RGB_IMAGE:
break;
default:
g_message (_("Cannot operate on unknown image types."));
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("Cannot operate on unknown image types."));
return FALSE;
break;
}
gimp_progress_init_printf (_("Saving '%s'"),
gimp_filename_to_utf8 (filename));
gimp_file_get_utf8_name (file));
/* Open the output file. */
ofp = g_fopen (filename, "wb");
if (!ofp)
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
{
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
_("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (filename), g_strerror (errno));
return FALSE;
}
save_ps_header (ofp, filename);
if (! save_ps_header (output, file, error))
goto fail;
switch (drawable_type)
{
case GIMP_INDEXED_IMAGE:
retval = save_index (ofp, image_ID, drawable_ID);
if (! save_index (output, image_ID, drawable_ID, error))
goto fail;
break;
case GIMP_GRAY_IMAGE:
retval = save_gray (ofp, image_ID, drawable_ID);
if (! save_gray (output, image_ID, drawable_ID, error))
goto fail;
break;
case GIMP_RGB_IMAGE:
retval = save_rgb (ofp, image_ID, drawable_ID);
if (! save_rgb (output, image_ID, drawable_ID, error))
goto fail;
break;
default:
g_message (_("Cannot operate on unknown image types."));
retval = FALSE;
g_return_val_if_reached (FALSE);
}
save_ps_trailer (ofp);
if (! save_ps_trailer (output, error))
goto fail;
fclose (ofp);
if (! g_output_stream_close (output, NULL, error))
goto fail;
return retval;
g_object_unref (output);
return TRUE;
fail:
g_object_unref (output);
return FALSE;
}
......@@ -1970,7 +2068,7 @@ load_ps (const gchar *filename,
scan_lines++;
total_scan_lines++;
if ((scan_lines == tile_height) || ((i+1) == image_height))
if ((scan_lines == tile_height) || ((i + 1) == image_height))
{
gegl_buffer_set (buffer,
GEGL_RECTANGLE (0, i-scan_lines+1,
......@@ -1984,7 +2082,7 @@ load_ps (const gchar *filename,
}
if ((i % 20) == 0)
gimp_progress_update ((double)(i+1) / (double)image_height);
gimp_progress_update ((gdouble) (i + 1) / (gdouble) image_height);
if (err)
break;
......@@ -2006,7 +2104,7 @@ load_ps (const gchar *filename,
scan_lines++;
total_scan_lines++;
if ((scan_lines == tile_height) || ((i+1) == image_height))
if ((scan_lines == tile_height) || ((i + 1) == image_height))
{
gegl_buffer_set (buffer,
GEGL_RECTANGLE (0, i-scan_lines+1,
......@@ -2020,7 +2118,7 @@ load_ps (const gchar *filename,