Files correlati : pdflib Ricompilazione Demo : [ ] Commento : Aggiornata pdflib.dll alla versione 7.0.4 git-svn-id: svn://10.65.10.50/trunk@18580 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.4 2009-03-23 08:51:17 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 */
 |