53
58
#define _O_BINARY 0
62
#define LOAD_PROC "file-pnm-load"
63
#define PNM_SAVE_PROC "file-pnm-save"
64
#define PBM_SAVE_PROC "file-pbm-save"
65
#define PGM_SAVE_PROC "file-pgm-save"
66
#define PPM_SAVE_PROC "file-ppm-save"
67
#define PLUG_IN_BINARY "pnm"
56
70
/* Declare local data types
59
73
typedef struct _PNMScanner
61
gint fd; /* The file descriptor of the file being read */
62
gchar cur; /* The current character in the input stream */
63
gint eof; /* Have we reached end of file? */
64
gchar *inbuf; /* Input buffer - initially 0 */
65
gint inbufsize; /* Size of input buffer */
75
gint fd; /* The file descriptor of the file being read */
76
gchar cur; /* The current character in the input stream */
77
gint eof; /* Have we reached end of file? */
78
gchar *inbuf; /* Input buffer - initially 0 */
79
gint inbufsize; /* Size of input buffer */
66
80
gint inbufvalidsize; /* Size of input buffer with valid data */
67
81
gint inbufpos; /* Position in input buffer */
70
84
typedef struct _PNMInfo
72
gint xres, yres; /* The size of the image */
73
gint maxval; /* For ascii image files, the max value
74
* which we need to normalize to */
75
gint np; /* Number of image planes (0 for pbm) */
76
gint asciibody; /* 1 if ascii body, 0 if raw body */
77
jmp_buf jmpbuf; /* Where to jump to on an error loading */
86
gint xres, yres; /* The size of the image */
87
gint maxval; /* For ascii image files, the max value
88
* which we need to normalize to */
89
gint np; /* Number of image planes (0 for pbm) */
90
gint asciibody; /* 1 if ascii body, 0 if raw body */
91
jmp_buf jmpbuf; /* Where to jump to on an error loading */
78
92
/* Routine to use to load the pnm body */
79
93
void (* loader) (PNMScanner *, struct _PNMInfo *, GimpPixelRgn *);
115
129
GimpParam **return_vals);
116
130
static gint32 load_image (const gchar *filename);
117
131
static gint save_image (const gchar *filename,
121
136
static gint save_dialog (void);
123
static void pnm_load_ascii (PNMScanner *scan,
125
GimpPixelRgn *pixel_rgn);
126
static void pnm_load_raw (PNMScanner *scan,
128
GimpPixelRgn *pixel_rgn);
129
static void pnm_load_rawpbm (PNMScanner *scan,
131
GimpPixelRgn *pixel_rgn);
138
static void pnm_load_ascii (PNMScanner *scan,
140
GimpPixelRgn *pixel_rgn);
141
static void pnm_load_raw (PNMScanner *scan,
143
GimpPixelRgn *pixel_rgn);
144
static void pnm_load_rawpbm (PNMScanner *scan,
146
GimpPixelRgn *pixel_rgn);
133
148
static void pnmsaverow_ascii (PNMRowInfo *ri,
135
150
static void pnmsaverow_raw (PNMRowInfo *ri,
152
static void pnmsaverow_raw_pbm (PNMRowInfo *ri,
154
static void pnmsaverow_ascii_pbm (PNMRowInfo *ri,
137
156
static void pnmsaverow_ascii_indexed (PNMRowInfo *ri,
139
158
static void pnmsaverow_raw_indexed (PNMRowInfo *ri,
142
161
static void pnmscanner_destroy (PNMScanner *s);
143
162
static void pnmscanner_createbuffer (PNMScanner *s,
145
164
static void pnmscanner_getchar (PNMScanner *s);
146
165
static void pnmscanner_eatwhitespace (PNMScanner *s);
147
166
static void pnmscanner_gettoken (PNMScanner *s,
150
169
static void pnmscanner_getsmalltoken (PNMScanner *s,
153
172
static PNMScanner * pnmscanner_create (gint fd);
201
static GimpParamDef load_args[] =
220
static const GimpParamDef load_args[] =
203
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
204
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
205
{ GIMP_PDB_STRING, "raw_filename", "The name of the file to load" }
222
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
223
{ GIMP_PDB_STRING, "filename", "The name of the file to load" },
224
{ GIMP_PDB_STRING, "raw-filename", "The name of the file to load" }
207
static GimpParamDef load_return_vals[] =
226
static const GimpParamDef load_return_vals[] =
209
228
{ GIMP_PDB_IMAGE, "image", "Output image" }
212
static GimpParamDef save_args[] =
231
static const GimpParamDef save_args[] =
214
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
215
{ GIMP_PDB_IMAGE, "image", "Input image" },
216
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
233
{ GIMP_PDB_INT32, "run-mode", "Interactive, non-interactive" },
234
{ GIMP_PDB_IMAGE, "image", "Input image" },
235
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" },
217
236
{ GIMP_PDB_STRING, "filename", "The name of the file to save the image in" },
218
{ GIMP_PDB_STRING, "raw_filename", "The name of the file to save the image in" },
237
{ GIMP_PDB_STRING, "raw-filename", "The name of the file to save the image in" },
219
238
{ GIMP_PDB_INT32, "raw", "Specify non-zero for raw output, zero for ascii output" }
222
gimp_install_procedure ("file_pnm_load",
241
gimp_install_procedure (LOAD_PROC,
223
242
"loads files of the pnm file format",
224
243
"FIXME: write help for pnm_load",
231
250
G_N_ELEMENTS (load_args),
232
251
G_N_ELEMENTS (load_return_vals),
233
252
load_args, load_return_vals);
235
gimp_register_file_handler_mime ("file_pnm_load", "image/x-portable-anymap");
236
gimp_register_magic_load_handler ("file_pnm_load",
254
gimp_register_file_handler_mime (LOAD_PROC, "image/x-portable-anymap");
255
gimp_register_magic_load_handler (LOAD_PROC,
237
256
"pnm,ppm,pgm,pbm",
239
"0,string,P1,0,string,P2,0,string,P3,0,"
240
"string,P4,0,string,P5,0,string,P6");
258
"0,string,P1,0,string,P2,0,string,P3,0,"
259
"string,P4,0,string,P5,0,string,P6");
242
gimp_install_procedure ("file_pnm_save",
261
gimp_install_procedure (PNM_SAVE_PROC,
243
262
"saves files in the pnm file format",
244
263
"PNM saving handles all image types without transparency.",
249
"RGB, GRAY, INDEXED",
251
G_N_ELEMENTS (save_args), 0,
254
gimp_install_procedure ("file_pgm_save",
268
"RGB, GRAY, INDEXED",
270
G_N_ELEMENTS (save_args), 0,
273
gimp_install_procedure (PBM_SAVE_PROC,
274
"saves files in the pnm file format",
275
"PBM saving produces mono images without transparency.",
280
"RGB, GRAY, INDEXED",
282
G_N_ELEMENTS (save_args), 0,
285
gimp_install_procedure (PGM_SAVE_PROC,
255
286
"saves files in the pnm file format",
256
287
"PGM saving produces grayscale images without transparency.",
261
"RGB, GRAY, INDEXED",
292
"RGB, GRAY, INDEXED",
263
294
G_N_ELEMENTS (save_args), 0,
264
295
save_args, NULL);
266
gimp_install_procedure ("file_ppm_save",
297
gimp_install_procedure (PPM_SAVE_PROC,
267
298
"saves files in the pnm file format",
268
299
"PPM saving handles RGB images without transparency.",
273
"RGB, GRAY, INDEXED",
304
"RGB, GRAY, INDEXED",
275
306
G_N_ELEMENTS (save_args), 0,
276
307
save_args, NULL);
278
gimp_register_file_handler_mime ("file_pgm_save", "image/x-portable-graymap");
279
gimp_register_file_handler_mime ("file_ppm_save", "image/x-portable-pixmap");
280
gimp_register_save_handler ("file_pgm_save", "pgm", "");
281
gimp_register_save_handler ("file_ppm_save", "ppm", "");
309
gimp_register_file_handler_mime (PNM_SAVE_PROC, "image/x-portable-anymap");
310
gimp_register_file_handler_mime (PBM_SAVE_PROC, "image/x-portable-bitmap");
311
gimp_register_file_handler_mime (PGM_SAVE_PROC, "image/x-portable-graymap");
312
gimp_register_file_handler_mime (PPM_SAVE_PROC, "image/x-portable-pixmap");
313
gimp_register_save_handler (PNM_SAVE_PROC, "pnm", "");
314
gimp_register_save_handler (PBM_SAVE_PROC, "pbm", "");
315
gimp_register_save_handler (PGM_SAVE_PROC, "pgm", "");
316
gimp_register_save_handler (PPM_SAVE_PROC, "ppm", "");
307
if (strcmp (name, "file_pnm_load") == 0)
343
if (strcmp (name, LOAD_PROC) == 0)
309
345
image_ID = load_image (param[1].data.d_string);
311
347
if (image_ID != -1)
314
values[1].type = GIMP_PDB_IMAGE;
315
values[1].data.d_image = image_ID;
350
values[1].type = GIMP_PDB_IMAGE;
351
values[1].data.d_image = image_ID;
319
status = GIMP_PDB_EXECUTION_ERROR;
355
status = GIMP_PDB_EXECUTION_ERROR;
322
else if (strcmp (name, "file_pnm_save") == 0
323
|| strcmp (name, "file_pgm_save") == 0
324
|| strcmp (name, "file_ppm_save") == 0 )
358
else if (strcmp (name, PNM_SAVE_PROC) == 0 ||
359
strcmp (name, PBM_SAVE_PROC) == 0 ||
360
strcmp (name, PGM_SAVE_PROC) == 0 ||
361
strcmp (name, PPM_SAVE_PROC) == 0)
326
image_ID = param[1].data.d_int32;
327
drawable_ID = param[2].data.d_int32;
363
image_ID = param[1].data.d_int32;
364
drawable_ID = param[2].data.d_int32;
329
366
/* eventually export the image */
330
367
switch (run_mode)
332
case GIMP_RUN_INTERACTIVE:
333
case GIMP_RUN_WITH_LAST_VALS:
334
gimp_ui_init ("pnm", FALSE);
335
if (strcmp (name, "file_pnm_save") == 0)
336
export = gimp_export_image (&image_ID, &drawable_ID, "PNM",
337
(GIMP_EXPORT_CAN_HANDLE_RGB |
338
GIMP_EXPORT_CAN_HANDLE_GRAY |
339
GIMP_EXPORT_CAN_HANDLE_INDEXED));
340
else if (strcmp (name, "file_pgm_save") == 0)
341
export = gimp_export_image (&image_ID, &drawable_ID, "PGM",
342
(GIMP_EXPORT_CAN_HANDLE_GRAY));
369
case GIMP_RUN_INTERACTIVE:
370
case GIMP_RUN_WITH_LAST_VALS:
371
gimp_ui_init (PLUG_IN_BINARY, FALSE);
373
if (strcmp (name, PNM_SAVE_PROC) == 0)
375
export = gimp_export_image (&image_ID, &drawable_ID, "PNM",
376
GIMP_EXPORT_CAN_HANDLE_RGB |
377
GIMP_EXPORT_CAN_HANDLE_GRAY |
378
GIMP_EXPORT_CAN_HANDLE_INDEXED);
380
else if (strcmp (name, PBM_SAVE_PROC) == 0)
382
export = gimp_export_image (&image_ID, &drawable_ID, "PBM",
383
GIMP_EXPORT_CAN_HANDLE_BITMAP);
384
pbm = TRUE; /* gimp has no mono image type so hack it */
386
else if (strcmp (name, PGM_SAVE_PROC) == 0)
388
export = gimp_export_image (&image_ID, &drawable_ID, "PGM",
389
GIMP_EXPORT_CAN_HANDLE_GRAY);
344
export = gimp_export_image (&image_ID, &drawable_ID, "PPM",
345
(GIMP_EXPORT_CAN_HANDLE_RGB |
346
GIMP_EXPORT_CAN_HANDLE_INDEXED));
348
if (export == GIMP_EXPORT_CANCEL)
350
values[0].data.d_status = GIMP_PDB_CANCEL;
393
export = gimp_export_image (&image_ID, &drawable_ID, "PPM",
394
GIMP_EXPORT_CAN_HANDLE_RGB |
395
GIMP_EXPORT_CAN_HANDLE_INDEXED);
398
if (export == GIMP_EXPORT_CANCEL)
400
values[0].data.d_status = GIMP_PDB_CANCEL;
358
409
switch (run_mode)
360
case GIMP_RUN_INTERACTIVE:
361
/* Possibly retrieve data */
362
gimp_get_data (name, &psvals);
364
/* First acquire information with a dialog */
365
if (! save_dialog ())
366
status = GIMP_PDB_CANCEL;
369
case GIMP_RUN_NONINTERACTIVE:
370
/* Make sure all the arguments are there! */
373
status = GIMP_PDB_CALLING_ERROR;
377
psvals.raw = (param[5].data.d_int32) ? TRUE : FALSE;
380
case GIMP_RUN_WITH_LAST_VALS:
381
/* Possibly retrieve data */
382
gimp_get_data (name, &psvals);
411
case GIMP_RUN_INTERACTIVE:
412
/* Possibly retrieve data */
413
gimp_get_data (name, &psvals);
415
/* First acquire information with a dialog */
416
if (! save_dialog ())
417
status = GIMP_PDB_CANCEL;
420
case GIMP_RUN_NONINTERACTIVE:
421
/* Make sure all the arguments are there! */
424
status = GIMP_PDB_CALLING_ERROR;
428
psvals.raw = (param[5].data.d_int32) ? TRUE : FALSE;
431
case GIMP_RUN_WITH_LAST_VALS:
432
/* Possibly retrieve data */
433
gimp_get_data (name, &psvals);
389
440
if (status == GIMP_PDB_SUCCESS)
391
if (save_image (param[3].data.d_string, image_ID, drawable_ID))
393
/* Store psvals data */
394
gimp_set_data (name, &psvals, sizeof (PNMSaveVals));
398
status = GIMP_PDB_EXECUTION_ERROR;
442
if (save_image (param[3].data.d_string, image_ID, drawable_ID, pbm))
444
/* Store psvals data */
445
gimp_set_data (name, &psvals, sizeof (PNMSaveVals));
449
status = GIMP_PDB_EXECUTION_ERROR;
402
453
if (export == GIMP_EXPORT_EXPORT)
403
gimp_image_delete (image_ID);
454
gimp_image_delete (image_ID);
449
497
/* If we get here, we had a problem reading the file */
451
pnmscanner_destroy (scan);
499
pnmscanner_destroy (scan);
453
501
g_free (pnminfo);
454
502
if (image_ID != -1)
455
gimp_image_delete (image_ID);
503
gimp_image_delete (image_ID);
459
if (!(scan = pnmscanner_create(fd)))
460
longjmp(pnminfo->jmpbuf,1);
507
if (!(scan = pnmscanner_create (fd)))
508
longjmp (pnminfo->jmpbuf, 1);
462
510
/* Get magic number */
463
511
pnmscanner_gettoken (scan, buf, BUFLEN);
464
CHECK_FOR_ERROR(pnmscanner_eof(scan), pnminfo->jmpbuf,
465
_("PNM: Premature end of file."));
466
CHECK_FOR_ERROR((buf[0] != 'P' || buf[2]), pnminfo->jmpbuf,
467
_("PNM: Invalid file."));
512
CHECK_FOR_ERROR (pnmscanner_eof (scan), pnminfo->jmpbuf,
513
_("Premature end of file."));
514
CHECK_FOR_ERROR ((buf[0] != 'P' || buf[2]), pnminfo->jmpbuf,
469
517
/* Look up magic number to see what type of PNM this is */
470
for (ctr=0; pnm_types[ctr].name; ctr++)
518
for (ctr = 0; pnm_types[ctr].name; ctr++)
471
519
if (buf[1] == pnm_types[ctr].name)
473
pnminfo->np = pnm_types[ctr].np;
474
pnminfo->asciibody = pnm_types[ctr].asciibody;
475
pnminfo->maxval = pnm_types[ctr].maxval;
476
pnminfo->loader = pnm_types[ctr].loader;
521
pnminfo->np = pnm_types[ctr].np;
522
pnminfo->asciibody = pnm_types[ctr].asciibody;
523
pnminfo->maxval = pnm_types[ctr].maxval;
524
pnminfo->loader = pnm_types[ctr].loader;
478
527
if (!pnminfo->loader)
480
529
g_message (_("File not in a supported format."));
481
longjmp(pnminfo->jmpbuf,1);
530
longjmp (pnminfo->jmpbuf,1);
484
pnmscanner_gettoken(scan, buf, BUFLEN);
485
CHECK_FOR_ERROR(pnmscanner_eof(scan), pnminfo->jmpbuf,
486
_("PNM: Premature end of file."));
487
pnminfo->xres = g_ascii_isdigit(*buf)?atoi(buf):0;
488
CHECK_FOR_ERROR(pnminfo->xres<=0, pnminfo->jmpbuf,
489
_("PNM: Invalid X resolution."));
491
pnmscanner_gettoken(scan, buf, BUFLEN);
492
CHECK_FOR_ERROR(pnmscanner_eof(scan), pnminfo->jmpbuf,
493
_("PNM: Premature end of file."));
494
pnminfo->yres = g_ascii_isdigit(*buf)?atoi(buf):0;
495
CHECK_FOR_ERROR(pnminfo->yres<=0, pnminfo->jmpbuf,
496
_("PNM: Invalid Y resolution."));
498
if (pnminfo->np != 0) /* pbm's don't have a maxval field */
533
pnmscanner_gettoken (scan, buf, BUFLEN);
534
CHECK_FOR_ERROR (pnmscanner_eof (scan), pnminfo->jmpbuf,
535
_("Premature end of file."));
536
pnminfo->xres = g_ascii_isdigit(*buf) ? atoi (buf) : 0;
537
CHECK_FOR_ERROR (pnminfo->xres <= 0, pnminfo->jmpbuf,
538
_("Invalid X resolution."));
540
pnmscanner_gettoken (scan, buf, BUFLEN);
541
CHECK_FOR_ERROR (pnmscanner_eof (scan), pnminfo->jmpbuf,
542
_("Premature end of file."));
543
pnminfo->yres = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
544
CHECK_FOR_ERROR (pnminfo->yres <= 0, pnminfo->jmpbuf,
545
_("Invalid Y resolution."));
547
if (pnminfo->np != 0) /* pbm's don't have a maxval field */
500
pnmscanner_gettoken(scan, buf, BUFLEN);
501
CHECK_FOR_ERROR(pnmscanner_eof(scan), pnminfo->jmpbuf,
502
_("PNM: Premature end of file."));
549
pnmscanner_gettoken (scan, buf, BUFLEN);
550
CHECK_FOR_ERROR (pnmscanner_eof (scan), pnminfo->jmpbuf,
551
_("Premature end of file."));
504
pnminfo->maxval = g_ascii_isdigit(*buf)?atoi(buf):0;
505
CHECK_FOR_ERROR(((pnminfo->maxval<=0)
506
|| (pnminfo->maxval>255 && !pnminfo->asciibody)),
508
_("PNM: Invalid maximum value."));
553
pnminfo->maxval = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
554
CHECK_FOR_ERROR (((pnminfo->maxval<=0)
555
|| (pnminfo->maxval>255 && !pnminfo->asciibody)),
557
_("Invalid maximum value."));
511
560
/* Create a new image of the proper size and associate the filename with it.
513
562
image_ID = gimp_image_new (pnminfo->xres, pnminfo->yres,
514
(pnminfo->np >= 3) ? GIMP_RGB : GIMP_GRAY);
563
(pnminfo->np >= 3) ? GIMP_RGB : GIMP_GRAY);
515
564
gimp_image_set_filename (image_ID, filename);
517
566
layer_ID = gimp_layer_new (image_ID, _("Background"),
518
pnminfo->xres, pnminfo->yres,
519
(pnminfo->np >= 3) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE,
520
100, GIMP_NORMAL_MODE);
567
pnminfo->xres, pnminfo->yres,
568
(pnminfo->np >= 3) ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE,
569
100, GIMP_NORMAL_MODE);
521
570
gimp_image_add_layer (image_ID, layer_ID, 0);
523
572
drawable = gimp_drawable_get (layer_ID);
524
573
gimp_pixel_rgn_init (&pixel_rgn, drawable,
525
0, 0, drawable->width, drawable->height, TRUE, FALSE);
574
0, 0, drawable->width, drawable->height, TRUE, FALSE);
527
576
pnminfo->loader (scan, pnminfo, &pixel_rgn);
570
619
for (i = 0; i < scanlines; i++)
571
for (x = 0; x < info->xres; x++)
573
for (b = 0; b < np; b++)
575
/* Truncated files will just have all 0's at the end of the images */
576
CHECK_FOR_ERROR(pnmscanner_eof(scan), info->jmpbuf,
577
_("PNM: Premature end of file."));
579
pnmscanner_gettoken(scan, buf, BUFLEN);
581
pnmscanner_getsmalltoken(scan, buf);
582
switch (info->maxval)
585
d[b] = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
588
d[b] = (*buf=='0')?0xff:0x00;
591
d[b] = (255.0 * (((gdouble)(g_ascii_isdigit (*buf) ? atoi (buf) : 0))
620
for (x = 0; x < info->xres; x++)
622
for (b = 0; b < np; b++)
624
/* Truncated files will just have all 0's at the end of the images */
625
if (pnmscanner_eof (scan))
626
g_message (_("Premature end of file."));
628
pnmscanner_gettoken (scan, buf, BUFLEN);
630
pnmscanner_getsmalltoken (scan, buf);
632
switch (info->maxval)
635
d[b] = g_ascii_isdigit (*buf) ? atoi (buf) : 0;
639
d[b] = (*buf == '0') ? 0xff : 0x00;
643
d[b] = (255.0 * (((gdouble)(g_ascii_isdigit (*buf) ? atoi (buf) : 0))
592
644
/ (gdouble)(info->maxval)));
599
651
gimp_progress_update ((double) y / (double) info->yres);
600
652
gimp_pixel_rgn_set_rect (pixel_rgn, data, 0, y, info->xres, scanlines);
656
gimp_progress_update (1.0);
608
pnm_load_raw (PNMScanner *scan,
610
GimpPixelRgn *pixel_rgn)
662
pnm_load_raw (PNMScanner *scan,
664
GimpPixelRgn *pixel_rgn)
612
666
guchar *data, *d;
614
668
gint start, end, scanlines;
617
data = g_malloc (gimp_tile_height () * info->xres * info->np);
618
fd = pnmscanner_fd(scan);
671
data = g_new (guchar, gimp_tile_height () * info->xres * info->np);
672
fd = pnmscanner_fd (scan);
620
674
for (y = 0; y < info->yres; )
628
682
for (i = 0; i < scanlines; i++)
630
CHECK_FOR_ERROR((info->xres*info->np
631
!= read(fd, d, info->xres*info->np)),
633
_("PNM: Premature end of file."));
684
CHECK_FOR_ERROR ((info->xres*info->np
685
!= read(fd, d, info->xres*info->np)),
687
_("Premature end of file."));
635
if (info->maxval != 255) /* Normalize if needed */
637
for (x = 0; x < info->xres * info->np; x++)
689
if (info->maxval != 255) /* Normalize if needed */
691
for (x = 0; x < info->xres * info->np; x++)
639
693
d[x] = MIN (d[x], info->maxval); /* guard against overflow */
640
694
d[x] = 255.0 * (gdouble) d[x] / (gdouble) info->maxval;
644
d += info->xres * info->np;
698
d += info->xres * info->np;
647
701
gimp_progress_update ((double) y / (double) info->yres);
648
702
gimp_pixel_rgn_set_rect (pixel_rgn, data, 0, y, info->xres, scanlines);
706
gimp_progress_update (1.0);
656
pnm_load_rawpbm (PNMScanner *scan,
658
GimpPixelRgn *pixel_rgn)
712
pnm_load_rawpbm (PNMScanner *scan,
714
GimpPixelRgn *pixel_rgn)
661
unsigned char curbyte;
662
unsigned char *data, *d;
664
int start, end, scanlines;
720
gint start, end, scanlines;
668
fd = pnmscanner_fd(scan);
669
rowlen = (int)ceil((double)(info->xres)/8.0);
670
data = g_malloc (gimp_tile_height () * info->xres);
671
buf = g_new (unsigned char, rowlen);
724
fd = pnmscanner_fd (scan);
725
rowlen = (int)ceil ((double)(info->xres)/8.0);
726
data = g_new (guchar, gimp_tile_height () * info->xres);
727
buf = g_new (guchar, rowlen);
673
729
for (y = 0; y < info->yres; )
681
737
for (i = 0; i < scanlines; i++)
683
CHECK_FOR_ERROR((rowlen != read(fd, buf, rowlen)),
684
info->jmpbuf, _("PNM: Error reading file."));
688
for (x = 0; x < info->xres; x++)
691
curbyte = buf[bufpos++];
692
d[x] = (curbyte&0x80) ? 0x00 : 0xff;
739
CHECK_FOR_ERROR ((rowlen != read(fd, buf, rowlen)),
740
info->jmpbuf, _("Error reading file."));
744
for (x = 0; x < info->xres; x++)
747
curbyte = buf[bufpos++];
748
d[x] = (curbyte & 0x80) ? 0x00 : 0xff;
699
755
gimp_progress_update ((double) y / (double) info->yres);
700
756
gimp_pixel_rgn_set_rect (pixel_rgn, data, 0, y, info->xres, scanlines);
760
gimp_progress_update (1.0);
766
/* Writes out mono raw rows */
768
pnmsaverow_raw_pbm (PNMRowInfo *ri,
772
gchar *rbcur = ri->rowbuf;
773
gint32 len = (int)ceil ((double)(ri->xres)/8.0);
775
for (b = 0; b < len; b++) /* each output byte */
778
for (i = 0; i < 8; i++) /* each bit in this byte */
784
*(rbcur+b) |= (char) (1 << (7 - i));
790
write (ri->fd, ri->rowbuf, len);
793
/* Writes out mono ascii rows */
795
pnmsaverow_ascii_pbm (PNMRowInfo *ri,
798
static gint line_len = 0; /* ascii pbm lines must be <= 70 chars long */
801
gchar *rbcur = ri->rowbuf;
803
for (i = 0; i < ri->xres; i++)
824
write (ri->fd, ri->rowbuf, len);
708
827
/* Writes out RGB and greyscale raw rows */
710
pnmsaverow_raw (PNMRowInfo *ri,
829
pnmsaverow_raw (PNMRowInfo *ri,
713
write(ri->fd, data, ri->xres*ri->np);
832
write (ri->fd, data, ri->xres*ri->np);
716
835
/* Writes out indexed raw rows */
718
pnmsaverow_raw_indexed (PNMRowInfo *ri,
837
pnmsaverow_raw_indexed (PNMRowInfo *ri,
722
char *rbcur = ri->rowbuf;
841
gchar *rbcur = ri->rowbuf;
724
843
for (i = 0; i < ri->xres; i++)
727
846
*(rbcur++) = ri->grn[*data];
728
847
*(rbcur++) = ri->blu[*(data++)];
730
write(ri->fd, ri->rowbuf, ri->xres*3);
850
write (ri->fd, ri->rowbuf, ri->xres * 3);
733
853
/* Writes out RGB and greyscale ascii rows */
735
pnmsaverow_ascii (PNMRowInfo *ri,
855
pnmsaverow_ascii (PNMRowInfo *ri,
739
char *rbcur = ri->rowbuf;
859
gchar *rbcur = ri->rowbuf;
741
861
for (i = 0; i < ri->xres*ri->np; i++)
743
sprintf((char *) rbcur,"%d\n", 0xff & *(data++));
744
rbcur += strlen(rbcur);
863
sprintf ((char *) rbcur,"%d\n", 0xff & *(data++));
864
rbcur += strlen (rbcur);
746
write(ri->fd, ri->rowbuf, strlen((char *) ri->rowbuf));
867
write (ri->fd, ri->rowbuf, strlen ((char *) ri->rowbuf));
749
870
/* Writes out RGB and greyscale ascii rows */
751
pnmsaverow_ascii_indexed (PNMRowInfo *ri,
872
pnmsaverow_ascii_indexed (PNMRowInfo *ri,
755
char *rbcur = ri->rowbuf;
876
gchar *rbcur = ri->rowbuf;
757
878
for (i = 0; i < ri->xres; i++)
759
sprintf((char *) rbcur,"%d\n", 0xff & ri->red[*(data)]);
760
rbcur += strlen(rbcur);
761
sprintf((char *) rbcur,"%d\n", 0xff & ri->grn[*(data)]);
762
rbcur += strlen(rbcur);
763
sprintf((char *) rbcur,"%d\n", 0xff & ri->blu[*(data++)]);
764
rbcur += strlen(rbcur);
880
sprintf ((char *) rbcur,"%d\n", 0xff & ri->red[*(data)]);
881
rbcur += strlen (rbcur);
882
sprintf ((char *) rbcur,"%d\n", 0xff & ri->grn[*(data)]);
883
rbcur += strlen (rbcur);
884
sprintf ((char *) rbcur,"%d\n", 0xff & ri->blu[*(data++)]);
885
rbcur += strlen (rbcur);
766
write(ri->fd, ri->rowbuf, strlen((char *) ri->rowbuf));
888
write (ri->fd, ri->rowbuf, strlen ((char *) ri->rowbuf));
770
892
save_image (const gchar *filename,
774
GimpPixelRgn pixel_rgn;
775
GimpDrawable *drawable;
776
GimpImageType drawable_type;
778
void (*saverow) (PNMRowInfo *, unsigned char *) = NULL;
779
unsigned char red[256];
780
unsigned char grn[256];
781
unsigned char blu[256];
782
unsigned char *data, *d;
897
GimpPixelRgn pixel_rgn;
898
GimpDrawable *drawable;
899
GimpImageType drawable_type;
901
void (*saverow) (PNMRowInfo *, guchar *) = NULL;
792
914
drawable = gimp_drawable_get (drawable_ID);
793
915
drawable_type = gimp_drawable_type (drawable_ID);
794
916
gimp_pixel_rgn_init (&pixel_rgn, drawable,
795
0, 0, drawable->width, drawable->height, FALSE, FALSE);
917
0, 0, drawable->width, drawable->height, FALSE, FALSE);
797
919
/* Make sure we're not saving an image with an alpha channel */
798
920
if (gimp_drawable_has_alpha (drawable_ID))
800
g_message (_("PNM save cannot handle images with alpha channels."));
922
g_message (_("Cannot save images with alpha channel."));
804
926
/* open the file */
805
fd = open (filename, O_WRONLY | O_CREAT | O_TRUNC | _O_BINARY, 0644);
927
fd = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | _O_BINARY, 0644);
814
temp = g_strdup_printf (_("Saving '%s'..."),
815
gimp_filename_to_utf8 (filename));
816
gimp_progress_init (temp);
936
gimp_progress_init_printf (_("Saving '%s'"),
937
gimp_filename_to_utf8 (filename));
819
939
xres = drawable->width;
820
940
yres = drawable->height;
822
942
/* write out magic number */
823
943
if (psvals.raw == FALSE)
824
switch (drawable_type)
826
case GIMP_GRAY_IMAGE:
827
write(fd, "P2\n", 3);
829
rowbufsize = xres * 4;
830
saverow = pnmsaverow_ascii;
833
write(fd, "P3\n", 3);
835
rowbufsize = xres * 12;
836
saverow = pnmsaverow_ascii;
838
case GIMP_INDEXED_IMAGE:
839
write(fd, "P3\n", 3);
841
rowbufsize = xres * 12;
842
saverow = pnmsaverow_ascii_indexed;
845
g_warning ("pnm: unknown drawable_type\n");
947
write (fd, "P1\n", 3);
949
rowbufsize = xres + (int) (xres / 70) + 1;
950
saverow = pnmsaverow_ascii_pbm;
954
switch (drawable_type)
956
case GIMP_GRAY_IMAGE:
957
write (fd, "P2\n", 3);
959
rowbufsize = xres * 4;
960
saverow = pnmsaverow_ascii;
964
write (fd, "P3\n", 3);
966
rowbufsize = xres * 12;
967
saverow = pnmsaverow_ascii;
970
case GIMP_INDEXED_IMAGE:
971
write (fd, "P3\n", 3);
973
rowbufsize = xres * 12;
974
saverow = pnmsaverow_ascii_indexed;
978
g_warning ("pnm: unknown drawable_type\n");
848
983
else if (psvals.raw == TRUE)
849
switch (drawable_type)
851
case GIMP_GRAY_IMAGE:
852
write(fd, "P5\n", 3);
855
saverow = pnmsaverow_raw;
858
write(fd, "P6\n", 3);
860
rowbufsize = xres * 3;
861
saverow = pnmsaverow_raw;
863
case GIMP_INDEXED_IMAGE:
864
write(fd, "P6\n", 3);
866
rowbufsize = xres * 3;
867
saverow = pnmsaverow_raw_indexed;
870
g_warning ("pnm: unknown drawable_type\n");
987
write (fd, "P4\n", 3);
989
rowbufsize = (int)ceil ((double)(xres)/8.0);
990
saverow = pnmsaverow_raw_pbm;
994
switch (drawable_type)
996
case GIMP_GRAY_IMAGE:
997
write (fd, "P5\n", 3);
1000
saverow = pnmsaverow_raw;
1003
case GIMP_RGB_IMAGE:
1004
write (fd, "P6\n", 3);
1006
rowbufsize = xres * 3;
1007
saverow = pnmsaverow_raw;
1010
case GIMP_INDEXED_IMAGE:
1011
write (fd, "P6\n", 3);
1013
rowbufsize = xres * 3;
1014
saverow = pnmsaverow_raw_indexed;
1018
g_warning ("pnm: unknown drawable_type\n");
874
if (drawable_type == GIMP_INDEXED_IMAGE)
1024
if (drawable_type == GIMP_INDEXED_IMAGE && !pbm)
943
1099
save_dialog (void)
946
1102
GtkWidget *frame;
949
dlg = gimp_dialog_new (_("Save as PNM"), "pnm",
951
gimp_standard_help_func, "file-pnm-save",
953
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
954
GTK_STOCK_OK, GTK_RESPONSE_OK,
1105
dialog = gimp_dialog_new (_("Save as PNM"), PLUG_IN_BINARY,
1107
gimp_standard_help_func, PNM_SAVE_PROC,
1109
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1110
GTK_STOCK_SAVE, GTK_RESPONSE_OK,
1114
gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
1116
GTK_RESPONSE_CANCEL,
1119
gimp_window_set_transient (GTK_WINDOW (dialog));
958
1121
/* file save type */
959
1122
frame = gimp_int_radio_group_new (TRUE, _("Data formatting"),
960
G_CALLBACK (gimp_radio_button_update),
961
&psvals.raw, psvals.raw,
963
_("Raw"), TRUE, NULL,
964
_("Ascii"), FALSE, NULL,
1123
G_CALLBACK (gimp_radio_button_update),
1124
&psvals.raw, psvals.raw,
1126
_("Raw"), TRUE, NULL,
1127
_("Ascii"), FALSE, NULL,
967
1130
gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
968
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, FALSE, TRUE, 0);
1131
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
1132
frame, FALSE, TRUE, 0);
970
1133
gtk_widget_show (frame);
972
gtk_widget_show (dlg);
974
run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);
976
gtk_widget_destroy (dlg);
1135
gtk_widget_show (dialog);
1137
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
1139
gtk_widget_destroy (dialog);