429faed747
Files correlati : pdflib Ricompilazione Demo : [ ] Commento : Aggiornata PDFlib git-svn-id: svn://10.65.10.50/trunk@17433 c028cbd2-c16b-5b4b-a496-9718f37d4682
744 lines
18 KiB
C
Executable File
744 lines
18 KiB
C
Executable File
/*---------------------------------------------------------------------------*
|
|
| PDFlib - A library for generating PDF on the fly |
|
|
+---------------------------------------------------------------------------+
|
|
| Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
|
|
+---------------------------------------------------------------------------+
|
|
| |
|
|
| This software is subject to the PDFlib license. It is NOT in the |
|
|
| public domain. Extended versions and commercial licenses are |
|
|
| available, please check http://www.pdflib.com. |
|
|
| |
|
|
*---------------------------------------------------------------------------*/
|
|
|
|
/* $Id: p_gif.c,v 1.3 2008-10-20 14:34:15 guy Exp $
|
|
*
|
|
* GIF processing for PDFlib
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This module contains modified parts of the giftopnm.c progam in the
|
|
* netpbm package. It contained the following copyright notice:
|
|
*/
|
|
|
|
/* +-------------------------------------------------------------------+ */
|
|
/* | Copyright 1990 - 1994, David Koblas. (koblas@netcom.com) | */
|
|
/* | Permission to use, copy, modify, and distribute this software | */
|
|
/* | and its documentation for any purpose and without fee is hereby | */
|
|
/* | granted, provided that the above copyright notice appear in all | */
|
|
/* | copies and that both that copyright notice and this permission | */
|
|
/* | notice appear in supporting documentation. This software is | */
|
|
/* | provided "as is" without express or implied warranty. | */
|
|
/* +-------------------------------------------------------------------+ */
|
|
|
|
#include "p_intern.h"
|
|
#include "p_color.h"
|
|
#include "p_image.h"
|
|
|
|
#ifndef PDF_GIF_SUPPORTED
|
|
|
|
pdc_bool
|
|
pdf_is_GIF_file(PDF *p, pdc_file *fp)
|
|
{
|
|
(void) p;
|
|
(void) fp;
|
|
|
|
return pdc_false;
|
|
}
|
|
|
|
int
|
|
pdf_process_GIF_data(
|
|
PDF *p,
|
|
int imageslot)
|
|
{
|
|
(void) imageslot;
|
|
|
|
pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "GIF", 0, 0, 0);
|
|
|
|
return -1;
|
|
}
|
|
|
|
void
|
|
pdf_cleanup_gif(PDF *p, pdf_image *image)
|
|
{
|
|
(void) p;
|
|
(void) image;
|
|
}
|
|
|
|
#else
|
|
|
|
#define LOCALCOLORMAP 0x80
|
|
#define BitSet(byteval, bitval) (((byteval) & (bitval)) == (bitval))
|
|
|
|
static int ReadColorMap(pdc_core *pdc, pdc_file *fp,
|
|
int number, pdf_colormap *buffer);
|
|
static int DoExtension(PDF *p, pdf_image *image, int label);
|
|
static int GetDataBlock(PDF *p, pdf_image *image, unsigned char *buf);
|
|
static void ReadImage(PDF *p, pdf_image *image, PDF_data_source *src);
|
|
|
|
static void
|
|
pdf_data_source_GIF_init(PDF *p, PDF_data_source *src)
|
|
{
|
|
pdf_image *image;
|
|
|
|
image = (pdf_image *) src->private_data;
|
|
|
|
src->buffer_length = (size_t) (image->width * image->height * 1);
|
|
src->buffer_start = (pdc_byte *) pdc_malloc(p->pdc, src->buffer_length,
|
|
"pdf_data_source_GIF_init");
|
|
src->bytes_available= 0;
|
|
src->next_byte = NULL;
|
|
}
|
|
|
|
static pdc_bool
|
|
pdf_data_source_GIF_fill(PDF *p, PDF_data_source *src)
|
|
{
|
|
pdf_image *image;
|
|
|
|
if (src->next_byte != NULL) /* all finished in one turn */
|
|
return pdc_false;
|
|
|
|
image = (pdf_image *) src->private_data;
|
|
|
|
src->next_byte = src->buffer_start;
|
|
src->bytes_available = src->buffer_length;
|
|
|
|
PDC_TRY(p->pdc)
|
|
{
|
|
ReadImage(p, image, src);
|
|
}
|
|
PDC_CATCH(p->pdc)
|
|
{
|
|
image->corrupt = pdc_true;
|
|
}
|
|
|
|
pdf_cleanup_gif(p, image);
|
|
|
|
return !image->corrupt;
|
|
}
|
|
|
|
static void
|
|
pdf_data_source_GIF_terminate(PDF *p, PDF_data_source *src)
|
|
{
|
|
pdc_free(p->pdc, (void *) src->buffer_start);
|
|
}
|
|
|
|
#define PDF_STRING_GIF "\107\111\106"
|
|
#define PDF_STRING_87a "\070\067\141"
|
|
#define PDF_STRING_89a "\070\071\141"
|
|
|
|
pdc_bool
|
|
pdf_is_GIF_file(PDF *p, pdc_file *fp)
|
|
{
|
|
unsigned char buf[3];
|
|
|
|
pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type GIF...\n");
|
|
|
|
if (!PDC_OK_FREAD(fp, buf, 3) ||
|
|
strncmp((const char *) buf, PDF_STRING_GIF, 3) != 0)
|
|
{
|
|
pdc_fseek(fp, 0L, SEEK_SET);
|
|
return pdc_false;
|
|
}
|
|
return pdc_true;
|
|
}
|
|
|
|
int
|
|
pdf_process_GIF_data(
|
|
PDF *p,
|
|
int imageslot)
|
|
{
|
|
unsigned char buf[16];
|
|
char c;
|
|
int imageCount = 0;
|
|
char version[4];
|
|
int errcode = 0;
|
|
pdf_image *image;
|
|
pdf_colorspace cs;
|
|
pdf_colormap colormap;
|
|
int slot;
|
|
|
|
image = &p->images[imageslot];
|
|
|
|
image->info.gif.stack = NULL;
|
|
image->info.gif.table = NULL;
|
|
|
|
/* we invert this flag later */
|
|
if (image->ignoremask)
|
|
image->transparent = pdc_true;
|
|
|
|
if (image->page == pdc_undef)
|
|
image->page = 1;
|
|
|
|
/* Error reading magic number or not a GIF file */
|
|
if (pdf_is_GIF_file(p, image->fp) == pdc_false) {
|
|
errcode = PDC_E_IO_BADFORMAT;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
|
|
/* Version number */
|
|
if (! PDC_OK_FREAD(image->fp, buf, 3)) {
|
|
errcode = PDC_E_IO_BADFORMAT;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
strncpy(version, (const char *) buf, 3);
|
|
version[3] = '\0';
|
|
if ((strcmp(version, PDF_STRING_87a) != 0) &&
|
|
(strcmp(version, PDF_STRING_89a) != 0)) {
|
|
errcode = PDC_E_IO_BADFORMAT;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
|
|
/* Failed to read screen descriptor */
|
|
if (! PDC_OK_FREAD(image->fp, buf, 7)) {
|
|
errcode = PDC_E_IO_BADFORMAT;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
|
|
cs.type = Indexed;
|
|
/* size of the global color table */
|
|
cs.val.indexed.palette_size = 2 << (buf[4] & 0x07);
|
|
cs.val.indexed.base = DeviceRGB;
|
|
cs.val.indexed.colormap = &colormap;
|
|
cs.val.indexed.colormap_id = PDC_BAD_ID;
|
|
|
|
if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
|
|
if (ReadColorMap(p->pdc, image->fp,
|
|
cs.val.indexed.palette_size, &colormap)) {
|
|
errcode = PDF_E_IMAGE_COLORMAP;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
}
|
|
|
|
/* translate the aspect ratio to PDFlib notation */
|
|
if (buf[6] != 0) {
|
|
image->dpi_x = (pdc_scalar) (-(buf[6] + 15.0) / 64.0);
|
|
image->dpi_y = -1.0;
|
|
}
|
|
|
|
for (/* */ ; /* */ ; /* */) {
|
|
/* EOF / read error in image data */
|
|
if (!PDC_OK_FREAD(image->fp, &c, 1)) {
|
|
errcode = PDC_E_IO_READ;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
|
|
#define PDF_SEMICOLON ((char) 0x3b) /* ASCII ';' */
|
|
|
|
if (c == PDF_SEMICOLON) { /* GIF terminator */
|
|
/* Not enough images found in file */
|
|
if (imageCount < image->page) {
|
|
if (!imageCount)
|
|
errcode = PDF_E_IMAGE_CORRUPT;
|
|
else
|
|
errcode = PDF_E_IMAGE_NOPAGE;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
break;
|
|
}
|
|
|
|
#define PDF_EXCLAM ((char) 0x21) /* ASCII '!' */
|
|
|
|
if (c == PDF_EXCLAM) { /* Extension */
|
|
if (!PDC_OK_FREAD(image->fp, &c, 1)) {
|
|
/* EOF / read error on extension function code */
|
|
errcode = PDC_E_IO_READ;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
DoExtension(p, image, (int) c);
|
|
continue;
|
|
}
|
|
|
|
#define PDF_COMMA ((char) 0x2c) /* ASCII ',' */
|
|
|
|
if (c != PDF_COMMA) { /* Not a valid start character */
|
|
/* Bogus character, ignoring */
|
|
continue;
|
|
}
|
|
|
|
++imageCount;
|
|
|
|
if (! PDC_OK_FREAD(image->fp, buf, 9)) {
|
|
/* Couldn't read left/top/width/height */
|
|
errcode = PDC_E_IO_READ;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
|
|
image->components = 1;
|
|
image->bpc = 8;
|
|
image->width = (pdc_scalar) pdc_get_le_ushort(&buf[4]);
|
|
image->height = (pdc_scalar) pdc_get_le_ushort(&buf[6]);
|
|
|
|
#define INTERLACE 0x40
|
|
image->info.gif.interlace= BitSet(buf[8], INTERLACE);
|
|
|
|
if (image->imagemask)
|
|
{
|
|
if (p->compatibility <= PDC_1_3) {
|
|
errcode = PDF_E_IMAGE_MASK1BIT13;
|
|
goto PDF_GIF_ERROR;
|
|
} else {
|
|
/* images with more than one bit will be written as /SMask,
|
|
* and don't require an /ImageMask entry.
|
|
*/
|
|
image->imagemask = pdc_false;
|
|
}
|
|
image->colorspace = DeviceGray;
|
|
}
|
|
|
|
if (BitSet(buf[8], LOCALCOLORMAP)) {
|
|
/* The local color map may have a different size */
|
|
cs.val.indexed.palette_size = 2 << (buf[8] & 0x07);
|
|
|
|
if (ReadColorMap(p->pdc, image->fp,
|
|
cs.val.indexed.palette_size, &colormap))
|
|
{
|
|
errcode = PDF_E_IMAGE_COLORMAP;
|
|
goto PDF_GIF_ERROR;
|
|
}
|
|
}
|
|
|
|
if (imageCount == image->page)
|
|
break;
|
|
}
|
|
|
|
image->src.init = pdf_data_source_GIF_init;
|
|
image->src.fill = pdf_data_source_GIF_fill;
|
|
image->src.terminate = pdf_data_source_GIF_terminate;
|
|
image->src.private_data = (void *) image;
|
|
|
|
image->compression = pdf_comp_none;
|
|
image->use_raw = pdc_false;
|
|
|
|
image->in_use = pdc_true; /* mark slot as used */
|
|
|
|
slot = pdf_add_colorspace(p, &cs, pdc_false);
|
|
image->colorspace = slot;
|
|
|
|
|
|
|
|
|
|
pdf_put_image(p, imageslot, pdc_true, pdc_true);
|
|
|
|
if (!image->corrupt)
|
|
return imageslot;
|
|
|
|
PDF_GIF_ERROR:
|
|
{
|
|
const char *stemp = NULL;
|
|
|
|
if (errcode)
|
|
stemp = pdf_get_image_filename(p, image);
|
|
|
|
switch (errcode)
|
|
{
|
|
case PDC_E_IO_READ:
|
|
case PDF_E_IMAGE_COLORMAP:
|
|
case PDF_E_IMAGE_MASK1BIT13:
|
|
pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0);
|
|
break;
|
|
|
|
case PDC_E_IO_BADFORMAT:
|
|
pdc_set_errmsg(p->pdc, errcode, stemp, "GIF", 0, 0);
|
|
break;
|
|
|
|
case PDF_E_IMAGE_CORRUPT:
|
|
pdc_set_errmsg(p->pdc, errcode, "GIF", stemp, 0, 0);
|
|
break;
|
|
|
|
case PDF_E_IMAGE_NOPAGE:
|
|
pdc_set_errmsg(p->pdc, errcode,
|
|
pdc_errprintf(p->pdc, "%d", image->page), "GIF", stemp, 0);
|
|
break;
|
|
|
|
case 0: /* error code and message already set */
|
|
break;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
} /* pdf_open_GIF_data */
|
|
|
|
static int
|
|
ReadColorMap(pdc_core *pdc, pdc_file *fp, int number, pdf_colormap *buffer)
|
|
{
|
|
int i;
|
|
unsigned char rgb[3];
|
|
|
|
(void) pdc;
|
|
|
|
for (i = 0; i < number; ++i) {
|
|
if (! PDC_OK_FREAD(fp, rgb, sizeof(rgb))) {
|
|
return pdc_true; /* yk: true == error */
|
|
}
|
|
|
|
(*buffer)[i][0] = rgb[0] ;
|
|
(*buffer)[i][1] = rgb[1] ;
|
|
(*buffer)[i][2] = rgb[2] ;
|
|
}
|
|
return pdc_false; /* yk: false == ok. */
|
|
} /* ReadColorMap */
|
|
|
|
static int
|
|
DoExtension(PDF *p, pdf_image *image, int label)
|
|
{
|
|
pdc_byte buf[256];
|
|
|
|
switch ((unsigned char) label) {
|
|
case 0x01: /* Plain Text Extension */
|
|
break;
|
|
|
|
case 0xff: /* Application Extension */
|
|
break;
|
|
|
|
case 0xfe: /* Comment Extension */
|
|
while (GetDataBlock(p, image, (unsigned char*) buf) != 0) {
|
|
/* */
|
|
}
|
|
return pdc_false;
|
|
|
|
case 0xf9: /* Graphic Control Extension */
|
|
(void) GetDataBlock(p, image, (unsigned char*) buf);
|
|
|
|
if ((buf[0] & 0x1) != 0) {
|
|
image->transparent = !image->transparent;
|
|
image->transval[0] = buf[3];
|
|
}
|
|
|
|
while (GetDataBlock(p, image, (unsigned char*) buf) != 0) {
|
|
/* */ ;
|
|
}
|
|
return pdc_false;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
while (GetDataBlock(p, image, (unsigned char*) buf) != 0) {
|
|
/* */ ;
|
|
}
|
|
|
|
return pdc_false;
|
|
} /* DoExtension */
|
|
|
|
/*
|
|
* A bunch of formely static variables which are now kept in the
|
|
* image structure in order to keep the GIF reader thread-safe.
|
|
*/
|
|
|
|
/* for GetDataBlock() */
|
|
#define ZeroDataBlock (image->info.gif.ZeroDataBlock)
|
|
|
|
/* for initLWZ() */
|
|
#define curbit (image->info.gif.curbit)
|
|
#define lastbit (image->info.gif.lastbit)
|
|
#define get_done (image->info.gif.get_done)
|
|
#define last_byte (image->info.gif.last_byte)
|
|
#define return_clear (image->info.gif.return_clear)
|
|
|
|
#define sp (image->info.gif.sp)
|
|
#define code_size (image->info.gif.code_size)
|
|
#define set_code_size (image->info.gif.set_code_size)
|
|
#define max_code (image->info.gif.max_code)
|
|
#define max_code_size (image->info.gif.max_code_size)
|
|
#define clear_code (image->info.gif.clear_code)
|
|
#define end_code (image->info.gif.end_code)
|
|
|
|
/* for nextCode() */
|
|
#define buf (image->info.gif.buf)
|
|
|
|
/* for nextLWZ() */
|
|
#define stack (image->info.gif.stack)
|
|
#define table (image->info.gif.table)
|
|
#define firstcode (image->info.gif.firstcode)
|
|
#define oldcode (image->info.gif.oldcode)
|
|
|
|
static int
|
|
GetDataBlock(PDF *p, pdf_image *image, unsigned char *lbuf)
|
|
{
|
|
unsigned char count;
|
|
pdc_file *fp = image->fp;
|
|
|
|
if (!PDC_OK_FREAD(fp, &count, 1))
|
|
return -1; /* Error in getting DataBlock size */
|
|
|
|
ZeroDataBlock = (count == (unsigned char) 0);
|
|
|
|
if ((count != (unsigned char) 0) && (!PDC_OK_FREAD(fp, lbuf, count)))
|
|
{
|
|
/* Error in reading DataBlock */
|
|
pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF",
|
|
pdf_get_image_filename(p, image), 0, 0);
|
|
}
|
|
|
|
return count;
|
|
} /* GetDataBlock */
|
|
|
|
static void
|
|
initLWZ(PDF *p, pdf_image *image, int input_code_size)
|
|
{
|
|
#define GIF_TABLE_SIZE (sizeof(int [2][GIF_TABLE_ELEMENTS]))
|
|
#define GIF_STACK_SIZE (sizeof(int [GIF_TABLE_ELEMENTS*2]))
|
|
|
|
table = (int(*)[GIF_TABLE_ELEMENTS])
|
|
pdc_malloc(p->pdc, GIF_TABLE_SIZE, "initLWZ");
|
|
stack = (int *) pdc_malloc(p->pdc, GIF_STACK_SIZE, "initLWZ");
|
|
|
|
set_code_size = input_code_size;
|
|
code_size = set_code_size + 1;
|
|
clear_code = 1 << set_code_size ;
|
|
end_code = clear_code + 1;
|
|
max_code_size = 2 * clear_code;
|
|
max_code = clear_code + 2;
|
|
|
|
curbit = lastbit = 0;
|
|
last_byte = 2;
|
|
get_done = pdc_false;
|
|
|
|
return_clear = pdc_true;
|
|
|
|
sp = stack;
|
|
}
|
|
|
|
/*
|
|
* We clean up after decompressing the image; in rare cases (exception
|
|
* caused by damaged compressed data) this may also be called when
|
|
* cleaning up the full image struct.
|
|
*/
|
|
void
|
|
pdf_cleanup_gif(PDF *p, pdf_image *image)
|
|
{
|
|
if (table)
|
|
{
|
|
pdc_free(p->pdc, table);
|
|
table = NULL;
|
|
}
|
|
if (stack)
|
|
{
|
|
pdc_free(p->pdc, stack);
|
|
stack = NULL;
|
|
}
|
|
}
|
|
|
|
static int
|
|
nextCode(PDF *p, pdf_image *image, int codesize)
|
|
{
|
|
static const int maskTbl[16] = {
|
|
0x0000, 0x0001, 0x0003, 0x0007,
|
|
0x000f, 0x001f, 0x003f, 0x007f,
|
|
0x00ff, 0x01ff, 0x03ff, 0x07ff,
|
|
0x0fff, 0x1fff, 0x3fff, 0x7fff,
|
|
};
|
|
int i, j, ret, end;
|
|
|
|
if (return_clear) {
|
|
return_clear = pdc_false;
|
|
return clear_code;
|
|
}
|
|
|
|
end = curbit + codesize;
|
|
|
|
if (end >= lastbit) {
|
|
int count;
|
|
|
|
if (get_done) {
|
|
if (curbit >= lastbit)
|
|
{
|
|
/*
|
|
ERROR("ran off the end of my bits" );
|
|
*/
|
|
pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF",
|
|
pdf_get_image_filename(p, image), 0, 0);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if (last_byte >= 2)
|
|
{
|
|
buf[0] = buf[last_byte-2];
|
|
buf[1] = buf[last_byte-1];
|
|
}
|
|
|
|
if ((count = GetDataBlock(p, image, &buf[2])) == 0)
|
|
get_done = pdc_true;
|
|
|
|
last_byte = 2 + count;
|
|
curbit = (curbit - lastbit) + 16;
|
|
lastbit = (2+count)*8 ;
|
|
|
|
end = curbit + codesize;
|
|
}
|
|
|
|
j = end / 8;
|
|
i = curbit / 8;
|
|
|
|
if (i == j)
|
|
ret = buf[i];
|
|
else if (i + 1 == j)
|
|
ret = buf[i] | (buf[i+1] << 8);
|
|
else
|
|
ret = buf[i] | (buf[i+1] << 8) | (buf[i+2] << 16);
|
|
|
|
ret = (ret >> (curbit % 8)) & maskTbl[codesize];
|
|
|
|
curbit += codesize;
|
|
|
|
return ret;
|
|
}
|
|
|
|
#define readLWZ(p, image) ((sp > stack) ? *--sp : nextLWZ(p, image))
|
|
|
|
static int
|
|
nextLWZ(PDF *p, pdf_image *image)
|
|
{
|
|
int code, incode;
|
|
int i;
|
|
|
|
while ((code = nextCode(p, image, code_size)) >= 0) {
|
|
if (code == clear_code) {
|
|
for (i = 0; i < clear_code; ++i) {
|
|
table[0][i] = 0;
|
|
table[1][i] = i;
|
|
}
|
|
for (; i < (1<<MAX_LWZ_BITS); ++i)
|
|
table[0][i] = table[1][i] = 0;
|
|
code_size = set_code_size+1;
|
|
max_code_size = 2*clear_code;
|
|
max_code = clear_code+2;
|
|
sp = stack;
|
|
do {
|
|
firstcode = oldcode = nextCode(p, image, code_size);
|
|
} while (firstcode == clear_code);
|
|
|
|
return firstcode;
|
|
}
|
|
if (code == end_code) {
|
|
int count;
|
|
unsigned char lbuf[260];
|
|
|
|
if (ZeroDataBlock)
|
|
return -2;
|
|
|
|
while ((count = GetDataBlock(p, image, lbuf)) > 0)
|
|
;
|
|
|
|
/* count != 0: INFO_MSG(("missing EOD in data stream")); */
|
|
|
|
return -2;
|
|
}
|
|
|
|
incode = code;
|
|
|
|
if (code >= max_code) {
|
|
*sp++ = firstcode;
|
|
code = oldcode;
|
|
}
|
|
|
|
while (code >= clear_code) {
|
|
*sp++ = table[1][code];
|
|
if (code == table[0][code])
|
|
{
|
|
/* ERROR("circular table entry BIG ERROR"); */
|
|
pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF",
|
|
pdf_get_image_filename(p, image), 0, 0);
|
|
}
|
|
code = table[0][code];
|
|
}
|
|
|
|
*sp++ = firstcode = table[1][code];
|
|
|
|
if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
|
|
table[0][code] = oldcode;
|
|
table[1][code] = firstcode;
|
|
++max_code;
|
|
if ((max_code >= max_code_size) &&
|
|
(max_code_size < (1<<MAX_LWZ_BITS))) {
|
|
max_code_size *= 2;
|
|
++code_size;
|
|
}
|
|
}
|
|
|
|
oldcode = incode;
|
|
|
|
if (sp > stack)
|
|
return *--sp;
|
|
}
|
|
return code;
|
|
}
|
|
|
|
static void
|
|
ReadImage(PDF *p, pdf_image *image, PDF_data_source *src)
|
|
{
|
|
unsigned char c;
|
|
int v;
|
|
unsigned int xpos = 0, ypos = 0;
|
|
pdc_byte *dp;
|
|
unsigned int h = (unsigned int) image->height;
|
|
unsigned int w = (unsigned int) image->width;
|
|
|
|
/*
|
|
* Initialize the Compression routines
|
|
*/
|
|
ZeroDataBlock = pdc_false;
|
|
|
|
if (!PDC_OK_FREAD(image->fp, &c, 1))
|
|
{
|
|
pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "GIF",
|
|
pdf_get_image_filename(p, image), 0, 0);
|
|
}
|
|
|
|
initLWZ(p, image, c);
|
|
|
|
if (image->info.gif.interlace) {
|
|
int i;
|
|
int pass = 0, step = 8;
|
|
|
|
for (i = 0; i < (int) h; i++) {
|
|
dp = &src->buffer_start[w * ypos];
|
|
for (xpos = 0; xpos < w; xpos++) {
|
|
if ((v = readLWZ(p, image)) < 0)
|
|
goto fini;
|
|
|
|
*dp++ = v;
|
|
}
|
|
if ((ypos += step) >= h) {
|
|
do {
|
|
if (pass++ > 0)
|
|
step /= 2;
|
|
ypos = step / 2;
|
|
} while (ypos > h);
|
|
}
|
|
}
|
|
} else {
|
|
dp = src->buffer_start;
|
|
for (ypos = 0; ypos < h; ypos++) {
|
|
for (xpos = 0; xpos < w; xpos++) {
|
|
if ((v = readLWZ(p, image)) < 0)
|
|
goto fini;
|
|
|
|
*dp++ = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
fini:
|
|
if (readLWZ(p, image) >= 0)
|
|
/* Too much input data in GIF file '%s', ignoring extra. */
|
|
;
|
|
}
|
|
|
|
#undef fresh
|
|
#undef code_size
|
|
#undef set_code_size
|
|
#undef max_code
|
|
#undef max_code_size
|
|
#undef firstcode
|
|
#undef oldcode
|
|
#undef clear_code
|
|
#undef end_code
|
|
#undef sp
|
|
#undef table
|
|
#undef stack
|
|
|
|
#endif /* PDF_GIF_SUPPORTED */
|