5 #include "gdk_imlib_private.h"
8 gdk_imlib_save_image(GdkImlibImage
* im
, char *file
, GdkImlibSaveInfo
* info
)
13 GdkImlibSaveInfo defaults
;
18 defaults
.quality
= 208;
19 defaults
.scaling
= 1024;
20 defaults
.xjustification
= 512;
21 defaults
.yjustification
= 512;
22 defaults
.page_size
= PAGE_SIZE_LETTER
;
27 ext
= g_GetExtension(file
);
29 if ((!strcasecmp(ext
, "ppm")) || (!strcasecmp(ext
, "pnm")))
31 f
= fopen(file
, "wb");
34 if (!fprintf(f
, "P6\n# Created by Imlib\n%i %i\n255\n", im
->rgb_width
, im
->rgb_height
))
39 if (!fwrite(im
->rgb_data
, 1, (im
->rgb_width
* im
->rgb_height
* 3), f
))
48 else if (!strcasecmp(ext
, "pgm"))
51 unsigned char *ptr
, val
;
54 f
= fopen(file
, "wb");
57 if (!fprintf(f
, "P5\n# Created by Imlib\n%i %i\n255\n", im
->rgb_width
, im
->rgb_height
))
63 for (y
= 0; y
< im
->rgb_height
; y
++)
65 for (x
= 0; x
< im
->rgb_width
; x
++)
70 val
= (unsigned char)(v
/ 3);
71 if (!fwrite(&val
, 1, 1, f
))
82 else if (!strcasecmp(ext
, "ps"))
92 f
= fopen(file
, "wb");
100 switch (info
->page_size
)
102 case PAGE_SIZE_EXECUTIVE
:
106 case PAGE_SIZE_LETTER
:
110 case PAGE_SIZE_LEGAL
:
126 case PAGE_SIZE_FOLIO
:
131 bxx
= ((sx
- (tx
* 2)) * info
->scaling
) >> 10;
132 byy
= ((h
* bxx
/ w
) * info
->scaling
) >> 10;
133 if ((((sy
- (ty
* 2)) * info
->scaling
) >> 10) < byy
)
135 byy
= ((sy
- (ty
* 2)) * info
->scaling
) >> 10;
136 bxx
= ((w
* byy
/ h
) * info
->scaling
) >> 10;
138 bx
= tx
+ ((((sx
- (tx
* 2)) - bxx
) * info
->xjustification
) >> 10);
139 by
= ty
+ ((((sy
- (ty
* 2)) - byy
) * info
->yjustification
) >> 10);
142 fprintf(f
, "%%!PS-Adobe-2.0 EPSF-2.0\n");
143 fprintf(f
, "%%%%Title: %s\n", file
);
144 fprintf(f
, "%%%%Creator: Imlib by The Rasterman\n");
145 fprintf(f
, "%%%%BoundingBox: %i %i %i %i\n", bx
, by
, bxx
, byy
);
146 fprintf(f
, "%%%%Pages: 1\n");
147 fprintf(f
, "%%%%DocumentFonts:\n");
148 fprintf(f
, "%%%%EndComments\n");
149 fprintf(f
, "%%%%EndProlog\n");
150 fprintf(f
, "%%%%Page: 1 1\n");
151 fprintf(f
, "/origstate save def\n");
152 fprintf(f
, "20 dict begin\n");
155 fprintf(f
, "/pix %i string def\n", w
* 3);
156 fprintf(f
, "/grays %i string def\n", w
);
157 fprintf(f
, "/npixls 0 def\n");
158 fprintf(f
, "/rgbindx 0 def\n");
159 fprintf(f
, "%i %i translate\n", bx
, by
);
160 fprintf(f
, "%i %i scale\n", bxx
, byy
);
162 "/colorimage where\n"
166 "/rgbdata exch store\n"
167 "rgbdata length 3 idiv\n"
168 "/npixls exch store\n"
170 "0 1 npixls 1 sub {\n"
172 "rgbdata rgbindx get 20 mul\n"
173 "rgbdata rgbindx 1 add get 32 mul\n"
174 "rgbdata rgbindx 2 add get 12 mul\n"
177 "/rgbindx rgbindx 3 add store\n"
179 "grays 0 npixls getinterval\n"
201 "{colortogray} mergeprocs\n"
205 fprintf(f
, "%i %i 8\n", w
, h
);
206 fprintf(f
, "[%i 0 0 -%i 0 %i]\n", w
, h
, h
);
207 fprintf(f
, "{currentfile pix readhexstring pop}\n");
208 fprintf(f
, "false 3 colorimage\n");
211 for (y
= 0; y
< h
; y
++)
213 for (x
= 0; x
< w
; x
++)
217 fprintf(f
, "0%x", v
);
222 fprintf(f
, "0%x", v
);
227 fprintf(f
, "0%x", v
);
236 fprintf(f
, "/pix %i string def\n", w
);
237 fprintf(f
, "/grays %i string def\n", w
);
238 fprintf(f
, "/npixls 0 def\n");
239 fprintf(f
, "/rgbindx 0 def\n");
240 fprintf(f
, "%i %i translate\n", bx
, by
);
241 fprintf(f
, "%i %i scale\n", bxx
, byy
);
242 fprintf(f
, "%i %i 8\n", w
, h
);
243 fprintf(f
, "[%i 0 0 -%i 0 %i]\n", w
, h
, h
);
244 fprintf(f
, "{currentfile pix readhexstring pop}\n");
245 fprintf(f
, "image\n");
248 for (y
= 0; y
< h
; y
++)
250 for (x
= 0; x
< w
; x
++)
257 fprintf(f
, "0%x", v
);
265 fprintf(f
, "showpage\n");
267 fprintf(f
, "origstate restore\n");
268 fprintf(f
, "%%%%Trailer\n");
273 else if ((!strcasecmp(ext
, "jpeg")) || (!strcasecmp(ext
, "jpg")))
276 struct jpeg_compress_struct cinfo
;
277 struct jpeg_error_mgr jerr
;
278 JSAMPROW row_pointer
[1];
282 f
= fopen(file
, "wb");
285 cinfo
.err
= jpeg_std_error(&jerr
);
286 jpeg_create_compress(&cinfo
);
287 jpeg_stdio_dest(&cinfo
, f
);
288 cinfo
.image_width
= im
->rgb_width
;
289 cinfo
.image_height
= im
->rgb_height
;
290 cinfo
.input_components
= 3;
291 cinfo
.in_color_space
= JCS_RGB
;
292 jpeg_set_defaults(&cinfo
);
293 jpeg_set_quality(&cinfo
, (100 * info
->quality
) >> 8, TRUE
);
294 jpeg_start_compress(&cinfo
, TRUE
);
295 row_stride
= cinfo
.image_width
* 3;
296 while (cinfo
.next_scanline
< cinfo
.image_height
)
298 row_pointer
[0] = im
->rgb_data
+ (cinfo
.next_scanline
* row_stride
);
299 jpeg_write_scanlines(&cinfo
, row_pointer
, 1);
301 jpeg_finish_compress(&cinfo
);
307 else if (!strcasecmp(ext
, "png"))
312 unsigned char *data
, *ptr
;
317 f
= fopen(file
, "wb");
320 png_ptr
= png_create_write_struct(PNG_LIBPNG_VER_STRING
,
327 info_ptr
= png_create_info_struct(png_ptr
);
328 if (info_ptr
== NULL
)
331 png_destroy_write_struct(&png_ptr
, (png_infopp
) NULL
);
334 if (setjmp(png_ptr
->jmpbuf
))
337 png_destroy_write_struct(&png_ptr
, (png_infopp
) NULL
);
340 png_init_io(png_ptr
, f
);
341 png_set_IHDR(png_ptr
, info_ptr
, im
->rgb_width
, im
->rgb_height
, 8,
342 PNG_COLOR_TYPE_RGB_ALPHA
, PNG_INTERLACE_NONE
,
343 PNG_COMPRESSION_TYPE_BASE
, PNG_FILTER_TYPE_BASE
);
348 png_set_sBIT(png_ptr
, info_ptr
, &sig_bit
);
349 png_write_info(png_ptr
, info_ptr
);
350 png_set_shift(png_ptr
, &sig_bit
);
351 png_set_packing(png_ptr
);
352 data
= malloc(im
->rgb_width
* 4);
356 png_destroy_write_struct(&png_ptr
, (png_infopp
) NULL
);
359 for (y
= 0; y
< im
->rgb_height
; y
++)
361 ptr
= im
->rgb_data
+ (y
* im
->rgb_width
* 3);
362 for (x
= 0; x
< im
->rgb_width
; x
++)
364 data
[(x
<< 2) + 0] = *ptr
++;
365 data
[(x
<< 2) + 1] = *ptr
++;
366 data
[(x
<< 2) + 2] = *ptr
++;
367 if ((data
[(x
<< 2) + 0] == im
->shape_color
.r
) &&
368 (data
[(x
<< 2) + 1] == im
->shape_color
.g
) &&
369 (data
[(x
<< 2) + 2] == im
->shape_color
.b
))
370 data
[(x
<< 2) + 3] = 0;
372 data
[(x
<< 2) + 3] = 255;
375 png_write_rows(png_ptr
, &row_ptr
, 1);
378 png_write_end(png_ptr
, info_ptr
);
379 png_destroy_write_struct(&png_ptr
, (png_infopp
) NULL
);
386 else if ((!strcasecmp(ext
, "tiff")) || (!strcasecmp(ext
, "tif")))
390 unsigned char *ptr
, *data
;
394 tif
= TIFFOpen(file
, "w");
397 TIFFSetField(tif
, TIFFTAG_IMAGEWIDTH
, im
->rgb_width
);
398 TIFFSetField(tif
, TIFFTAG_IMAGELENGTH
, im
->rgb_height
);
399 TIFFSetField(tif
, TIFFTAG_ORIENTATION
, ORIENTATION_TOPLEFT
);
400 TIFFSetField(tif
, TIFFTAG_BITSPERSAMPLE
, 8);
401 TIFFSetField(tif
, TIFFTAG_PLANARCONFIG
, PLANARCONFIG_CONTIG
);
402 TIFFSetField(tif
, TIFFTAG_COMPRESSION
, COMPRESSION_LZW
);
404 TIFFSetField(tif
, TIFFTAG_SAMPLESPERPIXEL
, 3);
405 TIFFSetField(tif
, TIFFTAG_PHOTOMETRIC
, PHOTOMETRIC_RGB
);
406 w
= TIFFScanlineSize(tif
);
407 TIFFSetField(tif
, TIFFTAG_ROWSPERSTRIP
,
408 TIFFDefaultStripSize(tif
, -1));
409 for (y
= 0; y
< im
->rgb_height
; y
++)
411 data
= im
->rgb_data
+ (y
* im
->rgb_width
* 3);
412 TIFFWriteScanline(tif
, data
, y
, 0);
422 f
= open_helper("%C/convert pnm:- %s", file
, "wb");
425 if (!fprintf(f
, "P6\n# Created by Imlib\n%i %i\n255\n", im
->rgb_width
, im
->rgb_height
))
430 if (!fwrite(im
->rgb_data
, 1, (im
->rgb_width
* im
->rgb_height
* 3), f
))
440 if (!strcasecmp(ext
, "jpeg"))
441 g_snprintf(cmd
, sizeof(cmd
), "%%H -quality %i -progressive -outfile %%s", 100 * info
->quality
/ 256);
442 else if (!strcasecmp(ext
, "jpg"))
443 g_snprintf(cmd
, sizeof(cmd
), "%%H -quality %i -progressive -outfile %%s", 100 * info
->quality
/ 256);
444 else if (!strcasecmp(ext
, "bmp"))
445 strcpy(cmd
, "%Q %N/ppmtobmp >%s");
446 else if (!strcasecmp(ext
, "gif"))
447 strcpy(cmd
, "%Q %N/ppmtogif -interlace >%s");
448 else if (!strcasecmp(ext
, "ilbm"))
449 strcpy(cmd
, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
450 else if (!strcasecmp(ext
, "ilb"))
451 strcpy(cmd
, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
452 else if (!strcasecmp(ext
, "iff"))
453 strcpy(cmd
, "%N/ppmtoilbm -24if -hires -lace -compress >%s");
454 else if (!strcasecmp(ext
, "icr"))
455 strcpy(cmd
, "%N/ppmtoicr >%s");
456 else if (!strcasecmp(ext
, "map"))
457 strcpy(cmd
, "%N/ppmtomap >%s");
458 else if (!strcasecmp(ext
, "mit"))
459 strcpy(cmd
, "%N/ppmtomitsu -sharpness 4 >%s");
460 else if (!strcasecmp(ext
, "mitsu"))
461 strcpy(cmd
, "%N/ppmtomitsu -sharpness 4 >%s");
462 else if (!strcasecmp(ext
, "pcx"))
463 strcpy(cmd
, "%N/ppmtopcx -24bit -packed >%s");
464 else if (!strcasecmp(ext
, "pgm"))
465 strcpy(cmd
, "%N/ppmtopgm >%s");
466 else if (!strcasecmp(ext
, "pi1"))
467 strcpy(cmd
, "%N/ppmtopi1 >%s");
468 else if (!strcasecmp(ext
, "pic"))
469 strcpy(cmd
, "%Q %N/ppmtopict >%s");
470 else if (!strcasecmp(ext
, "pict"))
471 strcpy(cmd
, "%Q %N/ppmtopict >%s");
472 else if (!strcasecmp(ext
, "pj"))
473 strcpy(cmd
, "%N/ppmtopj >%s");
474 else if (!strcasecmp(ext
, "pjxl"))
475 strcpy(cmd
, "%N/ppmtopjxl >%s");
476 else if (!strcasecmp(ext
, "puz"))
477 strcpy(cmd
, "%N/ppmtopuzz >%s");
478 else if (!strcasecmp(ext
, "puzz"))
479 strcpy(cmd
, "%N/ppmtopuzz >%s");
480 else if (!strcasecmp(ext
, "rgb3"))
481 strcpy(cmd
, "%N/ppmtorgb3 >%s");
482 else if (!strcasecmp(ext
, "six"))
483 strcpy(cmd
, "%N/ppmtosixel >%s");
484 else if (!strcasecmp(ext
, "sixel"))
485 strcpy(cmd
, "%N/ppmtosizel >%s");
486 else if (!strcasecmp(ext
, "tga"))
487 strcpy(cmd
, "%N/ppmtotga -rgb >%s");
488 else if (!strcasecmp(ext
, "targa"))
489 strcpy(cmd
, "%N/ppmtotga -rgb >%s");
490 else if (!strcasecmp(ext
, "uil"))
491 strcpy(cmd
, "%N/ppmtouil >%s");
492 else if (!strcasecmp(ext
, "xpm"))
493 strcpy(cmd
, "%Q %N/ppmtoxpm >%s");
494 else if (!strcasecmp(ext
, "yuv"))
495 strcpy(cmd
, "%N/ppmtoyuv >%s");
496 else if (!strcasecmp(ext
, "png"))
497 strcpy(cmd
, "%N/pnmtopng >%s");
498 else if (!strcasecmp(ext
, "ps"))
499 strcpy(cmd
, "%N/pnmtops -center -scale 100 >%s");
500 else if (!strcasecmp(ext
, "rast"))
501 strcpy(cmd
, "%N/pnmtorast -rle >%s");
502 else if (!strcasecmp(ext
, "ras"))
503 strcpy(cmd
, "%N/pnmtorast -rle >%s");
504 else if (!strcasecmp(ext
, "sgi"))
505 strcpy(cmd
, "%N/pnmtosgi >%s");
506 else if (!strcasecmp(ext
, "sir"))
507 strcpy(cmd
, "%N/pnmtosir >%s");
508 else if (!strcasecmp(ext
, "tif"))
509 strcpy(cmd
, "%N/pnmtotiff -lzw >%s");
510 else if (!strcasecmp(ext
, "tiff"))
511 strcpy(cmd
, "%N/pnmtotiff -lzw >%s");
512 else if (!strcasecmp(ext
, "xwd"))
513 strcpy(cmd
, "%N/pnmtoxwd >%s");
518 f
= open_helper(cmd
, file
, "wb");
521 if (!fprintf(f
, "P6\n# Created by Imlib\n%i %i\n255\n", im
->rgb_width
, im
->rgb_height
))
526 if (!fwrite(im
->rgb_data
, 1, (im
->rgb_width
* im
->rgb_height
* 3), f
))