Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 650 git-svn-id: svn://10.65.10.50/trunk@14148 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			795 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			795 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*---------------------------------------------------------------------------*
 | 
						|
 |              PDFlib - A library for generating PDF on the fly             |
 | 
						|
 +---------------------------------------------------------------------------+
 | 
						|
 | Copyright (c) 1997-2005 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_bmp.c,v 1.2 2006-07-11 13:10:33 alex Exp $
 | 
						|
 *
 | 
						|
 * BMP processing for PDFlib
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#include "p_intern.h"
 | 
						|
#include "p_color.h"
 | 
						|
#include "p_image.h"
 | 
						|
 | 
						|
#ifndef PDF_BMP_SUPPORTED
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_is_BMP_file(PDF *p, pdc_file *fp)
 | 
						|
{
 | 
						|
    (void) p;
 | 
						|
    (void) fp;
 | 
						|
 | 
						|
    return pdc_false;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdf_process_BMP_data(
 | 
						|
    PDF *p,
 | 
						|
    int imageslot)
 | 
						|
{
 | 
						|
    (void) imageslot;
 | 
						|
 | 
						|
    pdc_warning(p->pdc, PDF_E_UNSUPP_IMAGE, "BMP", 0, 0, 0);
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
#else  /* !PDF_BMP_SUPPORTED */
 | 
						|
 | 
						|
/* for documentation only */
 | 
						|
#if 0
 | 
						|
 | 
						|
/* BMP file header structure */
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
    pdc_ushort  bfType;           /* Magic number for file */
 | 
						|
    pdc_uint32  bfSize;           /* Size of file */
 | 
						|
    pdc_ushort  bfReserved1;      /* Reserved */
 | 
						|
    pdc_ushort  bfReserved2;      /* ... */
 | 
						|
    pdc_uint32  bfOffBits;        /* Offset to bitmap data */
 | 
						|
}
 | 
						|
BITMAPFILEHEADER;
 | 
						|
 | 
						|
/* BMP file info structure */
 | 
						|
typedef struct
 | 
						|
{
 | 
						|
    pdc_uint32  biSize;           /* Size of info header */
 | 
						|
    pdc_sint32  biWidth;          /* Width of image */
 | 
						|
    pdc_sint32  biHeight;         /* Height of image */
 | 
						|
    pdc_ushort  biPlanes;         /* Number of color planes */
 | 
						|
    pdc_ushort  biBitCount;       /* Number of bits per pixel */
 | 
						|
    pdc_uint32  biCompression;    /* Type of compression to use */
 | 
						|
    pdc_uint32  biSizeImage;      /* Size of image data */
 | 
						|
    pdc_sint32  biXPelsPerMeter;  /* X pixels per meter */
 | 
						|
    pdc_sint32  biYPelsPerMeter;  /* Y pixels per meter */
 | 
						|
    pdc_uint32  biClrUsed;        /* Number of colors used */
 | 
						|
    pdc_uint32  biClrImportant;   /* Number of important colors */
 | 
						|
}
 | 
						|
BITMAPINFOHEADER;
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#define PDF_GET_BYTE(pos)   *pos,                   pos += sizeof(pdc_byte)
 | 
						|
#define PDF_GET_SHORT(pos)  pdc_get_le_short(pos),  pos += sizeof(pdc_short)
 | 
						|
#define PDF_GET_USHORT(pos) pdc_get_le_ushort(pos), pos += sizeof(pdc_ushort)
 | 
						|
#define PDF_GET_LONG(pos)   pdc_get_le_long(pos),   pos += sizeof(pdc_sint32)
 | 
						|
#define PDF_GET_ULONG(pos)  pdc_get_le_ulong(pos),  pos += sizeof(pdc_uint32)
 | 
						|
 | 
						|
#define PDF_BMP_STRING     "\102\115"   /* "BM" */
 | 
						|
 | 
						|
#define PDF_BMP_RGB                 0   /* No compression - straight BGR data */
 | 
						|
#define PDF_BMP_RLE8                1   /* 8-bit run-length compression */
 | 
						|
#define PDF_BMP_RLE4                2   /* 4-bit run-length compression */
 | 
						|
#define PDF_BMP_BITFIELDS           3   /* RGB bitmap with RGB masks */
 | 
						|
 | 
						|
#define PDF_BMP_FILE_HEADSIZE      14   /* File header size */
 | 
						|
#define PDF_BMP_INFO_HEAD2SIZE     12   /* Info header size BMP Version 2 */
 | 
						|
#define PDF_BMP_INFO_HEAD3SIZE     40   /* Info header size BMP Version 3 */
 | 
						|
#define PDF_BMP_INFO_HEAD4SIZE    108   /* Info header size BMP Version 4 */
 | 
						|
 | 
						|
static void
 | 
						|
pdf_data_source_BMP_init(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    static const char *fn = "pdf_data_source_BMP_init";
 | 
						|
    pdf_image *image = (pdf_image *) src->private_data;
 | 
						|
 | 
						|
    src->buffer_length = image->info.bmp.rowbytes_buf;
 | 
						|
    src->buffer_start = (pdc_byte *)
 | 
						|
        pdc_calloc(p->pdc, image->info.bmp.rowbytes_pad, fn);
 | 
						|
    src->bytes_available = image->info.bmp.rowbytes_pdf;
 | 
						|
    src->next_byte = src->buffer_start;
 | 
						|
}
 | 
						|
 | 
						|
static pdc_bool
 | 
						|
pdf_data_source_BMP_fill(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    pdf_image *image = (pdf_image *) src->private_data;
 | 
						|
    int i, j;
 | 
						|
 | 
						|
    if (image->info.bmp.bpp == 16)
 | 
						|
    {
 | 
						|
        if (image->info.bmp.pos < image->info.bmp.end)
 | 
						|
        {
 | 
						|
            pdc_ushort pixel, ppixel;
 | 
						|
            int ilast = image->info.bmp.rowbytes_buf - 3;
 | 
						|
 | 
						|
            i = 0;
 | 
						|
            for (j = 0; j < (int) image->info.bmp.rowbytes; j += 2)
 | 
						|
            {
 | 
						|
                pixel = PDF_GET_USHORT(image->info.bmp.pos);
 | 
						|
 | 
						|
                if (i <= ilast)
 | 
						|
                {
 | 
						|
                    ppixel = (pixel & image->info.bmp.redmask);
 | 
						|
                    ppixel = (ppixel >> image->info.bmp.redmove);
 | 
						|
                    src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                               image->info.bmp.redmax);
 | 
						|
                    i++;
 | 
						|
 | 
						|
                    ppixel = (pixel & image->info.bmp.greenmask);
 | 
						|
                    ppixel = (ppixel >> image->info.bmp.greenmove);
 | 
						|
                    src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                               image->info.bmp.greenmax);
 | 
						|
                    i++;
 | 
						|
 | 
						|
                    ppixel = (pixel & image->info.bmp.bluemask);
 | 
						|
                    ppixel = (ppixel >> image->info.bmp.bluemove);
 | 
						|
                    src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                               image->info.bmp.bluemax);
 | 
						|
                    i++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            src->bytes_available = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    else if (image->info.bmp.bpp == 32 ||
 | 
						|
             image->info.bmp.compression == PDF_BMP_RGB)
 | 
						|
    {
 | 
						|
        size_t avail;
 | 
						|
 | 
						|
        /* Read 1 padded row from file */
 | 
						|
        avail = pdc_fread(src->buffer_start, 1, image->info.bmp.rowbytes_pad,
 | 
						|
                          image->fp);
 | 
						|
        if (avail > 0)
 | 
						|
        {
 | 
						|
            /* Fill up remaining bytes */
 | 
						|
            if (avail < image->info.bmp.rowbytes_pad)
 | 
						|
            {
 | 
						|
                for (i = (int) avail; i < (int) src->buffer_length; i++)
 | 
						|
                    src->buffer_start[i] = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            if (image->colorspace == DeviceRGB)
 | 
						|
            {
 | 
						|
                /* Swap red and blue */
 | 
						|
                if (image->info.bmp.bpp == 32)
 | 
						|
                {
 | 
						|
                    pdc_uint32 pixel, ppixel;
 | 
						|
                    pdc_byte *pos = src->buffer_start;
 | 
						|
 | 
						|
                    i = 0;
 | 
						|
                    for (j = 0; j < (int) image->info.bmp.rowbytes_buf; j += 4)
 | 
						|
                    {
 | 
						|
                        pixel = PDF_GET_ULONG(pos);
 | 
						|
 | 
						|
                        ppixel = (pixel & image->info.bmp.redmask);
 | 
						|
                        ppixel = (ppixel >> image->info.bmp.redmove);
 | 
						|
                        src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                                   image->info.bmp.redmax);
 | 
						|
                        i++;
 | 
						|
 | 
						|
                        ppixel = (pixel & image->info.bmp.greenmask);
 | 
						|
                        ppixel = (ppixel >> image->info.bmp.greenmove);
 | 
						|
                        src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                                   image->info.bmp.greenmax);
 | 
						|
                        i++;
 | 
						|
 | 
						|
                        ppixel = (pixel & image->info.bmp.bluemask);
 | 
						|
                        ppixel = (ppixel >> image->info.bmp.bluemove);
 | 
						|
                        src->buffer_start[i] = (pdc_byte) ((ppixel * 255) /
 | 
						|
                                                   image->info.bmp.bluemax);
 | 
						|
                        i++;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    for (j = 0; j < (int) image->info.bmp.rowbytes_buf; j += 3)
 | 
						|
                    {
 | 
						|
                        pdc_byte c = src->buffer_start[j];
 | 
						|
                        src->buffer_start[j] = src->buffer_start[j + 2];
 | 
						|
                        src->buffer_start[j + 2] = c;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            src->bytes_available = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* Compression methods RLE8 and RLE4 */
 | 
						|
    else
 | 
						|
    {
 | 
						|
        int col = 0;
 | 
						|
        int fnibble = 1;
 | 
						|
        pdc_byte c, cc, ccc, cn[2], ccn;
 | 
						|
 | 
						|
        if (image->info.bmp.pos < image->info.bmp.end)
 | 
						|
        {
 | 
						|
            if (image->info.bmp.skiprows)
 | 
						|
            {
 | 
						|
                for (; col < (int) image->info.bmp.rowbytes; col++)
 | 
						|
                    src->buffer_start[col] = 0;
 | 
						|
                image->info.bmp.skiprows--;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                while (1)
 | 
						|
                {
 | 
						|
                    c = *image->info.bmp.pos;
 | 
						|
                    image->info.bmp.pos++;
 | 
						|
                    if (image->info.bmp.pos >= image->info.bmp.end)
 | 
						|
                        goto PDF_BMP_CORRUPT;
 | 
						|
                    cc = *image->info.bmp.pos;
 | 
						|
 | 
						|
                    if (c != 0)
 | 
						|
                    {
 | 
						|
                        /* Repeat c time pixel value */
 | 
						|
                        if (image->info.bmp.compression == PDF_BMP_RLE8)
 | 
						|
                        {
 | 
						|
                            for (i = 0; i < (int) c; i++)
 | 
						|
                            {
 | 
						|
                                if (col >= (int) image->info.bmp.rowbytes)
 | 
						|
                                    goto PDF_BMP_CORRUPT;
 | 
						|
                                src->buffer_start[col] = cc;
 | 
						|
                                col++;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            cn[0] = (pdc_byte) ((cc & 0xF0) >> 4);
 | 
						|
                            cn[1] = (pdc_byte) (cc & 0x0F);
 | 
						|
                            for (i = 0; i < (int) c; i++)
 | 
						|
                            {
 | 
						|
                                if (col >= (int) image->info.bmp.rowbytes)
 | 
						|
                                    goto PDF_BMP_CORRUPT;
 | 
						|
                                ccn = cn[i%2];
 | 
						|
                                if (fnibble)
 | 
						|
                                {
 | 
						|
                                    fnibble = 0;
 | 
						|
                                    src->buffer_start[col] =
 | 
						|
                                        (pdc_byte) (ccn << 4);
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    fnibble = 1;
 | 
						|
                                    src->buffer_start[col] |= ccn;
 | 
						|
                                    col++;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    else if (cc > 2)
 | 
						|
                    {
 | 
						|
                        /* cc different pixel values */
 | 
						|
                        if (image->info.bmp.compression == PDF_BMP_RLE8)
 | 
						|
                        {
 | 
						|
                            for (i = 0; i < (int) cc; i++)
 | 
						|
                            {
 | 
						|
                                image->info.bmp.pos++;
 | 
						|
                                if (image->info.bmp.pos >= image->info.bmp.end)
 | 
						|
                                    goto PDF_BMP_CORRUPT;
 | 
						|
                                if (col >= (int) image->info.bmp.rowbytes)
 | 
						|
                                    goto PDF_BMP_CORRUPT;
 | 
						|
                                src->buffer_start[col] = *image->info.bmp.pos;
 | 
						|
                                col++;
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            for (i = 0; i < (int) cc; i++)
 | 
						|
                            {
 | 
						|
                                if (!(i%2))
 | 
						|
                                {
 | 
						|
                                    image->info.bmp.pos++;
 | 
						|
                                    if (image->info.bmp.pos >=
 | 
						|
                                        image->info.bmp.end)
 | 
						|
                                        goto PDF_BMP_CORRUPT;
 | 
						|
                                    ccc = *image->info.bmp.pos;
 | 
						|
                                    cn[0] = (pdc_byte) ((ccc & 0xF0) >> 4);
 | 
						|
                                    cn[1] = (pdc_byte) (ccc & 0x0F);
 | 
						|
                                }
 | 
						|
                                if (col >= (int) image->info.bmp.rowbytes)
 | 
						|
                                    goto PDF_BMP_CORRUPT;
 | 
						|
                                ccn = cn[i%2];
 | 
						|
                                if (fnibble)
 | 
						|
                                {
 | 
						|
                                    fnibble = 0;
 | 
						|
                                    src->buffer_start[col] =
 | 
						|
                                        (pdc_byte) (ccn << 4);
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    fnibble = 1;
 | 
						|
                                    src->buffer_start[col] |= ccn;
 | 
						|
                                    col++;
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            if (cc % 2) cc++;
 | 
						|
                            cc /= 2;
 | 
						|
                        }
 | 
						|
 | 
						|
                        /* Odd number of bytes */
 | 
						|
                        if (cc % 2)
 | 
						|
                            image->info.bmp.pos++;
 | 
						|
                    }
 | 
						|
                    else if (cc < 2)
 | 
						|
                    {
 | 
						|
                        /* End of scan line or end of bitmap data*/
 | 
						|
                        for (; col < (int) image->info.bmp.rowbytes; col++)
 | 
						|
                            src->buffer_start[col] = 0;
 | 
						|
                    }
 | 
						|
                    else if (cc == 2)
 | 
						|
                    {
 | 
						|
                        int cola;
 | 
						|
 | 
						|
                        /* Run offset marker */
 | 
						|
                        if (image->info.bmp.pos >= image->info.bmp.end - 1)
 | 
						|
                            goto PDF_BMP_CORRUPT;
 | 
						|
                        image->info.bmp.pos++;
 | 
						|
                        c = *image->info.bmp.pos;
 | 
						|
                        image->info.bmp.pos++;
 | 
						|
                        cc = *image->info.bmp.pos;
 | 
						|
 | 
						|
                        /* Fill current row */
 | 
						|
                        cola = col;
 | 
						|
                        for (; col < (int) image->info.bmp.rowbytes; col++)
 | 
						|
                            src->buffer_start[col] = 0;
 | 
						|
                        if (col - cola != (int) c)
 | 
						|
                            goto PDF_BMP_CORRUPT;
 | 
						|
 | 
						|
                        /* Number of rows to be skipped */
 | 
						|
                        image->info.bmp.skiprows = (size_t) cc;
 | 
						|
                    }
 | 
						|
 | 
						|
                    image->info.bmp.pos++;
 | 
						|
                    if (col >= (int) image->info.bmp.rowbytes)
 | 
						|
                    {
 | 
						|
                        /* Skip end of scan line marker */
 | 
						|
                        if (image->info.bmp.pos < image->info.bmp.end - 1)
 | 
						|
                        {
 | 
						|
                            c = *image->info.bmp.pos;
 | 
						|
                            cc = *(image->info.bmp.pos + 1);
 | 
						|
                            if(cc == 0 && cc <= 1)
 | 
						|
                                image->info.bmp.pos += 2;
 | 
						|
                        }
 | 
						|
                        break;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            src->bytes_available = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return (src->bytes_available ? pdc_true : pdc_false);
 | 
						|
 | 
						|
    PDF_BMP_CORRUPT:
 | 
						|
    pdc_error(p->pdc, PDF_E_IMAGE_CORRUPT, "BMP",
 | 
						|
        pdc_errprintf(p->pdc, "%.*s", PDC_ET_MAXSTRLEN, image->filename), 0, 0);
 | 
						|
    src->bytes_available = 0;
 | 
						|
    return pdc_false;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
pdf_data_source_BMP_terminate(PDF *p, PDF_data_source *src)
 | 
						|
{
 | 
						|
    pdf_image *image = (pdf_image *) src->private_data;
 | 
						|
 | 
						|
    pdc_free(p->pdc, (void *) src->buffer_start);
 | 
						|
    if (image->info.bmp.bitmap != NULL)
 | 
						|
        pdc_free(p->pdc, (void *) image->info.bmp.bitmap);
 | 
						|
}
 | 
						|
 | 
						|
pdc_bool
 | 
						|
pdf_is_BMP_file(PDF *p, pdc_file *fp)
 | 
						|
{
 | 
						|
    pdc_byte buf[2];
 | 
						|
 | 
						|
    pdc_trace_protocol(p->pdc, 1, trc_image, "\tChecking image type BMP...\n");
 | 
						|
 | 
						|
    if (pdc_fread(buf, 1, 2, fp) < 2 ||
 | 
						|
        strncmp((const char *) buf, PDF_BMP_STRING, 2) != 0)
 | 
						|
    {
 | 
						|
        pdc_fseek(fp, 0L, SEEK_SET);
 | 
						|
        return pdc_false;
 | 
						|
    }
 | 
						|
    return pdc_true;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
pdf_process_BMP_data(
 | 
						|
    PDF *p,
 | 
						|
    int imageslot)
 | 
						|
{
 | 
						|
    static const char *fn = "pdf_process_BMP_data";
 | 
						|
    pdc_byte buf[256], *pos, *cmap, bdummy;
 | 
						|
    pdf_image *image = &p->images[imageslot];
 | 
						|
    pdc_file *fp = image->fp;
 | 
						|
    pdc_uint32 uldummy, infosize = 0, offras = 0, planes = 0, bitmapsize = 0;
 | 
						|
    pdc_uint32 ncolors = 0, importcolors = 0, compression = PDF_BMP_RGB;
 | 
						|
    pdc_ushort usdummy, bpp = 0, bpp_pdf = 0;
 | 
						|
    pdc_sint32 width = 0, height = 0, dpi_x = 0, dpi_y = 0;
 | 
						|
    pdc_uint32 redmask = 0, greenmask = 0, bluemask = 0, ccmax;
 | 
						|
    size_t nbytes;
 | 
						|
    pdf_colorspace cs;
 | 
						|
    pdf_colormap colormap;
 | 
						|
    int i, slot, colsize = 0, errcode = 0;
 | 
						|
 | 
						|
    /* Error reading magic number or not a BMP file */
 | 
						|
    if (pdf_is_BMP_file(p, image->fp) == pdc_false)
 | 
						|
    {
 | 
						|
        errcode = PDC_E_IO_BADFORMAT;
 | 
						|
        goto PDF_BMP_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    /* read file header without FileType field + */
 | 
						|
    /* Size field of info header */
 | 
						|
    pos = &buf[2];
 | 
						|
    nbytes = PDF_BMP_FILE_HEADSIZE - 2 + 4;
 | 
						|
    if (!PDC_OK_FREAD(fp, pos, nbytes))
 | 
						|
    {
 | 
						|
        errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
        goto PDF_BMP_ERROR;
 | 
						|
    }
 | 
						|
    uldummy = PDF_GET_ULONG(pos);
 | 
						|
    usdummy = PDF_GET_USHORT(pos);
 | 
						|
    usdummy = PDF_GET_USHORT(pos);
 | 
						|
    offras = PDF_GET_ULONG(pos);
 | 
						|
    infosize = PDF_GET_ULONG(pos);
 | 
						|
 | 
						|
    /* no support of later version than 3 */
 | 
						|
    if (infosize != PDF_BMP_INFO_HEAD2SIZE &&
 | 
						|
        infosize != PDF_BMP_INFO_HEAD3SIZE)
 | 
						|
    {
 | 
						|
        errcode = PDF_E_BMP_VERSUNSUPP;
 | 
						|
        goto PDF_BMP_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    /* info header */
 | 
						|
    pos = buf;
 | 
						|
    nbytes = infosize - 4;
 | 
						|
    if (!PDC_OK_FREAD(fp, pos, nbytes))
 | 
						|
    {
 | 
						|
        errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
        goto PDF_BMP_ERROR;
 | 
						|
    }
 | 
						|
    if (infosize == PDF_BMP_INFO_HEAD2SIZE)
 | 
						|
    {
 | 
						|
        width = PDF_GET_SHORT(pos);
 | 
						|
        height = PDF_GET_SHORT(pos);
 | 
						|
        planes = PDF_GET_USHORT(pos);
 | 
						|
        bpp = PDF_GET_USHORT(pos);
 | 
						|
        colsize = 3;
 | 
						|
    }
 | 
						|
    else if (infosize == PDF_BMP_INFO_HEAD3SIZE)
 | 
						|
    {
 | 
						|
        width = PDF_GET_LONG(pos);
 | 
						|
        height = PDF_GET_LONG(pos);
 | 
						|
        planes = PDF_GET_USHORT(pos);
 | 
						|
        bpp = PDF_GET_USHORT(pos);
 | 
						|
        compression = PDF_GET_ULONG(pos);
 | 
						|
        bitmapsize = PDF_GET_ULONG(pos);
 | 
						|
        dpi_x = PDF_GET_LONG(pos);
 | 
						|
        dpi_y = PDF_GET_LONG(pos);
 | 
						|
        ncolors = PDF_GET_ULONG(pos);
 | 
						|
        importcolors = PDF_GET_ULONG(pos);
 | 
						|
        colsize = 4;
 | 
						|
    }
 | 
						|
 | 
						|
    /* compressed BMP images by bitfields */
 | 
						|
    if (compression == PDF_BMP_BITFIELDS)
 | 
						|
    {
 | 
						|
        pos = buf;
 | 
						|
        nbytes = 3 * sizeof(pdc_uint32);
 | 
						|
        if (!PDC_OK_FREAD(fp, pos, nbytes))
 | 
						|
        {
 | 
						|
            errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
            goto PDF_BMP_ERROR;
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            redmask = PDF_GET_ULONG(pos);
 | 
						|
            greenmask = PDF_GET_ULONG(pos);
 | 
						|
            bluemask = PDF_GET_ULONG(pos);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    pdc_trace_protocol(p->pdc, 5, trc_image,
 | 
						|
                       "\t\t\tinfosize = %d\n"
 | 
						|
                       "\t\t\twidth = %d\n"
 | 
						|
                       "\t\t\theight = %d\n"
 | 
						|
                       "\t\t\tplanes = %d\n"
 | 
						|
                       "\t\t\tbpp = %d\n"
 | 
						|
                       "\t\t\tcompression = %d\n"
 | 
						|
                       "\t\t\tbitmapsize = %d\n"
 | 
						|
                       "\t\t\tdpi_x = %d\n"
 | 
						|
                       "\t\t\tdpi_y = %d\n"
 | 
						|
                       "\t\t\tncolors = %d\n"
 | 
						|
                       "\t\t\timportcolors = %d\n"
 | 
						|
                       "\t\t\tcolsize = %d\n"
 | 
						|
                       "\t\t\tredmask   = 0x%08X\n"
 | 
						|
                       "\t\t\tgreenmask = 0x%08X\n"
 | 
						|
                       "\t\t\tbluemask  = 0x%08X\n",
 | 
						|
                       infosize, width, height, planes, bpp, compression,
 | 
						|
                       bitmapsize, dpi_x, dpi_y, ncolors, importcolors,
 | 
						|
                       colsize, redmask, greenmask, bluemask);
 | 
						|
 | 
						|
    image->bpc = bpp;
 | 
						|
    image->width = width;
 | 
						|
    image->height = -height;
 | 
						|
    image->dpi_x = (pdc_scalar) (PDC_INCH2METER * dpi_x);
 | 
						|
    image->dpi_y = (pdc_scalar) (PDC_INCH2METER * dpi_y);
 | 
						|
    image->info.bmp.bpp = bpp;
 | 
						|
    bpp_pdf = bpp;
 | 
						|
 | 
						|
    /* color map only for bpp = 1, 4, 8 */
 | 
						|
    if (bpp < 16)
 | 
						|
    {
 | 
						|
        if (!ncolors)
 | 
						|
            ncolors = (pdc_uint32) (1 << bpp);
 | 
						|
        if (ncolors > (offras - PDF_BMP_FILE_HEADSIZE - infosize) / colsize)
 | 
						|
        {
 | 
						|
            errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
            goto PDF_BMP_ERROR;
 | 
						|
        }
 | 
						|
 | 
						|
        /* allocate and read color map */
 | 
						|
        nbytes = colsize * ncolors;
 | 
						|
        cmap = (pdc_byte *) pdc_malloc(p->pdc, nbytes, fn);
 | 
						|
        if (!PDC_OK_FREAD(fp, cmap, nbytes))
 | 
						|
        {
 | 
						|
            errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
            goto PDF_BMP_ERROR;
 | 
						|
        }
 | 
						|
 | 
						|
        /* set color map (bgr) */
 | 
						|
        pos = cmap;
 | 
						|
        for (i = 0; i < (int) ncolors; i++)
 | 
						|
        {
 | 
						|
            colormap[i][2] = PDF_GET_BYTE(pos);
 | 
						|
            colormap[i][1] = PDF_GET_BYTE(pos);
 | 
						|
            colormap[i][0] = PDF_GET_BYTE(pos);
 | 
						|
            if (infosize == PDF_BMP_INFO_HEAD3SIZE)
 | 
						|
            {
 | 
						|
                bdummy = PDF_GET_BYTE(pos);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        pdc_free(p->pdc, cmap);
 | 
						|
 | 
						|
        pdc_trace_protocol(p->pdc, 5, trc_image,
 | 
						|
                           "\t\t\tcolor map with %d colors generated\n",
 | 
						|
                           ncolors);
 | 
						|
 | 
						|
        image->components = 1;
 | 
						|
 | 
						|
	    cs.type = Indexed;
 | 
						|
	    cs.val.indexed.base = DeviceRGB;
 | 
						|
	    cs.val.indexed.palette_size = (int) ncolors;
 | 
						|
	    cs.val.indexed.colormap = &colormap;
 | 
						|
	    cs.val.indexed.colormap_id = PDC_BAD_ID;
 | 
						|
	    slot = pdf_add_colorspace(p, &cs, pdc_false);
 | 
						|
 | 
						|
	    image->colorspace = (pdf_colorspacetype) slot;
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        image->colorspace = DeviceRGB;
 | 
						|
        image->components = 3;
 | 
						|
        image->bpc = 8;
 | 
						|
        if (bpp == 16)
 | 
						|
        {
 | 
						|
            bpp = 24;
 | 
						|
            bpp_pdf = 24;
 | 
						|
            if (compression == PDF_BMP_RGB)
 | 
						|
            {
 | 
						|
                redmask   = 0x00007C00;
 | 
						|
                greenmask = 0x000003E0;
 | 
						|
                bluemask  = 0x0000001F;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        if (bpp == 32)
 | 
						|
        {
 | 
						|
            bpp_pdf = 24;
 | 
						|
            if (compression == PDF_BMP_RGB)
 | 
						|
            {
 | 
						|
                redmask   = 0x00FF0000;
 | 
						|
                greenmask = 0x0000FF00;
 | 
						|
                bluemask  = 0x000000FF;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /* maximum and movement */
 | 
						|
        if (image->info.bmp.bpp != 24)
 | 
						|
        {
 | 
						|
            for (i = 0; i < 32; i++)
 | 
						|
            {
 | 
						|
                ccmax = (redmask >> i);
 | 
						|
                if (ccmax & 0x00000001)
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
            image->info.bmp.redmask = redmask;
 | 
						|
            image->info.bmp.redmax = ccmax;
 | 
						|
            image->info.bmp.redmove = i;
 | 
						|
 | 
						|
 | 
						|
            for (i = 0; i < 32; i++)
 | 
						|
            {
 | 
						|
                ccmax = (greenmask >> i);
 | 
						|
                if (ccmax & 0x00000001)
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
            image->info.bmp.greenmask = greenmask;
 | 
						|
            image->info.bmp.greenmax = ccmax;
 | 
						|
            image->info.bmp.greenmove = i;
 | 
						|
 | 
						|
            for (i = 0; i < 32; i++)
 | 
						|
            {
 | 
						|
                ccmax = (bluemask >> i);
 | 
						|
                if (ccmax & 0x00000001)
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
            image->info.bmp.bluemask = bluemask;
 | 
						|
            image->info.bmp.bluemax = ccmax;
 | 
						|
            image->info.bmp.bluemove = i;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->imagemask)
 | 
						|
    {
 | 
						|
	if (image->components != 1) {
 | 
						|
	    errcode = PDF_E_IMAGE_BADMASK;
 | 
						|
	    goto PDF_BMP_ERROR;
 | 
						|
	}
 | 
						|
 | 
						|
        if (p->compatibility <= PDC_1_3) {
 | 
						|
            if (image->components != 1 || image->bpc != 1) {
 | 
						|
                errcode = PDF_E_IMAGE_MASK1BIT13;
 | 
						|
                goto PDF_BMP_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;
 | 
						|
        }
 | 
						|
        image->colorspace = DeviceGray;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /* we invert this flag later */
 | 
						|
    if (image->ignoremask)
 | 
						|
        image->transparent = pdc_true;
 | 
						|
 | 
						|
    /* number of bytes per row  */
 | 
						|
    image->info.bmp.rowbytes_pdf = (size_t) ((bpp_pdf * width + 7) / 8);
 | 
						|
    image->info.bmp.rowbytes_buf = (size_t) ((bpp * width + 7) / 8);
 | 
						|
    if (bpp == 4)
 | 
						|
        image->info.bmp.rowbytes = image->info.bmp.rowbytes_buf;
 | 
						|
    else if (image->info.bmp.bpp == 16)
 | 
						|
        image->info.bmp.rowbytes =
 | 
						|
                   (size_t) (4 * ((image->info.bmp.bpp * width + 31) / 32));
 | 
						|
    else
 | 
						|
        image->info.bmp.rowbytes = (size_t) ((bpp * width) / 8);
 | 
						|
    image->info.bmp.rowbytes_pad = (size_t) (4 * ((bpp * width + 31) / 32));
 | 
						|
    image->info.bmp.compression = compression;
 | 
						|
    image->info.bmp.skiprows = 0;
 | 
						|
    image->info.bmp.bitmap = NULL;
 | 
						|
 | 
						|
    pdc_trace_protocol(p->pdc, 5, trc_image,
 | 
						|
                       "\t\t\tinternal variables:\n"
 | 
						|
                       "\t\t\t\tbpp_pdf = %d\n"
 | 
						|
                       "\t\t\t\trowbytes = %d\n"
 | 
						|
                       "\t\t\t\trowbytes_buf = %d\n"
 | 
						|
                       "\t\t\t\trowbytes_pdf = %d\n"
 | 
						|
                       "\t\t\t\trowbytes_pad = %d\n",
 | 
						|
    bpp_pdf, image->info.bmp.rowbytes, image->info.bmp.rowbytes_buf,
 | 
						|
    image->info.bmp.rowbytes_pdf, image->info.bmp.rowbytes_pad);
 | 
						|
 | 
						|
    /* read whole bitmap */
 | 
						|
    if (image->info.bmp.bpp < 24 && (image->info.bmp.bpp == 16 ||
 | 
						|
        image->info.bmp.compression != PDF_BMP_RGB))
 | 
						|
    {
 | 
						|
        if (!bitmapsize)
 | 
						|
        {
 | 
						|
            bitmapsize = (int) (pdc_file_size(fp) - pdc_ftell(fp));
 | 
						|
            pdc_trace_protocol(p->pdc, 5, trc_image,
 | 
						|
                               "\t\t\tcalculated bitmapsize = %d\n",
 | 
						|
                               bitmapsize);
 | 
						|
        }
 | 
						|
 | 
						|
        image->info.bmp.bitmap =
 | 
						|
            (pdc_byte *) pdc_malloc(p->pdc, bitmapsize, fn);
 | 
						|
        if (!PDC_OK_FREAD(fp, image->info.bmp.bitmap, bitmapsize))
 | 
						|
        {
 | 
						|
            pdc_free(p->pdc, (void *) image->info.bmp.bitmap);
 | 
						|
            errcode = PDF_E_IMAGE_CORRUPT;
 | 
						|
            goto PDF_BMP_ERROR;
 | 
						|
        }
 | 
						|
        image->info.bmp.pos = image->info.bmp.bitmap;
 | 
						|
        image->info.bmp.end = image->info.bmp.bitmap + bitmapsize;
 | 
						|
    }
 | 
						|
 | 
						|
#if 0
 | 
						|
if (image->info.bmp.bpp == 16)
 | 
						|
goto PDF_BMP_ERROR;
 | 
						|
#endif
 | 
						|
 | 
						|
    /* offset bitmap data */
 | 
						|
    pdc_fseek(image->fp, (pdc_sint32) offras, SEEK_SET);
 | 
						|
 | 
						|
    /* put image data */
 | 
						|
    image->src.init = pdf_data_source_BMP_init;
 | 
						|
    image->src.fill = pdf_data_source_BMP_fill;
 | 
						|
    image->src.terminate = pdf_data_source_BMP_terminate;
 | 
						|
    image->src.private_data  = (void *) image;
 | 
						|
 | 
						|
    image->use_raw = pdc_false;
 | 
						|
    image->in_use = pdc_true;
 | 
						|
 | 
						|
    pdf_put_image(p, imageslot, pdc_true, pdc_true);
 | 
						|
 | 
						|
    return imageslot;
 | 
						|
 | 
						|
    PDF_BMP_ERROR:
 | 
						|
    {
 | 
						|
        const char *stemp =
 | 
						|
            pdc_errprintf(p->pdc, "%.*s", PDC_ET_MAXSTRLEN, image->filename);
 | 
						|
        switch (errcode)
 | 
						|
        {
 | 
						|
            case PDF_E_IMAGE_MASK1BIT13:
 | 
						|
            case PDF_E_BMP_VERSUNSUPP:
 | 
						|
            case PDF_E_BMP_COMPUNSUPP:
 | 
						|
            case PDF_E_IMAGE_BADMASK:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode, stemp, 0, 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDC_E_IO_BADFORMAT:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode, stemp, "BMP", 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
            case PDF_E_IMAGE_CORRUPT:
 | 
						|
		pdc_set_errmsg(p->pdc, errcode, "BMP", stemp, 0, 0);
 | 
						|
		break;
 | 
						|
 | 
						|
	    case 0: 		/* error code and message already set */
 | 
						|
		break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (image->verbose)
 | 
						|
	pdc_error(p->pdc, -1, 0, 0, 0, 0);
 | 
						|
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* PDF_BMP_SUPPORTED */
 | 
						|
 |