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
		
			
				
	
	
		
			1212 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1212 lines
		
	
	
		
			35 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_tiff.c,v 1.4 2009-03-23 08:55:35 guy Exp $
 | 
						|
 *
 | 
						|
 * TIFF processing for PDFlib
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include "p_intern.h"
 | 
						|
#include "p_color.h"
 | 
						|
#include "p_image.h"
 | 
						|
 | 
						|
#ifndef HAVE_LIBTIFF
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_is_TIFF_file(PDF *p, pdc_file *fp, pdf_tiff_info *tiff, pdc_bool check)
 | 
						|
{
 | 
						|
    (void) p;
 | 
						|
    (void) fp;
 | 
						|
    (void) tiff;
 | 
						|
    (void) check;
 | 
						|
 | 
						|
    return pdc_false;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdf_process_TIFF_data(
 | 
						|
    PDF *p,
 | 
						|
    int imageslot)
 | 
						|
{
 | 
						|
    (void) imageslot;
 | 
						|
 | 
						|
    pdc_set_errmsg(p->pdc, PDF_E_UNSUPP_IMAGE, "TIFF", 0, 0, 0);
 | 
						|
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
#include "tiffiop.h"
 | 
						|
static tsize_t
 | 
						|
pdf_libtiff_read(void* fd, tdata_t buf, tsize_t size)
 | 
						|
{
 | 
						|
    pdc_file *fp = (pdc_file *) fd;
 | 
						|
 | 
						|
    return ((tsize_t) pdc_fread(buf, 1, (size_t) size, fp));
 | 
						|
}
 | 
						|
 | 
						|
static toff_t
 | 
						|
pdf_libtiff_seek(void* fd, toff_t off, int whence)
 | 
						|
{
 | 
						|
    pdc_file *fp = (pdc_file *) fd;
 | 
						|
 | 
						|
    return ((toff_t) pdc_fseek(fp, (long) off, whence));
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
pdf_libtiff_close(void* fd)
 | 
						|
{
 | 
						|
    (void) fd;
 | 
						|
 | 
						|
    /* pdc_fclose(fp); this happens in caller function */
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static toff_t
 | 
						|
pdf_libtiff_size(void* fd)
 | 
						|
{
 | 
						|
    pdc_file *fp = (pdc_file *) fd;
 | 
						|
 | 
						|
    return (toff_t) pdc_file_size(fp);
 | 
						|
}
 | 
						|
 | 
						|
static void *
 | 
						|
pdf_libtiff_malloc(TIFF *t, tsize_t size)
 | 
						|
{
 | 
						|
    PDF *p = (PDF*) t->pdflib_opaque;
 | 
						|
    return pdc_calloc(p->pdc, (size_t)size, "libtiff");
 | 
						|
}
 | 
						|
 | 
						|
static void *
 | 
						|
pdf_libtiff_realloc(TIFF *t, tdata_t mem, tsize_t size)
 | 
						|
{
 | 
						|
    PDF *p = (PDF*) t->pdflib_opaque;
 | 
						|
    return(pdc_realloc(p->pdc, (void*)mem, (size_t)size, "libtiff"));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
pdf_libtiff_free(TIFF *t, tdata_t mem)
 | 
						|
{
 | 
						|
    PDF *p = (PDF*) t->pdflib_opaque;
 | 
						|
    pdc_free(p->pdc, (void*)mem);
 | 
						|
}
 | 
						|
 | 
						|
#define PDF_TIFF_LENGTH_MAX 512
 | 
						|
static void
 | 
						|
pdf_libtiff_error(TIFF *t, const char* module, const char* fmt, va_list ap)
 | 
						|
{
 | 
						|
    PDF *p = (PDF*) t->pdflib_opaque;
 | 
						|
 | 
						|
    if (pdc_logg_is_enabled(p->pdc, 5, trc_image))
 | 
						|
    {
 | 
						|
        char buffer[PDF_TIFF_LENGTH_MAX];
 | 
						|
 | 
						|
        /* Create the message */
 | 
						|
        pdc_vsnprintf(p->pdc, buffer, PDF_TIFF_LENGTH_MAX, fmt, ap);
 | 
						|
        pdc_logg(p->pdc, "\tlibtiff(%s): %s\n", module, buffer);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
pdf_data_source_TIFF_init(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    static const char *fn = "pdf_data_source_TIFF_init";
 | 
						|
    pdf_image	*image;
 | 
						|
 | 
						|
    image = (pdf_image *) src->private_data;
 | 
						|
 | 
						|
    if (image->strips == 1)
 | 
						|
	image->info.tiff.cur_line = 0;
 | 
						|
 | 
						|
    if (image->use_raw)
 | 
						|
    {
 | 
						|
	/* malloc is done in the fill function */
 | 
						|
	src->buffer_length = (size_t) 0;
 | 
						|
	src->buffer_start = (pdc_byte *) NULL;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	if (image->bpc == 1)
 | 
						|
	    src->buffer_length =
 | 
						|
		(size_t) (image->components * ((int) image->width+7)/8);
 | 
						|
	else
 | 
						|
	    src->buffer_length =
 | 
						|
		(size_t) (image->components * image->width);
 | 
						|
 | 
						|
	src->buffer_start = (pdc_byte *)
 | 
						|
	    pdc_malloc(p->pdc, src->buffer_length, fn);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* Convert the a and b samples of Lab data from signed to unsigned. */
 | 
						|
 | 
						|
static void
 | 
						|
pdf_signed_to_unsigned(pdc_byte *buf, size_t count)
 | 
						|
{
 | 
						|
    size_t i;
 | 
						|
 | 
						|
    for(i=0; i < count; i+=3)
 | 
						|
    {
 | 
						|
	buf[i+1] ^= 0x80;
 | 
						|
	buf[i+2] ^= 0x80;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#define MYTIFF		image->info.tiff.tif
 | 
						|
 | 
						|
static pdc_bool
 | 
						|
pdf_data_source_TIFF_fill(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    static const char *fn = "pdf_data_source_TIFF_fill";
 | 
						|
    pdf_image	*image;
 | 
						|
    int		col;
 | 
						|
    pdc_byte	*dest;
 | 
						|
    uint16	fillorder;
 | 
						|
    uint32	*s, *bc;
 | 
						|
 | 
						|
    image = (pdf_image *) src->private_data;
 | 
						|
 | 
						|
    PDC_TRY(p->pdc)
 | 
						|
    {
 | 
						|
        if (image->use_raw)
 | 
						|
        {
 | 
						|
            if (image->info.tiff.cur_line == image->strips)
 | 
						|
            {
 | 
						|
                PDC_EXIT_TRY(p->pdc);
 | 
						|
                return pdc_false;
 | 
						|
            }
 | 
						|
 | 
						|
            TIFFGetField(MYTIFF, TIFFTAG_STRIPBYTECOUNTS, &bc);
 | 
						|
 | 
						|
            if (bc[image->info.tiff.cur_line] > src->buffer_length)
 | 
						|
            {
 | 
						|
                src->buffer_length = bc[image->info.tiff.cur_line];
 | 
						|
                src->buffer_start = (pdc_byte *)
 | 
						|
                    pdc_realloc(p->pdc, src->buffer_start,
 | 
						|
                    src->buffer_length, fn);
 | 
						|
            }
 | 
						|
 | 
						|
            if (TIFFReadRawStrip(MYTIFF, (tstrip_t) image->info.tiff.cur_line,
 | 
						|
                            (tdata_t) src->buffer_start,
 | 
						|
                            (tsize_t) bc[image->info.tiff.cur_line]) == -1)
 | 
						|
            {
 | 
						|
                pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "TIFF",
 | 
						|
                          pdf_get_image_filename(p, image), 0, 0);
 | 
						|
            }
 | 
						|
 | 
						|
            src->next_byte = src->buffer_start;
 | 
						|
            src->bytes_available = bc[image->info.tiff.cur_line];
 | 
						|
 | 
						|
            /* special handling for uncompressed 16-bit images */
 | 
						|
            if (MYTIFF->tif_header.tiff_magic == TIFF_LITTLEENDIAN &&
 | 
						|
                image->compression == pdf_comp_none && image->bpc == 16)
 | 
						|
            {
 | 
						|
                TIFFSwabArrayOfShort((uint16 *) src->buffer_start,
 | 
						|
                        (unsigned long) src->bytes_available/2);
 | 
						|
            }
 | 
						|
 | 
						|
            if (TIFFGetField(MYTIFF, TIFFTAG_FILLORDER, &fillorder)
 | 
						|
                && (fillorder == FILLORDER_LSB2MSB))
 | 
						|
            {
 | 
						|
                TIFFReverseBits((unsigned char *) src->buffer_start,
 | 
						|
                    (unsigned long) src->bytes_available);
 | 
						|
            }
 | 
						|
 | 
						|
            /* The a and b values of (uncompressed) Lab must be adjusted */
 | 
						|
            if (p->colorspaces[image->colorspace].type == Lab)
 | 
						|
            {
 | 
						|
                pdf_signed_to_unsigned(src->buffer_start, src->bytes_available);
 | 
						|
            }
 | 
						|
 | 
						|
            if (image->strips > 1)
 | 
						|
            {
 | 
						|
                /* only a single strip of a multi-strip image */
 | 
						|
                image->info.tiff.cur_line = image->strips;
 | 
						|
            }
 | 
						|
            else
 | 
						|
                image->info.tiff.cur_line++;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            {
 | 
						|
            if (image->info.tiff.cur_line++ == image->height)
 | 
						|
            {
 | 
						|
                PDC_EXIT_TRY(p->pdc);
 | 
						|
                return pdc_false;
 | 
						|
            }
 | 
						|
 | 
						|
            src->next_byte = src->buffer_start;
 | 
						|
            src->bytes_available = src->buffer_length;
 | 
						|
 | 
						|
            dest = src->buffer_start;
 | 
						|
            s = image->info.tiff.raster +
 | 
						|
                ((int)image->height - image->info.tiff.cur_line) *
 | 
						|
                (int) image->width;
 | 
						|
 | 
						|
            switch (image->components)
 | 
						|
            {
 | 
						|
                case 1:
 | 
						|
                if (image->bpc == 1)
 | 
						|
                {
 | 
						|
                    unsigned char mask;
 | 
						|
 | 
						|
                    memset((void*) dest, 0, src->buffer_length);
 | 
						|
 | 
						|
                    for (mask=0x80, col = 0; col < image->width; col++)
 | 
						|
                    {
 | 
						|
                        if (TIFFGetR(*s++) != 0)
 | 
						|
                            *dest |= mask;
 | 
						|
 | 
						|
                        if ((mask>>=1) == 0)
 | 
						|
                        {
 | 
						|
                            mask = 0x80;
 | 
						|
                            ++dest;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else	/* bpc == 8 */
 | 
						|
                {
 | 
						|
                    for (col = 0; col < image->width; col++, s++)
 | 
						|
                    {
 | 
						|
                        *dest++ = (pdc_byte) TIFFGetR(*s);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
                case 3:
 | 
						|
                for (col = 0; col < image->width; col++, s++)
 | 
						|
                {
 | 
						|
                    *dest++ = (pdc_byte) TIFFGetR(*s);
 | 
						|
                    *dest++ = (pdc_byte) TIFFGetG(*s);
 | 
						|
                    *dest++ = (pdc_byte) TIFFGetB(*s);
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
                case 4:
 | 
						|
                for (col = 0; col < image->width; col++, s++)
 | 
						|
                {
 | 
						|
                    unsigned char* t = (unsigned char*)&(*s);
 | 
						|
                    *dest++ = (pdc_byte) t[0];
 | 
						|
                    *dest++ = (pdc_byte) t[1];
 | 
						|
                    *dest++ = (pdc_byte) t[2];
 | 
						|
                    *dest++ = (pdc_byte) t[3];
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
                default:
 | 
						|
                pdc_error(p->pdc, PDF_E_IMAGE_BADCOMP,
 | 
						|
                      pdc_errprintf(p->pdc, "%d", image->components),
 | 
						|
                      pdf_get_image_filename(p, image), 0, 0);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    PDC_CATCH(p->pdc)
 | 
						|
    {
 | 
						|
        image->corrupt = pdc_true;
 | 
						|
    }
 | 
						|
 | 
						|
    return !image->corrupt;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
pdf_data_source_TIFF_terminate(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    pdc_free(p->pdc, (void *) src->buffer_start);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
pdf_check_colormap(int n, uint16* r, uint16* g, uint16* b)
 | 
						|
{
 | 
						|
    while (n-- > 0)
 | 
						|
	if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
 | 
						|
		return(16);
 | 
						|
    return(8);
 | 
						|
}
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_is_TIFF_file(PDF *p, pdc_file *fp, pdf_tiff_info *tiff_info, pdc_bool check)
 | 
						|
{
 | 
						|
    const char *filename;
 | 
						|
 | 
						|
    pdc_logg_cond(p->pdc, 1, trc_image, "\tChecking image type TIFF...\n");
 | 
						|
 | 
						|
    filename = pdc_file_name(fp);
 | 
						|
    tiff_info->tif = TIFFClientOpen(filename, "rc",
 | 
						|
            (void *)fp,
 | 
						|
            pdf_libtiff_read, NULL,
 | 
						|
            pdf_libtiff_seek, pdf_libtiff_close, pdf_libtiff_size,
 | 
						|
            NULL, NULL, (void *)p,
 | 
						|
            pdf_libtiff_malloc, pdf_libtiff_realloc, pdf_libtiff_free,
 | 
						|
            pdf_libtiff_error, pdf_libtiff_error);
 | 
						|
    if (tiff_info->tif == NULL)
 | 
						|
    {
 | 
						|
        pdc_fseek(fp, 0L, SEEK_SET);
 | 
						|
        return pdc_false;
 | 
						|
    }
 | 
						|
    if (check)
 | 
						|
        TIFFClose(tiff_info->tif);
 | 
						|
    return pdc_true;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdf_process_TIFF_data(
 | 
						|
    PDF *p,
 | 
						|
    int imageslot)
 | 
						|
{
 | 
						|
    static const char *fn = "pdf_process_TIFF_data";
 | 
						|
    uint32 width, height;
 | 
						|
    uint16 unit, bpc, compression, photometric, extra, *sinfo;
 | 
						|
    uint16 orientation, planarconfig;
 | 
						|
    uint16 *rmap, *gmap, *bmap;
 | 
						|
    tsample_t components;
 | 
						|
    pdf_image *image;
 | 
						|
    float res_x, res_y;  /* sic! */
 | 
						|
    pdf_colorspace cs;
 | 
						|
    int slot;
 | 
						|
    int errint = 0;
 | 
						|
    int errcode = 0;
 | 
						|
    pdc_bool isopen = pdc_false;
 | 
						|
    int strips;
 | 
						|
 | 
						|
    image = &p->images[imageslot];
 | 
						|
 | 
						|
    image->info.tiff.raster = (uint32 *) NULL;
 | 
						|
 | 
						|
    if (!pdf_is_TIFF_file(p, image->fp, &image->info.tiff, pdc_false))
 | 
						|
    {
 | 
						|
        errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
        goto PDF_TIFF_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    MYTIFF->tif_fd = (FILE*) image->fp;
 | 
						|
    isopen = pdc_true;
 | 
						|
 | 
						|
    if (image->page != 1)
 | 
						|
    {
 | 
						|
        if (TIFFSetDirectory(MYTIFF, (tdir_t) (image->page - 1)) != 1 )
 | 
						|
	{
 | 
						|
            errint = image->page;
 | 
						|
            errcode = PDF_E_IMAGE_NOPAGE;
 | 
						|
            goto PDF_TIFF_ERROR;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_ORIENTATION, &orientation);
 | 
						|
    image->orientation = orientation;
 | 
						|
 | 
						|
    TIFFGetField(MYTIFF, TIFFTAG_COMPRESSION, &compression);
 | 
						|
 | 
						|
    TIFFGetField(MYTIFF, TIFFTAG_IMAGEWIDTH, &width);
 | 
						|
    image->width        = (pdc_scalar) width;
 | 
						|
 | 
						|
    TIFFGetField(MYTIFF, TIFFTAG_IMAGELENGTH, &height);
 | 
						|
    image->height       = (pdc_scalar) height;
 | 
						|
 | 
						|
    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_BITSPERSAMPLE, &bpc);
 | 
						|
    image->bpc		= bpc;
 | 
						|
 | 
						|
    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_SAMPLESPERPIXEL, &components);
 | 
						|
    image->components	= components;
 | 
						|
 | 
						|
    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_EXTRASAMPLES, &extra, &sinfo);
 | 
						|
 | 
						|
    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_PLANARCONFIG, &planarconfig);
 | 
						|
 | 
						|
    photometric = 255;	/* dummy value */
 | 
						|
    TIFFGetField(MYTIFF, TIFFTAG_PHOTOMETRIC, &photometric);
 | 
						|
 | 
						|
    /* fetch the resolution values if found in the file */
 | 
						|
    if (TIFFGetField(MYTIFF, TIFFTAG_XRESOLUTION, &res_x) &&
 | 
						|
	TIFFGetField(MYTIFF, TIFFTAG_YRESOLUTION, &res_y) &&
 | 
						|
	TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_RESOLUTIONUNIT, &unit) &&
 | 
						|
	res_x > 0 && res_y > 0) {
 | 
						|
 | 
						|
	if (unit == RESUNIT_INCH) {
 | 
						|
	    image->dpi_x = res_x;
 | 
						|
	    image->dpi_y = res_y;
 | 
						|
 | 
						|
	} else if (unit == RESUNIT_CENTIMETER) {
 | 
						|
	    image->dpi_x = res_x * 2.54;
 | 
						|
	    image->dpi_y = res_y * 2.54;
 | 
						|
 | 
						|
	} else if (unit == RESUNIT_NONE) {
 | 
						|
	    image->dpi_x = -res_x;
 | 
						|
	    image->dpi_y = -res_y;
 | 
						|
	}
 | 
						|
 | 
						|
#define PDF_REALLY_BIG_DPI	10000
 | 
						|
 | 
						|
	/* Guard against obviously wrong values */
 | 
						|
	if (unit != RESUNIT_NONE &&
 | 
						|
	    (image->dpi_x <= 1 ||
 | 
						|
	    image->dpi_y <= 1 ||
 | 
						|
	    image->dpi_x > PDF_REALLY_BIG_DPI ||
 | 
						|
	    image->dpi_y > PDF_REALLY_BIG_DPI))
 | 
						|
 | 
						|
	    image->dpi_x = image->dpi_y = 0;	/* unknown */
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /* ------------------------------------------------------------
 | 
						|
     * Reject unsupported flavors.
 | 
						|
     * ---------------------------------------------------------- */
 | 
						|
 | 
						|
    /* Catch some rare properties related to compression, photometric,
 | 
						|
     * and bpc which are definitely not supported (neither in pass-through
 | 
						|
     * mode nor libtiff) in order to provide a better error message than
 | 
						|
     * the generic "Error reading data".
 | 
						|
     */
 | 
						|
 | 
						|
    /* Unsupported compression types */
 | 
						|
    switch ((int) compression)
 | 
						|
    {
 | 
						|
	case /* 34661 */ COMPRESSION_JBIG:
 | 
						|
	case /* 34712 */ COMPRESSION_JP2000:
 | 
						|
	case 9 		/* JBIG T85 */:
 | 
						|
	case 10 	/* TIFF-FX JBIG (T.82) MRC (T.43) */:
 | 
						|
	case 34715	/* TFX */:
 | 
						|
	    errint = (int) compression;
 | 
						|
	    errcode = PDF_E_TIFF_UNSUPP_COMPRESSION;
 | 
						|
	    goto PDF_TIFF_ERROR;
 | 
						|
	    break;
 | 
						|
 | 
						|
	default:
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Unsupported photometric values */
 | 
						|
    switch ((int) photometric)
 | 
						|
    {
 | 
						|
	case PHOTOMETRIC_ICCLAB /*  9 */:
 | 
						|
	case PHOTOMETRIC_ITULAB /* 10 */:
 | 
						|
	    errint = (int) photometric;
 | 
						|
	    errcode = PDF_E_TIFF_UNSUPP_COLORSPACE;
 | 
						|
	    goto PDF_TIFF_ERROR;
 | 
						|
	    break;
 | 
						|
 | 
						|
	default:
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
 | 
						|
    /* 32-bit images are not supported */
 | 
						|
    if (image->bpc > 16)
 | 
						|
    {
 | 
						|
	errcode = PDF_E_TIFF_16BIT_UNSUPP;
 | 
						|
	goto PDF_TIFF_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    /* We don't support 16-bit CMYK unless it's uncompressed */
 | 
						|
    if (image->bpc == 16 && components == 4 && compression != COMPRESSION_NONE)
 | 
						|
    {
 | 
						|
	errcode = PDF_E_TIFF_16BITCMYK_UNSUPP;
 | 
						|
	goto PDF_TIFF_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /* ------------------------------------------------------------
 | 
						|
     * We assume pass-through mode in the beginning, and disable it
 | 
						|
     * for image types where it doesn't work.
 | 
						|
     * ---------------------------------------------------------- */
 | 
						|
 | 
						|
    image->use_raw = image->passthrough;
 | 
						|
 | 
						|
    /* Pass-through is not implemented for tiled images */
 | 
						|
    if (TIFFIsTiled(MYTIFF))
 | 
						|
	image->use_raw = pdc_false;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /* Can't handle these colorspaces in raw mode (except with OJPEG) */
 | 
						|
    if (compression != COMPRESSION_OJPEG &&
 | 
						|
	(photometric == PHOTOMETRIC_YCBCR ||
 | 
						|
	photometric == PHOTOMETRIC_CIELAB ||
 | 
						|
	photometric == PHOTOMETRIC_MASK))
 | 
						|
    {
 | 
						|
	    image->use_raw = pdc_false;
 | 
						|
    }
 | 
						|
 | 
						|
    /* Can't pass through extra bits or use multiple data sources in raw mode
 | 
						|
     * (except with OJPEG).
 | 
						|
     */
 | 
						|
    if (extra != 0 ||
 | 
						|
       (compression != COMPRESSION_OJPEG &&
 | 
						|
        planarconfig == PLANARCONFIG_SEPARATE && components > 1))
 | 
						|
    {
 | 
						|
	image->components -= extra;	/* ignore the extra channels */
 | 
						|
	image->use_raw = pdc_false;
 | 
						|
    }
 | 
						|
 | 
						|
    /* PDF doesn't support other values of the color depth */
 | 
						|
    if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16)
 | 
						|
	image->use_raw = pdc_false;
 | 
						|
 | 
						|
    /* Disable pass-through for a large number of strips to avoid
 | 
						|
     * file size bloat (due to many small Image XObjects) and
 | 
						|
     * ugly display in Acrobat (because of banding artifacts).
 | 
						|
     * The threshold for the number of strips has been determined empirically
 | 
						|
     * as a good compromise between file size and performance.
 | 
						|
     *
 | 
						|
     * We must still maintain pass-through mode for those cases where it
 | 
						|
     * is functionally more advanced, and benefit from its better performance
 | 
						|
     * for small numbers of strips.
 | 
						|
     *
 | 
						|
     * Also, we maintain pass-through mode for very large images since
 | 
						|
     * pass-through mode - especially with pixel mode (RGBA retrieval) -
 | 
						|
     * may run out of memory.
 | 
						|
     */
 | 
						|
 | 
						|
/* ca. 10K x 10K pixels (nopassthrough requires up to 4 times as many bytes!) */
 | 
						|
#define PDF_TIFF_THRESHOLD  0x6000000
 | 
						|
 | 
						|
    strips = (int) TIFFNumberOfStrips(MYTIFF);
 | 
						|
 | 
						|
    if (strips > 25 &&
 | 
						|
	compression != COMPRESSION_OJPEG && compression != COMPRESSION_JPEG &&
 | 
						|
	photometric != PHOTOMETRIC_PALETTE &&
 | 
						|
	image->width * image->height < PDF_TIFF_THRESHOLD)
 | 
						|
    {
 | 
						|
	image->use_raw = pdc_false;
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->bpc == 16)
 | 
						|
    {
 | 
						|
	/* PDF < 1.5 doesn't support 16-bit images, so we cannot pass through */
 | 
						|
	if (p->compatibility < PDC_1_5)
 | 
						|
	{
 | 
						|
	    image->use_raw = pdc_false;
 | 
						|
	}
 | 
						|
 | 
						|
	/*
 | 
						|
	 * PDF requires big-endian 16-bit data. We therefore use passthrough
 | 
						|
	 * mode only for big-endian input or uncompressed data.
 | 
						|
	 *
 | 
						|
	 * It's not nice to pull the endianness directly from the TIFF
 | 
						|
	 * structure, but there doesn't seem to be a public interface for it.
 | 
						|
	 */
 | 
						|
	if (MYTIFF->tif_header.tiff_magic == TIFF_LITTLEENDIAN &&
 | 
						|
	    (compression == COMPRESSION_DEFLATE ||
 | 
						|
	    compression == COMPRESSION_ADOBE_DEFLATE))
 | 
						|
	{
 | 
						|
	    image->use_raw = pdc_false;
 | 
						|
	}
 | 
						|
 | 
						|
	/* We don't support 16-bit CMYK unless in passthrough mode.
 | 
						|
	 * Compressed images have already been rejected earlier.
 | 
						|
	 */
 | 
						|
	if (components == 4 && image->use_raw == pdc_false)
 | 
						|
	{
 | 
						|
	    errcode = PDF_E_TIFF_16BITCMYK_UNSUPP;
 | 
						|
	    goto PDF_TIFF_ERROR;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
     * Disable pass-through for unknown compression schemes,
 | 
						|
     * and collect the necessary parameters for well-known schemes.
 | 
						|
     */
 | 
						|
 | 
						|
    if (image->use_raw == pdc_true)
 | 
						|
    {
 | 
						|
	uint32 group3opts;
 | 
						|
	uint16 predictor;
 | 
						|
	toff_t jpegifoffset, jpegifbytecount;
 | 
						|
 | 
						|
        switch ((int) compression)
 | 
						|
        {
 | 
						|
            case COMPRESSION_CCITTRLE:
 | 
						|
            case COMPRESSION_CCITTRLEW:
 | 
						|
                image->params = (char *) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING,
 | 
						|
                    fn);
 | 
						|
 | 
						|
                strcpy(image->params, "/EndOfBlock false");
 | 
						|
                strcat(image->params, "/EncodedByteAlign true");
 | 
						|
 | 
						|
                if (photometric == PHOTOMETRIC_MINISBLACK)
 | 
						|
                    strcat(image->params, "/BlackIs1 true");
 | 
						|
 | 
						|
                image->compression = pdf_comp_ccitt;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_CCITTFAX3:
 | 
						|
                image->params = (char*) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING,
 | 
						|
                    fn);
 | 
						|
 | 
						|
                strcpy(image->params, "/EndOfBlock false");
 | 
						|
 | 
						|
                /* The following contains disabled code segments.
 | 
						|
                 * Apparently, and contrary to my reading of the specs,
 | 
						|
                 * the following can not be deduced from the respective
 | 
						|
                 * TIFF entry or option:
 | 
						|
                 * - /EncodedByteAlign can not reliably be deduced from
 | 
						|
                 *   GROUP3OPT_FILLBITS;
 | 
						|
                 *
 | 
						|
                 * From practical experience, the respective lines are
 | 
						|
                 * disabled, but I don't have any clear explanation for this.
 | 
						|
                 * A few TIFF images still don't work with this setting,
 | 
						|
                 * unfortunately.
 | 
						|
                 */
 | 
						|
 | 
						|
                /* SEE ABOVE!
 | 
						|
                strcat(image->params, "/DamagedRowsBeforeError 1");
 | 
						|
                */
 | 
						|
 | 
						|
                if (TIFFGetField(MYTIFF, TIFFTAG_GROUP3OPTIONS, &group3opts))
 | 
						|
                {
 | 
						|
                    /* /K = 0 (= G3,1D) is default */
 | 
						|
                    if (group3opts & GROUP3OPT_2DENCODING)
 | 
						|
                        strcat(image->params, "/K 1");
 | 
						|
 | 
						|
                    /* SEE ABOVE!
 | 
						|
                    if (group3opts & GROUP3OPT_FILLBITS)
 | 
						|
                        strcat(image->params, "/EncodedByteAlign true");
 | 
						|
                    */
 | 
						|
                }
 | 
						|
 | 
						|
                if (photometric == PHOTOMETRIC_MINISBLACK)
 | 
						|
                    strcat(image->params, "/BlackIs1 true");
 | 
						|
 | 
						|
                image->compression = pdf_comp_ccitt;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_CCITTFAX4:
 | 
						|
                image->params = (char*) pdc_malloc(p->pdc, PDF_MAX_PARAMSTRING,
 | 
						|
                                                   fn);
 | 
						|
 | 
						|
                strcpy(image->params, "/K -1");
 | 
						|
                /* Required for bug #511 */
 | 
						|
                strcat(image->params, "/EndOfBlock false");
 | 
						|
 | 
						|
                if (photometric == PHOTOMETRIC_MINISBLACK)
 | 
						|
                    strcat(image->params, "/BlackIs1 true");
 | 
						|
 | 
						|
                image->compression = pdf_comp_ccitt;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_OJPEG:
 | 
						|
                /*
 | 
						|
                 * Check whether a full-blown JPEG can be found inside the TIFF
 | 
						|
                 *
 | 
						|
                 * Heuristic:
 | 
						|
                 * If we find a positive JPEGIFOFFSET there should be valid
 | 
						|
                 * JFIF data; however, sometimes there isn't and we must not
 | 
						|
                 *call the JPEG module. Strangely enough, various creators which
 | 
						|
                 * do not emit valid JFIF do emit the JPEGIFBYTECOUNT tag.
 | 
						|
                 * Therefore we use the absence of JPEGIFBYTECOUNT as a hint
 | 
						|
                 * that JFIF processing might work.
 | 
						|
                 *
 | 
						|
                 * Known trouble-makers which include JPEGIFBYTECOUNT:
 | 
						|
                 * "Oi/GFS, writer v00.06.02"
 | 
						|
                 */
 | 
						|
                if (TIFFGetField(MYTIFF, TIFFTAG_JPEGIFOFFSET, &jpegifoffset) &&
 | 
						|
                    jpegifoffset != 0 &&
 | 
						|
                   !TIFFGetField(MYTIFF, TIFFTAG_JPEGIFBYTECOUNT,
 | 
						|
                                 &jpegifbytecount))
 | 
						|
                {
 | 
						|
                    /* stop TIFF processing */
 | 
						|
                    TIFFClose(MYTIFF);
 | 
						|
 | 
						|
                    /* store data offset for the JPEG module (after TIFFClose()
 | 
						|
                     * the image->info union is no longer used by the TIFF
 | 
						|
                     * module)
 | 
						|
                     */
 | 
						|
                    image->info.jpeg.jpegifoffset = jpegifoffset;
 | 
						|
 | 
						|
                    /* ...and process the data at the offset as JPEG */
 | 
						|
                    pdc_logg_cond(p->pdc, 1, trc_image,
 | 
						|
                        "\tTIFF with OJPEG: switching to JPEG processing...\n");
 | 
						|
                    return pdf_process_JPEG_data(p, imageslot);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    /* We must repeat the check here since we omitted the OJPEG
 | 
						|
                     * case when we applied the test for the first time.
 | 
						|
                     */
 | 
						|
                    if (extra != 0 ||
 | 
						|
                      (planarconfig == PLANARCONFIG_SEPARATE && components > 1))
 | 
						|
                    {
 | 
						|
                        /* ignore the extra channels */
 | 
						|
                        image->components -= extra;
 | 
						|
                    }
 | 
						|
                    image->use_raw = pdc_false;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_NONE:
 | 
						|
                if (photometric == PHOTOMETRIC_MINISWHITE)
 | 
						|
                    image->invert = !image->invert;
 | 
						|
 | 
						|
                image->compression = pdf_comp_none;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_LZW:
 | 
						|
                if (TIFFGetField(MYTIFF, TIFFTAG_PREDICTOR, &predictor)) {
 | 
						|
                    if (predictor != pred_default && predictor != pred_tiff) {
 | 
						|
                        image->use_raw = pdc_false;
 | 
						|
                        break;
 | 
						|
                    } else
 | 
						|
                        image->predictor = (pdf_predictor) predictor;
 | 
						|
                }
 | 
						|
 | 
						|
                if (photometric == PHOTOMETRIC_MINISWHITE)
 | 
						|
                    image->invert = !image->invert;
 | 
						|
 | 
						|
                image->compression = pdf_comp_lzw;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_PACKBITS:
 | 
						|
                if (photometric == PHOTOMETRIC_MINISWHITE)
 | 
						|
                    image->invert = !image->invert;
 | 
						|
 | 
						|
                image->compression = pdf_comp_runlength;
 | 
						|
                break;
 | 
						|
 | 
						|
            case COMPRESSION_DEFLATE:
 | 
						|
            case COMPRESSION_ADOBE_DEFLATE:
 | 
						|
                if (TIFFGetField(MYTIFF, TIFFTAG_PREDICTOR, &predictor)) {
 | 
						|
                    if (predictor != pred_default && predictor != pred_tiff) {
 | 
						|
                        image->use_raw = pdc_false;
 | 
						|
                        break;
 | 
						|
                    } else
 | 
						|
                        image->predictor = (pdf_predictor) predictor;
 | 
						|
                }
 | 
						|
 | 
						|
                if (photometric == PHOTOMETRIC_MINISWHITE)
 | 
						|
                    image->invert = !image->invert;
 | 
						|
 | 
						|
                image->compression = pdf_comp_flate;
 | 
						|
                break;
 | 
						|
 | 
						|
            default:
 | 
						|
                image->use_raw = pdc_false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->use_raw)
 | 
						|
    {
 | 
						|
	/* pass-through mode: directly copy chunks of strip data */
 | 
						|
	image->strips = strips;
 | 
						|
 | 
						|
	pdc_logg_cond(p->pdc, 1, trc_image, "\tpassthrough mode...\n");
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
	/* libtiff cannot handle JPEG-compressed TIFFs with separate image
 | 
						|
	 * planes
 | 
						|
	 */
 | 
						|
	if (planarconfig == PLANARCONFIG_SEPARATE &&
 | 
						|
	    (compression == COMPRESSION_OJPEG || compression==COMPRESSION_JPEG))
 | 
						|
	{
 | 
						|
	    errcode = PDF_E_TIFF_UNSUPP_SEPARATE;
 | 
						|
	    goto PDF_TIFF_ERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Fallback: use TIFFlib to retrieve pixel data */
 | 
						|
 | 
						|
	/* We have special handling for preserving bpc=1 if components=1,
 | 
						|
	 * and therefore don't change bpc in this case.
 | 
						|
	 */
 | 
						|
	if (!(image->components == 1 && image->bpc == 1))
 | 
						|
	{
 | 
						|
	    /* Retrieve pixel data with libtiff, which converts to 8 bits. */
 | 
						|
	    image->bpc = 8;
 | 
						|
	}
 | 
						|
 | 
						|
	image->strips = 1;
 | 
						|
        image->compression = pdf_comp_none;
 | 
						|
 | 
						|
	/* Palette images are automatically converted to RGB by TIFFlib.
 | 
						|
	 * Since there are actually 1-bit images (photometric=min-is-white)
 | 
						|
	 * with a palette out there (which are invalid TIFF, and are not
 | 
						|
	 * converted to RGB by TIFFlib) we must also check photometric.
 | 
						|
	 */
 | 
						|
	if (image->components == 1 && photometric == PHOTOMETRIC_PALETTE &&
 | 
						|
	    TIFFGetField(MYTIFF, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap))
 | 
						|
	{
 | 
						|
	    image->components = 3;
 | 
						|
	    image->bpc = 8;
 | 
						|
	}
 | 
						|
	pdc_logg_cond(p->pdc, 1, trc_image, "\tno passthrough mode...\n");
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->imagemask)
 | 
						|
    {
 | 
						|
	if (image->components != 1)
 | 
						|
        {
 | 
						|
	    errcode = PDF_E_IMAGE_BADMASK;
 | 
						|
	    goto PDF_TIFF_ERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	if (p->compatibility == PDC_1_3)
 | 
						|
        {
 | 
						|
	    if (image->components != 1 || image->bpc != 1)
 | 
						|
            {
 | 
						|
		errcode = PDF_E_IMAGE_MASK1BIT13;
 | 
						|
		goto PDF_TIFF_ERROR;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
        else if (image->bpc > 1)
 | 
						|
        {
 | 
						|
	    /* images with more than one bit will be written as /SMask,
 | 
						|
	     * and don't require an /ImageMask entry.
 | 
						|
	     */
 | 
						|
	    image->imagemask = pdc_false;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->mask != pdc_undef)
 | 
						|
    {
 | 
						|
        if (image->strips != 1)
 | 
						|
        {
 | 
						|
            errcode = PDF_E_TIFF_MASK_MULTISTRIP;
 | 
						|
            goto PDF_TIFF_ERROR;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->colorspace == pdc_undef)
 | 
						|
    {
 | 
						|
	uint16 inkset;
 | 
						|
 | 
						|
        switch (image->components)
 | 
						|
        {
 | 
						|
            case 1:
 | 
						|
                image->colorspace = DeviceGray;
 | 
						|
                break;
 | 
						|
 | 
						|
            case 3:
 | 
						|
		image->colorspace = DeviceRGB;
 | 
						|
                break;
 | 
						|
 | 
						|
            case 4:
 | 
						|
                if (photometric == PHOTOMETRIC_SEPARATED)
 | 
						|
                {
 | 
						|
		    /* Can't handle CMYK with mask */
 | 
						|
		    if (extra != 0)
 | 
						|
		    {
 | 
						|
			errint = image->components;
 | 
						|
			errcode = PDF_E_TIFF_CMYK_MASK;
 | 
						|
			goto PDF_TIFF_ERROR;
 | 
						|
		    }
 | 
						|
 | 
						|
                    TIFFGetFieldDefaulted(MYTIFF, TIFFTAG_INKSET, &inkset);
 | 
						|
                    if (inkset != INKSET_CMYK)
 | 
						|
                    {
 | 
						|
                        errint = inkset;
 | 
						|
                        errcode = PDF_E_TIFF_UNSUPP_SEP_NONCMYK;
 | 
						|
                        goto PDF_TIFF_ERROR;
 | 
						|
                    }
 | 
						|
                    image->colorspace = DeviceCMYK;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    /* if it's not separated it must be RGB with alpha */
 | 
						|
                    image->components = 3;
 | 
						|
                    image->colorspace = DeviceRGB;
 | 
						|
                    image->compression = pdf_comp_none;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
 | 
						|
            default:
 | 
						|
                errint = image->components;
 | 
						|
                errcode = PDF_E_IMAGE_BADCOMP;
 | 
						|
                goto PDF_TIFF_ERROR;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    image->src.private_data	= (void *) image;
 | 
						|
    image->src.init		= pdf_data_source_TIFF_init;
 | 
						|
    image->src.fill		= pdf_data_source_TIFF_fill;
 | 
						|
    image->src.terminate	= pdf_data_source_TIFF_terminate;
 | 
						|
    image->in_use = pdc_true;	/* mark slot as used */
 | 
						|
    image->src.next_byte        = NULL;
 | 
						|
 | 
						|
    if (image->use_raw) {
 | 
						|
	uint32 row, rowsperstrip;
 | 
						|
	int strip;
 | 
						|
 | 
						|
	/* must handle colormap ourselves */
 | 
						|
	if (photometric == PHOTOMETRIC_PALETTE)
 | 
						|
        {
 | 
						|
	    int i;
 | 
						|
	    pdf_colormap colormap;
 | 
						|
 | 
						|
	    if (!TIFFGetField(MYTIFF, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap))
 | 
						|
            {
 | 
						|
                errcode = PDF_E_IMAGE_COLORMAP;
 | 
						|
                goto PDF_TIFF_ERROR;
 | 
						|
	    }
 | 
						|
 | 
						|
	    /* CCITT compression implicitly carries 
 | 
						|
	     * photometric==PHOTOMETRIC_MINISWHITE. Although the combination
 | 
						|
	     * of CCITT compression and palette probably doesn't conform
 | 
						|
	     * to the TIFF spec, we accept it, but must invert the color
 | 
						|
	     * palette in order to match Acrobat's behavior.
 | 
						|
	     * Note that most TIFF viewers either ignore the palette in
 | 
						|
	     * this case or display the image with wrong colors.
 | 
						|
	     */
 | 
						|
	    if (compression == COMPRESSION_CCITTRLE ||
 | 
						|
		compression == COMPRESSION_CCITTRLEW ||
 | 
						|
		compression == COMPRESSION_CCITTFAX3 ||
 | 
						|
		compression == COMPRESSION_CCITTFAX4)
 | 
						|
	    {
 | 
						|
		image->invert = !image->invert;
 | 
						|
		pdc_logg_cond(p->pdc, 1, trc_image,
 | 
						|
		    "\tinverting colors for CCITT-compressed "
 | 
						|
		    "image with palette...\n");
 | 
						|
	    }
 | 
						|
 | 
						|
	    cs.type = Indexed;
 | 
						|
	    cs.val.indexed.palette_size = 1 << bpc;
 | 
						|
	    cs.val.indexed.colormap = &colormap;
 | 
						|
	    cs.val.indexed.colormap_id = PDC_BAD_ID;
 | 
						|
 | 
						|
	    cs.val.indexed.base = DeviceRGB;
 | 
						|
 | 
						|
#define CVT(x) (uint16) ((x)>>8)
 | 
						|
	    /* TODO: properly deal with 16-bit palette entries in PDF 1.5 */
 | 
						|
	    if (pdf_check_colormap(cs.val.indexed.palette_size,
 | 
						|
		rmap, gmap, bmap) == 16)
 | 
						|
	    {
 | 
						|
                /* convert colormap to 8 bit values  */
 | 
						|
		for (i = 0; i < cs.val.indexed.palette_size; i++)
 | 
						|
                {
 | 
						|
		    rmap[i] = CVT(rmap[i]);
 | 
						|
		    gmap[i] = CVT(gmap[i]);
 | 
						|
		    bmap[i] = CVT(bmap[i]);
 | 
						|
		}
 | 
						|
	    }
 | 
						|
#undef CVT
 | 
						|
 | 
						|
	    for (i = 0; i < cs.val.indexed.palette_size; i++)
 | 
						|
            {
 | 
						|
		colormap[i][0] = (pdc_byte) rmap[i];
 | 
						|
		colormap[i][1] = (pdc_byte) gmap[i];
 | 
						|
		colormap[i][2] = (pdc_byte) bmap[i];
 | 
						|
	    }
 | 
						|
 | 
						|
	    image->components = 1;
 | 
						|
 | 
						|
		slot = pdf_add_colorspace(p, &cs, pdc_false);
 | 
						|
		image->colorspace = slot;
 | 
						|
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	if (image->strips > image->height)
 | 
						|
	    image->strips = (int) image->height;
 | 
						|
 | 
						|
	if (TIFFGetFieldDefaulted(MYTIFF,
 | 
						|
	    TIFFTAG_ROWSPERSTRIP, &rowsperstrip) == 1 && (int)rowsperstrip!= -1)
 | 
						|
	    image->rowsperstrip = (int) rowsperstrip;
 | 
						|
	else
 | 
						|
	    image->rowsperstrip = (int) image->height;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * The first strip must be handled separately because it carries the
 | 
						|
	 * colormap for indexed images. Other strips reuse this colormap.
 | 
						|
	 */
 | 
						|
	image->info.tiff.cur_line = 0;
 | 
						|
        image->height = (pdc_scalar)
 | 
						|
	    (image->rowsperstrip > (int) height ?
 | 
						|
                                   (int) height : image->rowsperstrip);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Images may also be written to the output before the first page
 | 
						|
	 * We do this ourselves (instead of in pdf_put_image() to avoid
 | 
						|
	 * many empty contents sections for multi-strip images.
 | 
						|
	 */
 | 
						|
	if (PDF_GET_STATE(p) == pdf_state_page)
 | 
						|
	    pdf_end_contents_section(p);
 | 
						|
 | 
						|
	pdf_put_image(p, imageslot, pdc_true, pdc_false);
 | 
						|
 | 
						|
	for (row = (uint32) image->rowsperstrip, strip = 1;
 | 
						|
		row < height; row += (uint32) image->rowsperstrip, strip++)
 | 
						|
        {
 | 
						|
            image->height = (pdc_scalar) (row+image->rowsperstrip > height ?
 | 
						|
                                  (int) (height - row) : image->rowsperstrip);
 | 
						|
 | 
						|
	    /*
 | 
						|
	     * tell pdf_data_source_TIFF_fill() to read only data of the
 | 
						|
	     * current strip
 | 
						|
	     */
 | 
						|
	    image->info.tiff.cur_line = strip;
 | 
						|
	    pdf_put_image(p, imageslot, pdc_false, pdc_false);
 | 
						|
            /* Refresh, in case p->images reallocate */
 | 
						|
            image = &p->images[imageslot];
 | 
						|
	}
 | 
						|
 | 
						|
        image->height = (pdc_scalar) height;
 | 
						|
	image->no -= (image->strips - 1);	/* number of first strip */
 | 
						|
 | 
						|
	/* Special handling for multi-strip images (see comment above) */
 | 
						|
	if (PDF_GET_STATE(p) == pdf_state_page)
 | 
						|
	    pdf_begin_contents_section(p);
 | 
						|
 | 
						|
    }
 | 
						|
    else /* !use_raw */
 | 
						|
    {
 | 
						|
	size_t npixels;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Retrieve full scan lines from TIFFlib for these color spaces,
 | 
						|
	 * and Gray, RGB, or CMYK pixel data otherwise.
 | 
						|
	 */
 | 
						|
	if (p->colorspaces[image->colorspace].type == DeviceCMYK ||
 | 
						|
	    (p->colorspaces[image->colorspace].type == ICCBased &&
 | 
						|
		image->components == 4))
 | 
						|
	{
 | 
						|
	    pdc_logg_cond(p->pdc, 1, trc_image,
 | 
						|
		"\tRetrieving full scan lines in native color space...\n");
 | 
						|
	    image->pixelmode = pdc_false;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
	    pdc_logg_cond(p->pdc, 1, trc_image,
 | 
						|
		"\tRetrieving converted pixel data (pixel mode)...\n");
 | 
						|
	    image->pixelmode = pdc_true;
 | 
						|
	}
 | 
						|
 | 
						|
        if (planarconfig == PLANARCONFIG_SEPARATE)
 | 
						|
	{
 | 
						|
            errcode = PDF_E_TIFF_UNSUPP_SEPARATE;
 | 
						|
            goto PDF_TIFF_ERROR;
 | 
						|
        }
 | 
						|
	else if (image->pixelmode)
 | 
						|
	{
 | 
						|
	    npixels = (size_t) (width * height);
 | 
						|
 | 
						|
	    image->info.tiff.raster = (uint32 *) pdc_malloc(p->pdc,
 | 
						|
		(size_t) (npixels * sizeof (uint32)), fn);
 | 
						|
 | 
						|
	    if (!TIFFReadRGBAImageOriented(MYTIFF,
 | 
						|
		    width, height, image->info.tiff.raster, orientation, 1))
 | 
						|
            {
 | 
						|
                errcode = PDC_E_IO_READ;
 | 
						|
                goto PDF_TIFF_ERROR;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
        else
 | 
						|
        {
 | 
						|
	    int linecounter = 0, sclsize = TIFFScanlineSize(MYTIFF);
 | 
						|
 | 
						|
            npixels = (size_t) (sclsize * height);
 | 
						|
	    image->info.tiff.raster = (uint32 *)pdc_malloc(p->pdc, npixels, fn);
 | 
						|
 | 
						|
	    while (linecounter < (int) height)
 | 
						|
                {
 | 
						|
                    size_t ndots = (size_t)((height - linecounter - 1) * width);
 | 
						|
 | 
						|
                    if (npixels <= sizeof(uint32) * ndots)
 | 
						|
                    {
 | 
						|
                        errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
                        goto PDF_TIFF_ERROR;
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (TIFFReadScanline(MYTIFF,
 | 
						|
                        (tdata_t) (image->info.tiff.raster + ndots),
 | 
						|
                        (uint32) linecounter, (tsample_t) 0) == -1)
 | 
						|
                    {
 | 
						|
                        errcode = PDC_E_IO_READ;
 | 
						|
                        goto PDF_TIFF_ERROR;
 | 
						|
                    }
 | 
						|
                    linecounter++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
	pdf_put_image(p, imageslot, pdc_true, pdc_true);
 | 
						|
 | 
						|
        if (image->info.tiff.raster != NULL){
 | 
						|
	    pdc_free(p->pdc, (void *) image->info.tiff.raster);
 | 
						|
            image->info.tiff.raster = NULL;
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    if (!image->corrupt)
 | 
						|
    {
 | 
						|
        TIFFClose(MYTIFF);
 | 
						|
        return imageslot;
 | 
						|
    }
 | 
						|
 | 
						|
    PDF_TIFF_ERROR:
 | 
						|
    {
 | 
						|
        const char *stemp = NULL;
 | 
						|
 | 
						|
        if (errcode)
 | 
						|
            stemp = pdf_get_image_filename(p, image);
 | 
						|
 | 
						|
        if (image->info.tiff.raster != NULL)
 | 
						|
            pdc_free(p->pdc, (void *) image->info.tiff.raster);
 | 
						|
 | 
						|
        if (isopen)
 | 
						|
            TIFFClose(MYTIFF);
 | 
						|
 | 
						|
        switch (errcode)
 | 
						|
        {
 | 
						|
            case PDC_E_IO_READ:
 | 
						|
            case PDF_E_IMAGE_ICC:
 | 
						|
            case PDF_E_IMAGE_ICC2:
 | 
						|
            case PDF_E_IMAGE_MASK1BIT13:
 | 
						|
            case PDF_E_IMAGE_COLORIZE:
 | 
						|
            case PDF_E_TIFF_MASK_MULTISTRIP:
 | 
						|
            case PDF_E_IMAGE_COLORMAP:
 | 
						|
            case PDF_E_IMAGE_BADMASK:
 | 
						|
            case PDF_E_TIFF_CMYK_MASK:
 | 
						|
            case PDF_E_TIFF_UNSUPP_SEPARATE:
 | 
						|
            case PDF_E_TIFF_16BITCMYK_UNSUPP:
 | 
						|
            case PDF_E_TIFF_16BIT_UNSUPP:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDF_E_IMAGE_CORRUPT:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode, "TIFF", stemp, 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDF_E_TIFF_UNSUPP_COLORSPACE:
 | 
						|
            case PDF_E_TIFF_UNSUPP_COMPRESSION:
 | 
						|
            case PDF_E_IMAGE_BADCOMP:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode,
 | 
						|
		    pdc_errprintf(p->pdc, "%d", errint), stemp, 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDF_E_IMAGE_NOPAGE:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode,
 | 
						|
		    pdc_errprintf(p->pdc, "%d", errint), "TIFF", stemp, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDF_E_TIFF_UNSUPP_SEP_NONCMYK:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode,
 | 
						|
		    stemp, pdc_errprintf(p->pdc, "%d", errint), 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
	    case 0: 		/* error code and message already set */
 | 
						|
		break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
#undef MYTIFF
 | 
						|
#endif	/* HAVE_LIBTIFF */
 |