diff options
Diffstat (limited to 'tiff/tools/tiff2pdf.c')
-rw-r--r-- | tiff/tools/tiff2pdf.c | 409 |
1 files changed, 259 insertions, 150 deletions
diff --git a/tiff/tools/tiff2pdf.c b/tiff/tools/tiff2pdf.c index 779c1662..acaef0d6 100644 --- a/tiff/tools/tiff2pdf.c +++ b/tiff/tools/tiff2pdf.c @@ -70,6 +70,8 @@ extern int getopt(int argc, char * const argv[], const char *optstring); #define TIFF_DIR_MAX 65534 +#define DEFAULT_MAX_MALLOC (256 * 1024 * 1024) + /* This type is of PDF color spaces. */ typedef enum { T2P_CS_BILEVEL = 0x01, /* Bilevel, black and white */ @@ -176,6 +178,7 @@ typedef struct { uint16 tiff_orientation; toff_t tiff_dataoffset; tsize_t tiff_datasize; + tsize_t tiff_maxdatasize; uint16 tiff_resunit; uint16 pdf_centimeters; uint16 pdf_overrideres; @@ -207,14 +210,19 @@ typedef struct { char pdf_datetime[TIFF2PDF_DATETIME_SIZE]; #define TIFF2PDF_CREATOR_SIZE 512 char pdf_creator[TIFF2PDF_CREATOR_SIZE]; + int pdf_creator_set; #define TIFF2PDF_AUTHOR_SIZE 512 char pdf_author[TIFF2PDF_AUTHOR_SIZE]; + int pdf_author_set; #define TIFF2PDF_TITLE_SIZE 512 char pdf_title[TIFF2PDF_TITLE_SIZE]; + int pdf_title_set; #define TIFF2PDF_SUBJECT_SIZE 512 char pdf_subject[TIFF2PDF_SUBJECT_SIZE]; + int pdf_subject_set; #define TIFF2PDF_KEYWORDS_SIZE 512 char pdf_keywords[TIFF2PDF_KEYWORDS_SIZE]; + int pdf_keywords_set; t2p_cs_t pdf_colorspace; uint16 pdf_colorspace_invert; uint16 pdf_switchdecode; @@ -224,7 +232,7 @@ typedef struct { t2p_compress_t pdf_defaultcompression; uint16 pdf_defaultcompressionquality; t2p_compress_t pdf_compression; - uint16 pdf_compressionquality; + uint16 pdf_compressionquality; /* for deflate : 100 * zipquality + predictor */ uint16 pdf_nopassthrough; t2p_transcode_t pdf_transcode; t2p_sample_t pdf_sample; @@ -255,7 +263,7 @@ typedef struct { /* These functions are called by main. */ -void tiff2pdf_usage(void); +static void tiff2pdf_usage(int); int tiff2pdf_match_paper_size(float*, float*, char*); /* These functions are used to generate a PDF from a TIFF. */ @@ -301,8 +309,8 @@ tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t, uint32); tsize_t t2p_write_pdf_header(T2P*, TIFF*); tsize_t t2p_write_pdf_obj_start(uint32, TIFF*); tsize_t t2p_write_pdf_obj_end(TIFF*); -tsize_t t2p_write_pdf_name(unsigned char*, TIFF*); -tsize_t t2p_write_pdf_string(char*, TIFF*); +tsize_t t2p_write_pdf_name(const unsigned char*, TIFF*); +tsize_t t2p_write_pdf_string(const char*, TIFF*); tsize_t t2p_write_pdf_stream(tdata_t, tsize_t, TIFF*); tsize_t t2p_write_pdf_stream_start(TIFF*); tsize_t t2p_write_pdf_stream_end(TIFF*); @@ -617,8 +625,11 @@ int main(int argc, char** argv){ while (argv && (c = getopt(argc, argv, - "o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){ + "m:o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){ switch (c) { + case 'm': + t2p->tiff_maxdatasize = (tsize_t)strtoul(optarg, NULL, 0) << 20; + break; case 'o': outfilename = optarg; break; @@ -718,31 +729,37 @@ int main(int argc, char** argv){ case 'c': strncpy(t2p->pdf_creator, optarg, sizeof(t2p->pdf_creator) - 1); t2p->pdf_creator[sizeof(t2p->pdf_creator) - 1] = '\0'; + t2p->pdf_creator_set = 1; break; case 'a': strncpy(t2p->pdf_author, optarg, sizeof(t2p->pdf_author) - 1); t2p->pdf_author[sizeof(t2p->pdf_author) - 1] = '\0'; + t2p->pdf_author_set = 1; break; case 't': strncpy(t2p->pdf_title, optarg, sizeof(t2p->pdf_title) - 1); t2p->pdf_title[sizeof(t2p->pdf_title) - 1] = '\0'; + t2p->pdf_title_set = 1; break; case 's': strncpy(t2p->pdf_subject, optarg, sizeof(t2p->pdf_subject) - 1); t2p->pdf_subject[sizeof(t2p->pdf_subject) - 1] = '\0'; + t2p->pdf_subject_set = 1; break; case 'k': strncpy(t2p->pdf_keywords, optarg, sizeof(t2p->pdf_keywords) - 1); t2p->pdf_keywords[sizeof(t2p->pdf_keywords) - 1] = '\0'; + t2p->pdf_keywords_set = 1; break; case 'b': t2p->pdf_image_interpolate = 1; break; - case 'h': - case '?': - tiff2pdf_usage(); + case 'h': + tiff2pdf_usage(EXIT_SUCCESS); goto success; - break; + case '?': + tiff2pdf_usage(EXIT_FAILURE); + goto fail; } } @@ -759,14 +776,14 @@ int main(int argc, char** argv){ } } else { TIFFError(TIFF2PDF_MODULE, "No input file specified"); - tiff2pdf_usage(); + tiff2pdf_usage(EXIT_FAILURE); goto fail; } if(argc > optind) { TIFFError(TIFF2PDF_MODULE, "No support for multiple input files"); - tiff2pdf_usage(); + tiff2pdf_usage(EXIT_FAILURE); goto fail; } @@ -828,8 +845,8 @@ success: } -void tiff2pdf_usage(){ - char* lines[]={ +static void tiff2pdf_usage(int code) { + static const char* lines[]={ "usage: tiff2pdf [options] input.tiff", "options:", " -o: output to file name", @@ -850,7 +867,7 @@ void tiff2pdf_usage(){ " -l: length in units", " -r: 'd' for resolution default, 'o' for resolution override", " -p: paper size, eg \"letter\", \"legal\", \"A4\"", - " -F: make the tiff fill the PDF page", + " -F: make the tiff fill the PDF page", " -f: set PDF \"Fit Window\" user preference", " -e: date, overrides image or current date/time default, YYYYMMDDHHMMSS", " -c: sets document creator, overrides image software default", @@ -859,14 +876,16 @@ void tiff2pdf_usage(){ " -s: sets document subject, overrides image image description default", " -k: sets document keywords", " -b: set PDF \"Interpolate\" user preference", + " -m: set memory allocation limit (in MiB). set to 0 to disable limit", " -h: usage", NULL }; int i=0; + FILE * out = (code == EXIT_SUCCESS) ? stdout : stderr; - fprintf(stderr, "%s\n\n", TIFFGetVersion()); + fprintf(out, "%s\n\n", TIFFGetVersion()); for (i=0;lines[i]!=NULL;i++){ - fprintf(stderr, "%s\n", lines[i]); + fprintf(out, "%s\n", lines[i]); } return; @@ -954,6 +973,7 @@ T2P* t2p_init() t2p->pdf_defaultpagewidth=612.0; t2p->pdf_defaultpagelength=792.0; t2p->pdf_xrefcount=3; /* Catalog, Info, Pages */ + t2p->tiff_maxdatasize = DEFAULT_MAX_MALLOC; return(t2p); } @@ -1012,14 +1032,14 @@ void t2p_validate(T2P* t2p){ #endif #ifdef ZIP_SUPPORT if(t2p->pdf_defaultcompression==T2P_COMPRESS_ZIP){ - uint16 m=t2p->pdf_defaultcompressionquality%100; - if(t2p->pdf_defaultcompressionquality/100 > 9 || - (m>1 && m<10) || m>15){ - t2p->pdf_defaultcompressionquality=0; + uint16 m=t2p->pdf_defaultcompressionquality%100; + if(t2p->pdf_defaultcompressionquality/100 > 9 || + (m>1 && m<10) || m>15){ + t2p->pdf_defaultcompressionquality=0; } if(t2p->pdf_defaultcompressionquality%100 !=0){ - t2p->pdf_defaultcompressionquality/=100; - t2p->pdf_defaultcompressionquality*=100; + t2p->pdf_defaultcompressionquality/=100; + t2p->pdf_defaultcompressionquality*=100; TIFFError( TIFF2PDF_MODULE, "PNG Group predictor differencing not implemented, assuming compression quality %u", @@ -1804,8 +1824,12 @@ void t2p_read_tiff_data(T2P* t2p, TIFF* input){ if(t2p->tiff_compression== COMPRESSION_ADOBE_DEFLATE || t2p->tiff_compression==COMPRESSION_DEFLATE){ if(TIFFIsTiled(input) || (TIFFNumberOfStrips(input)==1) ){ + uint16 predictor; t2p->pdf_transcode = T2P_TRANSCODE_RAW; t2p->pdf_compression=T2P_COMPRESS_ZIP; + TIFFGetField(input, TIFFTAG_PREDICTOR, &predictor); + t2p->pdf_compressionquality = predictor; + /* TIFFTAG_ZIPQUALITY is always Z_DEFAULT_COMPRESSION on reading */ } } #endif @@ -2063,9 +2087,17 @@ void t2p_read_tiff_size(T2P* t2p, TIFF* input){ #endif (void) 0; } - k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); - if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ - k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); +#ifdef JPEG_SUPPORT + if(t2p->pdf_compression == T2P_COMPRESS_JPEG + && t2p->tiff_photometric == PHOTOMETRIC_YCBCR) { + k = checkMultiply64(TIFFNumberOfStrips(input), TIFFStripSize(input), t2p); + } else +#endif + { + k = checkMultiply64(TIFFScanlineSize(input), t2p->tiff_length, t2p); + if(t2p->tiff_planar==PLANARCONFIG_SEPARATE){ + k = checkMultiply64(k, t2p->tiff_samplesperpixel, t2p); + } } if (k == 0) { /* Assume we had overflow inside TIFFScanlineSize */ @@ -2115,7 +2147,7 @@ void t2p_read_tiff_size_tile(T2P* t2p, TIFF* input, ttile_t tile){ k=tbc[tile]; #ifdef OJPEG_SUPPORT if(t2p->tiff_compression==COMPRESSION_OJPEG){ - k = checkAdd64(k, 2048, t2p); + k = checkAdd64(k, 2048, t2p); } #endif #ifdef JPEG_SUPPORT @@ -2205,6 +2237,9 @@ int t2p_tile_is_corner_edge(T2P_TILES tiles, ttile_t tile){ return(t2p_tile_is_right_edge(tiles, tile) & t2p_tile_is_bottom_edge(tiles, tile) ); } +#if defined(JPEG_SUPPORT) || defined(OJPEG_SUPPORT) +static const unsigned char jpeg_eof_marker[] = { 0xff, 0xd9 }; +#endif /* This function reads the raster image data from the input TIFF for an image and writes @@ -2252,16 +2287,22 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if (buffer == NULL) { - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for " - "t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for " + "t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawStrip(input, 0, (tdata_t) buffer, - t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawStrip(input, 0, (tdata_t) buffer, + t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawStrip() failed"); + _TIFFfree(buffer); + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ /* * make sure is lsb-to-msb @@ -2281,16 +2322,21 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer == NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); - TIFFReadRawStrip(input, 0, (tdata_t) buffer, - t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawStrip(input, 0, (tdata_t) buffer, + t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawStrip() failed"); + _TIFFfree(buffer); + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB) { TIFFReverseBits(buffer, t2p->tiff_datasize); @@ -2308,14 +2354,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer == NULL) { - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); if(t2p->pdf_ojpegiflength==0){ inputoffset=t2pSeekFile(input, 0, SEEK_CUR); @@ -2375,8 +2421,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ } } else { if(! t2p->pdf_ojpegdata){ - TIFFError(TIFF2PDF_MODULE, - "No support for OJPEG image %s with bad tables", + TIFFError(TIFF2PDF_MODULE, + "No support for OJPEG image %s with bad tables", TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); @@ -2384,32 +2430,39 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); bufferoffset=t2p->pdf_ojpegdatalength; stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ + tsize_t retTIFFReadRawStrip; if(i != 0){ buffer[bufferoffset++]=0xff; buffer[bufferoffset++]=(0xd0 | ((i-1)%8)); } - bufferoffset+=TIFFReadRawStrip(input, + retTIFFReadRawStrip = TIFFReadRawStrip(input, i, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); + if (retTIFFReadRawStrip < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawStrip()"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + bufferoffset += retTIFFReadRawStrip; } + t2pWriteFile(output, (tdata_t) buffer, bufferoffset); if( ! ( (buffer[bufferoffset-1]==0xd9) && (buffer[bufferoffset-2]==0xff) ) ){ - buffer[bufferoffset++]=0xff; - buffer[bufferoffset++]=0xd9; + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); } - t2pWriteFile(output, (tdata_t) buffer, bufferoffset); _TIFFfree(buffer); return(bufferoffset); #if 0 @@ -2433,14 +2486,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); if (TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if(count > 4) { _TIFFmemcpy(buffer, jpt, count); @@ -2455,16 +2508,24 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ stripbuffer = (unsigned char*) _TIFFmalloc(max_striplength); if(stripbuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s", - max_striplength, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %u bytes of memory for t2p_readwrite_pdf_image, %s", + max_striplength, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(stripbuffer, 0, max_striplength); for(i=0;i<stripcount;i++){ striplength=TIFFReadRawStrip(input, i, (tdata_t) stripbuffer, -1); + if (striplength < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawStrip() failed"); + _TIFFfree(samplebuffer); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if(!t2p_process_jpeg_strip( stripbuffer, &striplength, @@ -2482,9 +2543,8 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ return(0); } } - buffer[bufferoffset++]=0xff; - buffer[bufferoffset++]=0xd9; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); _TIFFfree(stripbuffer); _TIFFfree(buffer); return(bufferoffset); @@ -2496,14 +2556,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ @@ -2534,19 +2594,19 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); samplebuffer = (unsigned char*) _TIFFmalloc(stripsize); if(samplebuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; _TIFFfree(buffer); @@ -2561,9 +2621,9 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ (tdata_t) &(samplebuffer[samplebufferoffset]), TIFFmin(sepstripsize, stripsize - samplebufferoffset)); if(read==-1){ - TIFFError(TIFF2PDF_MODULE, - "Error on decoding strip %u of %s", - i + j*stripcount, + TIFFError(TIFF2PDF_MODULE, + "Error on decoding strip %u of %s", + i + j*stripcount, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; @@ -2584,14 +2644,14 @@ tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, - "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", - (unsigned long) t2p->tiff_datasize, + TIFFError(TIFF2PDF_MODULE, + "Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } - memset(buffer, 0, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); stripsize=TIFFStripSize(input); stripcount=TIFFNumberOfStrips(input); for(i=0;i<stripcount;i++){ @@ -2855,7 +2915,14 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } @@ -2876,7 +2943,14 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } - TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize); + memset(buffer, 0, t2p->tiff_datasize); + if (TIFFReadRawTile(input, tile, (tdata_t) buffer, t2p->tiff_datasize) < 0) { + TIFFError(TIFF2PDF_MODULE, + "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } if (t2p->tiff_fillorder==FILLORDER_LSB2MSB){ TIFFReverseBits(buffer, t2p->tiff_datasize); } @@ -2887,6 +2961,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ #endif #ifdef OJPEG_SUPPORT if(t2p->tiff_compression == COMPRESSION_OJPEG){ + tsize_t retTIFFReadRawTile; if(! t2p->pdf_ojpegdata){ TIFFError(TIFF2PDF_MODULE, "No support for OJPEG image %s with " @@ -2905,6 +2980,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); _TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength); if(edge!=0){ if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile)){ @@ -2920,14 +2996,20 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ (t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth ) & 0xff; } } - bufferoffset=t2p->pdf_ojpegdatalength; - bufferoffset+=TIFFReadRawTile(input, + bufferoffset = t2p->pdf_ojpegdatalength; + retTIFFReadRawTile = TIFFReadRawTile(input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), -1); - ((unsigned char*)buffer)[bufferoffset++]=0xff; - ((unsigned char*)buffer)[bufferoffset++]=0xd9; + if (retTIFFReadRawTile < 0) { + TIFFError(TIFF2PDF_MODULE, "TIFFReadRawTile() failed"); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } + bufferoffset += retTIFFReadRawTile; t2pWriteFile(output, (tdata_t) buffer, bufferoffset); + t2pWriteFile(output, (tdata_t) jpeg_eof_marker, sizeof(jpeg_eof_marker)); _TIFFfree(buffer); return(bufferoffset); } @@ -2946,9 +3028,10 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) { if (count > 4) { - int retTIFFReadRawTile; + tsize_t retTIFFReadRawTile; /* Ignore EOI marker of JpegTables */ _TIFFmemcpy(buffer, jpt, count - 2); bufferoffset += count - 2; @@ -2957,7 +3040,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ table_end[1] = buffer[bufferoffset-1]; xuint32 = bufferoffset; bufferoffset -= 2; - retTIFFReadRawTile= TIFFReadRawTile( + retTIFFReadRawTile = TIFFReadRawTile( input, tile, (tdata_t) &(((unsigned char*)buffer)[bufferoffset]), @@ -2994,6 +3077,7 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); read = TIFFReadEncodedTile( input, @@ -3019,25 +3103,27 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ tilecount=septilecount/t2p->tiff_samplesperpixel; buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); samplebuffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(samplebuffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(samplebuffer, 0, t2p->tiff_datasize); samplebufferoffset=0; for(i=0;i<t2p->tiff_samplesperpixel;i++){ read = @@ -3069,23 +3155,24 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ if(buffer==NULL){ buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize); if(buffer==NULL){ - TIFFError(TIFF2PDF_MODULE, + TIFFError(TIFF2PDF_MODULE, "Can't allocate %lu bytes of memory " - "for t2p_readwrite_pdf_image_tile, %s", - (unsigned long) t2p->tiff_datasize, + "for t2p_readwrite_pdf_image_tile, %s", + (unsigned long) t2p->tiff_datasize, TIFFFileName(input)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } + memset(buffer, 0, t2p->tiff_datasize); read = TIFFReadEncodedTile( input, tile, (tdata_t) &buffer[bufferoffset], t2p->tiff_datasize); if(read==-1){ - TIFFError(TIFF2PDF_MODULE, - "Error on decoding tile %u of %s", - tile, + TIFFError(TIFF2PDF_MODULE, + "Error on decoding tile %u of %s", + tile, TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error=T2P_ERR_ERROR; @@ -3108,8 +3195,8 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ } if(t2p->pdf_sample & T2P_SAMPLE_YCBCR_TO_RGB){ - TIFFError(TIFF2PDF_MODULE, - "No support for YCbCr to RGB in tile for %s", + TIFFError(TIFF2PDF_MODULE, + "No support for YCbCr to RGB in tile for %s", TIFFFileName(input)); _TIFFfree(buffer); t2p->t2p_error = T2P_ERR_ERROR; @@ -3242,18 +3329,26 @@ tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_ break; } + if (TIFFStripSize(output) > t2p->tiff_datasize) { + TIFFError(TIFF2PDF_MODULE, + "Size mismatch input %ld, output %ld", + t2p->tiff_datasize, TIFFStripSize(output)); + _TIFFfree(buffer); + t2p->t2p_error = T2P_ERR_ERROR; + return(0); + } t2p_enable(output); t2p->outputwritten = 0; bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t) 0, buffer, - TIFFStripSize(output)); + TIFFStripSize(output)); if (buffer != NULL) { _TIFFfree(buffer); buffer = NULL; } if (bufferoffset == -1) { - TIFFError(TIFF2PDF_MODULE, - "Error writing encoded tile to output PDF %s", - TIFFFileName(output)); + TIFFError(TIFF2PDF_MODULE, + "Error writing encoded tile to output PDF %s", + TIFFFileName(output)); t2p->t2p_error = T2P_ERR_ERROR; return(0); } @@ -3731,6 +3826,11 @@ tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){ for(i=sample_count;i>0;i--){ palette_offset=buffer[i-1] * component_count; sample_offset= (i-1) * component_count; + if(palette_offset + component_count > t2p->pdf_palettesize){ + TIFFError(TIFF2PDF_MODULE, + "Error: palette_offset + component_count > t2p->pdf_palettesize"); + return 1; + } for(j=0;j<component_count;j++){ buffer[sample_offset+j]=t2p->pdf_palette[palette_offset+j]; } @@ -3886,7 +3986,7 @@ tsize_t t2p_write_pdf_obj_end(TIFF* output){ This function writes a PDF name object to output. */ -tsize_t t2p_write_pdf_name(unsigned char* name, TIFF* output){ +tsize_t t2p_write_pdf_name(const unsigned char* name, TIFF* output){ tsize_t written=0; uint32 i=0; @@ -3984,7 +4084,7 @@ tsize_t t2p_write_pdf_name(unsigned char* name, TIFF* output){ * This function writes a PDF string object to output. */ -tsize_t t2p_write_pdf_string(char* pdfstr, TIFF* output) +tsize_t t2p_write_pdf_string(const char* pdfstr, TIFF* output) { tsize_t written = 0; uint32 i = 0; @@ -4175,7 +4275,7 @@ tsize_t t2p_write_pdf_catalog(T2P* t2p, TIFF* output) tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output) { tsize_t written = 0; - char* info; + const char* info; char buffer[512]; if(t2p->pdf_datetime[0] == '\0') @@ -4190,60 +4290,51 @@ tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output) snprintf(buffer, sizeof(buffer), "libtiff / tiff2pdf - %d", TIFFLIB_VERSION); written += t2p_write_pdf_string(buffer, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); + if (!t2p->pdf_creator_set) { + if (TIFFGetField(input, TIFFTAG_SOFTWARE, &info) != 0 && info) { + strncpy(t2p->pdf_creator, info, sizeof(t2p->pdf_creator) - 1); + t2p->pdf_creator[sizeof(t2p->pdf_creator) - 1] = '\0'; + } + } if (t2p->pdf_creator[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); written += t2p_write_pdf_string(t2p->pdf_creator, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_SOFTWARE, &info) != 0 && info) { - if(strlen(info) >= sizeof(t2p->pdf_creator)) - info[sizeof(t2p->pdf_creator) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Creator ", 9); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_author_set) { + if ((TIFFGetField(input, TIFFTAG_ARTIST, &info) != 0 + || TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0) + && info) { + strncpy(t2p->pdf_author, info, sizeof(t2p->pdf_author) - 1); + t2p->pdf_author[sizeof(t2p->pdf_author) - 1] = '\0'; } } if (t2p->pdf_author[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Author ", 8); written += t2p_write_pdf_string(t2p->pdf_author, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if ((TIFFGetField(input, TIFFTAG_ARTIST, &info) != 0 - || TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0) - && info) { - if (strlen(info) >= sizeof(t2p->pdf_author)) - info[sizeof(t2p->pdf_author) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Author ", 8); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_title_set) { + if (TIFFGetField(input, TIFFTAG_DOCUMENTNAME, &info) != 0 && info) { + strncpy(t2p->pdf_title, info, sizeof(t2p->pdf_title) - 1); + t2p->pdf_title[sizeof(t2p->pdf_title) - 1] = '\0'; } } if (t2p->pdf_title[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Title ", 7); written += t2p_write_pdf_string(t2p->pdf_title, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_DOCUMENTNAME, &info) != 0){ - if(strlen(info) > 511) { - info[512] = '\0'; - } - written += t2pWriteFile(output, (tdata_t) "/Title ", 7); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); + } + if (!t2p->pdf_subject_set) { + if (TIFFGetField(input, TIFFTAG_IMAGEDESCRIPTION, &info) != 0 && info) { + strncpy(t2p->pdf_subject, info, sizeof(t2p->pdf_subject) - 1); + t2p->pdf_subject[sizeof(t2p->pdf_subject) - 1] = '\0'; } } if (t2p->pdf_subject[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); written += t2p_write_pdf_string(t2p->pdf_subject, output); written += t2pWriteFile(output, (tdata_t) "\n", 1); - } else { - if (TIFFGetField(input, TIFFTAG_IMAGEDESCRIPTION, &info) != 0 && info) { - if (strlen(info) >= sizeof(t2p->pdf_subject)) - info[sizeof(t2p->pdf_subject) - 1] = '\0'; - written += t2pWriteFile(output, (tdata_t) "/Subject ", 9); - written += t2p_write_pdf_string(info, output); - written += t2pWriteFile(output, (tdata_t) "\n", 1); - } } if (t2p->pdf_keywords[0] != '\0') { written += t2pWriteFile(output, (tdata_t) "/Keywords ", 10); @@ -4928,8 +5019,18 @@ tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t tile, return(written); } + +/* used to normalize the White Point */ +#define normalizePoint(x,y,z) do { \ + if (y != 0.0F) { \ + x /= y; \ + z /= y; \ + y = 1.0F; \ + } \ +} while(0) + /* - * This function writes a PDF Image XObject Colorspace name to output. + * This function writes a PDF Image XObject Colorspace name to output. */ @@ -4988,9 +5089,7 @@ tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){ X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0F; + normalizePoint(X_W, Y_W, Z_W); buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W); check_snprintf_ret(t2p, buflen, buffer); written += t2pWriteFile(output, (tdata_t) buffer, buflen); @@ -5119,9 +5218,7 @@ tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ X_W = t2p->tiff_whitechromaticities[0]; Y_W = t2p->tiff_whitechromaticities[1]; Z_W = 1.0F - (X_W + Y_W); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0F; + normalizePoint(X_W, Y_W, Z_W); } if(t2p->pdf_colorspace & T2P_CS_CALRGB){ written += t2pWriteFile(output, (tdata_t) "/CalRGB ", 8); @@ -5146,9 +5243,7 @@ tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){ X_W = (X_R * R) + (X_G * G) + (X_B * B); Y_W = (Y_R * R) + (Y_G * G) + (Y_B * B); Z_W = (Z_R * R) + (Z_G * G) + (Z_B * B); - X_W /= Y_W; - Z_W /= Y_W; - Y_W = 1.0; + normalizePoint(X_W, Y_W, Z_W); } written += t2pWriteFile(output, (tdata_t) "<< \n", 4); if(t2p->pdf_colorspace & T2P_CS_CALGRAY){ @@ -5597,6 +5692,13 @@ tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size_tile(t2p, input, i2); + if (t2p->tiff_maxdatasize && (t2p->tiff_datasize > t2p->tiff_maxdatasize)) { + TIFFError(TIFF2PDF_MODULE, + "Allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ". Use -m option to change limit", + (uint64)t2p->tiff_datasize, (uint64)t2p->tiff_maxdatasize); + t2p->t2p_error = T2P_ERR_ERROR; + return (0); + } written += t2p_readwrite_pdf_image_tile(t2p, input, output, i2); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} @@ -5620,6 +5722,13 @@ tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){ written += t2p_write_pdf_stream_start(output); streamlen=written; t2p_read_tiff_size(t2p, input); + if (t2p->tiff_maxdatasize && (t2p->tiff_datasize > t2p->tiff_maxdatasize)) { + TIFFError(TIFF2PDF_MODULE, + "Allocation of " TIFF_UINT64_FORMAT " bytes is forbidden. Limit is " TIFF_UINT64_FORMAT ". Use -m option to change limit", + (uint64)t2p->tiff_datasize, (uint64)t2p->tiff_maxdatasize); + t2p->t2p_error = T2P_ERR_ERROR; + return (0); + } written += t2p_readwrite_pdf_image(t2p, input, output); t2p_write_advance_directory(t2p, output); if(t2p->t2p_error!=T2P_ERR_OK){return(0);} |