#include "image-private.h"
int
_cupsImageReadPNM(
cups_image_t *img,
FILE *fp,
cups_icspace_t primary,
cups_icspace_t secondary,
int saturation,
int hue,
const cups_ib_t *lut)
{
int x, y;
int bpp;
cups_ib_t *in,
*inptr,
*out,
*outptr,
bit;
char line[255],
*lineptr;
int format,
val,
maxval;
if ((lineptr = fgets(line, sizeof(line), fp)) == NULL)
{
fputs("DEBUG: Bad PNM header!\n", stderr);
fclose(fp);
return (1);
}
lineptr ++;
format = atoi(lineptr);
while (isdigit(*lineptr & 255))
lineptr ++;
while (lineptr != NULL && img->xsize == 0)
{
if (*lineptr == '\0' || *lineptr == '#')
lineptr = fgets(line, sizeof(line), fp);
else if (isdigit(*lineptr & 255))
{
img->xsize = atoi(lineptr);
while (isdigit(*lineptr & 255))
lineptr ++;
}
else
lineptr ++;
}
while (lineptr != NULL && img->ysize == 0)
{
if (*lineptr == '\0' || *lineptr == '#')
lineptr = fgets(line, sizeof(line), fp);
else if (isdigit(*lineptr & 255))
{
img->ysize = atoi(lineptr);
while (isdigit(*lineptr & 255))
lineptr ++;
}
else
lineptr ++;
}
if (format != 1 && format != 4)
{
maxval = 0;
while (lineptr != NULL && maxval == 0)
{
if (*lineptr == '\0' || *lineptr == '#')
lineptr = fgets(line, sizeof(line), fp);
else if (isdigit(*lineptr & 255))
{
maxval = atoi(lineptr);
while (isdigit(*lineptr & 255))
lineptr ++;
}
else
lineptr ++;
}
}
else
maxval = 1;
if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH ||
img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT)
{
fprintf(stderr, "DEBUG: Bad PNM dimensions %dx%d!\n",
img->xsize, img->ysize);
fclose(fp);
return (1);
}
if (maxval == 0)
{
fprintf(stderr, "DEBUG: Bad PNM max value %d!\n", maxval);
fclose(fp);
return (1);
}
if (format == 1 || format == 2 || format == 4 || format == 5)
img->colorspace = secondary;
else
img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
cupsImageSetMaxTiles(img, 0);
bpp = cupsImageGetDepth(img);
if ((in = malloc(img->xsize * 3)) == NULL)
{
fputs("DEBUG: Unable to allocate memory!\n", stderr);
fclose(fp);
return (1);
}
if ((out = malloc(img->xsize * bpp)) == NULL)
{
fputs("DEBUG: Unable to allocate memory!\n", stderr);
fclose(fp);
free(in);
return (1);
}
for (y = 0; y < img->ysize; y ++)
{
switch (format)
{
case 1 :
for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
if (fscanf(fp, "%d", &val) == 1)
*inptr = val ? 0 : 255;
break;
case 2 :
for (x = img->xsize, inptr = in; x > 0; x --, inptr ++)
if (fscanf(fp, "%d", &val) == 1)
*inptr = 255 * val / maxval;
break;
case 3 :
for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3)
{
if (fscanf(fp, "%d", &val) == 1)
inptr[0] = 255 * val / maxval;
if (fscanf(fp, "%d", &val) == 1)
inptr[1] = 255 * val / maxval;
if (fscanf(fp, "%d", &val) == 1)
inptr[2] = 255 * val / maxval;
}
break;
case 4 :
fread(out, (img->xsize + 7) / 8, 1, fp);
for (x = img->xsize, inptr = in, outptr = out, bit = 128;
x > 0;
x --, inptr ++)
{
if (*outptr & bit)
*inptr = 0;
else
*inptr = 255;
if (bit > 1)
bit >>= 1;
else
{
bit = 128;
outptr ++;
}
}
break;
case 5 :
fread(in, img->xsize, 1, fp);
break;
case 6 :
fread(in, img->xsize, 3, fp);
break;
}
switch (format)
{
case 1 :
case 2 :
case 4 :
case 5 :
if (img->colorspace == CUPS_IMAGE_WHITE)
{
if (lut)
cupsImageLut(in, img->xsize, lut);
_cupsImagePutRow(img, 0, y, img->xsize, in);
}
else
{
switch (img->colorspace)
{
default :
break;
case CUPS_IMAGE_RGB :
cupsImageWhiteToRGB(in, out, img->xsize);
break;
case CUPS_IMAGE_BLACK :
cupsImageWhiteToBlack(in, out, img->xsize);
break;
case CUPS_IMAGE_CMY :
cupsImageWhiteToCMY(in, out, img->xsize);
break;
case CUPS_IMAGE_CMYK :
cupsImageWhiteToCMYK(in, out, img->xsize);
break;
}
if (lut)
cupsImageLut(out, img->xsize * bpp, lut);
_cupsImagePutRow(img, 0, y, img->xsize, out);
}
break;
default :
if ((saturation != 100 || hue != 0) && bpp > 1)
cupsImageRGBAdjust(in, img->xsize, saturation, hue);
switch (img->colorspace)
{
default :
break;
case CUPS_IMAGE_WHITE :
cupsImageRGBToWhite(in, out, img->xsize);
break;
case CUPS_IMAGE_RGB :
cupsImageRGBToRGB(in, out, img->xsize);
break;
case CUPS_IMAGE_BLACK :
cupsImageRGBToBlack(in, out, img->xsize);
break;
case CUPS_IMAGE_CMY :
cupsImageRGBToCMY(in, out, img->xsize);
break;
case CUPS_IMAGE_CMYK :
cupsImageRGBToCMYK(in, out, img->xsize);
break;
}
if (lut)
cupsImageLut(out, img->xsize * bpp, lut);
_cupsImagePutRow(img, 0, y, img->xsize, out);
break;
}
}
free(in);
free(out);
fclose(fp);
return (0);
}