Pillow/libImaging/File.c
2010-07-30 22:52:47 -04:00

194 lines
3.3 KiB
C

/*
* The Python Imaging Library
* $Id$
*
* built-in image file handling
*
* history:
* 1995-11-26 fl Created, supports PGM/PPM
* 1996-08-07 fl Write "1" images as PGM
* 1999-02-21 fl Don't write non-standard modes
*
* Copyright (c) 1997-99 by Secret Labs AB.
* Copyright (c) 1995-96 by Fredrik Lundh.
*
* See the README file for information on usage and redistribution.
*/
#include "Imaging.h"
#include <ctype.h>
Imaging
ImagingOpenPPM(const char* infile)
{
FILE* fp;
int i, c, v;
char* mode;
int x, y, max;
Imaging im;
if (!infile)
return ImagingError_ValueError(NULL);
fp = fopen(infile, "rb");
if (!fp)
return ImagingError_IOError();
/* PPM magic */
if (fgetc(fp) != 'P')
goto error;
switch (fgetc(fp)) {
case '4': /* FIXME: 1-bit images are not yet supported */
goto error;
case '5':
mode = "L";
break;
case '6':
mode = "RGB";
break;
default:
goto error;
}
i = 0;
c = fgetc(fp);
x = y = max = 0;
while (i < 3) {
/* Ignore optional comment fields */
while (c == '\n') {
c = fgetc(fp);
if (c == '#') {
do {
c = fgetc(fp);
if (c == EOF)
goto error;
} while (c != '\n');
c = fgetc(fp);
}
}
/* Skip forward to next value */
while (isspace(c))
c = fgetc(fp);
/* And parse it */
v = 0;
while (isdigit(c)) {
v = v * 10 + (c - '0');
c = fgetc(fp);
}
if (c == EOF)
goto error;
switch (i++) {
case 0:
x = v;
break;
case 1:
y = v;
break;
case 2:
max = v;
break;
}
}
im = ImagingNew(mode, x, y);
if (!im)
return NULL;
/* if (max != 255) ... FIXME: does anyone ever use this feature? */
if (strcmp(im->mode, "L") == 0) {
/* PPM "L" */
for (y = 0; y < im->ysize; y++)
if (fread(im->image[y], im->xsize, 1, fp) != 1)
goto error;
} else {
/* PPM "RGB" or PyPPM mode */
for (y = 0; y < im->ysize; y++)
for (x = i = 0; x < im->xsize; x++, i += im->pixelsize)
if (fread(im->image[y]+i, im->bands, 1, fp) != 1)
goto error;
}
fclose(fp);
return im;
error:
fclose(fp);
return ImagingError_IOError();
}
int
ImagingSaveRaw(Imaging im, FILE* fp)
{
int x, y, i;
if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
/* @PIL227: FIXME: for mode "1", map != 0 to 255 */
/* PGM "L" */
for (y = 0; y < im->ysize; y++)
fwrite(im->image[y], 1, im->xsize, fp);
} else {
/* PPM "RGB" or other internal format */
for (y = 0; y < im->ysize; y++)
for (x = i = 0; x < im->xsize; x++, i += im->pixelsize)
fwrite(im->image[y]+i, 1, im->bands, fp);
}
return 1;
}
int
ImagingSavePPM(Imaging im, const char* outfile)
{
FILE* fp;
if (!im) {
(void) ImagingError_ValueError(NULL);
return 0;
}
fp = fopen(outfile, "wb");
if (!fp) {
(void) ImagingError_IOError();
return 0;
}
if (strcmp(im->mode, "1") == 0 || strcmp(im->mode, "L") == 0) {
/* Write "PGM" */
fprintf(fp, "P5\n%d %d\n255\n", im->xsize, im->ysize);
} else if (strcmp(im->mode, "RGB") == 0) {
/* Write "PPM" */
fprintf(fp, "P6\n%d %d\n255\n", im->xsize, im->ysize);
} else {
(void) ImagingError_ModeError();
return 0;
}
ImagingSaveRaw(im, fp);
fclose(fp);
return 1;
}