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.

303 lines
5.6 KiB

#include <config.h>
#include <setjmp.h>
#define id _gdk_imlib_data
#include "gdk_imlib.h"
#include "gdk_imlib_private.h"
unsigned char *
loader_ppm (FILE * f, int *w, int *h, int *t)
{
int done;
unsigned char *ptr;
unsigned char chr;
char s[256];
int a, b, i, j;
int color, scale, ascii, bw;
*t = 0;
a = b = scale = ascii = bw = color = 0;
fgets(s, 256, f);
s[2] = 0;
if (!strcmp(s, "P6"))
color = 1;
else if (!strcmp(s, "P5"))
color = 0;
else if (!strcmp(s, "P4"))
bw = 1;
else if (!strcmp(s, "P3"))
{
color = 1;
ascii = 1;
}
else if (!strcmp(s, "P2"))
{
ascii = 1;
}
else if (!strcmp(s, "P1"))
{
ascii = 1;
bw = 1;
}
else
return NULL;
done = 1;
ptr = NULL;
while (done)
{
if (fgets(s, 256, f) == NULL)
break;
if (s[0] != '#')
{
done = 0;
sscanf(s, "%i %i", w, h);
a = *w;
b = *h;
if (a > 32767)
{
fprintf(stderr, "gdk_imlib ERROR: Image width > 32767 pixels for file\n");
return NULL;
}
if (b > 32767)
{
fprintf(stderr, "gdk_imlib ERROR: Image height > 32767 pixels for file\n");
return NULL;
}
if (!bw)
{
fgets(s, 256, f);
sscanf(s, "%i", &scale);
}
else
scale = 99999;
ptr = (unsigned char *)_gdk_malloc_image(a, b);
if (!ptr)
{
fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for RGB data in file");
return ptr;
}
if ((color) && (!ascii) && (!bw))
{
fread(ptr, a * b * 3, 1, f);
}
else if ((!color) && (!ascii) && (!bw))
{
b = (a * b * 3);
a = 0;
while ((fread(&chr, 1, 1, f)) && (a < b))
{
ptr[a++] = chr;
ptr[a++] = chr;
ptr[a++] = chr;
}
}
else if ((!color) && (!ascii) && (bw))
{
b = (a * b * 3);
a = 0;
j = 0;
while ((fread(&chr, 1, 1, f)) && (a < b))
{
for (i = 7; i >= 0; i--)
{
j++;
if (j <= *w)
{
if (chr & (1 << i))
{
ptr[a++] = 0;
ptr[a++] = 0;
ptr[a++] = 0;
}
else
{
ptr[a++] = 255;
ptr[a++] = 255;
ptr[a++] = 255;
}
}
}
if (j >= *w)
j = 0;
}
}
else if ((color) && (ascii) && (!bw))
{
b = (a * b * 3);
a = 0;
i = 0;
if (scale != 255)
{
while ((fread(&chr, 1, 1, f)) && (a < b))
{
s[i++] = chr;
if (!isdigit(chr))
{
s[i - 1] = 0;
if ((i > 1) && (isdigit(s[i - 2])))
{
ptr[a++] = ((atoi(s)) * 255) / scale;
}
i = 0;
}
}
}
else
{
while ((fread(&chr, 1, 1, f)) && (a < b))
{
s[i++] = chr;
if (!isdigit(chr))
{
s[i - 1] = 0;
if ((i > 1) && (isdigit(s[i - 2])))
{
ptr[a++] = atoi(s);
}
i = 0;
}
}
}
}
else if ((!color) && (ascii) && (!bw))
{
b = (a * b * 3);
a = 0;
i = 0;
if (scale != 255)
{
while ((fread(&chr, 1, 1, f)) && (a < b))
{
s[i++] = chr;
if (!isdigit(chr))
{
s[i - 1] = 0;
if ((i > 1) && (isdigit(s[i - 2])))
{
ptr[a++] = ((atoi(s)) * 255) / scale;
ptr[a++] = ptr[a - 1];
ptr[a++] = ptr[a - 1];
}
i = 0;
}
}
}
else
{
while ((fread(&chr, 1, 1, f)) && (a < b))
{
s[i++] = chr;
if (!isdigit(chr))
{
s[i - 1] = 0;
if ((i > 1) && (isdigit(s[i - 2])))
{
ptr[a++] = atoi(s);
ptr[a++] = ptr[a - 1];
ptr[a++] = ptr[a - 1];
}
i = 0;
}
}
}
}
else if ((!color) && (ascii) && (bw))
{
}
}
}
if (!ptr)
return NULL;
if (scale == 0)
{
free(ptr);
return NULL;
}
if ((scale < 255) && (!ascii))
{
int rot;
unsigned char *po;
if (scale <= 1)
rot = 7;
else if (scale <= 3)
rot = 6;
else if (scale <= 7)
rot = 5;
else if (scale <= 15)
rot = 4;
else if (scale <= 31)
rot = 3;
else if (scale <= 63)
rot = 2;
else
rot = 1;
if (rot > 0)
{
po = ptr;
while (po < (ptr + (*w ** h * 3)))
{
*po++ <<= rot;
*po++ <<= rot;
*po++ <<= rot;
}
}
}
return ptr;
}
gint
saver_ppm (GdkImlibImage *im, char *file, GdkImlibSaveInfo *info)
{
char *ext = _gdk_imlib_GetExtension (file);
int x, y;
unsigned char *ptr, val;
int v;
FILE *f;
f = fopen(file, "wb");
if (!f)
return 0;
if (strcmp (ext, "pgm") == 0){
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 (!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;
}
}