#include "image-private.h"
int
_cupsImageReadPhotoCD(
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 xdir,
xstart;
int bpp;
int pass;
int rotation;
int temp,
temp2,
cb, cr;
cups_ib_t *in,
*iy,
*icb,
*icr,
*rgb,
*rgbptr,
*out;
(void)secondary;
fseek(fp, 72, SEEK_SET);
rotation = (getc(fp) & 63) != 8;
fseek(fp, 0x30000, SEEK_SET);
img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary;
img->xppi = 128;
img->yppi = 128;
if (rotation)
{
img->xsize = 512;
img->ysize = 768;
}
else
{
img->xsize = 768;
img->ysize = 512;
}
cupsImageSetMaxTiles(img, 0);
bpp = cupsImageGetDepth(img);
if ((in = malloc(768 * 3)) == NULL)
{
fputs("DEBUG: Unable to allocate memory!\n", stderr);
fclose(fp);
return (1);
}
if ((out = malloc(768 * bpp)) == NULL)
{
fputs("DEBUG: Unable to allocate memory!\n", stderr);
fclose(fp);
free(in);
return (1);
}
if (bpp > 1)
{
if ((rgb = malloc(768 * 3)) == NULL)
{
fputs("DEBUG: Unable to allocate memory!\n", stderr);
fclose(fp);
free(in);
free(out);
return (1);
}
}
else
rgb = NULL;
if (rotation)
{
xstart = 767 * bpp;
xdir = -2 * bpp;
}
else
{
xstart = 0;
xdir = 0;
}
for (y = 0; y < 512; y += 2)
{
if (fread(in, 1, 768 * 3, fp) < (768 * 3))
{
free(in);
free(out);
if (bpp > 1)
free(rgb);
return (-1);
}
for (pass = 0, iy = in; pass < 2; pass ++)
{
if (bpp == 1)
{
if (primary == CUPS_IMAGE_BLACK)
{
if (rotation)
{
for (rgbptr = out + xstart, x = 0; x < 768; x ++)
*rgbptr-- = 255 - *iy++;
if (lut)
cupsImageLut(out, 768, lut);
_cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
}
else
{
cupsImageWhiteToBlack(iy, out, 768);
if (lut)
cupsImageLut(out, 768, lut);
_cupsImagePutRow(img, 0, y + pass, 768, out);
iy += 768;
}
}
else if (rotation)
{
for (rgbptr = out + xstart, x = 0; x < 768; x ++)
*rgbptr-- = 255 - *iy++;
if (lut)
cupsImageLut(out, 768, lut);
_cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
}
else
{
if (lut)
cupsImageLut(iy, 768, lut);
_cupsImagePutRow(img, 0, y + pass, 768, iy);
iy += 768;
}
}
else
{
cb = cr = 0.0f;
for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920;
x < 768;
x ++, iy ++, rgbptr += xdir)
{
if (!(x & 1))
{
cb = (float)(*icb - 156);
cr = (float)(*icr - 137);
}
temp = 92241 * (*iy);
temp2 = (temp + 86706 * cr) / 65536;
if (temp2 < 0)
*rgbptr++ = 0;
else if (temp2 > 255)
*rgbptr++ = 255;
else
*rgbptr++ = temp2;
temp2 = (temp - 25914 * cb - 44166 * cr) / 65536;
if (temp2 < 0)
*rgbptr++ = 0;
else if (temp2 > 255)
*rgbptr++ = 255;
else
*rgbptr++ = temp2;
temp2 = (temp + 133434 * cb) / 65536;
if (temp2 < 0)
*rgbptr++ = 0;
else if (temp2 > 255)
*rgbptr++ = 255;
else
*rgbptr++ = temp2;
if (x & 1)
{
icb ++;
icr ++;
}
}
if (saturation != 100 || hue != 0)
cupsImageRGBAdjust(rgb, 768, saturation, hue);
switch (img->colorspace)
{
default :
break;
case CUPS_IMAGE_RGB :
cupsImageRGBToRGB(rgb, out, 768);
break;
case CUPS_IMAGE_CMY :
cupsImageRGBToCMY(rgb, out, 768);
break;
case CUPS_IMAGE_CMYK :
cupsImageRGBToCMYK(rgb, out, 768);
break;
}
if (lut)
cupsImageLut(out, 768 * bpp, lut);
if (rotation)
_cupsImagePutCol(img, 511 - y - pass, 0, 768, out);
else
_cupsImagePutRow(img, 0, y + pass, 768, out);
}
}
}
free(in);
free(out);
if (bpp > 1)
free(rgb);
return (0);
}