You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
556 lines
15 KiB
556 lines
15 KiB
4 years ago
|
#define _GNU_SOURCE
|
||
|
#include <config.h>
|
||
|
#include "Imlib.h"
|
||
|
#include "Imlib_private.h"
|
||
|
|
||
|
#ifndef HAVE_SNPRINTF
|
||
|
#define snprintf my_snprintf
|
||
|
#ifdef HAVE_STDARGS
|
||
|
int my_snprintf(char *str, size_t count, const char *fmt,...);
|
||
|
|
||
|
#else
|
||
|
int my_snprintf(va_alist);
|
||
|
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
int
|
||
|
Imlib_save_image(ImlibData * id, ImlibImage * im, char *file, ImlibSaveInfo * info)
|
||
|
{
|
||
|
char *ext;
|
||
|
char cmd[10240];
|
||
|
FILE *f;
|
||
|
ImlibSaveInfo defaults;
|
||
|
|
||
|
if (!im || !file)
|
||
|
return 0;
|
||
|
|
||
|
defaults.quality = 208;
|
||
|
defaults.scaling = 1024;
|
||
|
defaults.xjustification = 512;
|
||
|
defaults.yjustification = 512;
|
||
|
defaults.page_size = PAGE_SIZE_LETTER;
|
||
|
defaults.color = 1;
|
||
|
|
||
|
if (!info)
|
||
|
info = &defaults;
|
||
|
ext = _GetExtension(file);
|
||
|
|
||
|
if ((!strcasecmp(ext, "ppm")) || (!strcasecmp(ext, "pnm")))
|
||
|
{
|
||
|
f = fopen(file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
|
||
|
{
|
||
|
fclose(f);
|
||
|
return 0;
|
||
|
}
|
||
|
if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
|
||
|
{
|
||
|
fclose(f);
|
||
|
return 0;
|
||
|
}
|
||
|
fclose(f);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
else if (!strcasecmp(ext, "pgm"))
|
||
|
{
|
||
|
int x, y;
|
||
|
unsigned char *ptr, val;
|
||
|
int v;
|
||
|
|
||
|
f = fopen(file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
if (!fprintf(f, "P5\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
|
||
|
{
|
||
|
fclose(f);
|
||
|
return 0;
|
||
|
}
|
||
|
ptr = im->rgb_data;
|
||
|
for (y = 0; y < im->rgb_height; y++)
|
||
|
{
|
||
|
for (x = 0; x < im->rgb_width; x++)
|
||
|
{
|
||
|
v = (int)(*ptr++);
|
||
|
v += (int)(*ptr++);
|
||
|
v += (int)(*ptr++);
|
||
|
val = (unsigned char)(v / 3);
|
||
|
if (!fwrite(&val, 1, 1, f))
|
||
|
{
|
||
|
fclose(f);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fclose(f);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
else if (!strcasecmp(ext, "ps"))
|
||
|
{
|
||
|
int bx, by, bxx, byy;
|
||
|
int w, h;
|
||
|
int sx, sy;
|
||
|
int tx = 35, ty = 35;
|
||
|
int x, y;
|
||
|
unsigned char *ptr;
|
||
|
int v;
|
||
|
|
||
|
sx = 0;
|
||
|
sy = 0;
|
||
|
f = fopen(file, "wb");
|
||
|
|
||
|
if (f == NULL)
|
||
|
return 0;
|
||
|
|
||
|
w = im->rgb_width;
|
||
|
h = im->rgb_height;
|
||
|
|
||
|
switch (info->page_size)
|
||
|
{
|
||
|
case PAGE_SIZE_EXECUTIVE:
|
||
|
sx = 540;
|
||
|
sy = 720;
|
||
|
break;
|
||
|
case PAGE_SIZE_LETTER:
|
||
|
sx = 612;
|
||
|
sy = 792;
|
||
|
break;
|
||
|
case PAGE_SIZE_LEGAL:
|
||
|
sx = 612;
|
||
|
sy = 1008;
|
||
|
break;
|
||
|
case PAGE_SIZE_A4:
|
||
|
sx = 595;
|
||
|
sy = 842;
|
||
|
break;
|
||
|
case PAGE_SIZE_A3:
|
||
|
sx = 842;
|
||
|
sy = 1190;
|
||
|
break;
|
||
|
case PAGE_SIZE_A5:
|
||
|
sx = 420;
|
||
|
sy = 595;
|
||
|
break;
|
||
|
case PAGE_SIZE_FOLIO:
|
||
|
sx = 612;
|
||
|
sy = 936;
|
||
|
break;
|
||
|
}
|
||
|
bxx = ((sx - (tx * 2)) * info->scaling) >> 10;
|
||
|
byy = (int)(((float)h / (float)w) * (float)bxx);
|
||
|
if ((((sy - (ty * 2)) * info->scaling) >> 10) < byy)
|
||
|
{
|
||
|
byy = ((sy - (ty * 2)) * info->scaling) >> 10;
|
||
|
bxx = (int)(((float)w / (float)h) * (float)byy);
|
||
|
}
|
||
|
bx = tx + ((((sx - (tx * 2)) - bxx) * info->xjustification) >> 10);
|
||
|
by = ty + ((((sy - (ty * 2)) - byy) * info->yjustification) >> 10);
|
||
|
if (f)
|
||
|
{
|
||
|
fprintf(f, "%%!PS-Adobe-2.0 EPSF-2.0\n");
|
||
|
fprintf(f, "%%%%Title: %s\n", file);
|
||
|
fprintf(f, "%%%%Creator: Imlib by The Rasterman\n");
|
||
|
fprintf(f, "%%%%BoundingBox: %i %i %i %i\n", bx, by, bxx, byy);
|
||
|
fprintf(f, "%%%%Pages: 1\n");
|
||
|
fprintf(f, "%%%%DocumentFonts:\n");
|
||
|
fprintf(f, "%%%%EndComments\n");
|
||
|
fprintf(f, "%%%%EndProlog\n");
|
||
|
fprintf(f, "%%%%Page: 1 1\n");
|
||
|
fprintf(f, "/origstate save def\n");
|
||
|
fprintf(f, "20 dict begin\n");
|
||
|
if (info->color)
|
||
|
{
|
||
|
fprintf(f, "/pix %i string def\n", w * 3);
|
||
|
fprintf(f, "/grays %i string def\n", w);
|
||
|
fprintf(f, "/npixls 0 def\n");
|
||
|
fprintf(f, "/rgbindx 0 def\n");
|
||
|
fprintf(f, "%i %i translate\n", bx, by);
|
||
|
fprintf(f, "%i %i scale\n", bxx, byy);
|
||
|
fprintf(f,
|
||
|
"/colorimage where\n"
|
||
|
"{ pop }\n"
|
||
|
"{\n"
|
||
|
"/colortogray {\n"
|
||
|
"/rgbdata exch store\n"
|
||
|
"rgbdata length 3 idiv\n"
|
||
|
"/npixls exch store\n"
|
||
|
"/rgbindx 0 store\n"
|
||
|
"0 1 npixls 1 sub {\n"
|
||
|
"grays exch\n"
|
||
|
"rgbdata rgbindx get 20 mul\n"
|
||
|
"rgbdata rgbindx 1 add get 32 mul\n"
|
||
|
"rgbdata rgbindx 2 add get 12 mul\n"
|
||
|
"add add 64 idiv\n"
|
||
|
"put\n"
|
||
|
"/rgbindx rgbindx 3 add store\n"
|
||
|
"} for\n"
|
||
|
"grays 0 npixls getinterval\n"
|
||
|
"} bind def\n"
|
||
|
"/mergeprocs {\n"
|
||
|
"dup length\n"
|
||
|
"3 -1 roll\n"
|
||
|
"dup\n"
|
||
|
"length\n"
|
||
|
"dup\n"
|
||
|
"5 1 roll\n"
|
||
|
"3 -1 roll\n"
|
||
|
"add\n"
|
||
|
"array cvx\n"
|
||
|
"dup\n"
|
||
|
"3 -1 roll\n"
|
||
|
"0 exch\n"
|
||
|
"putinterval\n"
|
||
|
"dup\n"
|
||
|
"4 2 roll\n"
|
||
|
"putinterval\n"
|
||
|
"} bind def\n"
|
||
|
"/colorimage {\n"
|
||
|
"pop pop\n"
|
||
|
"{colortogray} mergeprocs\n"
|
||
|
"image\n"
|
||
|
"} bind def\n"
|
||
|
"} ifelse\n");
|
||
|
fprintf(f, "%i %i 8\n", w, h);
|
||
|
fprintf(f, "[%i 0 0 -%i 0 %i]\n", w, h, h);
|
||
|
fprintf(f, "{currentfile pix readhexstring pop}\n");
|
||
|
fprintf(f, "false 3 colorimage\n");
|
||
|
fprintf(f, "\n");
|
||
|
ptr = im->rgb_data;
|
||
|
for (y = 0; y < h; y++)
|
||
|
{
|
||
|
for (x = 0; x < w; x++)
|
||
|
{
|
||
|
v = (int)(*ptr++);
|
||
|
if (v < 0x10)
|
||
|
fprintf(f, "0%x", v);
|
||
|
else
|
||
|
fprintf(f, "%x", v);
|
||
|
v = (int)(*ptr++);
|
||
|
if (v < 0x10)
|
||
|
fprintf(f, "0%x", v);
|
||
|
else
|
||
|
fprintf(f, "%x", v);
|
||
|
v = (int)(*ptr++);
|
||
|
if (v < 0x10)
|
||
|
fprintf(f, "0%x", v);
|
||
|
else
|
||
|
fprintf(f, "%x", v);
|
||
|
}
|
||
|
fprintf(f, "\n");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fprintf(f, "/pix %i string def\n", w);
|
||
|
fprintf(f, "/grays %i string def\n", w);
|
||
|
fprintf(f, "/npixls 0 def\n");
|
||
|
fprintf(f, "/rgbindx 0 def\n");
|
||
|
fprintf(f, "%i %i translate\n", bx, by);
|
||
|
fprintf(f, "%i %i scale\n", bxx, byy);
|
||
|
fprintf(f, "%i %i 8\n", w, h);
|
||
|
fprintf(f, "[%i 0 0 -%i 0 %i]\n", w, h, h);
|
||
|
fprintf(f, "{currentfile pix readhexstring pop}\n");
|
||
|
fprintf(f, "image\n");
|
||
|
fprintf(f, "\n");
|
||
|
ptr = im->rgb_data;
|
||
|
for (y = 0; y < h; y++)
|
||
|
{
|
||
|
for (x = 0; x < w; x++)
|
||
|
{
|
||
|
v = (int)(*ptr++);
|
||
|
v += (int)(*ptr++);
|
||
|
v += (int)(*ptr++);
|
||
|
v /= 3;
|
||
|
if (v < 0x10)
|
||
|
fprintf(f, "0%x", v);
|
||
|
else
|
||
|
fprintf(f, "%x", v);
|
||
|
}
|
||
|
fprintf(f, "\n");
|
||
|
}
|
||
|
}
|
||
|
fprintf(f, "\n");
|
||
|
fprintf(f, "showpage\n");
|
||
|
fprintf(f, "end\n");
|
||
|
fprintf(f, "origstate restore\n");
|
||
|
fprintf(f, "%%%%Trailer\n");
|
||
|
fclose(f);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
else if ((!strcasecmp(ext, "jpeg")) || (!strcasecmp(ext, "jpg")))
|
||
|
{
|
||
|
#ifdef HAVE_LIBJPEG
|
||
|
struct jpeg_compress_struct cinfo;
|
||
|
struct jpeg_error_mgr jerr;
|
||
|
JSAMPROW row_pointer[1];
|
||
|
int row_stride;
|
||
|
|
||
|
f = fopen(file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
cinfo.err = jpeg_std_error(&jerr);
|
||
|
jpeg_create_compress(&cinfo);
|
||
|
jpeg_stdio_dest(&cinfo, f);
|
||
|
cinfo.image_width = im->rgb_width;
|
||
|
cinfo.image_height = im->rgb_height;
|
||
|
cinfo.input_components = 3;
|
||
|
cinfo.in_color_space = JCS_RGB;
|
||
|
jpeg_set_defaults(&cinfo);
|
||
|
jpeg_set_quality(&cinfo, (100 * info->quality) >> 8, TRUE);
|
||
|
jpeg_start_compress(&cinfo, TRUE);
|
||
|
row_stride = cinfo.image_width * 3;
|
||
|
while (cinfo.next_scanline < cinfo.image_height)
|
||
|
{
|
||
|
row_pointer[0] = im->rgb_data + (cinfo.next_scanline * row_stride);
|
||
|
jpeg_write_scanlines(&cinfo, row_pointer, 1);
|
||
|
}
|
||
|
jpeg_finish_compress(&cinfo);
|
||
|
fclose(f);
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else if (!strcasecmp(ext, "png"))
|
||
|
{
|
||
|
#ifdef HAVE_LIBPNG
|
||
|
png_structp png_ptr;
|
||
|
png_infop info_ptr;
|
||
|
unsigned char *data, *ptr;
|
||
|
int x, y;
|
||
|
png_bytep row_ptr;
|
||
|
png_color_8 sig_bit;
|
||
|
|
||
|
f = fopen(file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||
|
NULL, NULL, NULL);
|
||
|
if (!png_ptr)
|
||
|
{
|
||
|
fclose(f);
|
||
|
return 0;
|
||
|
}
|
||
|
info_ptr = png_create_info_struct(png_ptr);
|
||
|
if (info_ptr == NULL)
|
||
|
{
|
||
|
fclose(f);
|
||
|
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||
|
return 0;
|
||
|
}
|
||
|
if (setjmp(png_ptr->jmpbuf))
|
||
|
{
|
||
|
fclose(f);
|
||
|
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||
|
return 0;
|
||
|
}
|
||
|
png_init_io(png_ptr, f);
|
||
|
png_set_IHDR(png_ptr, info_ptr, im->rgb_width, im->rgb_height, 8,
|
||
|
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
|
||
|
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||
|
sig_bit.red = 8;
|
||
|
sig_bit.green = 8;
|
||
|
sig_bit.blue = 8;
|
||
|
sig_bit.alpha = 8;
|
||
|
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
|
||
|
png_write_info(png_ptr, info_ptr);
|
||
|
png_set_shift(png_ptr, &sig_bit);
|
||
|
png_set_packing(png_ptr);
|
||
|
data = malloc(im->rgb_width * 4);
|
||
|
if (!data)
|
||
|
{
|
||
|
fclose(f);
|
||
|
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||
|
return 0;
|
||
|
}
|
||
|
for (y = 0; y < im->rgb_height; y++)
|
||
|
{
|
||
|
ptr = im->rgb_data + (y * im->rgb_width * 3);
|
||
|
for (x = 0; x < im->rgb_width; x++)
|
||
|
{
|
||
|
data[(x << 2) + 0] = *ptr++;
|
||
|
data[(x << 2) + 1] = *ptr++;
|
||
|
data[(x << 2) + 2] = *ptr++;
|
||
|
if ((data[(x << 2) + 0] == im->shape_color.r) &&
|
||
|
(data[(x << 2) + 1] == im->shape_color.g) &&
|
||
|
(data[(x << 2) + 2] == im->shape_color.b))
|
||
|
data[(x << 2) + 3] = 0;
|
||
|
else
|
||
|
data[(x << 2) + 3] = 255;
|
||
|
}
|
||
|
row_ptr = data;
|
||
|
png_write_rows(png_ptr, &row_ptr, 1);
|
||
|
}
|
||
|
free(data);
|
||
|
png_write_end(png_ptr, info_ptr);
|
||
|
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
|
||
|
|
||
|
fclose(f);
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else if ((!strcasecmp(ext, "tiff")) || (!strcasecmp(ext, "tif")))
|
||
|
{
|
||
|
#ifdef HAVE_LIBTIFF
|
||
|
TIFF *tif;
|
||
|
unsigned char *data;
|
||
|
int y;
|
||
|
int w;
|
||
|
|
||
|
tif = TIFFOpen(file, "w");
|
||
|
if (tif)
|
||
|
{
|
||
|
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, im->rgb_width);
|
||
|
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, im->rgb_height);
|
||
|
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||
|
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
|
||
|
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||
|
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
|
||
|
{
|
||
|
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
|
||
|
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||
|
w = TIFFScanlineSize(tif);
|
||
|
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
|
||
|
TIFFDefaultStripSize(tif, -1));
|
||
|
for (y = 0; y < im->rgb_height; y++)
|
||
|
{
|
||
|
data = im->rgb_data + (y * im->rgb_width * 3);
|
||
|
TIFFWriteScanline(tif, data, y, 0);
|
||
|
}
|
||
|
}
|
||
|
TIFFClose(tif);
|
||
|
return 1;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
#if 0
|
||
|
/* Once again, no shell fallbacks. This is just asking for it */
|
||
|
if (id->fallback)
|
||
|
{
|
||
|
f = open_helper("%C/convert pnm:- '%s'", file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
|
||
|
{
|
||
|
close_helper(f);
|
||
|
return 0;
|
||
|
}
|
||
|
if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
|
||
|
{
|
||
|
close_helper(f);
|
||
|
return 0;
|
||
|
}
|
||
|
if (close_helper(f))
|
||
|
return 0;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (!strcasecmp(ext, "jpeg"))
|
||
|
snprintf(cmd, sizeof(cmd), "%%H -quality %i -progressive -outfile %%s", 100 * info->quality / 256);
|
||
|
else if (!strcasecmp(ext, "jpg"))
|
||
|
snprintf(cmd, sizeof(cmd), "%%H -quality %i -progressive -outfile %%s", 100 * info->quality / 256);
|
||
|
else if (!strcasecmp(ext, "bmp"))
|
||
|
strcpy(cmd, "%Q %N/ppmtobmp > %s");
|
||
|
else if (!strcasecmp(ext, "gif"))
|
||
|
strcpy(cmd, "%Q %N/ppmtogif -interlace > %s");
|
||
|
else if (!strcasecmp(ext, "ilbm"))
|
||
|
strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress > %s");
|
||
|
else if (!strcasecmp(ext, "ilb"))
|
||
|
strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress > %s");
|
||
|
else if (!strcasecmp(ext, "iff"))
|
||
|
strcpy(cmd, "%N/ppmtoilbm -24if -hires -lace -compress > %s");
|
||
|
else if (!strcasecmp(ext, "icr"))
|
||
|
strcpy(cmd, "%N/ppmtoicr > %s");
|
||
|
else if (!strcasecmp(ext, "map"))
|
||
|
strcpy(cmd, "%N/ppmtomap > %s");
|
||
|
else if (!strcasecmp(ext, "mit"))
|
||
|
strcpy(cmd, "%N/ppmtomitsu -sharpness 4 > %s");
|
||
|
else if (!strcasecmp(ext, "mitsu"))
|
||
|
strcpy(cmd, "%N/ppmtomitsu -sharpness 4 > %s");
|
||
|
else if (!strcasecmp(ext, "pcx"))
|
||
|
strcpy(cmd, "%N/ppmtopcx -24bit -packed > %s");
|
||
|
else if (!strcasecmp(ext, "pgm"))
|
||
|
strcpy(cmd, "%N/ppmtopgm > %s");
|
||
|
else if (!strcasecmp(ext, "pi1"))
|
||
|
strcpy(cmd, "%N/ppmtopi1 > %s");
|
||
|
else if (!strcasecmp(ext, "pic"))
|
||
|
strcpy(cmd, "%Q %N/ppmtopict > %s");
|
||
|
else if (!strcasecmp(ext, "pict"))
|
||
|
strcpy(cmd, "%Q %N/ppmtopict > %s");
|
||
|
else if (!strcasecmp(ext, "pj"))
|
||
|
strcpy(cmd, "%N/ppmtopj > %s");
|
||
|
else if (!strcasecmp(ext, "pjxl"))
|
||
|
strcpy(cmd, "%N/ppmtopjxl > %s");
|
||
|
else if (!strcasecmp(ext, "puz"))
|
||
|
strcpy(cmd, "%N/ppmtopuzz > %s");
|
||
|
else if (!strcasecmp(ext, "puzz"))
|
||
|
strcpy(cmd, "%N/ppmtopuzz > %s");
|
||
|
else if (!strcasecmp(ext, "rgb3"))
|
||
|
strcpy(cmd, "%N/ppmtorgb3 > %s");
|
||
|
else if (!strcasecmp(ext, "six"))
|
||
|
strcpy(cmd, "%N/ppmtosixel > %s");
|
||
|
else if (!strcasecmp(ext, "sixel"))
|
||
|
strcpy(cmd, "%N/ppmtosizel > %s");
|
||
|
else if (!strcasecmp(ext, "tga"))
|
||
|
strcpy(cmd, "%N/ppmtotga -rgb > %s");
|
||
|
else if (!strcasecmp(ext, "targa"))
|
||
|
strcpy(cmd, "%N/ppmtotga -rgb > %s");
|
||
|
else if (!strcasecmp(ext, "uil"))
|
||
|
strcpy(cmd, "%N/ppmtouil > %s");
|
||
|
else if (!strcasecmp(ext, "xpm"))
|
||
|
strcpy(cmd, "%Q %N/ppmtoxpm > %s");
|
||
|
else if (!strcasecmp(ext, "yuv"))
|
||
|
strcpy(cmd, "%N/ppmtoyuv > %s");
|
||
|
else if (!strcasecmp(ext, "png"))
|
||
|
strcpy(cmd, "%N/pnmtopng > %s");
|
||
|
else if (!strcasecmp(ext, "ps"))
|
||
|
strcpy(cmd, "%N/pnmtops -center -scale 100 > %s");
|
||
|
else if (!strcasecmp(ext, "rast"))
|
||
|
strcpy(cmd, "%N/pnmtorast -rle > %s");
|
||
|
else if (!strcasecmp(ext, "ras"))
|
||
|
strcpy(cmd, "%N/pnmtorast -rle > %s");
|
||
|
else if (!strcasecmp(ext, "sgi"))
|
||
|
strcpy(cmd, "%N/pnmtosgi > %s");
|
||
|
else if (!strcasecmp(ext, "sir"))
|
||
|
strcpy(cmd, "%N/pnmtosir > %s");
|
||
|
else if (!strcasecmp(ext, "tif"))
|
||
|
strcpy(cmd, "%N/pnmtotiff -lzw > %s");
|
||
|
else if (!strcasecmp(ext, "tiff"))
|
||
|
strcpy(cmd, "%N/pnmtotiff -lzw > %s");
|
||
|
else if (!strcasecmp(ext, "xwd"))
|
||
|
strcpy(cmd, "%N/pnmtoxwd > %s");
|
||
|
else
|
||
|
ext = "";
|
||
|
if (ext[0])
|
||
|
{
|
||
|
f = open_helper(cmd, file, "wb");
|
||
|
if (f)
|
||
|
{
|
||
|
if (!fprintf(f, "P6\n# Created by Imlib\n%i %i\n255\n", im->rgb_width, im->rgb_height))
|
||
|
{
|
||
|
close_helper(f);
|
||
|
return 0;
|
||
|
}
|
||
|
if (!fwrite(im->rgb_data, 1, (im->rgb_width * im->rgb_height * 3), f))
|
||
|
{
|
||
|
close_helper(f);
|
||
|
return 0;
|
||
|
}
|
||
|
if (close_helper(f))
|
||
|
return 0;
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
fprintf(stderr, "IMLIB ERROR: Cannot save image: %s\n", file);
|
||
|
fprintf(stderr, "All fallbacks failed.\n");
|
||
|
|
||
|
return 0;
|
||
|
}
|