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
		
			
				
	
	
		
			2303 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2303 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*---------------------------------------------------------------------------*
 | |
|  |              PDFlib - A library for generating PDF on the fly             |
 | |
|  +---------------------------------------------------------------------------+
 | |
|  | Copyright (c) 1997-2007 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_image.c,v 1.4 2009-03-23 08:51:17 guy Exp $
 | |
|  *
 | |
|  * PDFlib image routines
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #define P_IMAGE_C
 | |
| 
 | |
| #include "p_intern.h"
 | |
| #include "p_color.h"
 | |
| #include "p_defopt.h"
 | |
| #include "p_font.h"
 | |
| #include "p_image.h"
 | |
| #include "p_layer.h"
 | |
| #include "p_tagged.h"
 | |
| 
 | |
| static void
 | |
| pdf_init_image_struct(PDF *p, pdf_image *image)
 | |
| {
 | |
|     (void) p;
 | |
| 
 | |
|     /********** option variables *************/
 | |
|     image->verbose      = p->debug[(int) 'i'];
 | |
|     image->verbose      = pdf_get_errorpolicy(p, NULL, image->verbose);
 | |
|     image->bitreverse   = pdc_false;
 | |
|     image->bpc          = pdc_undef;
 | |
|     image->components   = pdc_undef;
 | |
|     image->height_pixel = pdc_undef;
 | |
|     image->ignoremask   = pdc_false;
 | |
|     image->ignoreorient = pdc_false;
 | |
|     image->doinline     = pdc_false;
 | |
|     image->interpolate  = pdc_false;
 | |
|     image->invert       = pdc_false;
 | |
|     image->jpegoptimize = pdc_true;
 | |
|     image->passthrough  = pdc_undef;
 | |
|     image->K            = 0;
 | |
|     image->imagemask    = pdc_false;
 | |
|     image->mask         = pdc_undef;
 | |
|     image->ri           = AutoIntent;
 | |
|     image->page         = 1;
 | |
|     image->reference    = pdf_ref_direct;
 | |
|     image->width_pixel  = pdc_undef;
 | |
|     image->topdown_save = pdc_false;
 | |
|     image->iconname     = (char *) NULL;
 | |
|     /*****************************************/
 | |
| 
 | |
|     image->orientation  = 1;
 | |
|     image->transparent  = pdc_false;
 | |
|     image->compression  = pdf_comp_none;
 | |
|     image->predictor	= pred_default;
 | |
|     image->in_use       = pdc_false;
 | |
|     image->corrupt      = pdc_false;
 | |
|     image->fp           = (pdc_file *) NULL;
 | |
|     image->filename	= (char *) NULL;
 | |
|     image->params	= (char *) NULL;
 | |
|     image->dpi_x	= 0;
 | |
|     image->dpi_y	= 0;
 | |
|     image->strips	= 1;
 | |
|     image->rowsperstrip	= 1;
 | |
|     image->colorspace   = pdc_undef;
 | |
|     image->dochandle    = pdc_undef;        /* this means "not a PDI page" */
 | |
|     image->use_raw	= pdc_false;
 | |
|     image->pixelmode	= pdc_undef;
 | |
|     image->type		= pdf_img_auto;
 | |
|     image->transval[0]	= 0;
 | |
|     image->transval[1]	= 0;
 | |
|     image->transval[2]	= 0;
 | |
|     image->transval[3]	= 0;
 | |
| 
 | |
| 
 | |
|     /********* image-type specific stuff *****/
 | |
|     /* This is ugly, but we must do it here since both the TIFF and JPEG
 | |
|      * modules are affected.
 | |
|      */
 | |
|     image->info.jpeg.jpegifoffset = 0L;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_init_images(PDF *p)
 | |
| {
 | |
|     int im;
 | |
| 
 | |
|     p->images_capacity = IMAGES_CHUNKSIZE;
 | |
| 
 | |
|     p->images = (pdf_image *)
 | |
|     	pdc_malloc(p->pdc,
 | |
| 	    sizeof(pdf_image) * p->images_capacity, "pdf_init_images");
 | |
| 
 | |
|     for (im = 0; im < p->images_capacity; im++)
 | |
| 	pdf_init_image_struct(p, &(p->images[im]));
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_grow_images(PDF *p)
 | |
| {
 | |
|     int im;
 | |
| 
 | |
|     p->images = (pdf_image *) pdc_realloc(p->pdc, p->images,
 | |
| 	sizeof(pdf_image) * 2 * p->images_capacity, "pdf_grow_images");
 | |
| 
 | |
|     for (im = p->images_capacity; im < 2 * p->images_capacity; im++)
 | |
| 	pdf_init_image_struct(p, &(p->images[im]));
 | |
|     for (im = 0; im < p->images_capacity; im++)
 | |
| 	p->images[im].src.private_data = &(p->images[im]);
 | |
| 
 | |
|     p->images_capacity *= 2;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_cleanup_image(PDF *p, int im)
 | |
| {
 | |
|     pdf_image *image = &p->images[im];
 | |
| 
 | |
|     /* clean up parameter string if necessary */
 | |
|     if (image->params)
 | |
|     {
 | |
|         pdc_free(p->pdc, image->params);
 | |
|         image->params = NULL;
 | |
|     }
 | |
| 
 | |
|     if (image->filename)
 | |
|     {
 | |
|         pdc_free(p->pdc, image->filename);
 | |
|         image->filename = NULL;
 | |
|     }
 | |
| 
 | |
|     if (image->fp)
 | |
|     {
 | |
|         pdc_fclose(image->fp);
 | |
|         image->fp = NULL;
 | |
|     }
 | |
| 
 | |
|     if (image->iconname)
 | |
|     {
 | |
|         pdc_free(p->pdc, image->iconname);
 | |
|         image->iconname = NULL;
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
|     /* type-specific cleanups */
 | |
|     if (image->type == pdf_img_gif)
 | |
| 	pdf_cleanup_gif(p, image);
 | |
| 
 | |
|     if (image->type == pdf_img_jpeg)
 | |
|         pdf_cleanup_jpeg(p, image);
 | |
| 
 | |
|     /* free the image slot and prepare for next use */
 | |
|     pdf_init_image_struct(p, image);
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_cleanup_images(PDF *p)
 | |
| {
 | |
|     int im;
 | |
| 
 | |
|     if (!p->images)
 | |
| 	return;
 | |
| 
 | |
|     /* Free images which the caller left open */
 | |
| 
 | |
|     /* When we think of inter-document survival of images,
 | |
|     ** we MUST NOT FORGET that the current TIFF algorithm
 | |
|     ** depends on contiguous image slots for the image strips!
 | |
|     */
 | |
|     for (im = 0; im < p->images_capacity; im++)
 | |
|     {
 | |
|         if (p->images[im].in_use)              /* found used slot */
 | |
| 	    pdf_cleanup_image(p, im);	/* free image descriptor */
 | |
|     }
 | |
| 
 | |
|     pdc_free(p->pdc, p->images);
 | |
|     p->images = NULL;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_init_xobjects(PDF *p)
 | |
| {
 | |
|     int idx;
 | |
| 
 | |
|     p->xobjects_number = 0;
 | |
| 
 | |
|     if (p->xobjects == (pdf_xobject *) 0)
 | |
|     {
 | |
| 	p->xobjects_capacity = XOBJECTS_CHUNKSIZE;
 | |
| 
 | |
| 	p->xobjects = (pdf_xobject *)
 | |
| 	    pdc_malloc(p->pdc, sizeof(pdf_xobject) * p->xobjects_capacity,
 | |
| 	    "pdf_init_xobjects");
 | |
|     }
 | |
| 
 | |
|     for (idx = 0; idx < p->xobjects_capacity; idx++)
 | |
| 	p->xobjects[idx].flags = 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| pdf_new_xobject(PDF *p, pdf_xobj_type type, pdc_id obj_id)
 | |
| {
 | |
|     static const char fn[] = "pdf_new_xobject";
 | |
|     int i, slot = p->xobjects_number++;
 | |
| 
 | |
|     if (slot == p->xobjects_capacity)
 | |
|     {
 | |
| 	p->xobjects = (pdf_xobject *) pdc_realloc(p->pdc, p->xobjects,
 | |
| 	    sizeof(pdf_xobject) * 2 * p->xobjects_capacity, fn);
 | |
| 
 | |
| 	for (i = p->xobjects_capacity; i < 2 * p->xobjects_capacity; i++)
 | |
| 	    p->xobjects[i].flags = 0;
 | |
| 
 | |
| 	p->xobjects_capacity *= 2;
 | |
|     }
 | |
| 
 | |
|     if (obj_id == PDC_NEW_ID)
 | |
| 	obj_id = pdc_begin_obj(p->out, PDC_NEW_ID);
 | |
| 
 | |
|     p->xobjects[slot].obj_id = obj_id;
 | |
|     p->xobjects[slot].type = type;
 | |
|     p->xobjects[slot].flags = xobj_flag_used;
 | |
| 
 | |
|     return slot;
 | |
| }
 | |
| 
 | |
| pdc_id
 | |
| pdf_get_xobject(PDF *p, int im)
 | |
| {
 | |
|     if (im >= 0 && im < p->images_capacity)
 | |
|     {
 | |
|         pdf_image *img = &p->images[im];
 | |
| 
 | |
|         if (img->in_use)
 | |
|             return p->xobjects[img->no].obj_id;
 | |
|     }
 | |
|     return PDC_BAD_ID;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_write_xobjects(PDF *p)
 | |
| {
 | |
|     if (p->xobjects_number > 0)
 | |
|     {
 | |
| 	pdc_bool hit = pdc_false;
 | |
| 	int i;
 | |
| 
 | |
| 	for (i = 0; i < p->xobjects_number; ++i)
 | |
| 	{
 | |
| 	    if (p->xobjects[i].flags & xobj_flag_write)
 | |
| 	    {
 | |
| 		if (!hit)
 | |
| 		{
 | |
| 		    pdc_puts(p->out, "/XObject");
 | |
| 		    pdc_begin_dict(p->out);
 | |
| 		    hit = pdc_true;
 | |
| 		}
 | |
| 
 | |
| 		pdc_printf(p->out, "/I%d", i);
 | |
| 		pdc_objref(p->out, "", p->xobjects[i].obj_id);
 | |
| 		p->xobjects[i].flags &= ~xobj_flag_write;
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	if (hit)
 | |
| 	    pdc_end_dict(p->out);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_get_page_xobjects(PDF *p, pdf_reslist *rl)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < p->xobjects_number; i++) {
 | |
| 	if (p->xobjects[i].flags & xobj_flag_write) {
 | |
| 	    p->xobjects[i].flags &= ~xobj_flag_write;
 | |
| 	    pdf_add_reslist(p, rl, i);
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_mark_page_xobject(PDF *p, int n)
 | |
| {
 | |
|     p->xobjects[n].flags |= xobj_flag_write;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_cleanup_xobjects(PDF *p)
 | |
| {
 | |
|     if (p->xobjects) {
 | |
| 	pdc_free(p->pdc, p->xobjects);
 | |
| 	p->xobjects = NULL;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ---------------------------- put image ----------------------------------- */
 | |
| 
 | |
| void
 | |
| pdf_put_inline_image(PDF *p, int im)
 | |
| {
 | |
|     static const char *fn = "pdf_put_inline_image";
 | |
|     pdf_image	*image;
 | |
|     pdc_matrix m;
 | |
|     PDF_data_source *src;
 | |
|     int		i;
 | |
| 
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     /* Image object */
 | |
| 
 | |
|     image->no = -1;
 | |
| 
 | |
|     pdf__save(p);
 | |
| 
 | |
|     pdc_scale_matrix(image->width, image->height, &m);
 | |
| 
 | |
|     pdf_concat_raw(p, &m);
 | |
| 
 | |
|     pdc_puts(p->out, "BI");
 | |
| 
 | |
|     pdc_printf(p->out, "/W %d", (int) image->width);
 | |
|     pdc_printf(p->out, "/H %d", (int) image->height);
 | |
| 
 | |
|     /* Acrobat 7 and 8 require /BPC even for image masks */
 | |
|     pdc_printf(p->out, "/BPC %d", image->bpc);
 | |
| 
 | |
|     if (image->imagemask == pdc_true) {
 | |
| 	pdc_puts(p->out, "/IM true");
 | |
| 
 | |
|     } else if (image->colorspace != pdc_undef) {
 | |
| 
 | |
| 	switch (p->colorspaces[image->colorspace].type) {
 | |
| 	    case DeviceGray:
 | |
| 		pdc_printf(p->out, "/CS/G");
 | |
| 		break;
 | |
| 
 | |
| 	    case DeviceRGB:
 | |
| 		pdc_printf(p->out, "/CS/RGB");
 | |
| 		break;
 | |
| 
 | |
| 	    case DeviceCMYK:
 | |
| 		pdc_printf(p->out, "/CS/CMYK");
 | |
| 		break;
 | |
| 
 | |
| 	    default:
 | |
| 		pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
 | |
| 		    pdc_errprintf(p->pdc, "%d", image->colorspace),
 | |
| 		    pdc_errprintf(p->pdc, "%d",
 | |
| 		    	(int) p->colorspaces[image->colorspace].type),
 | |
| 		    0);
 | |
| 		break;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     if (image->compression != pdf_comp_none) {
 | |
| 	pdc_printf(p->out, "/F/%s",
 | |
|             pdc_get_keyword(image->compression, pdf_shortfilter_pdfkeylist));
 | |
|     }
 | |
| 
 | |
|     /* prepare precompressed (raw) image data */
 | |
|     if (image->use_raw &&
 | |
|         (image->params ||
 | |
| 	 image->predictor != pred_default ||
 | |
|          image->compression == pdf_comp_ccitt)) {
 | |
| 
 | |
| 	pdc_printf(p->out, "/DP[<<");
 | |
| 
 | |
|         /* write EarlyChange */
 | |
|         if (image->params)
 | |
|             pdc_puts(p->out, image->params);
 | |
| 
 | |
|         if (image->compression == pdf_comp_ccitt) {
 | |
|             if (image->K != 0)
 | |
|                 pdc_printf(p->out, "/K %d", image->K);
 | |
|         }
 | |
| 
 | |
|         if (image->compression == pdf_comp_flate ||
 | |
|             image->compression == pdf_comp_lzw) {
 | |
| 	    if (image->predictor != pred_default) {
 | |
| 		pdc_printf(p->out, "/Predictor %d", (int) image->predictor);
 | |
| 		pdc_printf(p->out, "/Columns %d", (int) image->width);
 | |
| 		if (image->bpc != 8)
 | |
| 		    pdc_printf(p->out, "/BitsPerComponent %d", image->bpc);
 | |
| 
 | |
| 		if (image->components != 1)	/* 1 is default */
 | |
| 		    pdc_printf(p->out, "/Colors %d", image->components);
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
|         if (image->compression == pdf_comp_ccitt) {
 | |
| 	    if ((int) image->width != 1728)	/* CCITT default width */
 | |
| 		pdc_printf(p->out, "/Columns %d", (int) image->width);
 | |
| 
 | |
| 	    /* /Rows is optional, but it helps in certain cases with damaged
 | |
| 	     * CCITT compressed image data
 | |
| 	     */
 | |
| 	    pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
 | |
| 	}
 | |
| 	pdc_puts(p->out, ">>]");		/* DecodeParms dict and array */
 | |
|     }
 | |
| 
 | |
|     if (image->ri != AutoIntent) {
 | |
|         pdc_printf(p->out, "/Intent/%s",
 | |
|             pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist));
 | |
|     }
 | |
| 
 | |
|     if (image->interpolate) {
 | |
|         pdc_puts(p->out, "/I true");
 | |
|     }
 | |
| 
 | |
|     if (image->invert) {
 | |
| 	pdc_puts(p->out, "/D[1 0");
 | |
| 	for (i = 1; i < image->components; i++)
 | |
| 	    pdc_puts(p->out, " 1 0");
 | |
| 	pdc_puts(p->out, "]ID\n");
 | |
| 
 | |
|     } else {
 | |
| 	pdc_puts(p->out, " ID\n");
 | |
|     }
 | |
| 
 | |
|     /* Write the actual image data to the content stream */
 | |
| 
 | |
|     src = &image->src;
 | |
| 
 | |
|     /* We can't use pdf_copy_stream() here because it automatically
 | |
|      * generates a stream object, which is not correct for inline
 | |
|      * image data.
 | |
|      */
 | |
|     if (src->init)
 | |
| 	src->init(p, src);
 | |
| 
 | |
|     while (src->fill(p, src))
 | |
| 	pdc_write(p->out, src->next_byte, src->bytes_available);
 | |
| 
 | |
|     if (src->terminate)
 | |
| 	src->terminate(p, src);
 | |
| 
 | |
|     /* Acrobat requires whitespace between image data and "EI" */
 | |
|     pdc_puts(p->out, "\nEI\n");
 | |
| 
 | |
|     pdf__restore(p);
 | |
| 
 | |
|     /* Do the equivalent of PDF_close_image() since the image handle
 | |
|      * cannot be re-used anyway.
 | |
|      */
 | |
|     pdf_cleanup_image(p, im);
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_put_image(PDF *p, int im, pdc_bool firststrip, pdc_bool checkcontentstream)
 | |
| {
 | |
|     static const char *fn = "pdf_put_image";
 | |
|     pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image);
 | |
|     pdc_id	length_id;
 | |
|     pdf_image	*image;
 | |
|     int		i;
 | |
|     pdf_compression	compression;
 | |
| 
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc, "\t\t\tput image %d to PDF file ...\n", im);
 | |
| 
 | |
|     /* Images may also be written to the output before the first page */
 | |
|     if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page)
 | |
| 	pdf_end_contents_section(p);
 | |
| 
 | |
| 
 | |
| 
 | |
|     pdc_logg_cond(p->pdc, 2, trc_image,
 | |
|                        "\tpdf_put_image:\n"
 | |
|                        "\t\t\tim = %d\n"
 | |
|                        "\t\t\timage->colorspace = %d\n",
 | |
| 		       im,
 | |
| 		       image->colorspace);
 | |
| 
 | |
|     if (image->colorspace != pdc_undef)
 | |
|         pdc_logg_cond(p->pdc, 2, trc_image,
 | |
|                       "\t\t\tcolor space type = %d\n",
 | |
| 		      (int) p->colorspaces[image->colorspace].type);
 | |
| 
 | |
|     /* Image object */
 | |
| 
 | |
|     image->no = pdf_new_xobject(p, image_xobject, PDC_NEW_ID);
 | |
| 
 | |
|     pdc_begin_dict(p->out); 		/* XObject */
 | |
| 
 | |
|     pdc_puts(p->out, "/Subtype/Image\n");
 | |
| 
 | |
|     pdc_printf(p->out, "/Width %d\n", (int) image->width);
 | |
|     pdc_printf(p->out, "/Height %d\n", (int) fabs(image->height));
 | |
| 
 | |
|     /*
 | |
|      * Transparency handling
 | |
|      */
 | |
| 
 | |
|     /* Masking by color: single transparent color value */
 | |
|     if (image->transparent && image->colorspace != pdc_undef) {
 | |
| 	pdf_colorspace *cs = &p->colorspaces[image->colorspace];
 | |
| 
 | |
| 	switch (cs->type) {
 | |
| 	    case Indexed:
 | |
| 	    case DeviceGray:
 | |
| 	    pdc_printf(p->out,"/Mask[%d %d]\n",
 | |
| 		(int) image->transval[0], (int) image->transval[0]);
 | |
| 	    break;
 | |
| 
 | |
| 
 | |
| 	    case DeviceRGB:
 | |
| 	    pdc_printf(p->out,"/Mask[%d %d %d %d %d %d]\n",
 | |
| 		(int) image->transval[0], (int) image->transval[0],
 | |
| 		(int) image->transval[1], (int) image->transval[1],
 | |
| 		(int) image->transval[2], (int) image->transval[2]);
 | |
| 	    break;
 | |
| 
 | |
| 	    case DeviceCMYK:
 | |
| 	    pdc_printf(p->out,"/Mask[%d %d %d %d %d %d %d %d]\n",
 | |
| 		(int) image->transval[0], (int) image->transval[0],
 | |
| 		(int) image->transval[1], (int) image->transval[1],
 | |
| 		(int) image->transval[2], (int) image->transval[2],
 | |
| 		(int) image->transval[3], (int) image->transval[3]);
 | |
| 	    break;
 | |
| 
 | |
| 	    default:
 | |
| 	    pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
 | |
| 		pdc_errprintf(p->pdc, "%d", image->colorspace),
 | |
| 		pdc_errprintf(p->pdc, "%d",
 | |
| 		    (int) p->colorspaces[image->colorspace].type),
 | |
| 		0);
 | |
| 	}
 | |
| 
 | |
|     /* Masking by position: separate bitmap mask */
 | |
|     } else if (image->mask != pdc_undef && p->images[image->mask].bpc > 1) {
 | |
|         pdc_objref(p->out, "/SMask",
 | |
|             p->xobjects[p->images[image->mask].no].obj_id);
 | |
| 
 | |
|     } else if (image->mask != pdc_undef) {
 | |
|         pdc_objref(p->out, "/Mask",
 | |
|             p->xobjects[p->images[image->mask].no].obj_id);
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * /BitsPerComponent is optional for image masks according to the
 | |
|      * PDF reference, but some viewers require it nevertheless.
 | |
|      * We must therefore always write it.
 | |
|      */
 | |
|     if (image->type != pdf_img_jpeg2000)
 | |
|         pdc_printf(p->out, "/BitsPerComponent %d\n", image->bpc);
 | |
| 
 | |
|     if (image->imagemask) {
 | |
| 	pdc_puts(p->out, "/ImageMask true\n");
 | |
|         if (image->type == pdf_img_jpeg2000)
 | |
|             pdc_puts(p->out, "/SMaskInData 1\n");
 | |
| 
 | |
|     } else if (image->colorspace != pdc_undef) {
 | |
| 
 | |
| 	switch (p->colorspaces[image->colorspace].type) {
 | |
| 	    case DeviceGray:
 | |
| 		break;
 | |
| 
 | |
| 	    case DeviceRGB:
 | |
| 		break;
 | |
| 
 | |
| 	    case DeviceCMYK:
 | |
| 		break;
 | |
| 
 | |
| 	    case Indexed:
 | |
| 		break;
 | |
| 
 | |
| 
 | |
| 
 | |
| 	    default:
 | |
| 		pdc_error(p->pdc, PDF_E_INT_BADCS, fn,
 | |
| 		    pdc_errprintf(p->pdc, "%d", image->colorspace),
 | |
| 		    pdc_errprintf(p->pdc, "%d",
 | |
| 		    	(int) p->colorspaces[image->colorspace].type),
 | |
| 		    0);
 | |
|         }
 | |
| 
 | |
|         pdc_puts(p->out, "/ColorSpace");
 | |
|         pdf_write_colorspace(p, image->colorspace, pdc_false);
 | |
|         pdc_puts(p->out, "\n");
 | |
|     }
 | |
| 
 | |
|     if (image->invert) {
 | |
|         pdc_puts(p->out, "/Decode[1 0");
 | |
|         for (i = 1; i < image->components; i++)
 | |
|             pdc_puts(p->out, " 1 0");
 | |
| 	pdc_end_array(p->out);
 | |
|     }
 | |
| 
 | |
|     if (image->ri != AutoIntent) {
 | |
|         pdc_printf(p->out, "/Intent/%s\n",
 | |
|             pdc_get_keyword(image->ri, pdf_renderingintent_pdfkeylist));
 | |
|     }
 | |
| 
 | |
|     if (image->interpolate) {
 | |
|         pdc_puts(p->out, "/Interpolate true\n");
 | |
|     }
 | |
| 
 | |
|     /* special case: referenced image data instead of direct data */
 | |
|     if (image->reference != pdf_ref_direct) {
 | |
| 
 | |
|         if (image->compression != pdf_comp_none) {
 | |
| 	    pdc_printf(p->out, "/FFilter[/%s]\n",
 | |
|                 pdc_get_keyword(image->compression, pdf_filter_pdfkeylist));
 | |
| 	}
 | |
| 
 | |
|         if (image->compression == pdf_comp_ccitt) {
 | |
| 	    pdc_puts(p->out, "/FDecodeParms[<<");
 | |
| 
 | |
| 	    if ((int) image->width != 1728)	/* CCITT default width */
 | |
| 		pdc_printf(p->out, "/Columns %d", (int) image->width);
 | |
| 
 | |
| 	    /* /Rows is optional, but it helps in certain cases with damaged
 | |
| 	     * CCITT compressed image data
 | |
| 	     */
 | |
| 	    pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
 | |
| 
 | |
|             if (image->K != 0)
 | |
|                 pdc_printf(p->out, "/K %d", image->K);
 | |
| 
 | |
| 	    pdc_puts(p->out, ">>]\n");
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	if (image->reference == pdf_ref_file) {
 | |
| 
 | |
| 	    /* LATER: make image file name platform-neutral:
 | |
| 	     * Change : to / on the Mac
 | |
| 	     * Change \ to / on Windows
 | |
| 	     */
 | |
| 	    pdc_puts(p->out, "/F");
 | |
| 	    pdc_put_pdfstring(p->out, image->filename, 0);
 | |
|             pdc_puts(p->out, "/Length 0");
 | |
| 
 | |
| 	} else if (image->reference == pdf_ref_url) {
 | |
| 
 | |
| 	    pdc_puts(p->out, "/F<</FS/URL/F");
 | |
| 	    pdc_put_pdfstring(p->out, image->filename, 0);
 | |
| 	    pdc_puts(p->out, ">>/Length 0");
 | |
| 	}
 | |
| 
 | |
| 	pdc_end_dict(p->out);		/* XObject */
 | |
| 
 | |
| 	/* We must avoid pdc_begin/end_pdfstream() here in order to
 | |
| 	 * generate a really empty stream.
 | |
| 	 * Note: this doesn't work with AES encryption, but we don't
 | |
| 	 * bother to fix it since file references are no longer
 | |
| 	 * supported anyway.
 | |
| 	 */
 | |
| 	pdc_puts(p->out, "stream\n");	/* dummy image stream */
 | |
| 	pdc_puts(p->out, "endstream\n");
 | |
| 
 | |
|         pdc_end_obj(p->out);                    /* XObject */
 | |
| 
 | |
| 	if (PDF_GET_STATE(p) == pdf_state_page)
 | |
| 	    pdf_begin_contents_section(p);
 | |
| 
 | |
| 	return;
 | |
|     }
 | |
| 
 | |
|     compression = image->compression;
 | |
| 
 | |
|     /*
 | |
|      * Now the (more common) handling of actual image
 | |
|      * data to be included in the PDF output.
 | |
|      */
 | |
| 
 | |
|     /* force compression if not a recognized precompressed image format */
 | |
|     if ((!image->use_raw || compression == pdf_comp_none) &&
 | |
| 	pdc_get_compresslevel(p->out))
 | |
|         compression = pdf_comp_flate;
 | |
| 
 | |
|     if (compression != pdf_comp_none)
 | |
| 	pdc_printf(p->out, "/Filter/%s\n",
 | |
|                    pdc_get_keyword(compression, pdf_filter_pdfkeylist));
 | |
| 
 | |
|     /* prepare precompressed (raw) image data; avoid empty DecodeParms */
 | |
|     if (image->use_raw &&
 | |
|         (image->params ||
 | |
| 	 image->predictor != pred_default ||
 | |
|          compression == pdf_comp_ccitt)) {
 | |
| 
 | |
| 	pdc_printf(p->out, "/DecodeParms<<");
 | |
| 
 | |
|         /* write EarlyChange */
 | |
|         if (image->params)
 | |
|             pdc_puts(p->out, image->params);
 | |
| 
 | |
|         if (compression == pdf_comp_ccitt) {
 | |
|             if (image->K != 0)
 | |
|                 pdc_printf(p->out, "/K %d", image->K);
 | |
|         }
 | |
| 
 | |
|         if (compression == pdf_comp_flate || compression == pdf_comp_lzw) {
 | |
| 	    if (image->predictor != pred_default) {
 | |
| 		pdc_printf(p->out, "/Predictor %d", (int) image->predictor);
 | |
| 		pdc_printf(p->out, "/Columns %d", (int) image->width);
 | |
| 		if (image->bpc != 8)
 | |
| 		    pdc_printf(p->out, "/BitsPerComponent %d", image->bpc);
 | |
| 
 | |
| 		if (image->components != 1)	/* 1 is default */
 | |
| 		    pdc_printf(p->out, "/Colors %d", image->components);
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
|         if (compression == pdf_comp_ccitt) {
 | |
| 	    if ((int) image->width != 1728)	/* CCITT default width */
 | |
| 		pdc_printf(p->out, "/Columns %d", (int) image->width);
 | |
| 
 | |
| 	    /* /Rows is optional, but it helps in certain cases with damaged
 | |
| 	     * CCITT compressed image data
 | |
| 	     */
 | |
| 	    pdc_printf(p->out, "/Rows %d", (int) fabs(image->height));
 | |
| 	}
 | |
| 
 | |
| 	pdc_puts(p->out, ">>\n");		/* DecodeParms dict */
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|     /* Write the actual image data */
 | |
|     length_id = pdc_alloc_id(p->out);
 | |
| 
 | |
|     pdc_objref(p->out, "/Length", length_id);
 | |
|     pdc_end_dict(p->out);		/* XObject */
 | |
| 
 | |
|     /* image data */
 | |
| 
 | |
|     /*
 | |
|      * We must check "image->compression" here since this describes the
 | |
|      * actual status of the input data, as opposed to "compression"
 | |
|      * which describes the desired status of the output data.
 | |
|      */
 | |
| 
 | |
|     pdf_copy_stream(p, &image->src,
 | |
|             !image->use_raw || image->compression == pdf_comp_none);
 | |
| 
 | |
|     pdc_end_obj(p->out);	/* XObject */
 | |
| 
 | |
|     pdc_put_pdfstreamlength(p->out, length_id);
 | |
| 
 | |
|     if (p->flush & pdc_flush_content)
 | |
| 	pdc_flush_stream(p->out);
 | |
| 
 | |
|     /*
 | |
|      * Write colormap information for indexed color spaces
 | |
|      */
 | |
|     if (firststrip && image->colorspace != pdc_undef &&
 | |
|         p->colorspaces[image->colorspace].type == Indexed) {
 | |
| 	pdf_write_colormap(p, image->colorspace);
 | |
|     }
 | |
| 
 | |
|     if (checkcontentstream && PDF_GET_STATE(p) == pdf_state_page)
 | |
| 	pdf_begin_contents_section(p);
 | |
| 
 | |
|     if (p->flush & pdc_flush_content)
 | |
| 	pdc_flush_stream(p->out);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ---------------------------- fit image ----------------------------------- */
 | |
| 
 | |
| void
 | |
| pdf__fit_image(PDF *p, int im, pdc_scalar x, pdc_scalar y, const char *optlist)
 | |
| {
 | |
|     pdf_image *image;
 | |
|     int legal_states;
 | |
| 
 | |
|     pdf_check_handle(p, im, pdc_imagehandle);
 | |
| 
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (PDF_GET_STATE(p) == pdf_state_glyph && !pdf_get_t3colorized(p) &&
 | |
|         image->imagemask == pdc_false)
 | |
|         legal_states = pdf_state_page | pdf_state_pattern | pdf_state_template;
 | |
|     else if (PDF_GET_STATE(p) == pdf_state_pattern &&
 | |
|         pdf_get_shading_painttype(p) == 2 && image->imagemask == pdc_false)
 | |
|         legal_states = pdf_state_page | pdf_state_glyph | pdf_state_template;
 | |
|     else
 | |
|         legal_states = pdf_state_content;
 | |
|     PDF_CHECK_STATE(p, legal_states);
 | |
| 
 | |
|     if (PDF_GET_STATE(p) == pdf_state_template && im == p->templ)
 | |
|         pdc_error(p->pdc, PDF_E_TEMPLATE_SELF,
 | |
|             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
 | |
| 
 | |
|     pdc_check_number(p->pdc, "x", x);
 | |
|     pdc_check_number(p->pdc, "y", y);
 | |
| 
 | |
|     pdf_place_xobject(p, im, x, y, optlist);
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_init_xobject_options(PDF *p, pdf_xobject_options *xo)
 | |
| {
 | |
|     xo->adjustpage = pdc_false;
 | |
|     xo->blind = pdc_false;
 | |
|     xo->filename = NULL;
 | |
|     xo->flags = 0;
 | |
|     xo->imagewarning = p->debug[(int) 'i'];
 | |
|     xo->ignoreorientation = pdc_false;
 | |
|     xo->im = -1;
 | |
|     xo->mask = 0;
 | |
|     xo->dpi[0] = 0;
 | |
|     xo->dpi[1] = 0;
 | |
|     xo->page = 1;
 | |
|     xo->scale[0] = 1;
 | |
|     xo->scale[1] = 1;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_get_xobject_options(PDF *p, pdf_xobject_options *xo, pdc_resopt *resopts)
 | |
| {
 | |
|     int inum;
 | |
| 
 | |
|     (void) p;
 | |
| 
 | |
|     if (!(xo->flags & is_block))
 | |
|     {
 | |
|         pdc_get_optvalues("adjustpage", resopts, &xo->adjustpage, NULL);
 | |
| 
 | |
|         pdc_get_optvalues("blind", resopts, &xo->blind, NULL);
 | |
|     }
 | |
| 
 | |
|     if (xo->flags & is_image)
 | |
|     {
 | |
|         if (pdc_get_optvalues("ignoreorientation", resopts,
 | |
|                                                 &xo->ignoreorientation, NULL))
 | |
|             xo->mask |= (1L << xo_ignoreorientation);
 | |
| 
 | |
| 
 | |
|         inum = pdc_get_optvalues("dpi", resopts, xo->dpi, NULL);
 | |
|         if (inum)
 | |
|         {
 | |
|             if (inum == 1)
 | |
|                 xo->dpi[1] = xo->dpi[0];
 | |
|             xo->mask |= (1L << xo_dpi);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (xo->flags & is_block)
 | |
|     {
 | |
|         if (pdc_get_optvalues("imagewarning", resopts, &xo->imagewarning, NULL))
 | |
|             xo->mask |= (1L << xo_imagewarning);
 | |
|     }
 | |
| 
 | |
|     inum = pdc_get_optvalues("scale", resopts, xo->scale, NULL);
 | |
|     if (inum)
 | |
|     {
 | |
|         if (inum == 1)
 | |
|             xo->scale[1] = xo->scale[0];
 | |
|         xo->mask |= (1L << xo_scale);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* definitions of fit xobject options */
 | |
| static const pdc_defopt pdf_fit_xobject_options[] =
 | |
| {
 | |
|     PDF_XOBJECT_OPTIONS1
 | |
|     PDF_XOBJECT_OPTIONS2
 | |
|     PDF_XOBJECT_OPTIONS3
 | |
|     PDF_FIT_OPTIONS1
 | |
|     PDF_FIT_OPTIONS2
 | |
|     PDC_OPT_TERMINATE
 | |
| };
 | |
| 
 | |
| pdc_resopt *
 | |
| pdf_parse_fitxobject_optlist(PDF *p, int im, pdf_xobject_options *xo,
 | |
|                              pdf_fit_options *fit, const char *optlist)
 | |
| {
 | |
|     pdc_resopt *resopts = NULL;
 | |
|     pdf_image *image = &p->images[im];
 | |
| 
 | |
|     /* initialize */
 | |
|     pdf_init_xobject_options(p, xo);
 | |
|     xo->im = im;
 | |
|     if (p->xobjects[image->no].type == image_xobject)
 | |
|     {
 | |
|         xo->flags |= is_image;
 | |
|         xo->dpi[0] = dpi_internal;
 | |
|         xo->dpi[1] = dpi_internal;
 | |
|         xo->ignoreorientation = image->ignoreorient;
 | |
|     }
 | |
|     pdf_init_fit_options(p, pdc_false, fit);
 | |
|     fit->flags |= is_image;
 | |
| 
 | |
|     /* parsing option list */
 | |
|     if (optlist && strlen(optlist))
 | |
|     {
 | |
|         pdc_clientdata data;
 | |
| 
 | |
|         pdf_set_clientdata(p, &data);
 | |
|         resopts = pdc_parse_optionlist(p->pdc, optlist,
 | |
|                       pdf_fit_xobject_options, &data, pdc_true);
 | |
| 
 | |
|         pdf_get_xobject_options(p, xo, resopts);
 | |
|         pdf_get_fit_options(p, pdc_false, fit, resopts);
 | |
|     }
 | |
| 
 | |
|     return resopts;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_place_xobject(PDF *p, int im, pdc_scalar x, pdc_scalar y,
 | |
|                   const char *optlist)
 | |
| {
 | |
|     pdf_xobject_options xo;
 | |
|     pdf_fit_options fit;
 | |
| 
 | |
|     /* initialize */
 | |
|     pdf_parse_fitxobject_optlist(p, im, &xo, &fit, optlist);
 | |
|     fit.refpoint[0] = x;
 | |
|     fit.refpoint[1] = y;
 | |
| 
 | |
|     /* put out xobject */
 | |
|     if (!xo.blind)
 | |
|     {
 | |
|         pdf_end_text(p);
 | |
|         pdf_begin_contents_section(p);
 | |
| 
 | |
| 
 | |
| 
 | |
|         pdf__save(p);
 | |
|     }
 | |
| 
 | |
|     pdf_fit_xobject_internal(p, &xo, &fit, NULL);
 | |
| 
 | |
|     if (!xo.blind)
 | |
|         pdf__restore(p);
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_fit_xobject_internal(PDF *p, pdf_xobject_options *xo, pdf_fit_options *fit,
 | |
|                          pdc_matrix *immatrix)
 | |
| {
 | |
|     pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_image);
 | |
|     pdf_image *image = &p->images[xo->im];
 | |
|     pdf_xobject_options xo_save;
 | |
|     pdc_rectangle matchrect;
 | |
|     pdf_fit_options fit_save;
 | |
|     pdc_matrix m, mm, sm, ctm_clip, ctm_save;
 | |
|     pdc_vector tmpscale, elemscale, fitscale, purescale;
 | |
|     pdc_vector elemsize, mirror, shift, relpos;
 | |
|     pdc_vector polyline[5];
 | |
|     pdc_box fitbox, clipbox, elembox, redbox;
 | |
|     pdc_scalar x, y, ss;
 | |
|     pdc_scalar rowsize = 1, lastratio = 1;
 | |
|     pdc_scalar dpi_x, dpi_y, tx = 0, ty = 0, boxwidth, boxheight;
 | |
|     pdc_bool kclip = pdc_false, kcliptiff = pdc_false;
 | |
|     int indangle, indmirror;
 | |
|     int is, ip, islast;
 | |
|     int imageno;
 | |
| 
 | |
|     /* initialize */
 | |
|     tmpscale.x = 1;
 | |
|     tmpscale.y = 1;
 | |
|     if (image->mask != pdc_undef)
 | |
|     {
 | |
|         ctm_save = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 | |
|         xo_save = *xo;
 | |
|         fit_save = *fit;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         pdc_identity_matrix(&ctm_save);
 | |
|     }
 | |
| 
 | |
|     /* box size */
 | |
|     boxwidth = fit->boxsize[0];
 | |
|     boxheight = fit->boxsize[1];
 | |
| 
 | |
|     /* element size */
 | |
|     elemsize.x = fabs(image->width);
 | |
|     elemsize.y = fabs(image->height);
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\tfitbox size:  width=%g, height=%g\n"
 | |
|                  "\t\t\telement size: width=%g, height=%g\n",
 | |
|                  boxwidth, boxheight, elemsize.x, elemsize.y);
 | |
| 
 | |
|     /* clipping */
 | |
|     if (!kclip)
 | |
|     {
 | |
|         kclip = pdf_get_mbox_clipping(p, fit->matchbox, elemsize.x, elemsize.y,
 | |
|                                       &clipbox);
 | |
|     }
 | |
| 
 | |
|     if (logg3 && kclip)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g\n",
 | |
|                  clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y);
 | |
| 
 | |
|     /* TIFF image orientation */
 | |
|     if (image->orientation != 1 && !xo->ignoreorientation)
 | |
|     {
 | |
|         /* Tag Orientation     =  1,   2,   3,   4,   5,   6,   7,   8  */
 | |
|         const int addangle[8]  = {0,   0, 180, 180,  90, 270, 270,  90};
 | |
|         const int rowmirror[8] = {1,  -1,   1,  -1,  -1,   1,  -1,   1};
 | |
| 
 | |
|         if (logg3)
 | |
|             pdc_logg(p->pdc, "\t\t\torientation tag: %d\n", image->orientation);
 | |
| 
 | |
|         is = image->orientation - 1;
 | |
| 
 | |
| 	fit->orientate += addangle[is];
 | |
| 	if (fit->orientate >= 360)
 | |
| 	    fit->orientate -= 360;
 | |
|         tmpscale.x = rowmirror[is];
 | |
| 
 | |
|         if (kclip)
 | |
|         {
 | |
|             switch (addangle[is])
 | |
|             {
 | |
|                 default:
 | |
|                 elembox = clipbox;
 | |
|                 break;
 | |
| 
 | |
|                 case 90:
 | |
|                 elembox.ll.x = clipbox.ll.y;
 | |
|                 elembox.ll.y = elemsize.x - clipbox.ur.x;
 | |
|                 elembox.ur.x = clipbox.ur.y;
 | |
|                 elembox.ur.y = elemsize.x - clipbox.ll.x;
 | |
|                 break;
 | |
| 
 | |
|                 case 180:
 | |
|                 elembox.ll.x = elemsize.x - clipbox.ur.x;
 | |
|                 elembox.ll.y = elemsize.y - clipbox.ur.y;
 | |
|                 elembox.ur.x = elemsize.x - clipbox.ll.x;
 | |
|                 elembox.ur.y = elemsize.y - clipbox.ll.y;
 | |
|                 break;
 | |
| 
 | |
|                 case 270:
 | |
|                 elembox.ll.x = elemsize.y - clipbox.ur.y;
 | |
|                 elembox.ll.y = clipbox.ll.x;
 | |
|                 elembox.ur.x = elemsize.y - clipbox.ll.y;
 | |
|                 elembox.ur.y = clipbox.ur.x;
 | |
|                 break;
 | |
|             }
 | |
|             clipbox = elembox;
 | |
| 
 | |
|             if (tmpscale.x == -1)
 | |
|             {
 | |
|                 clipbox.ll.x = elemsize.x - elembox.ur.x;
 | |
|                 clipbox.ur.x = elemsize.x - elembox.ll.x;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* Compensate inverted direction handling in TIFFReadRGBAImageOriented() */
 | |
|     if (!image->use_raw && image->pixelmode == pdc_true)
 | |
|     {
 | |
|         tmpscale.y = -1;
 | |
|         elembox = clipbox;
 | |
|         clipbox.ll.y = elemsize.y - elembox.ur.y;
 | |
|         clipbox.ur.y = elemsize.y - elembox.ll.y;
 | |
|     }
 | |
| 
 | |
|     if (logg3 && kclip)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\tclip box: llx=%g, lly=%g, urx=%g, ury=%g  "
 | |
|                  "(corrected)\n",
 | |
|                  clipbox.ll.x, clipbox.ll.y, clipbox.ur.x, clipbox.ur.y);
 | |
| 
 | |
|     /* image scale */
 | |
|     elemscale.x = tmpscale.x * xo->scale[0];
 | |
|     elemscale.y = tmpscale.y * xo->scale[1];
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\telement scaling: sx=%g, sy=%g  "
 | |
|                  "(user, correction mirroring)\n",
 | |
|                  elemscale.x, elemscale.y);
 | |
| 
 | |
|     /* element size */
 | |
|     elemsize.x = fabs(clipbox.ur.x - clipbox.ll.x);
 | |
|     elemsize.y = fabs(clipbox.ur.y - clipbox.ll.y);
 | |
| 
 | |
|     /* calculation of image scale and size */
 | |
|     if (xo->flags & is_image)
 | |
|     {
 | |
|         tmpscale.x = 1.0;
 | |
|         tmpscale.y = 1.0;
 | |
|         if (xo->dpi[0] == dpi_internal)
 | |
|         {
 | |
|             dpi_x = image->dpi_x;
 | |
|             dpi_y = image->dpi_y;
 | |
|             if (dpi_x > 0 && dpi_y > 0)
 | |
|             {
 | |
|                 tmpscale.x = 72.0 / dpi_x;
 | |
|                 tmpscale.y = 72.0 / dpi_y;
 | |
|             }
 | |
|             else if (dpi_x < 0 && dpi_y < 0)
 | |
|             {
 | |
|                 tmpscale.y = dpi_y / dpi_x;
 | |
|             }
 | |
|         }
 | |
|         else if (xo->dpi[0] > 0)
 | |
|         {
 | |
|             tmpscale.x = 72.0 / xo->dpi[0];
 | |
|             tmpscale.y = 72.0 / xo->dpi[1];
 | |
|         }
 | |
| 
 | |
|         elemscale.x *= tmpscale.x;
 | |
|         elemscale.y *= tmpscale.y;
 | |
|         rowsize = elemscale.y * image->rowsperstrip;
 | |
| 
 | |
|         if (logg3)
 | |
|             pdc_logg(p->pdc,
 | |
|                "\t\t\telement scaling: sx=%g, sy=%g  "
 | |
|                "(relating to 72dpi)\n",
 | |
|                tmpscale.x, tmpscale.y);
 | |
|     }
 | |
| 
 | |
|     /* pure scaling without mirroring */
 | |
|     purescale.x = fabs(elemscale.x);
 | |
|     purescale.y = fabs(elemscale.y);
 | |
| 
 | |
|     /* element size */
 | |
|     elemsize.x *= purescale.x;
 | |
|     elemsize.y *= purescale.y;
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\telement size: width=%g, height=%g  (scaled)\n",
 | |
|                  elemsize.x, elemsize.y);
 | |
| 
 | |
|     if (xo->flags & is_image)
 | |
|     {
 | |
|         elemscale.x *= image->width;
 | |
|         elemscale.y *= image->height;
 | |
|         lastratio = (elemscale.y / rowsize) - (image->strips - 1);
 | |
|     }
 | |
| 
 | |
|     /* mirroring */
 | |
|     indmirror = 0;
 | |
|     if (elemscale.x < 0 && elemscale.y < 0)
 | |
|         indmirror = 2;
 | |
|     else if (elemscale.x < 0)
 | |
|         indmirror = 1;
 | |
|     else if (elemscale.y < 0)
 | |
|         indmirror = 3;
 | |
| 
 | |
|     /* orientation */
 | |
|     indangle = fit->orientate / 90;
 | |
|     if (indangle % 2)
 | |
|     {
 | |
|         ss = elemsize.x;
 | |
|         elemsize.x = elemsize.y;
 | |
|         elemsize.y = ss;
 | |
|     }
 | |
| 
 | |
|     /* box for fitting */
 | |
|     fitbox.ll.x = 0;
 | |
|     fitbox.ll.y = 0;
 | |
|     fitbox.ur.x = boxwidth;
 | |
|     fitbox.ur.y = boxheight;
 | |
| 
 | |
|     /* relative position */
 | |
|     relpos.x = fit->position[0] / 100.0;
 | |
|     relpos.y = fit->position[1] / 100.0;
 | |
| 
 | |
|     /* calculate image box */
 | |
|     if (fit->fitmethod == pdc_tauto)
 | |
|         fit->fitmethod = pdc_meet;
 | |
|     pdc_place_element(fit->fitmethod, 1.0, &fitbox, &relpos,
 | |
|                       &elemsize, &relpos, &elembox, &fitscale);
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\telement scaling: sx=%g, sy=%g  "
 | |
|                  "(relating to fitbox)\n",
 | |
|                  fitscale.x, fitscale.y);
 | |
| 
 | |
|     /* reference point */
 | |
|     x = fit->refpoint[0];
 | |
|     y = fit->refpoint[1];
 | |
| 
 | |
| 
 | |
|     /* adjust page size */
 | |
|     if (!xo->blind && xo->adjustpage && PDF_GET_STATE(p) == pdf_state_page)
 | |
|     {
 | |
| 	pdc_scalar urx, ury, width, height, theight;
 | |
| 
 | |
|         urx = 2 * x + elembox.ur.x;
 | |
|         ury = 2 * y + elembox.ur.y;
 | |
| 	pdc_transform_point(&p->curr_ppt->gstate[p->curr_ppt->sl].ctm,
 | |
| 			    urx, ury, &width, &theight);
 | |
| 	height = (p->ydirection > 0) ? theight
 | |
| 			: pdf_get_pageheight(p) - p->ydirection * theight;
 | |
| 
 | |
| 	if (height < p->ydirection * theight / 2.0)
 | |
| 	    pdc_error(p->pdc, PDF_E_IMAGE_NOADJUST, 0, 0, 0, 0);
 | |
| 
 | |
|         width = fabs(width);
 | |
|         height = fabs(height);
 | |
| 
 | |
| 	if ((width < PDF_ACRO_MINPAGE || width > PDF_ACRO_MAXPAGE ||
 | |
| 	     height < PDF_ACRO_MINPAGE || height > PDF_ACRO_MAXPAGE))
 | |
| 		pdc_warning(p->pdc, PDF_E_PAGE_SIZE_ACRO, 0, 0, 0, 0);
 | |
| 
 | |
| 	pdf_set_pagebox(p, pdf_mediabox, 0, 0, width, height);
 | |
|         pdf_set_pagebox(p, pdf_artbox, 0, 0, 0, 0);
 | |
|         pdf_set_pagebox(p, pdf_bleedbox, 0, 0, 0, 0);
 | |
|         pdf_set_pagebox(p, pdf_cropbox, 0, 0, 0, 0);
 | |
|         pdf_set_pagebox(p, pdf_trimbox, 0, 0, 0, 0);
 | |
|     }
 | |
| 
 | |
|     /* reference point */
 | |
|     pdc_translation_matrix(x, y, &m);
 | |
| 
 | |
|     /* optional rotation */
 | |
|     if (fabs(fit->rotate) > PDC_FLOAT_PREC)
 | |
|     {
 | |
|         pdc_rotation_matrix(p->ydirection * fit->rotate, &mm);
 | |
|         pdc_multiply_matrix(&mm, &m);
 | |
|     }
 | |
| 
 | |
|     /* output after translation and rotation */
 | |
|     if (!xo->blind)
 | |
|     {
 | |
|         /* new CTM */
 | |
|         if (fit->showborder ||
 | |
|             fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 | |
|         {
 | |
|             pdf_concat_raw(p, &m);
 | |
|             pdc_identity_matrix(&m);
 | |
|         }
 | |
| 
 | |
|         /* show border */
 | |
|         if (fit->showborder)
 | |
|         {
 | |
|             pdf__rect(p, 0, 0, boxwidth, boxheight);
 | |
|             pdf__stroke(p);
 | |
|         }
 | |
| 
 | |
|         /* clipping */
 | |
|         if (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 | |
|         {
 | |
|             if (boxwidth < PDC_FLOAT_PREC)
 | |
|                 boxwidth = PDF_ACRO_MAXPAGE;
 | |
|             if (boxheight < PDC_FLOAT_PREC)
 | |
|                 boxheight = PDF_ACRO_MAXPAGE;
 | |
|             pdf__rect(p, 0, 0, boxwidth, boxheight);
 | |
|             pdf__clip(p);
 | |
| 
 | |
|             ctm_clip = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 | |
|             redbox.ll.x = 0;
 | |
|             redbox.ll.y = 0;
 | |
|             redbox.ur.x = boxwidth;
 | |
|             redbox.ur.y = p->ydirection * boxheight;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* translation of element box */
 | |
|     elembox.ll.y *= p->ydirection;
 | |
|     elembox.ur.y *= p->ydirection;
 | |
|     pdc_box2polyline(NULL, &elembox, polyline);
 | |
|     ip = indangle + indmirror;
 | |
|     if (ip >= 4) ip -= 4;
 | |
|     tx = polyline[ip].x;
 | |
|     ty = polyline[ip].y;
 | |
|     pdc_translation_matrix(tx, ty, &mm);
 | |
|     pdc_multiply_matrix(&mm, &m);
 | |
|     boxwidth = elembox.ur.x - elembox.ll.x;
 | |
|     boxheight = elembox.ur.y - elembox.ll.y;
 | |
| 
 | |
|     /* orientation of image */
 | |
|     if (fit->orientate != 0)
 | |
|     {
 | |
|         pdc_rotation_matrix(p->ydirection * fit->orientate, &mm);
 | |
|         pdc_multiply_matrix(&mm, &m);
 | |
|         if (indangle % 2)
 | |
|         {
 | |
|             ss = fitscale.x;
 | |
|             fitscale.x = fitscale.y;
 | |
|             fitscale.y = ss;
 | |
| 
 | |
|             ss = boxwidth;
 | |
|             boxwidth = p->ydirection * boxheight;
 | |
|             boxheight = p->ydirection * ss;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* mirroring of image */
 | |
|     mirror.x = elemscale.x * fitscale.x;
 | |
|     elemscale.x = fabs(mirror.x);
 | |
|     mirror.x /= elemscale.x;
 | |
|     if (image->strips == 1)
 | |
|         mirror.y = p->ydirection * elemscale.y * fitscale.y;
 | |
|     else
 | |
|         mirror.y = p->ydirection * rowsize * fitscale.y;
 | |
|     elemscale.y = fabs(mirror.y);
 | |
|     mirror.y /= elemscale.y;
 | |
|     pdc_scale_matrix(mirror.x, mirror.y, &mm);
 | |
|     pdc_multiply_matrix(&mm, &m);
 | |
| 
 | |
|     if (logg3)
 | |
|         pdc_logg(p->pdc,
 | |
|                  "\t\t\tcumulative mirroring: mx=%g, my=%g\n",
 | |
|                  mirror.x, mirror.y);
 | |
| 
 | |
|     /* matchbox or clip path */
 | |
|     if (!xo->blind && (fit->matchbox || kclip || kcliptiff))
 | |
|     {
 | |
|         pdf_concat_raw(p, &m);
 | |
|         pdc_identity_matrix(&m);
 | |
| 
 | |
|         if (fit->matchbox)
 | |
|         {
 | |
|             matchrect.llx = 0;
 | |
|             matchrect.lly = 0;
 | |
|             matchrect.urx = boxwidth;
 | |
|             matchrect.ury = p->ydirection * boxheight;
 | |
| 
 | |
|             if (fit->fitmethod == pdc_clip || fit->fitmethod == pdc_slice)
 | |
|             {
 | |
|                 pdc_rectangle cliprect;
 | |
|                 pdc_matrix ctm_inv;
 | |
| 
 | |
|                 pdc_invert_matrix(p->pdc, &ctm_inv,
 | |
|                               &p->curr_ppt->gstate[p->curr_ppt->sl].ctm);
 | |
|                 pdc_multiply_matrix(&ctm_clip, &ctm_inv);
 | |
|                 pdc_box2polyline(&ctm_inv, &redbox, polyline);
 | |
|                 pdc_polyline2rect(polyline, 4, &cliprect);
 | |
| 
 | |
|                 pdc_rect_intersect(&matchrect, &matchrect, &cliprect);
 | |
|             }
 | |
| 
 | |
|             pdf_set_mbox_rectangle(p, fit->matchbox, &matchrect, 0);
 | |
|             pdf_draw_mbox_rectangle(p, fit->matchbox, mbox_area | mbox_border);
 | |
| 
 | |
|             pdf_add_page_mbox(p, fit->matchbox);
 | |
|         }
 | |
| 
 | |
|         /* displacement of image because of clipping */
 | |
|         shift = clipbox.ll;
 | |
|         purescale.x *= fitscale.x;
 | |
|         purescale.y *= fitscale.y;
 | |
|         if (kclip)
 | |
|         {
 | |
|             shift.x *= -purescale.x;
 | |
|             shift.y *= -purescale.y;
 | |
|         }
 | |
| 
 | |
|         if (kclip)
 | |
|         {
 | |
|             /* user clipping path */
 | |
|             pdf__rect(p, 0, 0, boxwidth, boxheight);
 | |
|             pdf__clip(p);
 | |
|         }
 | |
| 
 | |
|         if (kclip)
 | |
|         {
 | |
|             pdc_translation_matrix(shift.x, shift.y, &mm);
 | |
|             pdc_multiply_matrix(&mm, &m);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* scaling of image */
 | |
|     pdc_scale_matrix(elemscale.x, elemscale.y, &mm);
 | |
|     pdc_multiply_matrix(&mm, &m);
 | |
| 
 | |
|     /* ctm */
 | |
|     if (xo->blind)
 | |
|     {
 | |
|         if (immatrix == NULL)
 | |
|             mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 | |
|         else
 | |
|             mm = *immatrix;
 | |
|         pdc_multiply_matrix(&m, &mm);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         pdf_concat_raw(p, &m);
 | |
|         mm = p->curr_ppt->gstate[p->curr_ppt->sl].ctm;
 | |
|     }
 | |
| 
 | |
|     pdc_logg_cond(p->pdc, 5, trc_image,
 | |
|                        "\t\t\tCTM components of image %s\"%s\":\n"
 | |
|                        "\t\t\ta = %f\n"
 | |
|                        "\t\t\tb = %f\n"
 | |
|                        "\t\t\tc = %f\n"
 | |
|                        "\t\t\td = %f\n"
 | |
|                        "\t\t\te = %f\n"
 | |
|                        "\t\t\tf = %f\n",
 | |
|                        image->imagemask ? "mask " : "",
 | |
|                        image->filename, mm.a, mm.b, mm.c, mm.d, mm.e, mm.f);
 | |
| 
 | |
|     if (!xo->blind)
 | |
|         pdf_cleanup_fit_options(p, fit);
 | |
| 
 | |
|     /* check image orientation */
 | |
|     if (immatrix != NULL)
 | |
|     {
 | |
|         *immatrix = mm;
 | |
|         return;
 | |
|     }
 | |
|     if (image->mask != pdc_undef)
 | |
|     {
 | |
|         sm = ctm_save;
 | |
|         xo_save.im = image->mask;
 | |
|         xo_save.blind = pdc_true;
 | |
|         pdf_fit_xobject_internal(p, &xo_save, &fit_save, &sm);
 | |
| 
 | |
|         if ((sm.a * mm.a < 0) || (sm.b * mm.b < 0) ||
 | |
|             (sm.c * mm.c < 0) || (sm.d * mm.d < 0))
 | |
|         {
 | |
|             pdc_error(p->pdc, PDF_E_IMAGE_NOMATCH,
 | |
|                       p->images[image->mask].filename, image->filename, 0, 0);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (!(xo->flags & is_image) && !xo->blind)
 | |
|     {
 | |
|         pdf_reset_gstate(p);
 | |
|         pdf_reset_tstate(p);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     if (!xo->blind)
 | |
|     {
 | |
|         /* last strip first */
 | |
|         if (image->strips > 1 && lastratio != 1.0)
 | |
|         {
 | |
|             pdc_scale_matrix(1, lastratio, &m);
 | |
|             pdf_concat_raw(p, &m);
 | |
|         }
 | |
| 
 | |
|         /* put out image strips separately if available */
 | |
|         islast = image->strips - 1;
 | |
|         imageno = image->no + islast;
 | |
|         for (is = islast; is >= 0; is--)
 | |
|         {
 | |
|             pdc_printf(p->out, "/I%d Do\n", imageno);
 | |
|             p->xobjects[imageno].flags |= xobj_flag_write;
 | |
|             if (image->strips > 1 && is > 0)
 | |
|             {
 | |
|                 pdc_translation_matrix(0, 1, &m);
 | |
|                 if (is == islast && lastratio != 1.0)
 | |
| 		{
 | |
| 		    pdc_scale_matrix(1, (1.0 / lastratio), &sm);
 | |
|                     pdc_multiply_matrix(&sm, &m);
 | |
| 		}
 | |
|                 pdf_concat_raw(p, &m);
 | |
|                 imageno--;
 | |
|             }
 | |
|         }
 | |
|         if (image->mask != pdc_undef)
 | |
|         {
 | |
|             p->xobjects[p->images[image->mask].no].flags |= xobj_flag_write;
 | |
| 
 | |
|             if (p->images[image->mask].bpc > 1)
 | |
|                  pdf_set_autotgroup(p, pdc_true);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ---------------------------- info image --------------------------------- */
 | |
| 
 | |
| void
 | |
| pdf_get_image_size(PDF *p, int im, pdc_scalar *width, pdc_scalar *height)
 | |
| {
 | |
|     pdf_image *image;
 | |
| 
 | |
|     pdf_check_handle(p, im, pdc_imagehandle);
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (image->orientation < 5 || image->ignoreorient)
 | |
|     {
 | |
|         if (width)
 | |
|             *width = image->width;
 | |
|         if (height)
 | |
|             *height = fabs(image->height);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         if (width)
 | |
|             *width = fabs(image->height);
 | |
|         if (height)
 | |
|             *height = image->width;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf_get_image_resolution(PDF *p, int im, pdc_scalar *dpi_x, pdc_scalar *dpi_y)
 | |
| {
 | |
|     pdf_image *image;
 | |
| 
 | |
|     pdf_check_handle(p, im, pdc_imagehandle);
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (image->orientation < 5 || image->ignoreorient)
 | |
|     {
 | |
|         if (dpi_x)
 | |
|             *dpi_x = image->dpi_x;
 | |
|         if (dpi_y)
 | |
|             *dpi_y = image->dpi_y;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         if (dpi_x)
 | |
|             *dpi_x = image->dpi_y;
 | |
|         if (dpi_y)
 | |
|             *dpi_y = image->dpi_x;
 | |
|     }
 | |
| }
 | |
| 
 | |
| int
 | |
| pdf_get_image_colorspace(PDF *p, int im)
 | |
| {
 | |
|     pdf_image *image;
 | |
| 
 | |
|     pdf_check_handle(p, im, pdc_imagehandle);
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (image->colorspace != pdc_undef)
 | |
|         return  (int) p->colorspaces[image->colorspace].type;
 | |
| 
 | |
|     return (int) NoColor;
 | |
| }
 | |
| 
 | |
| 
 | |
| const char *
 | |
| pdf_get_image_filename(PDF *p, pdf_image *image)
 | |
| {
 | |
|     return pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN, image->filename);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* ---------------------------- load image --------------------------------- */
 | |
| 
 | |
| static const pdc_keyconn pdf_extension_names[] =
 | |
| {
 | |
|     {".bmp",   pdf_img_bmp},
 | |
|     {".ccitt", pdf_img_ccitt},
 | |
|     {".g3",    pdf_img_ccitt},
 | |
|     {".g4",    pdf_img_ccitt},
 | |
|     {".fax",   pdf_img_ccitt},
 | |
|     {".gif",   pdf_img_gif},
 | |
|     {".jpg",   pdf_img_jpeg},
 | |
|     {".jpeg",  pdf_img_jpeg},
 | |
|     {".jpx",   pdf_img_jpeg2000},
 | |
|     {".jp2",   pdf_img_jpeg2000},
 | |
|     {".jpf",   pdf_img_jpeg2000},
 | |
|     {".jpm",   pdf_img_jpeg2000},
 | |
|     {".j2k",   pdf_img_jpeg2000},
 | |
|     {".png",   pdf_img_png},
 | |
|     {".raw",   pdf_img_raw},
 | |
|     {".tif",   pdf_img_tiff},
 | |
|     {".tiff",  pdf_img_tiff},
 | |
|     {NULL, 0}
 | |
| };
 | |
| 
 | |
| /* allowed values for options 'bpc' */
 | |
| static const pdc_keyconn pdf_bpcvalues[] =
 | |
| {
 | |
|     {"1", 1}, {"2", 2}, {"4", 4}, {"8", 8}, {"16", 16}, {NULL, 0}
 | |
| };
 | |
| 
 | |
| /* allowed values for options 'components' */
 | |
| static const pdc_keyconn pdf_compvalues[] =
 | |
| {
 | |
|     {"1", 1}, {"3", 3}, {"4", 4}, {NULL, 0}
 | |
| };
 | |
| 
 | |
| #define PDF_OPIOPT_FLAG PDC_OPT_UNSUPP
 | |
| #define PDF_ICCOPT_FLAG PDC_OPT_UNSUPP
 | |
| #define PDF_CLIPPATH_FLAG PDC_OPT_UNSUPP
 | |
| 
 | |
| #define PDF_METADATA_FLAG  PDC_OPT_UNSUPP
 | |
| 
 | |
| #define PDF_LAYER_FLAG PDC_OPT_UNSUPP
 | |
| 
 | |
| /* definitions of open image options */
 | |
| static const pdc_defopt pdf_open_image_options[] =
 | |
| {
 | |
|     {"hypertextencoding", pdc_stringlist,  PDC_OPT_NONE, 1, 1,
 | |
|       0.0, PDF_MAX_NAMESTRING, NULL},
 | |
| 
 | |
|     {"bitreverse", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"bpc", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 16.0, pdf_bpcvalues},
 | |
| 
 | |
|     {"components", pdc_integerlist, PDC_OPT_INTLIST, 1, 1, 1.0, 4.0,
 | |
|       pdf_compvalues},
 | |
| 
 | |
|     {"height", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX,  NULL},
 | |
| 
 | |
|     {"width", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL},
 | |
| 
 | |
|     {"honoriccprofile", pdc_booleanlist, PDF_ICCOPT_FLAG, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     /* ordering of the next three options is significant */
 | |
| 
 | |
|     {"iccprofile", pdc_iccprofilehandle, PDF_ICCOPT_FLAG, 1, 1, 1.0, 0.0, NULL},
 | |
| 
 | |
|     {"colorize", pdc_colorhandle, PDC_OPT_IGNOREIF1, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"mask", pdc_booleanlist, PDC_OPT_IGNOREIF2, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"honorclippingpath", pdc_booleanlist, PDF_CLIPPATH_FLAG, 1, 1,
 | |
|      0.0, 0.0, NULL},
 | |
| 
 | |
|     {"clippingpathname", pdc_stringlist, PDF_CLIPPATH_FLAG, 1, 1,
 | |
|       1.0, 255.0, NULL},
 | |
| 
 | |
|     {"ignoremask", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"ignoreorientation", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     /* deprecated */
 | |
|     {"imagewarning", pdc_booleanlist, PDC_OPT_PDFLIB_7, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"inline", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"interpolate", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"invert", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"jpegoptimize", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"passthrough", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"K", pdc_integerlist, 0, 1, 1, -1.0, 1.0, NULL},
 | |
| 
 | |
|     {"masked", pdc_imagehandle, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"page", pdc_integerlist, 0, 1, 1, 1.0, PDC_INT_MAX, NULL},
 | |
| 
 | |
|     {"renderingintent", pdc_keywordlist, 0, 1, 1, 0.0, 0.0,
 | |
|       pdf_renderingintent_pdfkeylist},
 | |
| 
 | |
|     {"reftype", pdc_keywordlist, 0, 1, 1, 0.0, 0.0, pdf_reftype_keys},
 | |
| 
 | |
|     {"template", pdc_booleanlist, 0, 1, 1, 0.0, 0.0, NULL},
 | |
| 
 | |
|     {"iconname", pdc_stringlist, 0, 1, 1,
 | |
|       1.0, PDF_MAX_NAMESTRING, NULL},
 | |
| 
 | |
|     {"OPI-1.3", pdc_stringlist, PDF_OPIOPT_FLAG, 1, 1,
 | |
|       0.0, PDC_INT_MAX, NULL},
 | |
| 
 | |
|     {"OPI-2.0", pdc_stringlist, PDF_OPIOPT_FLAG | PDC_OPT_IGNOREIF1, 1, 1,
 | |
|       0.0, PDC_INT_MAX, NULL},
 | |
| 
 | |
|     {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1,
 | |
|       0.0, PDC_INT_MAX, NULL},
 | |
| 
 | |
|     {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1,
 | |
|       0.0, 0.0, NULL},
 | |
| 
 | |
|     PDF_ERRORPOLICY_OPTION
 | |
| 
 | |
|     PDC_OPT_TERMINATE
 | |
| };
 | |
| 
 | |
| int
 | |
| pdf__load_image(
 | |
|     PDF *p,
 | |
|     const char *type,
 | |
|     const char *filename,
 | |
|     const char *optlist)
 | |
| {
 | |
|     const char *keyword = NULL, *stemp1 = NULL, *stemp2 = NULL, *stemp3 = NULL;
 | |
|     char qualname[32], uptype[16], testfilename[PDC_FILENAMELEN + 1];
 | |
|     pdc_clientdata data;
 | |
|     pdc_resopt *resopts;
 | |
|     pdc_encoding htenc;
 | |
|     int htcp;
 | |
|     pdf_image_type imgtype;
 | |
|     pdc_file *fp = NULL;
 | |
|     int colorize = pdc_undef;
 | |
|     pdf_image *image;
 | |
|     pdc_bool indjpeg = pdc_false;
 | |
|     pdc_bool templ = pdc_false;
 | |
|     pdc_bool verbose = p->debug[(int) 'i'];
 | |
|     int legal_states = 0;
 | |
|     int i, k, inum, imageslot, retval = -1, errcode = 0;
 | |
| 
 | |
|     if (type == NULL || *type == '\0')
 | |
|         pdc_error(p->pdc, PDC_E_ILLARG_EMPTY, "type", 0, 0, 0);
 | |
| 
 | |
|     /* parsing image type */
 | |
|     k = pdc_get_keycode_ci(type, pdf_image_keylist);
 | |
|     if (k == PDC_KEY_NOTFOUND)
 | |
|         pdc_error(p->pdc, PDC_E_ILLARG_STRING, "type", type, 0, 0);
 | |
|     imgtype = (pdf_image_type) k;
 | |
|     type = pdc_get_keyword(imgtype, pdf_image_keylist);
 | |
| 
 | |
|     /* parsing option list */
 | |
|     pdf_set_clientdata(p, &data);
 | |
|     resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_open_image_options,
 | |
|                                    &data, pdc_true);
 | |
| 
 | |
|     keyword = "imagewarning";
 | |
|     pdc_get_optvalues(keyword, resopts, &verbose, NULL);
 | |
|     verbose = pdf_get_errorpolicy(p, resopts, verbose);
 | |
| 
 | |
|     /* filename must be already converted to UTF-8 */
 | |
|     pdc_logg_cond(p->pdc, 1, trc_image, "\tImage file: \"%s\"\n", filename);
 | |
| 
 | |
|     /* search for image file */
 | |
|     fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ", PDC_FILE_BINARY);
 | |
| 
 | |
|     /* automatic check */
 | |
|     if (imgtype == pdf_img_auto)
 | |
|     {
 | |
|         pdf_tiff_info tiff_info;
 | |
| 
 | |
|         /* search for files with other extensions */
 | |
|         if (fp == NULL)
 | |
|         {
 | |
|             pdc_logg_cond(p->pdc, 1, trc_image,
 | |
|                 "\tImage file not found; searching for files "
 | |
|                 "with alternative extensions\n");
 | |
| 
 | |
|             for (i = 0; i < 2; i++)
 | |
|             {
 | |
|                 for (k = 0; k < 100; k++)
 | |
|                 {
 | |
|                     const char *extension = pdf_extension_names[k].word;
 | |
|                     if (extension)
 | |
|                     {
 | |
|                         strcpy(testfilename, filename);
 | |
|                         strcpy(uptype, extension);
 | |
|                         if (i)
 | |
|                             pdc_strtoupper(uptype);
 | |
|                         strcat(testfilename, uptype);
 | |
| 
 | |
|                         fp = pdc_fsearch_fopen(p->pdc, testfilename, NULL,
 | |
|                                                "image ", PDC_FILE_BINARY);
 | |
|                         if (fp != NULL)
 | |
|                             break;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                 }
 | |
|                 if (fp != NULL)
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (fp != NULL)
 | |
|             {
 | |
|                 filename = (const char *) testfilename;
 | |
|                 pdc_logg_cond(p->pdc, 1, trc_image,
 | |
|                                   "\tImage file \"%s\" found\n", filename);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 fp = pdc_fsearch_fopen(p->pdc, filename, NULL, "image ",
 | |
|                                        PDC_FILE_BINARY);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* automatic type check */
 | |
|         if (fp != NULL)
 | |
|         {
 | |
|             if (pdf_is_BMP_file(p, fp))
 | |
|                 imgtype = pdf_img_bmp;
 | |
|             else if (pdf_is_GIF_file(p, fp))
 | |
|                 imgtype = pdf_img_gif;
 | |
|             else if (pdf_is_PNG_file(p, fp))
 | |
|                 imgtype = pdf_img_png;
 | |
|             else if (pdf_is_TIFF_file(p, fp, &tiff_info, pdc_true))
 | |
|                 imgtype = pdf_img_tiff;
 | |
|             else if (pdf_is_JPEG_file(p, fp))
 | |
|                 imgtype = pdf_img_jpeg;
 | |
|             else if (pdf_is_JPX_file(p, fp))
 | |
|                 imgtype = pdf_img_jpeg2000;
 | |
|             else
 | |
|             {
 | |
|                 pdc_fclose(fp);
 | |
| 
 | |
|                 pdc_set_errmsg(p->pdc, PDF_E_IMAGE_UNKNOWN, filename, 0, 0, 0);
 | |
| 
 | |
|                 if (verbose)
 | |
|                     PDC_RETHROW(p->pdc);
 | |
| 
 | |
|                 return -1;
 | |
|             }
 | |
|             type = pdc_get_keyword(imgtype, pdf_image_keylist);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (fp == NULL)
 | |
|     {
 | |
|         if (verbose)
 | |
|             PDC_RETHROW(p->pdc);
 | |
| 
 | |
|         return -1;
 | |
|     }
 | |
|     pdc_fclose(fp);
 | |
| 
 | |
|     strcpy(uptype, type);
 | |
|     pdc_strtoupper(uptype);
 | |
|     pdc_logg_cond(p->pdc, 1, trc_image,
 | |
|         "\tImage type \"%s\" detected\n", uptype);
 | |
| 
 | |
|     if (imgtype == pdf_img_jpeg2000)
 | |
|     {
 | |
|         pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_JPEG2000, 0, 0, 0, 0);
 | |
| 
 | |
|         if (verbose)
 | |
|             PDC_RETHROW(p->pdc);
 | |
| 
 | |
|         return -1;
 | |
|     }
 | |
| 
 | |
|     /* find free slot */
 | |
|     for (imageslot = 0; imageslot < p->images_capacity; imageslot++)
 | |
|         if (!p->images[imageslot].in_use)
 | |
|             break;
 | |
| 
 | |
|     if (imageslot == p->images_capacity)
 | |
|         pdf_grow_images(p);
 | |
|     image = &p->images[imageslot];
 | |
| 
 | |
|     /* copy filename */
 | |
|     image->filename = pdc_strdup(p->pdc, filename);
 | |
| 
 | |
|     /* inherit global flags */
 | |
|     image->verbose = verbose;
 | |
|     image->ri = p->rendintent;
 | |
| 
 | |
|     /* parsing optlist */
 | |
|     if (optlist && strlen(optlist))
 | |
|     {
 | |
|         keyword = "reftype";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &inum, NULL))
 | |
|         {
 | |
|             image->reference = (pdf_ref_type) inum;
 | |
|             if (image->reference != pdf_ref_direct &&
 | |
|                 imgtype != pdf_img_ccitt &&
 | |
|                 imgtype != pdf_img_jpeg &&
 | |
|                 imgtype != pdf_img_raw)
 | |
|             {
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 | |
|                             0, 0);
 | |
|                 image->reference = pdf_ref_direct;
 | |
|             }
 | |
|         }
 | |
|         indjpeg = (imgtype == pdf_img_jpeg &&
 | |
|                    image->reference != pdf_ref_direct) ? pdc_true : pdc_false;
 | |
| 
 | |
|         keyword = "bpc";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->bpc, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_raw && !indjpeg)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|             if (image->bpc == 16)
 | |
|             {
 | |
|                 if (p->compatibility < PDC_1_5)
 | |
|                 {
 | |
|                     errcode = PDC_E_OPT_VERSION;
 | |
|                     stemp1 = "bpc=16";
 | |
|                     stemp2 = pdc_get_pdfversion(p->pdc, p->compatibility);
 | |
|                     goto PDF_IMAGE_ERROR;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         keyword = "components";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->components, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_raw && !indjpeg)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "height";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->height_pixel, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_ccitt &&
 | |
|                 imgtype != pdf_img_raw && !indjpeg)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "width";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->width_pixel, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_raw &&
 | |
|                 imgtype != pdf_img_ccitt && !indjpeg)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "bitreverse";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->bitreverse, NULL))
 | |
|         {
 | |
|             if (image->bitreverse &&
 | |
|                (imgtype != pdf_img_ccitt || image->reference != pdf_ref_direct))
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "colorize";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &colorize, NULL))
 | |
|         {
 | |
|             if (imgtype == pdf_img_jpeg2000)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         keyword = "ignoremask";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->ignoremask, NULL))
 | |
|         {
 | |
|             if (imgtype == pdf_img_bmp ||
 | |
|                 imgtype == pdf_img_ccitt ||
 | |
|                 imgtype == pdf_img_raw)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "ignoreorientation";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->ignoreorient, NULL))
 | |
|         {
 | |
|             if (imgtype == pdf_img_tiff)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "inline";
 | |
|         if (pdc_get_optvalues(keyword, resopts,
 | |
|                               &image->doinline, NULL) && image->doinline)
 | |
|         {
 | |
|             if (imgtype != pdf_img_ccitt &&
 | |
|                 imgtype != pdf_img_jpeg &&
 | |
|                 imgtype != pdf_img_raw)
 | |
|             {
 | |
|                 pdc_warning(p->pdc,
 | |
|                     PDF_E_IMAGE_OPTUNSUPP, keyword, uptype, 0, 0);
 | |
|                 image->doinline = pdc_false;
 | |
|             }
 | |
|             else if (image->reference != pdf_ref_direct)
 | |
|             {
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|                 image->doinline = pdc_false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         keyword = "interpolate";
 | |
|         pdc_get_optvalues(keyword, resopts, &image->interpolate, NULL);
 | |
| 
 | |
| 
 | |
|         keyword = "invert";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->invert, NULL))
 | |
|         {
 | |
|             if (imgtype == pdf_img_jpeg2000)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "jpegoptimize";
 | |
|         pdc_get_optvalues(keyword, resopts, &image->jpegoptimize, NULL);
 | |
| 
 | |
|         keyword = "passthrough";
 | |
|         pdc_get_optvalues(keyword, resopts, &image->passthrough, NULL);
 | |
| 
 | |
|         keyword = "K";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->K, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_ccitt)
 | |
|                 pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNREAS, keyword, uptype,
 | |
|                             0, 0);
 | |
|         }
 | |
| 
 | |
|         keyword = "mask";
 | |
|         pdc_get_optvalues(keyword, resopts, &image->imagemask, NULL);
 | |
| 
 | |
| 
 | |
|         keyword = "masked";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->mask, NULL))
 | |
|         {
 | |
| 
 | |
| 
 | |
|             if (!p->images[image->mask].in_use ||
 | |
|                  p->images[image->mask].strips != 1 ||
 | |
|                 (p->compatibility <= PDC_1_3 &&
 | |
|                 (p->images[image->mask].imagemask != pdc_true ||
 | |
|                  p->images[image->mask].bpc != 1)))
 | |
|             {
 | |
|                 errcode = PDF_E_IMAGE_OPTBADMASK;
 | |
|                 stemp1 = keyword;
 | |
|                 stemp2 = pdc_errprintf(p->pdc, "%d", image->mask);
 | |
|                 goto PDF_IMAGE_ERROR;
 | |
|             }
 | |
| 
 | |
| 	    if (p->colorspaces[p->images[image->mask].colorspace].type !=
 | |
| 		DeviceGray)
 | |
|             {
 | |
|                 errcode = PDF_E_IMAGE_BADMASK;
 | |
|                 stemp1 = pdc_errprintf(p->pdc, "%s",
 | |
| 			p->images[image->mask].filename);
 | |
|                 goto PDF_IMAGE_ERROR;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         keyword = "renderingintent";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &inum, NULL))
 | |
|             image->ri = (pdf_renderingintent) inum;
 | |
| 
 | |
|         keyword = "page";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &image->page, NULL))
 | |
|         {
 | |
|             if (imgtype != pdf_img_tiff)
 | |
|             {
 | |
|                 if (image->page == 1)
 | |
|                 {
 | |
|                     pdc_warning(p->pdc, PDF_E_IMAGE_OPTUNSUPP, keyword,
 | |
|                                 uptype, 0, 0);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     errcode = PDF_E_IMAGE_NOPAGE;
 | |
|                     stemp1 = pdc_errprintf(p->pdc, "%d", image->page);
 | |
|                     stemp2 = uptype;
 | |
|                     stemp3 = pdc_errprintf(p->pdc, "%s", image->filename);
 | |
|                     goto PDF_IMAGE_ERROR;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         keyword = "template";
 | |
|         if (pdc_get_optvalues(keyword, resopts, &templ, NULL))
 | |
|         {
 | |
|             if (templ && image->doinline)
 | |
|             {
 | |
|                 pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline",
 | |
|                             0, 0);
 | |
|                 templ = pdc_false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         htenc =
 | |
|             pdf_get_hypertextencoding_opt(p, resopts, &htcp, pdc_true);
 | |
|         keyword = "iconname";
 | |
|         if (pdf_get_opt_textlist(p, keyword, resopts, htenc, htcp, pdc_true,
 | |
|                                  NULL, &image->iconname, NULL))
 | |
|         {
 | |
|             if (image->doinline)
 | |
|             {
 | |
|                 image->iconname = NULL;
 | |
|                 pdc_warning(p->pdc, PDC_E_OPT_IGNORE, keyword, "inline",
 | |
|                             0, 0);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
 | |
|                 templ = pdc_true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /* precise scope diagnosis */
 | |
|     if (image->doinline)
 | |
|         legal_states = pdf_state_content;
 | |
|     else if (templ)
 | |
|         legal_states = pdf_state_document;
 | |
|     else
 | |
|         legal_states = pdf_state_document | pdf_state_page | pdf_state_font;
 | |
|     PDF_CHECK_STATE(p, legal_states);
 | |
| 
 | |
|     /* required options */
 | |
|     if (imgtype == pdf_img_raw || imgtype == pdf_img_ccitt || indjpeg)
 | |
|     {
 | |
|         keyword = "";
 | |
|         if (image->height_pixel == pdc_undef)
 | |
|             keyword = "height";
 | |
|         else if (image->width_pixel == pdc_undef)
 | |
|             keyword = "width";
 | |
|         else
 | |
|         {
 | |
|             image->width = image->width_pixel;
 | |
|             image->height = image->height_pixel;
 | |
|         }
 | |
| 
 | |
|         if (imgtype == pdf_img_ccitt)
 | |
|         {
 | |
|             image->components = 1;
 | |
|             image->bpc = 1;
 | |
|         }
 | |
|         if (image->bpc == pdc_undef)
 | |
|             keyword = "bpc";
 | |
|         else if (image->components == pdc_undef)
 | |
|             keyword = "components";
 | |
| 
 | |
|         if (*keyword)
 | |
|         {
 | |
|             errcode = PDC_E_OPT_NOTFOUND;
 | |
|             stemp1 = keyword;
 | |
|             goto PDF_IMAGE_ERROR;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
|     /* set colorspace */
 | |
|     if (colorize != pdc_undef)
 | |
|     {
 | |
|         image->colorspace = colorize;
 | |
|     }
 | |
|     else if (image->imagemask == pdc_true)
 | |
|     {
 | |
|         image->colorspace = (int) DeviceGray;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         switch(image->components)
 | |
|         {
 | |
|             case 1:
 | |
|             image->colorspace = DeviceGray;
 | |
|             break;
 | |
| 
 | |
|             case 3:
 | |
|             image->colorspace = DeviceRGB;
 | |
|             break;
 | |
| 
 | |
|             case 4:
 | |
|             image->colorspace = DeviceCMYK;
 | |
|             break;
 | |
| 
 | |
|             default:
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* try to open image file */
 | |
|     if (image->reference == pdf_ref_direct)
 | |
|     {
 | |
| 	strcpy(qualname, uptype);
 | |
| 	strcat(qualname, " ");
 | |
|         image->fp = pdc_fsearch_fopen(p->pdc, image->filename, NULL, qualname,
 | |
|                                       PDC_FILE_BINARY);
 | |
|         if (image->fp == NULL)
 | |
|             goto PDF_IMAGE_ERROR;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     /* set image type */
 | |
|     image->type = imgtype;
 | |
| 
 | |
|     /* call working function */
 | |
|     switch (imgtype)
 | |
|     {
 | |
|         case pdf_img_bmp:
 | |
|         retval = pdf_process_BMP_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_ccitt:
 | |
|         retval = pdf_process_CCITT_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_gif:
 | |
|         retval = pdf_process_GIF_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_jpeg:
 | |
|         if (image->passthrough == pdc_undef)
 | |
|             image->passthrough = pdc_false;
 | |
|         retval = pdf_process_JPEG_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_jpeg2000:
 | |
|         retval = pdf_process_JPX_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_png:
 | |
|         retval = pdf_process_PNG_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         default:
 | |
|         case pdf_img_raw:
 | |
|         retval = pdf_process_RAW_data(p, imageslot);
 | |
|         break;
 | |
| 
 | |
|         case pdf_img_tiff:
 | |
|         if (image->passthrough == pdc_undef)
 | |
|             image->passthrough = pdc_true;
 | |
|         retval = pdf_process_TIFF_data(p, imageslot);
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     /* cleanup */
 | |
|     if (retval == -1)
 | |
|     {
 | |
|         pdf_cleanup_image(p, imageslot);
 | |
| 
 | |
|         if (verbose)
 | |
|             PDC_RETHROW(p->pdc);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         if (image->fp)
 | |
|             pdc_fclose(image->fp);
 | |
|         image->fp = NULL;
 | |
| 
 | |
|         /* logging protocol */
 | |
|         if (image->in_use && pdc_logg_is_enabled(p->pdc, 1, trc_image))
 | |
|         {
 | |
|             pdc_scalar width, height, dpi_x, dpi_y;
 | |
| 
 | |
|             pdf_get_image_size(p, imageslot, &width, &height);
 | |
|             pdf_get_image_resolution(p, imageslot, &dpi_x, &dpi_y);
 | |
| 
 | |
|             pdc_logg(p->pdc, "\tImage width: %g pixel\n"
 | |
|                               "\tImage height: %g pixel\n"
 | |
|                               "\tImage x resolution: %g dpi\n"
 | |
|                               "\tImage y resolution: %g dpi\n",
 | |
|                               width, height, dpi_x, dpi_y);
 | |
| 
 | |
|             if (imgtype == pdf_img_tiff)
 | |
|                 pdc_logg(p->pdc, "\tOrientation tag: %d\n",
 | |
|                                   image->orientation);
 | |
| 
 | |
|         }
 | |
| 
 | |
|         if (templ)
 | |
|         {
 | |
|             retval = pdf_embed_image(p, imageslot);
 | |
|             pdf_cleanup_image(p, imageslot);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return retval;
 | |
| 
 | |
|     PDF_IMAGE_ERROR:
 | |
| 
 | |
|     pdf_cleanup_image(p, imageslot);
 | |
| 
 | |
|     if (errcode)
 | |
|         pdc_set_errmsg(p->pdc, errcode, stemp1, stemp2, stemp3, 0);
 | |
|     if (verbose)
 | |
|         PDC_RETHROW(p->pdc);
 | |
| 
 | |
|     return retval;
 | |
| }
 | |
| 
 | |
| void
 | |
| pdf__close_image(PDF *p, int image)
 | |
| {
 | |
|     pdf_check_handle(p, image, pdc_imagehandle);
 | |
|     pdf_cleanup_image(p, image);
 | |
| }
 | |
| 
 | |
| 
 | |
| #define MAX_THUMBNAIL_SIZE      106
 | |
| 
 | |
| void
 | |
| pdf__add_thumbnail(PDF *p, int im)
 | |
| {
 | |
|     pdf_image *image;
 | |
| 
 | |
|     pdf_check_handle(p, im, pdc_imagehandle);
 | |
| 
 | |
|     if (pdf_get_thumb_id(p) != PDC_BAD_ID)
 | |
|         pdc_error(p->pdc, PDF_E_IMAGE_THUMB, 0, 0, 0, 0);
 | |
| 
 | |
|     image = &p->images[im];
 | |
| 
 | |
|     if (image->strips > 1)
 | |
|         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_MULTISTRIP,
 | |
|             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
 | |
| 
 | |
|     if (image->width > MAX_THUMBNAIL_SIZE || image->height > MAX_THUMBNAIL_SIZE)
 | |
|         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_SIZE,
 | |
|             pdc_errprintf(p->pdc, "%d", im),
 | |
|             pdc_errprintf(p->pdc, "%d", MAX_THUMBNAIL_SIZE), 0, 0);
 | |
| 
 | |
|     if (image->colorspace != (int) DeviceGray &&
 | |
|         image->colorspace != (int) DeviceRGB &&
 | |
|         image->colorspace != (int) Indexed)
 | |
|         pdc_error(p->pdc, PDF_E_IMAGE_THUMB_CS,
 | |
|             pdc_errprintf(p->pdc, "%d", im), 0, 0, 0);
 | |
| 
 | |
|     /* Add the image to the thumbnail key of the current page.  */
 | |
|     pdf_set_thumb_id(p, p->xobjects[image->no].obj_id);
 | |
| }
 |