Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 djview4 (4.10.6-6) unstable; urgency=medium
 .
   * merge upstream mods
   * bump policy version
   * djview4 run-time dependency on sensible-utils, for sensible-browser
Author: Barak A. Pearlmutter <bap@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2018-08-05

--- djview4-4.10.6.orig/NEWS
+++ djview4-4.10.6/NEWS
@@ -7,6 +7,7 @@ NEW SINCE VERSION 4.10
 - Spanish translations
 - Bug fixes
 - Workaround for qt5.5 embed bug
+- Fixed annotation display bugs revealed by qt5
 
 NEW IN VERSION 4.10
 -------------------
--- djview4-4.10.6.orig/README
+++ djview4-4.10.6/README
@@ -74,8 +74,14 @@ the variabled DDJVUAPI_CFLAGS and DDJVUA
 2.2 COMPILING AND INSTALLING UNDER UNIX
 ---------------------------------------
 
+First run the script 'configure' (or 'autogen.sh' as 
+explained above) to generate the makefiles.
 
-First run the script 'configure' to generate the makefiles.
+Note that there will be no configure file if you obtain the djvulibre 
+source using git clone. Instead there is a script 'autogen.sh' that 
+uses automake to generate and call the actual configure script.
+Since all autogen.sh arguments will be passed to configure,
+you can simply treat autogen.sh as a replacement for configure.
 
 Command 'configure --help' list options and environment 
 variables that affect the generation of makefile.
--- djview4-4.10.6.orig/configure.ac
+++ djview4-4.10.6/configure.ac
@@ -164,6 +164,7 @@ AC_CHECK_HEADERS(unistd.h string.h strin
 # ----------------------------------------
 
 AC_FUNC_FORK
+AC_FUNC_FSEEKO
 AC_CHECK_FUNCS(sigaction strerror waitpid wait3)
 
 
--- djview4-4.10.6.orig/desktopfiles/djvulibre-djview4.desktop
+++ djview4-4.10.6/desktopfiles/djvulibre-djview4.desktop
@@ -1,7 +1,7 @@
 [Desktop Entry]
 Type=Application
 Categories=Qt;Graphics;Viewer;
-MimeType=image/x-djvu;image/x.djvu;image/vnd.djvu;
+MimeType=image/x-djvu;image/x.djvu;image/vnd.djvu;image/vnd.djvu+multipage;image/vnd.djvu+singlepage
 Name=DjView4
 Exec=djview4 %f
 Terminal=false
--- djview4-4.10.6.orig/mac/qlgenerator_src/GeneratePreviewForURL.m
+++ djview4-4.10.6/mac/qlgenerator_src/GeneratePreviewForURL.m
@@ -1,9 +1,43 @@
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreServices/CoreServices.h>
 #include <QuickLook/QuickLook.h>
+
+#import <Foundation/Foundation.h>
 #import <Cocoa/Cocoa.h>
 
-#include "ddjvuRef.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "libdjvu/ddjvuapi.h"
+
+
+/* handle ddjvu messages */
+
+static void
+handle(ddjvu_context_t *ctx, int wait)
+{
+  const ddjvu_message_t *msg;
+  if (!ctx)
+    return;
+  if (wait)
+    msg = ddjvu_message_wait(ctx);
+  while ((msg = ddjvu_message_peek(ctx)))
+    {
+      switch(msg->m_any.tag)
+        {
+	case DDJVU_ERROR:
+	  NSLog(@"%s", msg->m_error.message);
+	  if (msg->m_error.filename)
+	    NSLog(@"'%s:%d'",
+		  msg->m_error.filename, msg->m_error.lineno);
+	default:
+	  break;
+        }
+      ddjvu_message_pop(ctx);
+    }
+}
 
 /* -----------------------------------------------------------------------------
    Generate a preview for file
@@ -16,150 +50,160 @@ GeneratePreviewForURL(void *thisInterfac
                       QLPreviewRequestRef preview,
                       CFURLRef url,
                       CFStringRef contentTypeUTI,
-                      CFDictionaryRef options)
+                      CFDictionaryRef cfOptions)
 {
-    CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview);
-    char *ddjvu = ddjvuPath(bundle);
-    if (ddjvu != NULL) {
-        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];        
-        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-        NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
-        CFUUIDRef uuid = NULL;
-        CFStringRef uuidString;
-        BOOL debug = FALSE;
-        NSString *tmpPath = nil;
-        
-        if (domain && [domain objectForKey:@"previewpages"])
-            if ([[domain objectForKey:@"previewpages"] intValue] == 0)
-                goto poppool;
-
-        if (domain && [domain objectForKey:@"debug"]) {
-            debug = [[domain objectForKey:@"debug"] boolValue];
-        }
-        
-        uuid = CFUUIDCreate(kCFAllocatorDefault);
-        if (uuid) {
-            uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid);
-            if (uuidString) {
-                tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:
-                           [NSString stringWithFormat:@"djvuql-%@", uuidString]];
-                CFRelease(uuidString);
-            }
-            CFRelease(uuid);
-        }
-        if (tmpPath) {
-            const char *cmd = NULL;
-            CFStringRef cmdRef;
-            int page = 0;
-            int pages = 1;
-            int maxpages = 5;
-            int width = 612;    // default 8.5x11 in points
-            int height = 792;
-            CGSize size;
-            MDItemRef mditem = NULL;
-            NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
-            NSString *dest = nil;
-            NSFileManager *fmgr = [NSFileManager defaultManager];
-            [fmgr createDirectoryAtPath:tmpPath attributes:nil];
-            
-            mditem = MDItemCreate(kCFAllocatorDefault, (CFStringRef)source);
-            if (mditem) {
-                CFTypeRef ref = NULL;
-                ref = MDItemCopyAttribute(mditem, kMDItemNumberOfPages);
-                if (ref) {
-                    CFNumberGetValue(ref, kCFNumberIntType, &pages);
-                    CFRelease(ref);
-                }
-                ref = MDItemCopyAttribute(mditem, kMDItemPageWidth);
-                if (ref) {
-                    CFNumberGetValue(ref, kCFNumberIntType, &width);
-                    CFRelease(ref);
-                }
-                ref = MDItemCopyAttribute(mditem, kMDItemPageHeight);
-                if (ref) {
-                    CFNumberGetValue(ref, kCFNumberIntType, &height);
-                    CFRelease(ref);
-                }
-                CFRelease(mditem);                
-            }
-            
-            if (domain && [domain objectForKey:@"previewpages"])
-                maxpages = [[domain objectForKey:@"previewpages"] intValue];
-            
-            if (debug) {
-                NSLog(@"metadata: pages=%d, width=%d, height=%d", pages, width, height);
-                NSLog(@"maxpages=%d", maxpages);                
-            }
-                        
-            CGRect rect = CGRectMake(0, 0, width, height);
-            CGContextRef c;
-            c = QLPreviewRequestCreatePDFContext(preview, &rect, NULL, NULL);
-            
-            page = 0;
-            do {
-                page++;
-                dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%04d.tiff", page]];
-                size = CGSizeMake(width, height);
-                cmdRef = CFStringCreateWithFormat(NULL, NULL, 
-						  CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), 
-						  ddjvu, page, width, height, 
-						  [source fileSystemRepresentation], [dest fileSystemRepresentation]);
-                cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding());
-                if (cmd != NULL) {
-                    if (debug)
-                        NSLog(@"%s", cmd);
-                    if ((system(cmd) == 0) && ([fmgr fileExistsAtPath:dest])) {
-                        NSURL *durl = [NSURL fileURLWithPath:dest];
-                        CGImageSourceRef  sourceRef;
-                        
-                        sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL);
-                        if(sourceRef) {
-                            CGImageRef imageRef = NULL;
-                            imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
-                            if (imageRef) {
-                                CGFloat offset = height * (page-1);
-                                CGRectOffset(rect, 0.0, offset);
-                                CGPDFContextBeginPage(c, NULL);
-                                CGContextSaveGState(c);
-                                CGContextDrawImage(c, rect, imageRef);
-                                if (page == maxpages && maxpages < pages) {
-                                    CGAffineTransform m;
-                                    CFURLRef more = CFBundleCopyResourceURL(bundle, CFSTR("more_pages"), CFSTR("pdf"), NULL);
-                                    CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL(more);
-                                    CGPDFPageRef pdf = CGPDFDocumentGetPage(doc, 1);
-                                    CGFloat offset = height * page;
-                                    CGRectOffset(rect, 0.0, offset);
-                                    CGContextSaveGState(c);
-                                    m = CGPDFPageGetDrawingTransform(pdf, kCGPDFMediaBox, rect, 0, true);
-                                    CGContextConcatCTM(c, m);
-                                    CGContextDrawPDFPage(c, pdf);
-                                    CGContextRestoreGState(c);
-                                    CFRelease(doc);
-                                }
-                                CGContextRestoreGState(c);
-                                CGPDFContextEndPage(c);
-                                CFRelease(imageRef);
-                            }
-                            CFRelease(sourceRef);
-                        }
-                    }
-                }
-                CFRelease(cmdRef);
-            } while (page < pages && page < maxpages);
-
-            CGPDFContextClose(c);
-            QLPreviewRequestFlushContext(preview, c);
-            CFRelease(c);
-            [fmgr removeFileAtPath:tmpPath handler:nil];
-            [source release];
-        }
-    poppool:
-        [pool release];
+  ddjvu_context_t *ctx = 0;
+  ddjvu_document_t *doc = 0;
+  ddjvu_format_t *fmt = 0;
+  ddjvu_page_t *pag = 0;
+  CGContextRef *cg = 0;
+  
+  @autoreleasepool {
+    
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
+    NSString *path = [(NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) autorelease];
+    int width, height;
+    int npages, page, maxpages = 5;
+    
+    /* Defaults */
+    if (domain && [domain objectForKey:@"previewpages"])
+      maxpages = [[domain objectForKey:@"previewpages"] intValue];
+    if (maxpages <= 0)
+      goto pop;
+    
+    /* Create context and document */
+    if (! (ctx = ddjvu_context_create([[[NSProcessInfo processInfo] processName]
+					cStringUsingEncoding:NSASCIIStringEncoding]))) {
+      NSLog(@"Cannot create djvu context for '%@'.", path);
+      goto pop;
+    }
+    if (! (doc = ddjvu_document_create_by_filename(ctx, [path fileSystemRepresentation], TRUE))) {
+      NSLog(@"Cannot open djvu document '%@'.", path);
+      goto pop;
     }
-    return noErr;
+    while (! ddjvu_document_decoding_done(doc))
+      handle(ctx, TRUE);
+    if (ddjvu_document_decoding_error(doc)) {
+      NSLog(@"Djvu document decoding error '%@'.", path);
+      goto pop;
+    }
+    
+    /* Loop on pages */
+    fmt = ddjvu_format_create(DDJVU_FORMAT_RGB24, 0, NULL);
+    ddjvu_format_set_row_order(fmt, TRUE);
+    npages = ddjvu_document_get_pagenum(doc);
+    for (page=0; page<npages && page<maxpages; page++)
+      {
+        int pw, ph, dpi;
+        ddjvu_rect_t rrect;
+        NSBitmapImageRep *bitmap;
+        NSDictionary *dict;
+        NSData *data;
+        CGRect cgrect;
+        CGImageRef cgimg;
+
+        @autoreleasepool {
+          
+          /* Decode page */
+          pag = ddjvu_page_create_by_pageno(doc, page);
+          while (! ddjvu_page_decoding_done(pag))
+            handle(ctx, TRUE);
+          if (ddjvu_page_decoding_error(pag)) {
+            NSLog(@"Djvu page decoding error '%@' (page %d).", path, page);
+            goto pop;
+          }
+          
+          /* Obtain page size at 100 dpi */
+          pw = ddjvu_page_get_width(pag);
+          ph = ddjvu_page_get_height(pag);
+          dpi = ddjvu_page_get_resolution(pag);
+          if (pw <= 0 || ph <= 0 || dpi <= 0) {
+            NSLog(@"Djvu page decoding error '%@' (page %d).", path, page);
+            goto pop;
+          }
+          rrect.x = rrect.y = 0;
+          rrect.w = pw * 150 / dpi;
+          rrect.h = ph * 150 / dpi;
+          
+          /* Render page */
+	  bitmap = [[NSBitmapImageRep alloc] autorelease];
+	  bitmap = [bitmap initWithBitmapDataPlanes:NULL
+					 pixelsWide:rrect.w
+					 pixelsHigh:rrect.h
+				      bitsPerSample:8
+				    samplesPerPixel:3
+					   hasAlpha:FALSE
+					   isPlanar:NO
+				     colorSpaceName:NSCalibratedRGBColorSpace
+					bytesPerRow:rrect.w * 3
+				       bitsPerPixel:24 ];
+	if (! ddjvu_page_render(pag, DDJVU_RENDER_COLOR, &rrect, &rrect,
+                                  fmt, rrect.w * 3, [bitmap bitmapData]) ) {
+            NSLog(@"Djvu page rendering error '%@' (page %d).", path, page);
+            goto pop;
+          }
+	  
+          /* Draw bitmap into CG */
+          cgrect.origin.x = cgrect.origin.y = 0;
+          cgrect.size.width = rrect.w;
+          cgrect.size.height = rrect.h;
+          [bitmap setSize:cgrect.size];
+          if (! cg)
+            cg = QLPreviewRequestCreatePDFContext(preview, &cgrect, NULL, NULL);
+          data = [NSData dataWithBytes:&cgrect length:sizeof(cgrect)];
+          dict = [NSDictionary dictionaryWithObject:data forKey:kCGPDFContextMediaBox];
+          CGPDFContextBeginPage(cg, (CFDictionaryRef)dict);
+          cgimg = [bitmap CGImage];
+          CGContextDrawImage(cg, cgrect, cgimg);
+
+          /* Show when there are more pages (old qlgenerator) */
+          if (page+1 == maxpages && page+1 < npages) {
+            CGAffineTransform m;
+            CFBundleRef bundle = QLPreviewRequestGetGeneratorBundle(preview);
+            CFURLRef more = CFBundleCopyResourceURL(bundle,CFSTR("more_pages"),CFSTR("pdf"),NULL);
+            CGPDFDocumentRef doc = CGPDFDocumentCreateWithURL(more);
+            CGPDFPageRef pdf = CGPDFDocumentGetPage(doc, 1);
+            CGContextSaveGState(cg);
+            m = CGPDFPageGetDrawingTransform(pdf, kCGPDFMediaBox, cgrect, 0, true);
+            CGContextConcatCTM(cg, m);
+            CGContextDrawPDFPage(cg, pdf);
+            CGContextRestoreGState(cg);
+            CFRelease(doc);
+          }
+
+          /* Cleanup */
+          CGPDFContextEndPage(cg);
+          ddjvu_page_release(pag);
+          pag = 0;
+        }  /* @autoreleasepool */
+      }
+    /* Flush pdf context */
+    if (cg)
+      {
+        CGPDFContextClose(cg);
+	QLPreviewRequestFlushContext(preview, cg);	
+      }
+  } /* @autoreleasepool */
+  /* Cleanup */
+ pop:
+  if (cg)
+    CFRelease(cg);
+  if (pag)
+    ddjvu_page_release(pag);
+  if (fmt)
+    ddjvu_format_release(fmt);
+  if (doc)
+    ddjvu_document_release(doc);
+  if (ctx)
+    ddjvu_context_release(ctx);
+  return noErr;
 }
 
+
 void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
 {
     // implement only if supported
 }
+
+
--- djview4-4.10.6.orig/mac/qlgenerator_src/GenerateThumbnailForURL.m
+++ djview4-4.10.6/mac/qlgenerator_src/GenerateThumbnailForURL.m
@@ -1,10 +1,43 @@
+
 #include <CoreFoundation/CoreFoundation.h>
 #include <CoreServices/CoreServices.h>
 #include <QuickLook/QuickLook.h>
+
+#import <Foundation/Foundation.h>
 #import <Cocoa/Cocoa.h>
-#include <ApplicationServices/ApplicationServices.h>
 
-#include "ddjvuRef.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "libdjvu/ddjvuapi.h"
+
+
+/* handle ddjvu messages */
+
+static void
+handle(ddjvu_context_t *ctx, int wait)
+{
+  const ddjvu_message_t *msg;
+  if (!ctx)
+    return;
+  if (wait)
+    msg = ddjvu_message_wait(ctx);
+  while ((msg = ddjvu_message_peek(ctx)))
+    {
+      switch(msg->m_any.tag)
+        {
+	case DDJVU_ERROR:
+	  NSLog(@"%s", msg->m_error.message);
+	  if (msg->m_error.filename)
+	    NSLog(@"'%s:%d'",
+		  msg->m_error.filename, msg->m_error.lineno);
+	default:
+	  break;
+        }
+      ddjvu_message_pop(ctx);
+    }
+}
 
 /* -----------------------------------------------------------------------------
     Generate a thumbnail for file
@@ -20,87 +53,84 @@ GenerateThumbnailForURL(void *thisInterf
                         CFDictionaryRef options,
                         CGSize maxSize)
 {
-    char *ddjvu = ddjvuPath(QLThumbnailRequestGetGeneratorBundle(thumbnail));
-    if (ddjvu != NULL) {
-        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-        NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
-        CFUUIDRef uuid;
-        CFStringRef uuidString;
-        NSString *tmpPath = nil;
-        BOOL debug = FALSE;
-        
-        if (domain && [domain objectForKey:@"debug"]) {
-            debug = [[domain objectForKey:@"debug"] boolValue];
-        }
-        if (domain && [domain objectForKey:@"thumbnail"] &&
-            ([[domain objectForKey:@"thumbnail"] boolValue] == FALSE))
-        {
-            if (debug)
-                NSLog(@"skip thumbnail for %@", url);
-            CFStringRef ext = CFURLCopyPathExtension(url);
-            if (ext) {
-                NSImage *img = [[NSWorkspace sharedWorkspace] iconForFileType:(NSString*)ext];
-                if (img) {
-                    NSData *data = [img TIFFRepresentation];
-                    QLThumbnailRequestSetImageWithData(thumbnail, (CFDataRef)data, NULL);
-                }
-                CFRelease(ext);
-            }
-        } else {
-            if (debug) {
-                CFShow(contentTypeUTI);
-                CFShow(options);            
-            }
-            
-            uuid = CFUUIDCreate(kCFAllocatorDefault);
-            if (uuid) {
-                uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuid);
-                if (uuidString) {
-                    tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:
-                               [NSString stringWithFormat:@"djvuql-%@", uuidString]];
-                    CFRelease(uuidString);
-                }
-                CFRelease(uuid);
-            }
-            if (tmpPath) {
-                NSFileManager *fmgr = [NSFileManager defaultManager];
-                const char *cmd = NULL;
-                CFStringRef cmdRef;
-                int page = 1;
-                NSString *source = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
-                NSString *dest = [tmpPath stringByAppendingPathComponent:[[source lastPathComponent] stringByAppendingFormat:@"_t_p%d.tiff", page]];
-                [fmgr createDirectoryAtPath:tmpPath attributes:nil];            
-                cmdRef = CFStringCreateWithFormat(NULL, NULL, 
-						  CFSTR("\"%s\" -format=tiff -page=%d -size=%dx%d \"%s\" \"%s\""), 
-						  ddjvu, page, (int)maxSize.width, (int)maxSize.height, 
-						  [source fileSystemRepresentation], [dest fileSystemRepresentation]);
-                cmd = CFStringGetCStringPtr(cmdRef, CFStringGetSystemEncoding());
-                if (cmd != NULL) {
-                    if (debug)
-                        NSLog(@"ddjvu: %s", cmd);
-                    if (system(cmd) == 0) {
-                        NSURL *durl = [NSURL fileURLWithPath:dest];
-                        CGImageRef imageRef = NULL;
-                        CGImageSourceRef  sourceRef;
-                        
-                        sourceRef = CGImageSourceCreateWithURL((CFURLRef)durl, NULL);
-                        if(sourceRef) {
-                            imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, NULL);
-                            if (imageRef)
-                                QLThumbnailRequestSetImage(thumbnail, imageRef, NULL);
-                            CFRelease(sourceRef);
-                        }
-                    }
-                }
-                [fmgr removeFileAtPath:tmpPath handler:nil];
-                CFRelease(cmdRef);
-                [source release];
-            }
-        }
-        [pool release];
+  ddjvu_context_t *ctx = 0;
+  ddjvu_document_t *doc = 0;
+  ddjvu_format_t *fmt = 0;
+  
+  @autoreleasepool {
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSDictionary *domain = [defaults persistentDomainForName:@"org.djvu.qlgenerator"];
+    NSString *path = [(NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) autorelease];
+    NSBitmapImageRep *bitmap;
+    NSSize size;
+    int width, height;
+    
+    /* If not generating thumbnails */
+    if (domain && [domain objectForKey:@"thumbnails"])
+      if ([[domain objectForKey:@"thumbnails"] boolValue] == FALSE)
+	goto pop;
+    
+    /* Create context and document */
+    if (! (ctx = ddjvu_context_create([[[NSProcessInfo processInfo] processName]
+					cStringUsingEncoding:NSASCIIStringEncoding]))) {
+      NSLog(@"Cannot create djvu context for '%@'.", path);
+      goto pop;
+    }
+    if (! (doc = ddjvu_document_create_by_filename_utf8(ctx, [path fileSystemRepresentation], TRUE))) {
+      NSLog(@"Cannot open djvu document '%@'.", path);
+      goto pop;
+    }
+    while (! ddjvu_document_decoding_done(doc))
+      handle(ctx, TRUE);
+    if (ddjvu_document_decoding_error(doc)) {
+      NSLog(@"Djvu document decoding error '%@'.", path);
+      goto pop;
+    }
+    
+    /* Prepare thumbnail */
+    while (ddjvu_thumbnail_status(doc, 0, 1) < DDJVU_JOB_OK)
+      handle(ctx, TRUE);
+    if (ddjvu_thumbnail_status(doc, 0, 0) != DDJVU_JOB_OK) {
+      NSLog(@"Djvu thumbnail generation error '%@'.", path);
+      goto pop;
+    }
+    
+    /* Get thumbnail image */
+    width = (int) maxSize.width;
+    height = (int) maxSize.height;
+    fmt = ddjvu_format_create(DDJVU_FORMAT_RGB24, 0, NULL);
+    ddjvu_format_set_row_order(fmt, TRUE);
+    bitmap = [[NSBitmapImageRep alloc] autorelease];
+    bitmap = [bitmap initWithBitmapDataPlanes:NULL
+				   pixelsWide:width
+				   pixelsHigh:height
+				bitsPerSample:8
+			      samplesPerPixel:3
+				     hasAlpha:FALSE
+				     isPlanar:NO
+			       colorSpaceName:NSCalibratedRGBColorSpace
+				  bytesPerRow:width*3
+				 bitsPerPixel:24 ];
+    if (!ddjvu_thumbnail_render(doc, 0, &width, &height, fmt, width*3, [bitmap bitmapData])) {
+      NSLog(@"Djvu thumbnail rendering error '%@'.", path);
+      goto pop;
     }
-    return noErr;
+    size.width = width;
+    size.height = height;
+    [bitmap setSize: size];
+    [bitmap setPixelsWide: width];
+    [bitmap setPixelsHigh: height];
+    QLThumbnailRequestSetImageWithData(thumbnail, (CFDataRef)[bitmap TIFFRepresentation], NULL);
+  }
+  /* Cleanup */
+ pop:
+  if (fmt)
+    ddjvu_format_release(fmt);
+  if (doc)
+    ddjvu_document_release(doc);
+  if (ctx)
+    ddjvu_context_release(ctx);
+  return noErr;
 }
 
 void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail)
--- djview4-4.10.6.orig/mac/qlgenerator_src/Makefile.am
+++ djview4-4.10.6/mac/qlgenerator_src/Makefile.am
@@ -4,10 +4,11 @@ mactoolsdir = ${libdir}/djview/mactools
 mactools_LTLIBRARIES = qlgenerator.la
 
 qlgenerator_la_SOURCES = \
-  GeneratePreviewForURL.m GenerateThumbnailForURL.m \
-  ddjvuRef.h ddjvuRef.c main.c 
+  GeneratePreviewForURL.m GenerateThumbnailForURL.m main.c
 
 qlgenerator_la_OBJCFLAGS = -w
+qlgenerator_la_CFLAGS = ${DDJVUAPI_CFLAGS}
+qlgenerator_la_LIBADD = ${DDJVUAPI_LIBS} 
 
 qlgenerator_la_LDFLAGS = -module -avoid-version \
   -framework System -framework CoreFoundation -framework CoreServices \
--- djview4-4.10.6.orig/mac/qlgenerator_src/main.c
+++ djview4-4.10.6/mac/qlgenerator_src/main.c
@@ -37,19 +37,27 @@
 // -----------------------------------------------------------------------------
 
 // The thumbnail generation function to be implemented in GenerateThumbnailForURL.c
-OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize);
-void CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
+OSStatus
+GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail,
+			CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options,
+			CGSize maxSize);
+
+void
+CancelThumbnailGeneration(void* thisInterface, QLThumbnailRequestRef thumbnail);
 
 // The preview generation function to be implemented in GeneratePreviewForURL.c
-OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
-void CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
+OSStatus
+GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview,
+		      CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options);
+
+void
+CancelPreviewGeneration(void *thisInterface, QLPreviewRequestRef preview);
 
 // The layout for an instance of QuickLookGeneratorPlugIn
-typedef struct __QuickLookGeneratorPluginType
-{
-    void        *conduitInterface;
-    CFUUIDRef    factoryID;
-    UInt32       refCount;
+typedef struct __QuickLookGeneratorPluginType {
+  void        *conduitInterface;
+  CFUUIDRef    factoryID;
+  UInt32       refCount;
 } QuickLookGeneratorPluginType;
 
 // -----------------------------------------------------------------------------
--- djview4-4.10.6.orig/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Info.plist
+++ djview4-4.10.6/mac/skel/Library/QuickLook/DjVu.qlgenerator/Contents/Info.plist
@@ -3,7 +3,7 @@
 <plist version="1.0">
 <dict>
 	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
+	<string>en</string>
 	<key>CFBundleDocumentTypes</key>
 	<array>
 		<dict>
@@ -11,16 +11,14 @@
 			<string>QLGenerator</string>
 			<key>LSItemContentTypes</key>
 			<array>
-				<string>org.djvu.DjView</string>
 				<string>org.djvuzone.djvulibre.djvu</string>
 				<string>com.lizardtech.djvu</string>
+				<string>public.djvu</string>
 			</array>
 		</dict>
 	</array>
 	<key>CFBundleExecutable</key>
 	<string>djvu</string>
-	<key>CFBundleGetInfoString</key>
-	<string>1.1, Copyright 2007, 2009 Corpus Callosum Corporation</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.djvu.qlgenerator</string>
 	<key>CFBundleInfoDictionaryVersion</key>
@@ -28,9 +26,9 @@
 	<key>CFBundleName</key>
 	<string>djvu</string>
 	<key>CFBundleShortVersionString</key>
-	<string>1.1</string>
+	<string>3.5.21</string>
 	<key>CFBundleVersion</key>
-	<string>1.1</string>
+	<string>3.5.21</string>
 	<key>CFPlugInDynamicRegisterFunction</key>
 	<string></string>
 	<key>CFPlugInDynamicRegistration</key>
@@ -49,8 +47,14 @@
 	</dict>
 	<key>CFPlugInUnloadFunction</key>
 	<string></string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright 2016 Leon Bottou</string>
 	<key>QLNeedsToBeRunInMainThread</key>
 	<false/>
+	<key>QLPreviewHeight</key>
+	<real>600</real>
+	<key>QLPreviewWidth</key>
+	<real>800</real>
 	<key>QLSupportsConcurrentRequests</key>
 	<true/>
 	<key>QLThumbnailMinimumSize</key>
--- djview4-4.10.6.orig/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Info.plist
+++ djview4-4.10.6/mac/skel/Library/Spotlight/DjVu.mdimporter/Contents/Info.plist
@@ -3,22 +3,14 @@
 <plist version="1.0">
 <dict>
 	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
+	<string>en</string>
 	<key>CFBundleDocumentTypes</key>
 	<array>
 		<dict>
-			<key>CFBundleTypeExtensions</key>
-			<array>
-				<string>djvu</string>
-				<string>djv</string>
-			</array>
-			<key>CFBundleTypeName</key>
-			<string>DjVu file</string>
 			<key>CFBundleTypeRole</key>
 			<string>MDImporter</string>
 			<key>LSItemContentTypes</key>
 			<array>
-				<string>org.djvu.DjView</string>
 				<string>org.djvuzone.djvulibre.djvu</string>
 				<string>com.lizardtech.djvu</string>
 				<string>public.djvu</string>
@@ -27,8 +19,6 @@
 	</array>
 	<key>CFBundleExecutable</key>
 	<string>DjVu</string>
-	<key>CFBundleGetInfoString</key>
-	<string>1.3, Copyright Corpus Callosum Corporation 2006</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.djvuzone.djvulibre.MDImporter.DjVu</string>
 	<key>CFBundleInfoDictionaryVersion</key>
@@ -36,7 +26,7 @@
 	<key>CFBundleName</key>
 	<string>DjVu Importer for Spotlight</string>
 	<key>CFBundleShortVersionString</key>
-	<string>1.3</string>
+	<string>3.5.21</string>
 	<key>CFBundleVersion</key>
 	<string>3.5.21</string>
 	<key>CFPlugInDynamicRegisterFunction</key>
@@ -57,6 +47,10 @@
 	</dict>
 	<key>CFPlugInUnloadFunction</key>
 	<string></string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.7</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright Corpus Callosum Corporation 2006</string>
 	<key>UTExportedTypeDeclarations</key>
 	<array>
 		<dict>
@@ -77,35 +71,6 @@
 			<key>UTTypeTagSpecification</key>
 			<dict>
 				<key>com.apple.ostype</key>
-				<string>AT&amp;T</string>
-				<key>public.filename-extension</key>
-				<array>
-					<string>djvu</string>
-					<string>djv</string>
-				</array>
-			</dict>
-		</dict>
-	</array>
-	<key>UTImportedTypeDeclarations</key>
-	<array>
-		<dict>
-			<key>UTTypeConformsTo</key>
-			<array>
-				<string>com.lizardtech.djvu</string>
-				<string>org.djvuzone.djvulibre.djvu</string>
-				<string>public.djvu</string>
-				<string>public.composite-content</string>
-				<string>public.data</string>
-			</array>
-			<key>UTTypeDescription</key>
-			<string>DjVu File</string>
-			<key>UTTypeIdentifier</key>
-			<string>com.lizardtech.djvu</string>
-			<key>UTTypeReferenceURL</key>
-			<string>http://www.lizardtech.com/</string>
-			<key>UTTypeTagSpecification</key>
-			<dict>
-				<key>com.apple.ostype</key>
 				<string>AT&amp;T</string>
 				<key>public.filename-extension</key>
 				<array>
--- djview4-4.10.6.orig/nsdejavu/nsdejavu.1.in
+++ djview4-4.10.6/nsdejavu/nsdejavu.1.in
@@ -213,7 +213,7 @@ tag:
 .SH INTERFACING THE DJVIEW PLUGIN WITH JAVASCRIPT
 Recent versions of the 
 .B djview4
-plugin can be controlled from the JavaScript intepreter of 
+plugin can be controlled from the JavaScript interpreter of 
 browsers implementing the Mozilla NPRuntime API.
 To access the plugin object,
 include the attribute
--- djview4-4.10.6.orig/src/djview.1
+++ djview4-4.10.6/src/djview.1
@@ -755,7 +755,7 @@ is active.
 Most features can be accessed using the menus, 
 the toolbar, the side bar or the pop-up menu
 shown when the right mouse button is depressed over a DjVu image.  
-Detailled help can be accessed by clicking the contextual 
+Detailed help can be accessed by clicking the contextual 
 help icon from the toolbar and then clicking on various 
 section of the djview user interface.
 
--- djview4-4.10.6.orig/src/djview.cpp
+++ djview4-4.10.6/src/djview.cpp
@@ -137,7 +137,12 @@ QDjViewApplication::QDjViewApplication(i
   extern void qt_mac_set_native_menubar(bool);
   qt_mac_set_native_menubar(false);
 #endif
-
+  
+  // Enable highdpi pixmaps
+#if QT_VERSION >= 0x50200
+  setAttribute(Qt::AA_UseHighDpiPixmaps, true);
+#endif
+  
   // Wire session management signals
   connect(this, SIGNAL(saveStateRequest(QSessionManager&)),
           this, SLOT(saveSessionState(QSessionManager&)) );
--- djview4-4.10.6.orig/src/djview.plist
+++ djview4-4.10.6/src/djview.plist
@@ -51,7 +51,9 @@
         <true/>
 	<key>LSItemContentTypes</key>
 	<array>
+	  <string>org.djvuzone.djvulibre.djvu</string>
 	  <string>com.lizardtech.djvu</string>
+	  <string>public.djvu</string>
 	</array>
       </dict>
     </array>
--- djview4-4.10.6.orig/src/djview.pro
+++ djview4-4.10.6/src/djview.pro
@@ -59,7 +59,7 @@ macx {
   RESOURCES.files = images/DjVu.icns
   QMAKE_BUNDLE_DATA += RESOURCES
   QMAKE_INFO_PLIST = djview.plist
-  QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
+  QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
 } 
 
 # --- windows stuff
--- djview4-4.10.6.orig/src/djview_cs.ts
+++ djview4-4.10.6/src/djview_cs.ts
@@ -2239,7 +2239,7 @@ Chcete jej nahradit?</translation>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Informace o dokumentu&lt;/b&gt;&lt;br/&gt;Tento panel zobrazuje informace o dokumentu a jeho souborech, z kterých se skládá. Na záložce &lt;tt&gt;Soubor&lt;/tt&gt; uvidíte informace o souboru vybraném v seznamu podílových souborů. Dvojklikem na podílový soubor zobrazíte odpovídající stránku v hlavním okně.&lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_de.ts
+++ djview4-4.10.6/src/djview_de.ts
@@ -2251,7 +2251,7 @@ Soll die Datei überschrieben werden?</t
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Dokument Informationen&lt;/b&gt;&lt;br&gt;Diese Seite zeigt Informationen über das Dokument und seine abhängigen Dateien. Die Detailinformationen zu der jeweils ausgewählten Datei findet man im &lt;tt&gt;Datei&lt;/tt&gt; tab. Durch einen Doppelklick wird die jeweilige Seite im Hauptfenster dargestellt. &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_es.ts
+++ djview4-4.10.6/src/djview_es.ts
@@ -2247,7 +2247,7 @@ Do you want to replace it?</source>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Información del documento&lt;/b&gt;&lt;br&gt;Este panel muestra información acerca del documento y sus componentes. Seleccionar un componente mostrara información detallada en la pestaña &lt;tt&gt;Archivo&lt;/tt&gt;. Doble click en un componente mostrara la correspondiente página en la ventana principal. &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_fr.ts
+++ djview4-4.10.6/src/djview_fr.ts
@@ -2334,7 +2334,7 @@ Voulez-vous le remplacer?</translation>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Information sur le document&lt;/b&gt;&lt;br&gt;Ce panneau montre les informations sur le document et les fichiers qui le composent. Sélectionnez un nom de fichier pour afficher ses informations sous l&apos;index &lt;tt&gt;Fichier&lt;/tt&gt;. Double-cliquez un nom de fichier pour montrer la page correspondante &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_ru.ts
+++ djview4-4.10.6/src/djview_ru.ts
@@ -2251,7 +2251,7 @@ Do you want to replace it?</source>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Информация о документе&lt;/b&gt;&lt;br&gt;Эта панель показывает информацию о документе и его файлах-компонентах. Выберите файл для просмотра подробной информации во вкладке &lt;tt&gt;Файл&lt;/tt&gt;. Вы можете перейти к странице двойным щелчком по соответствующей строке. &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_uk.ts
+++ djview4-4.10.6/src/djview_uk.ts
@@ -2256,7 +2256,7 @@ Do you want to replace it?</source>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;Інформація про документ&lt;/b&gt;&lt;br&gt;Ця панель показує інформацію про документ та файли, з яких його складено. Оберіть файл-компонент, щоб побачити детальну інформацію на сторінці &lt;tt&gt;Файл&lt;/tt&gt;. Двічі клацніть на файлі-компоненті, щоб побачити відповідну сторінку у головному вікні. &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_zh_cn.ts
+++ djview4-4.10.6/src/djview_zh_cn.ts
@@ -2245,7 +2245,7 @@ Do you want to replace it?</source>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;文档信息&lt;/b&gt;&lt;br&gt;此面板显示文档及其组成文件的信息。 选中组成文件可显示其详细信息于 &lt;tt&gt;文件&lt;/tt&gt; 页中。 双击组成文件可在主窗口中显示其页面。 &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/djview_zh_tw.ts
+++ djview4-4.10.6/src/djview_zh_tw.ts
@@ -2245,7 +2245,7 @@ Do you want to replace it?</source>
     </message>
     <message>
         <location filename="qdjviewdialogs.cpp" line="324"/>
-        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailled information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
+        <source>&lt;html&gt;&lt;b&gt;Document information&lt;/b&gt;&lt;br&gt;This panel shows information about the document and its component files. Select a component file to display detailed information in the &lt;tt&gt;File&lt;/tt&gt; tab. Double click a component file to show the corresponding page in the main window. &lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;b&gt;文件資訊&lt;/b&gt;&lt;br&gt;此面板察看文件及其組成檔案的資訊。 選中組成檔案可察看其詳細資訊於 &lt;tt&gt;檔案&lt;/tt&gt; 頁中。 按兩下組成檔案可在主視窗中察看其頁面。 &lt;/html&gt;</translation>
     </message>
     <message>
--- djview4-4.10.6.orig/src/qdjview.cpp
+++ djview4-4.10.6/src/qdjview.cpp
@@ -2710,13 +2710,78 @@ QDjView::open(QString filename)
 }
 
 
-/*! Open the djvu document available at url \a url.
-  Only the \a http: and \a file: protocols are supported. */
+/* Helper class to open remote documents */
+
+class QDjView::NetOpen : public QObject
+{
+  Q_OBJECT
+private:
+  QDjView *q;
+  QDjVuNetDocument *doc;
+  QUrl url;
+  bool inNewWindow;
+  bool maybeInBrowser;
+  bool startedBrowser;
+public:
+  ~NetOpen() {
+    if (doc) {
+      doc->deref();
+      if (! startedBrowser) {
+        q->addToErrorDialog(tr("Cannot open URL '%1'.").arg(url.toString()));
+        q->raiseErrorDialog(QMessageBox::Critical, tr("Opening DjVu document"));
+      }
+    }
+  }
+  NetOpen(QDjView *q, QDjVuNetDocument *d, QUrl u, bool n, bool b)
+    : QObject(q),
+      q(q), doc(d), url(u),
+      inNewWindow(n), maybeInBrowser(b),
+      startedBrowser(false) {
+    doc->ref();
+    connect(doc, SIGNAL(docinfo()),
+            this, SLOT(docinfo()) );
+    connect(doc, SIGNAL(gotContentType(QString,bool&)),
+            this, SLOT(gotContentType(QString,bool&)) );
+  }
+public slots:
+  void docinfo() {
+    int status = ddjvu_document_decoding_status(*doc);
+    if (status == DDJVU_JOB_OK) {
+      disconnect(doc,0,this,0);
+      if (inNewWindow) {
+        QDjView *other = q->copyWindow();
+        other->open(url);
+        other->show();
+      } else {
+        q->open(doc,url);
+      }
+      doc = 0;
+    }
+    if (status >= DDJVU_JOB_OK)
+      deleteLater();
+  }
+  void gotContentType(QString type, bool &okay) {
+    QRegExp re("image/(x[.]|vnd[.-]|)(djvu|dejavu|iw44)(;.*)?");
+    okay = re.exactMatch(type);
+    if (maybeInBrowser && !okay) {
+      startedBrowser = q->startBrowser(url);
+      if (startedBrowser) {
+        disconnect(doc,0,this,0);
+        deleteLater();
+      } else {
+        QString msg = tr("Cannot spawn a browser for url '%1'").arg(url.toString());
+        qWarning("%s",(const char*)msg.toLocal8Bit());
+      }
+    }
+  }
+};
+
+
+/*! Open the djvu document available at url \a url. */
 
 bool
-QDjView::open(QUrl url)
+QDjView::open(QUrl url, bool inNewWindow, bool maybeInBrowser)
 {
-  closeDocument();
   QDjVuNetDocument *doc = new QDjVuNetDocument(true);
   connect(doc, SIGNAL(error(QString,QString,int)),
           errorDialog, SLOT(error(QString,QString,int)));
@@ -2726,14 +2791,14 @@ QDjView::open(QUrl url)
           this, SLOT(sslWhiteList(QString,bool&)) );
   QUrl docurl = removeDjVuCgiArguments(url);
   doc->setUrl(&djvuContext, docurl);
-  if (!doc->isValid())
+  if (! (url.isValid() && doc->isValid()))
     {
       delete doc;
       addToErrorDialog(tr("Cannot open URL '%1'.").arg(url.toString()));
       raiseErrorDialog(QMessageBox::Critical, tr("Opening DjVu document"));
       return false;
     }
-  open(doc, url);
+  new NetOpen(this, doc, url, inNewWindow, maybeInBrowser);
   return true;
 }
 
@@ -4151,27 +4216,8 @@ QDjView::goToLink(QString link, QString
       emit pluginGetUrl(url, target);
       return;
     }
-  // Standalone can open djvu documents
-  QFileInfo file = url.toLocalFile();
-  QString suffix = file.suffix().toLower();
-  if (file.exists() && (suffix=="djvu" || suffix=="djv"))
-    {
-      if (inPlace)
-        open(url);
-      else
-        {
-          QDjView *other = copyWindow();
-          other->open(url);
-          other->show();
-        }
-      return;
-    }
-  // Open a browser
-  if (! startBrowser(url))
-    {
-      QString msg = tr("Cannot spawn a browser for url '%1'").arg(link);
-      qWarning("%s",(const char*)msg.toLocal8Bit());
-    }
+  // Standalone only: call open(QUrl,...) with adequate flags
+  open(url, !inPlace, true);
 }
 
 
@@ -4957,6 +5003,11 @@ QDjView::performCopyAnnotation()
 }
 
 
+// ----------------------------------------
+// MOC
+
+#include "qdjview.moc"
+
 
 /* -------------------------------------------------------------
    Local Variables:
--- djview4-4.10.6.orig/src/qdjview.h
+++ djview4-4.10.6/src/qdjview.h
@@ -131,7 +131,7 @@ class QDjView : public QMainWindow
 
 public slots:
   bool  open(QString filename);
-  bool  open(QUrl url);
+  bool  open(QUrl url, bool inNewWindow=false, bool maybeInBrowser=false);
   void  open(QDjVuDocument *document, QUrl url = QUrl());
   void  closeDocument();
   void  reloadDocument();
@@ -404,6 +404,8 @@ protected:
   QTimer *undoTimer;
   QList<UndoRedo> undoList;
   QList<UndoRedo> redoList;
+  // netopen
+  class NetOpen;
 };
 
 #endif
--- djview4-4.10.6.orig/src/qdjviewdialogs.cpp
+++ djview4-4.10.6/src/qdjviewdialogs.cpp
@@ -324,7 +324,7 @@ QDjViewInfoDialog::QDjViewInfoDialog(QDj
   wd->setWhatsThis(tr("<html><b>Document information</b><br>"
                       "This panel shows information about the document and "
                       "its component files. Select a component file "
-                      "to display detailled information in the <tt>File</tt> "
+                      "to display detailed information in the <tt>File</tt> "
                       "tab. Double click a component file to show "
                       "the corresponding page in the main window. "
                       "</html>"));
--- djview4-4.10.6.orig/src/qdjviewsidebar.cpp
+++ djview4-4.10.6/src/qdjviewsidebar.cpp
@@ -603,9 +603,14 @@ QDjViewThumbnails::Model::makeIcon(int p
   if (doc)
     {
       // render thumbnail
-      int w = size;
-      int h = size;
-      QImage img(size, size, QImage::Format_RGB32);
+#if QT_VERSION >= 0x50200
+      int dpr = djview->devicePixelRatio();
+#else
+      int dpr = 1;
+#endif
+      int w = size * dpr;
+      int h = size * dpr;
+      QImage img(size*dpr, size*dpr, QImage::Format_RGB32);
       int status = ddjvu_thumbnail_status(*doc, pageno, 0);
       if (status == DDJVU_JOB_NOTSTARTED)
         {
@@ -614,9 +619,9 @@ QDjViewThumbnails::Model::makeIcon(int p
       else if (ddjvu_thumbnail_render(*doc, pageno, &w, &h, format, 
                                       img.bytesPerLine(), (char*)img.bits() ))
         {
-          QPixmap pixmap(size,size);
+          QPixmap pixmap(size*dpr,size*dpr);
           pixmap.fill();
-          QPoint dst((size-w)/2, (size-h)/2);
+          QPoint dst((size*dpr-w)/2, (size*dpr-h)/2);
           QRect src(0,0,w,h);
           QPainter painter;
           painter.begin(&pixmap);
@@ -625,6 +630,9 @@ QDjViewThumbnails::Model::makeIcon(int p
           painter.setPen(Qt::darkGray);
           painter.drawRect(dst.x(), dst.y(), w-1, h-1);
           painter.end();
+#if QT_VERSION >= 0x50200
+          pixmap.setDevicePixelRatio(dpr);
+#endif
           return QIcon(pixmap);
         }
     }
--- djview4-4.10.6.orig/src/qdjvu.cpp
+++ djview4-4.10.6/src/qdjvu.cpp
@@ -561,7 +561,7 @@ QDjVuDocument::streamClose(int streamid,
 
 /*! Processes DDJVUAPI messages for this document. 
     The default implementation emits signals for
-    the \a m_error, \a m_info, \a m_docinfo, \a m_pageingo
+    the \a m_error, \a m_info, \a m_docinfo, \a m_pageinfo
     and \a m_thumbnail messsages. It also calls
     the virtual function \a newstream when processing
     a \m newstream message. The return value is a boolean indicating
--- djview4-4.10.6.orig/src/qdjvunet.cpp
+++ djview4-4.10.6/src/qdjvunet.cpp
@@ -64,8 +64,7 @@ public slots:
   void proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth);
 
 private:
-  void doRead(QNetworkReply *reply, int streamid);
-  void doError(QNetworkReply *reply, int streamid);
+  bool doHeaders(QNetworkReply *reply, int streamid);
   bool doAuth(QString why, QAuthenticator *auth);
 };
 
@@ -82,100 +81,115 @@ QDjVuNetDocument::Private::Private(QDjVu
 
 QDjVuNetDocument::Private::~Private()
 {
-  QMap<QNetworkReply*,int>::iterator it;
-  for(it = reqid.begin(); it != reqid.end(); ++it)
+  while (! reqid.isEmpty())
     {
+      QMap<QNetworkReply*,int>::iterator it = reqid.begin();
       QNetworkReply *reply = it.key();
       int streamid = it.value();
       if (streamid >= 0)
         ddjvu_stream_close(*q, streamid, true);
       reply->abort();
       reply->deleteLater();
+      reqid.remove(reply);
     }
   reqid.clear();
   reqok.clear();
 }
 
-void
-QDjVuNetDocument::Private::doRead(QNetworkReply *reply, int streamid)
+bool
+QDjVuNetDocument::Private::doHeaders(QNetworkReply *reply, int streamid)
 {
-  QByteArray b = reply->readAll();
-  if (streamid >= 0 && b.size() > 0)
+  if (streamid >= 0 && !reqok.value(reply, false))
     {
-      if (! reqok.value(reply, false))
+      int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+      QUrl location = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+      QByteArray type = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray();
+      // check redirection
+      if (location.isValid())
         {
-          int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-          QUrl location = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
-          QByteArray type = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray();
-          // check redirection
-          if (location.isValid())
-            {
-              reqid[reply] = -1;
-              QUrl nurl = reply->url().resolved(location);
-              if (streamid > 0 || status == 307)
-                { 
-                  q->newstream(streamid, QString(), nurl);
-                  return;
-                }
-              // Permanent redirect on main stream changes the base url.
-              ddjvu_stream_close(*q, streamid, false);
-              q->setUrl(ctx, nurl, cache);
-              if (q->isValid())
-                return;
-            }
-          // check status code
-          if (status != 200 && status != 203 && status != 0)
-            {
-              QString msg = tr("Received http status %1 while retrieving %2.",
-                               "%1 is an http status code")
-                .arg(status)
-                .arg(reply->url().toString());
-              emit q->error(msg, __FILE__, __LINE__);
-              return;
-            }
-          // check content type
-          if (type.startsWith("text/"))
-            {
-              QString msg = tr("Received <%1> data while retrieving %2.", 
-                               "%1 is a mime type")
-                .arg(QString::fromLatin1(type))
-                .arg(reply->url().toString());
-              emit q->error(msg, __FILE__, __LINE__);
-            }
-          reqok[reply] = true;
+          reqid[reply] = -1;
+          QUrl nurl = reply->url().resolved(location);
+          if (streamid > 0 || status == 307) {
+            q->newstream(streamid, QString(), nurl);
+          } else {
+            // Permanent redirect on main stream changes the base url.
+            ddjvu_document_set_user_data(*q, 0);
+            ddjvu_stream_close(*q, streamid, true);
+            q->setUrl(ctx, nurl, cache);
+          }
+          return false;
         }
-      // process data
-      ddjvu_stream_write(*q, streamid, b.data(), b.size());
+      // check status code
+      if (status != 200 && status != 203 && status != 0)
+        {
+          reqid[reply] = -1;
+          ddjvu_stream_close(*q, streamid, false);
+          QString msg = tr("Received http status %1 while retrieving %2.",
+                           "%1 is an http status code")
+            .arg(status)
+            .arg(reply->url().toString());
+          emit q->error(msg, __FILE__, __LINE__);
+          return false;
+        }
+      // broadcast content type
+      bool okay = !type.startsWith("text/");
+      if (! type.isEmpty())
+        emit q->gotContentType(type, okay);
+      if (! okay) 
+        {
+          reqid[reply] = -1;
+          ddjvu_stream_close(*q, streamid, false);
+          QString msg = tr("Received <%1> data while retrieving %2.", 
+                           "%1 is a mime type")
+            .arg(QString::fromLatin1(type))
+            .arg(reply->url().toString());
+          emit q->error(msg, __FILE__, __LINE__);
+          return false;
+        }
+      reqok[reply] = true;
+      return true;
     }
+  return false;
 }
 
-void
-QDjVuNetDocument::Private::doError(QNetworkReply *reply, int streamid)
+void 
+QDjVuNetDocument::Private::readyRead()
 {
-  QNetworkReply::NetworkError code = reply->error();
-  if (streamid >= 0 && code != QNetworkReply::NoError)
+  QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
+  if (reply) 
     {
-      QString msg = tr("%1 while retrieving '%2'.")
-        .arg(reply->errorString())
-        .arg(reply->url().toString());
-      emit q->error(msg , __FILE__, __LINE__);
-      ddjvu_stream_close(*q, streamid, false);
-      reqid[reply] = -1;
+      int streamid = reqid.value(reply, -1);
+      bool okay = reqok.value(reply, false);
+      if (streamid >= 0 && !okay)
+        okay = doHeaders(reply, streamid);
+      if (streamid >= 0 && okay)
+        {
+          QByteArray b = reply->readAll();
+          if (b.size() > 0)
+            ddjvu_stream_write(*q, streamid, b.data(), b.size());
+        }
     }
 }
 
 void 
-QDjVuNetDocument::Private::readyRead()
+QDjVuNetDocument::Private::error(QNetworkReply::NetworkError code)
 {
   QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
   if (reply) 
     {
       int streamid = reqid.value(reply, -1);
-      if (streamid >= 0)
-        doRead(reply, streamid);
+      if (streamid >= 0 && code != QNetworkReply::NoError)
+        {
+          reqid[reply] = -1;
+          ddjvu_stream_close(*q, streamid, false);
+          QString msg = tr("%1 while retrieving '%2'.")
+            .arg(reply->errorString())
+            .arg(reply->url().toString());
+          emit q->error(msg , __FILE__, __LINE__);
+        }
     }
 }
- 
+
 void 
 QDjVuNetDocument::Private::finished()
 {
@@ -183,14 +197,13 @@ QDjVuNetDocument::Private::finished()
   if (reply)
     {
       int streamid = reqid.value(reply, -1);
-      if (streamid >= 0)
+      bool okay = reqok.value(reply, false);
+      if (streamid >= 0 && !okay)
+        okay = doHeaders(reply, streamid);
+      if (streamid >= 0 && okay)
         {
-          if (reply->bytesAvailable() > 0)
-            doRead(reply, streamid);
-          if (reply->error() != QNetworkReply::NoError)
-            doError(reply, streamid);
-          else
-            ddjvu_stream_close(*q, streamid, false);
+          ddjvu_stream_close(*q, streamid, false);
+          reqid[reply] = -1;
         }
     }
   reqid.remove(reply);
@@ -199,18 +212,6 @@ QDjVuNetDocument::Private::finished()
 }
 
 void 
-QDjVuNetDocument::Private::error(QNetworkReply::NetworkError)
-{
-  QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
-  if (reply) 
-    {
-      int streamid = reqid.value(reply, -1);
-      if (streamid >= 0)
-        doError(reply, streamid);
-    }
-}
-
-void 
 QDjVuNetDocument::Private::sslErrors(const QList<QSslError>&)
 {
   QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
--- djview4-4.10.6.orig/src/qdjvunet.h
+++ djview4-4.10.6/src/qdjvunet.h
@@ -42,6 +42,7 @@ protected:
 signals:
   void authRequired(QString why, QString &user, QString &pass);
   void sslWhiteList(QString why, bool &okay);
+  void gotContentType(QString type, bool &okay);
 private:
   class Private;
   Private *p;
--- djview4-4.10.6.orig/src/qdjvuwidget.cpp
+++ djview4-4.10.6/src/qdjvuwidget.cpp
@@ -692,7 +692,7 @@ struct MapArea
   bool contains(const QPoint &p);
   void maybeRotate(struct Page *p);
   QPainterPath contour(QRectMapper &m, QPoint &offset);
-  void update(QWidget *w, QRectMapper &m, QPoint offset, bool clicked=false);
+  void update(QWidget *w, QRectMapper &m, QPoint offset, bool permanent=false);
   void paintBorder(QPaintDevice *w, QRectMapper &m, QPoint offset, bool allLinks=false);
   void paintPermanent(QPaintDevice *w, QRectMapper &m, QPoint o, double z=100);
   void paintTransient(QPaintDevice *w, QRectMapper &m, QPoint o, bool allLinks=false);
@@ -2220,7 +2220,8 @@ QDjVuWidget::setDocument(QDjVuDocument *
                   priv, SLOT(info(QString)));
           connect(priv->doc, SIGNAL(idle()),
                   priv, SLOT(makePageRequests()));
-          priv->docinfo();
+          // the document may already be ready
+          QTimer::singleShot(0, priv, SLOT(docinfo()));
         }
       // update
       priv->estimatedWidth = 0;
@@ -3404,10 +3405,12 @@ bool
 MapArea::hasTransient(bool allLinks)
 {
   Keywords &k = *keywords();
-  if (areaType == miniexp_nil || borderAlwaysVisible)
+  if (areaType == miniexp_nil)
     return false;
   if (allLinks && miniexp_stringp(url))
     return true;
+  if (borderAlwaysVisible)
+    return false;
   if (borderType == k.none || borderType == miniexp_nil)
     return false;
   return true;
@@ -3482,16 +3485,28 @@ MapArea::contains(const QPoint &p)
 }
 
 void 
-MapArea::update(QWidget *w, QRectMapper &m, QPoint offset, bool clicked)
+MapArea::update(QWidget *w, QRectMapper &m, QPoint offset, bool permanent)
 {
   // The mapper <m> maps page coordinates to 
   // widget coordinates translated by <offset>.
   Keywords &k = *keywords();
   int bw = borderWidth;
   QRect rect = m.mapped(areaRect).translated(-offset);
-  if (! rect.intersects(w->rect())) 
-    return;
-  if (areaType == k.oval || areaType == k.poly)
+  if (! rect.intersects(w->rect()))
+    {
+      return;
+    }
+  else if (permanent && hiliteColor.isValid() && hiliteOpacity>0)
+    {
+      int bw2 = (bw / 2) + 1;
+      w->update(rect.adjusted(-bw2-1, -bw2-1, bw2+1, bw2+1));
+    }
+  else if (permanent && (areaType == k.text || areaType == k.pushpin))
+    {
+      int bw2 = (bw / 2) + 1;
+      w->update(rect.adjusted(-bw2-1, -bw2-1, bw2+1, bw2+1));
+    }
+  else if (areaType == k.oval || areaType == k.poly)
     {
       int bw2 = (bw / 2) + 1;
       QPainterPath path = contour(m, offset);
@@ -3507,11 +3522,6 @@ MapArea::update(QWidget *w, QRectMapper
       region.translate(rect.topLeft());
       w->update(region);
     }
-  else if (clicked && (areaType == k.text || areaType == k.pushpin))
-    {
-      int bw2 = (bw / 2) + 1;
-      w->update(rect.adjusted(-bw2-1, -bw2-1, bw2+1, bw2+1));
-    }
   else
     {
       int bw2 = (bw / 2) + 1;
@@ -3824,7 +3834,7 @@ QDjVuPrivate::showTransientMapAreas(bool
           {
             MapArea &area = p->mapAreas[i];
             area.maybeRotate(p);
-            if (area.hasTransient(allLinksDisplayed))
+            if (area.hasTransient(true))
               area.update(widget->viewport(), p->mapper, 
                           visibleRect.topLeft() );
           }
@@ -3848,7 +3858,7 @@ QDjVuWidget::clearHighlights(int pageno)
           {
             MapArea &area = p->mapAreas[j];
             if (priv->pageMap.contains(pageno) && p->dpi>0)
-              area.update(viewport(), p->mapper, priv->visibleRect.topLeft());
+              area.update(viewport(), p->mapper, priv->visibleRect.topLeft(), true);
             priv->pixelCache.clear();
             p->mapAreas.removeAt(j);
           }
@@ -3882,7 +3892,7 @@ QDjVuWidget::addHighlight(int pageno, in
       p->mapAreas << area;
       priv->pixelCache.clear();
       if (priv->pageMap.contains(pageno) && p->dpi>0)
-        area.update(viewport(), p->mapper, priv->visibleRect.topLeft());
+        area.update(viewport(), p->mapper, priv->visibleRect.topLeft(), true);
     }
 }
 
--- djview4-4.10.6.orig/src/tiff2pdf.c
+++ djview4-4.10.6/src/tiff2pdf.c
@@ -1,4 +1,4 @@
-/*  -*- C -*-
+/*  -*- mode: C; tab-width: 4; c-basic-offset: 4 -*-
 //C- -------------------------------------------------------------------
 //C- DjView4
 //C- Copyright (c) 2006  Leon Bottou
@@ -20,8 +20,8 @@
 // Changes were made to make it independent from the private
 // include file tiffiop.h.
 */
-
-/* $Id: tiff2pdf.c,v 1.37.2.7 2009-01-01 00:10:43 bfriesen Exp $
+	
+/* $Id: tiff2pdf.c,v 1.103 2017-10-29 18:50:41 bfriesen Exp $
  *
  * tiff2pdf - converts a TIFF image to a PDF document
  *
@@ -56,6 +56,8 @@
 #include <string.h>
 #include <ctype.h>
 #include <time.h>
+#include <errno.h>
+#include <limits.h>
 
 #if HAVE_UNISTD_H
 # include <unistd.h>
@@ -65,10 +67,6 @@
 # include <fcntl.h>
 #endif
 
-#ifdef HAVE_GETOPT_H
-# include <getopt.h>
-#endif
-
 #if defined(__GNUC__) || defined(HAVE_LONG_LONG_INT)
 # define uint64 unsigned long long
 #elif defined(_MSC_VER)
@@ -76,6 +74,23 @@
 #else
 # define uint64 size_t
 #endif
+#ifndef TIFFSafeMultiply
+#  define TIFFSafeMultiply(t,v,m) \
+     ((((t)(m)!=(t)0)&&(((t)(((v)*(m))/(m)))==(t)(v)))?(t)((v)*(m)):(t)0)
+#endif
+#ifndef TIFF_SIZE_FORMAT
+# define TIFF_SIZE_T unsigned long
+# define TIFF_SIZE_FORMAT "%lu"
+#endif
+#ifndef TIFFmin
+# define TIFFmin(A,B) ((A)<(B)?(A):(B))
+#endif
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+
 
 #ifndef HAVE_GETOPT_H
 /*
@@ -195,6 +210,12 @@ getopt(int argc, char * const argv[], co
 }
 #endif
 
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS	0
+#endif
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE	1
+#endif
 
 #define TIFF2PDF_MODULE "tiff2pdf"
 
@@ -320,6 +341,7 @@ typedef struct {
 	float pdf_pagelength;
 	float pdf_imagewidth;
 	float pdf_imagelength;
+	int pdf_image_fillpage; /* 0 (default: no scaling, 1:scale imagesize to pagesize */
 	T2P_BOX pdf_mediabox;
 	T2P_BOX pdf_imagebox;
 	uint16 pdf_majorversion;
@@ -330,13 +352,20 @@ typedef struct {
 	uint32 pdf_palettecs;
 	uint16 pdf_fitwindow;
 	uint32 pdf_startxref;
-	unsigned char* pdf_fileid;
-	unsigned char* pdf_datetime;
-	unsigned char* pdf_creator;
-	unsigned char* pdf_author;
-	unsigned char* pdf_title;
-	unsigned char* pdf_subject;
-	unsigned char* pdf_keywords;
+#define TIFF2PDF_FILEID_SIZE 33
+	char pdf_fileid[TIFF2PDF_FILEID_SIZE];
+#define TIFF2PDF_DATETIME_SIZE 17
+	char pdf_datetime[TIFF2PDF_DATETIME_SIZE];
+#define TIFF2PDF_CREATOR_SIZE 512
+	char pdf_creator[TIFF2PDF_CREATOR_SIZE];
+#define TIFF2PDF_AUTHOR_SIZE 512
+	char pdf_author[TIFF2PDF_AUTHOR_SIZE];
+#define TIFF2PDF_TITLE_SIZE 512
+	char pdf_title[TIFF2PDF_TITLE_SIZE];
+#define TIFF2PDF_SUBJECT_SIZE 512
+	char pdf_subject[TIFF2PDF_SUBJECT_SIZE];
+#define TIFF2PDF_KEYWORDS_SIZE 512
+	char pdf_keywords[TIFF2PDF_KEYWORDS_SIZE];
 	t2p_cs_t pdf_colorspace;
 	uint16 pdf_colorspace_invert;
 	uint16 pdf_switchdecode;
@@ -377,7 +406,8 @@ typedef struct {
 
 /* These functions are called by main. */
 
-static int tiff2pdf_match_paper_size(float*, float*, char*);
+static
+int tiff2pdf_match_paper_size(float*, float*, char*);
 
 /* These functions are used to generate a PDF from a TIFF. */ 
 
@@ -385,76 +415,143 @@ static int tiff2pdf_match_paper_size(flo
 extern "C" {
 #endif
 
-static T2P* t2p_init(void);
-static void t2p_validate(T2P*);
-static tsize_t t2p_write_pdf(T2P*, TIFF*, TIFF*);
-static void t2p_free(T2P*);
+static
+T2P* t2p_init(void);
+static
+void t2p_validate(T2P*);
+static
+tsize_t t2p_write_pdf(T2P*, TIFF*, TIFF*);
+static
+void t2p_free(T2P*);
 
 #ifdef __cplusplus
 }
 #endif
 
-static void t2p_read_tiff_init(T2P*, TIFF*);
-static int t2p_cmp_t2p_page(const void*, const void*);
-static void t2p_read_tiff_data(T2P*, TIFF*);
-static void t2p_read_tiff_size(T2P*, TIFF*);
-static void t2p_read_tiff_size_tile(T2P*, TIFF*, ttile_t);
-static int t2p_tile_is_right_edge(T2P_TILES, ttile_t);
-static int t2p_tile_is_bottom_edge(T2P_TILES, ttile_t);
-/* static int t2p_tile_is_edge(T2P_TILES, ttile_t); */
-/* static int t2p_tile_is_corner_edge(T2P_TILES, ttile_t); */
-static tsize_t t2p_readwrite_pdf_image(T2P*, TIFF*, TIFF*);
-static tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t);
+static
+void t2p_read_tiff_init(T2P*, TIFF*);
+static
+int t2p_cmp_t2p_page(const void*, const void*);
+static
+void t2p_read_tiff_data(T2P*, TIFF*);
+static
+void t2p_read_tiff_size(T2P*, TIFF*);
+static
+void t2p_read_tiff_size_tile(T2P*, TIFF*, ttile_t);
+static
+int t2p_tile_is_right_edge(T2P_TILES, ttile_t);
+static
+int t2p_tile_is_bottom_edge(T2P_TILES, ttile_t);
+/* static 
+int t2p_tile_is_edge(T2P_TILES, ttile_t); */
+/* static 
+int t2p_tile_is_corner_edge(T2P_TILES, ttile_t); */
+static
+tsize_t t2p_readwrite_pdf_image(T2P*, TIFF*, TIFF*);
+static
+tsize_t t2p_readwrite_pdf_image_tile(T2P*, TIFF*, TIFF*, ttile_t);
 #ifdef OJPEG_SUPPORT
-static int t2p_process_ojpeg_tables(T2P*, TIFF*);
+static
+int t2p_process_ojpeg_tables(T2P*, TIFF*);
 #endif
 #ifdef JPEG_SUPPORT
-static int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t*, tstrip_t, uint32);
+static
+int t2p_process_jpeg_strip(unsigned char*, tsize_t*, unsigned char*, tsize_t, tsize_t*, tstrip_t, uint32);
 #endif
-static void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32);
-static void t2p_write_advance_directory(T2P*, TIFF*);
-static tsize_t t2p_sample_planar_separate_to_contig(T2P*, unsigned char*, unsigned char*, tsize_t);
-static tsize_t t2p_sample_realize_palette(T2P*, unsigned char*);
-static tsize_t t2p_sample_abgr_to_rgb(tdata_t, uint32);
-static tsize_t t2p_sample_rgba_to_rgb(tdata_t, uint32);
-static tsize_t t2p_sample_rgbaa_to_rgb(tdata_t, uint32);
-static tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t, uint32);
-static tsize_t t2p_write_pdf_header(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_obj_start(uint32, TIFF*);
-static tsize_t t2p_write_pdf_obj_end(TIFF*);
-/* static tsize_t t2p_write_pdf_name(unsigned char*, TIFF*); */
-static tsize_t t2p_write_pdf_string(unsigned char*, TIFF*);
-static tsize_t t2p_write_pdf_stream(tdata_t, tsize_t, TIFF*);
-static tsize_t t2p_write_pdf_stream_start(TIFF*);
-static tsize_t t2p_write_pdf_stream_end(TIFF*);
-static tsize_t t2p_write_pdf_stream_dict(tsize_t, uint32, TIFF*);
-static tsize_t t2p_write_pdf_stream_dict_start(TIFF*);
-static tsize_t t2p_write_pdf_stream_dict_end(TIFF*);
-static tsize_t t2p_write_pdf_stream_length(tsize_t, TIFF*);
-static tsize_t t2p_write_pdf_catalog(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_info(T2P*, TIFF*, TIFF*);
-static void t2p_pdf_currenttime(T2P*);
-static void t2p_pdf_tifftime(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_pages(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_page(uint32, T2P*, TIFF*);
-static void t2p_compose_pdf_page(T2P*);
-static void t2p_compose_pdf_page_orient(T2P_BOX*, uint16);
-static void t2p_compose_pdf_page_orient_flip(T2P_BOX*, uint16);
-/* static tsize_t t2p_write_pdf_page_content(T2P*, TIFF*); */
-static tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t, T2P*, TIFF*); 
-static tsize_t t2p_write_pdf_xobject_cs(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_transfer(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_transfer_dict(T2P*, TIFF*, uint16);
-static tsize_t t2p_write_pdf_transfer_stream(T2P*, TIFF*, uint16);
-static tsize_t t2p_write_pdf_xobject_calcs(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_xobject_icccs(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_xobject_icccs_dict(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_xobject_icccs_stream(T2P*, TIFF*);
+static
+void t2p_tile_collapse_left(tdata_t, tsize_t, uint32, uint32, uint32);
+static
+void t2p_write_advance_directory(T2P*, TIFF*);
+static
+tsize_t t2p_sample_planar_separate_to_contig(T2P*, unsigned char*, unsigned char*, tsize_t);
+static
+tsize_t t2p_sample_realize_palette(T2P*, unsigned char*);
+static
+tsize_t t2p_sample_abgr_to_rgb(tdata_t, uint32);
+static
+tsize_t t2p_sample_rgba_to_rgb(tdata_t, uint32);
+static
+tsize_t t2p_sample_rgbaa_to_rgb(tdata_t, uint32);
+static
+tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t, uint32);
+static
+tsize_t t2p_write_pdf_header(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_obj_start(uint32, TIFF*);
+static
+tsize_t t2p_write_pdf_obj_end(TIFF*);
+/* static 
+tsize_t t2p_write_pdf_name(unsigned char*, TIFF*); */
+static
+tsize_t t2p_write_pdf_string(char*, TIFF*);
+static
+tsize_t t2p_write_pdf_stream(tdata_t, tsize_t, TIFF*);
+static
+tsize_t t2p_write_pdf_stream_start(TIFF*);
+static
+tsize_t t2p_write_pdf_stream_end(TIFF*);
+static
+tsize_t t2p_write_pdf_stream_dict(tsize_t, uint32, TIFF*);
+static
+tsize_t t2p_write_pdf_stream_dict_start(TIFF*);
+static
+tsize_t t2p_write_pdf_stream_dict_end(TIFF*);
+static
+tsize_t t2p_write_pdf_stream_length(tsize_t, TIFF*);
+static
+tsize_t t2p_write_pdf_catalog(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_info(T2P*, TIFF*, TIFF*);
+static
+void t2p_pdf_currenttime(T2P*);
+static
+void t2p_pdf_tifftime(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_pages(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_page(uint32, T2P*, TIFF*);
+static
+void t2p_compose_pdf_page(T2P*);
+static
+void t2p_compose_pdf_page_orient(T2P_BOX*, uint16);
+static
+void t2p_compose_pdf_page_orient_flip(T2P_BOX*, uint16);
+/* static 
+tsize_t t2p_write_pdf_page_content(T2P*, TIFF*); */
+static
+tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t, T2P*, TIFF*); 
+static
+tsize_t t2p_write_pdf_xobject_cs(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_transfer(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_transfer_dict(T2P*, TIFF*, uint16);
+static
+tsize_t t2p_write_pdf_transfer_stream(T2P*, TIFF*, uint16);
+static
+tsize_t t2p_write_pdf_xobject_calcs(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xobject_icccs(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xobject_icccs_dict(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xobject_icccs_stream(T2P*, TIFF*);
 /* static tsize_t t2p_write_pdf_xobject_cs_stream(T2P*, TIFF*); */
-static tsize_t t2p_write_pdf_xobject_decode(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t, T2P*, TIFF*);
-static tsize_t t2p_write_pdf_xreftable(T2P*, TIFF*);
-static tsize_t t2p_write_pdf_trailer(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xobject_decode(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t, T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_xreftable(T2P*, TIFF*);
+static
+tsize_t t2p_write_pdf_trailer(T2P*, TIFF*);
+
+#define check_snprintf_ret(t2p, rv, buf) do { \
+	if ((rv) < 0) rv = 0; \
+	else if((rv) >= (int)sizeof(buf)) (rv) = sizeof(buf) - 1; \
+	else break; \
+	if ((t2p) != NULL) (t2p)->t2p_error = T2P_ERR_ERROR; \
+} while(0)
 
 static void
 t2p_disable(TIFF *tif)
@@ -474,45 +571,47 @@ t2p_enable(TIFF *tif)
  * Procs for TIFFClientOpen
  */
 
-static tsize_t 
-t2pReadFile(TIFF *tif, tdata_t data, tsize_t size)
+#ifdef OJPEG_SUPPORT
+static tmsize_t 
+t2pReadFile(TIFF *tif, tdata_t data, tmsize_t size)
 {
 	thandle_t client = TIFFClientdata(tif);
-	TIFFReadWriteProc proc =  TIFFGetReadProc(tif);
+	TIFFReadWriteProc proc = TIFFGetReadProc(tif);
 	if (proc)
 		return proc(client, data, size);
 	return -1;
 }
+#endif /* OJPEG_SUPPORT */
 
-static tsize_t 
-t2pWriteFile(TIFF *tif, tdata_t data, tsize_t size)
+static tmsize_t 
+t2pWriteFile(TIFF *tif, tdata_t data, tmsize_t size)
 {
 	thandle_t client = TIFFClientdata(tif);
-	TIFFReadWriteProc proc =  TIFFGetWriteProc(tif);
+	TIFFReadWriteProc proc = TIFFGetWriteProc(tif);
 	if (proc)
 		return proc(client, data, size);
 	return -1;
 }
 
-static toff_t
+static uint64
 t2pSeekFile(TIFF *tif, toff_t offset, int whence)
 {
 	thandle_t client = TIFFClientdata(tif);
-	TIFFSeekProc proc =  TIFFGetSeekProc(tif);
+	TIFFSeekProc proc = TIFFGetSeekProc(tif);
 	if (proc)
 		return proc(client, offset, whence);
 	return -1;
 }
 
-static tsize_t 
-t2p_readproc(thandle_t handle, tdata_t data, tsize_t size) 
+static tmsize_t 
+t2p_readproc(thandle_t handle, tdata_t data, tmsize_t size) 
 {
 	(void) handle, (void) data, (void) size;
 	return -1;
 }
 
-static tsize_t 
-t2p_writeproc(thandle_t handle, tdata_t data, tsize_t size) 
+static tmsize_t 
+t2p_writeproc(thandle_t handle, tdata_t data, tmsize_t size) 
 {
 	T2P *t2p = (T2P*) handle;
 	if (t2p->outputdisable <= 0 && t2p->outputfile) {
@@ -527,8 +626,13 @@ static toff_t
 t2p_seekproc(thandle_t handle, toff_t offset, int whence) 
 { 
 	T2P *t2p = (T2P*) handle;
-	if (t2p->outputdisable <= 0 && t2p->outputfile)
-		return fseek(t2p->outputfile, offset, whence);
+	if (t2p->outputdisable <= 0 && t2p->outputfile) {
+#if HAVE_FSEEKO
+        return fseeko(t2p->outputfile, (off_t) offset, whence);
+#else            
+        return fseek(t2p->outputfile, (long) offset, whence);
+#endif
+    }
 	return offset;
 }
 
@@ -536,7 +640,7 @@ static int
 t2p_closeproc(thandle_t handle)
 { 
 	(void) handle;
-	return 0; 
+	return 0;
 }
 
 static toff_t 
@@ -547,24 +651,25 @@ t2p_sizeproc(thandle_t handle)
 }
 
 static int 
-t2p_mapproc(thandle_t handle, tdata_t *data, toff_t *offset) 
+t2p_mapproc(thandle_t handle, void **data, toff_t *offset) 
 { 
 	(void) handle, (void) data, (void) offset;
 	return -1; 
 }
 
 static void 
-t2p_unmapproc(thandle_t handle, tdata_t data, toff_t offset)
+t2p_unmapproc(thandle_t handle, void *data, toff_t offset)
 { 
 	(void) handle, (void) data, (void) offset;
 }
 
+#if defined(OJPEG_SUPPORT) || defined(JPEG_SUPPORT)
 static uint64
 checkAdd64(uint64 summand1, uint64 summand2, T2P* t2p)
 {
 	uint64 bytes = summand1 + summand2;
 
-	if (bytes - summand1 != summand2) {
+	if (bytes < summand1) {
 		TIFFError(TIFF2PDF_MODULE, "Integer overflow");
 		t2p->t2p_error = T2P_ERR_ERROR;
 		bytes = 0;
@@ -572,6 +677,7 @@ checkAdd64(uint64 summand1, uint64 summa
 
 	return bytes;
 }
+#endif /* defined(OJPEG_SUPPORT) || defined(JPEG_SUPPORT) */
 
 static uint64
 checkMultiply64(uint64 first, uint64 second, T2P* t2p)
@@ -672,6 +778,7 @@ checkMultiply64(uint64 first, uint64 sec
     -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: set pdf "fit window" user preference
     -b:	set PDF "Interpolate" user preference
     -e: date, overrides image or current date/time default, YYYYMMDDHHMMSS
@@ -691,17 +798,17 @@ checkMultiply64(uint64 first, uint64 sec
 
         tiff2pdf input.tiff
 
-    The above example would generate PDF output from input.tiff and write it 
+    The above example would generate PDF output from input.tiff and write it
     to standard output.
 
         tiff2pdf -j -p letter -o output.pdf input.tiff
 
-    The above example would generate the file output.pdf from input.tiff, 
-    putting the image pages on a letter sized page, compressing the output 
+    The above example would generate the file output.pdf from input.tiff,
+    putting the image pages on a letter sized page, compressing the output
     with JPEG.
 
 	Please report bugs through:
-	 
+
 	http://bugzilla.remotesensing.org/buglist.cgi?product=libtiff
 
     See also libtiff.3t, tiffcp.
@@ -710,13 +817,10 @@ checkMultiply64(uint64 first, uint64 sec
 int
 tiff2pdf(TIFF *input, FILE *outputfile, int argc, const char **argv)
 {
-        char *outfilename = "<null>";
-        T2P *t2p = NULL;
-        TIFF *output = NULL;
-	tsize_t written = 0;
-	int c;
-
-        (void)written;
+	char *outfilename = "<null>";
+	T2P *t2p = NULL;
+	TIFF *output = NULL;
+	int c, ret = EXIT_SUCCESS;;
 
 	t2p = t2p_init();
 
@@ -727,7 +831,7 @@ tiff2pdf(TIFF *input, FILE *outputfile,
 
 	while (argv &&
 	       (c = getopt(argc, (void*)argv,
-			   "o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbh")) != -1){
+			   "o:q:u:x:y:w:l:r:p:e:c:a:t:s:k:jzndifbhF")) != -1){
 		switch (c) {
 			case 'o':
 				outfilename = optarg;
@@ -808,92 +912,43 @@ tiff2pdf(TIFF *input, FILE *outputfile,
 			case 'i':
 				t2p->pdf_colorspace_invert=1;
 				break;
+			case 'F':
+				t2p->pdf_image_fillpage = 1;
+				break;
 			case 'f': 
 				t2p->pdf_fitwindow=1;
 				break;
 			case 'e':
-				t2p->pdf_datetime =
-					(unsigned char*)_TIFFmalloc(17);
-				if(t2p->pdf_datetime==NULL){
-					TIFFError(TIFF2PDF_MODULE, 
-				"Can't allocate %u bytes of memory for main", 
-						17); 
-					goto fail;
-				}
-				if(strlen(optarg)==0){
-					t2p->pdf_datetime[0] = 0;
+				if (strlen(optarg) == 0) {
+					t2p->pdf_datetime[0] = '\0';
 				} else {
-					if(strlen(optarg)>14){optarg[14]=0;}
 					t2p->pdf_datetime[0] = 'D';
 					t2p->pdf_datetime[1] = ':';
-					strcpy((char *)t2p->pdf_datetime + 2,
-					       optarg);
+					strncpy(t2p->pdf_datetime + 2, optarg,
+						sizeof(t2p->pdf_datetime) - 3);
+					t2p->pdf_datetime[sizeof(t2p->pdf_datetime) - 1] = '\0';
 				}
 				break;
 			case 'c': 
-				t2p->pdf_creator = (unsigned char *)
-					_TIFFmalloc(strlen(optarg) + 1);
-				if(t2p->pdf_creator==NULL){
-					TIFFError(TIFF2PDF_MODULE, 
-				"Can't allocate %lu bytes of memory for main", 
-						  (long)strlen(optarg) + 1); 
-					goto fail;
-				}
-				strcpy((char *)t2p->pdf_creator, optarg);
-				t2p->pdf_creator[strlen(optarg)] = 0;
+				strncpy(t2p->pdf_creator, optarg, sizeof(t2p->pdf_creator) - 1);
+				t2p->pdf_creator[sizeof(t2p->pdf_creator) - 1] = '\0';
 				break;
 			case 'a': 
-				t2p->pdf_author = (unsigned char *)
-					_TIFFmalloc(strlen(optarg) + 1);
-				if(t2p->pdf_author==NULL){
-					TIFFError(
-						TIFF2PDF_MODULE, 
-				"Can't allocate %lu bytes of memory for main", 
-						(long)strlen(optarg) + 1); 
-					goto fail;
-				}
-				strcpy((char *)t2p->pdf_author, optarg);
-				t2p->pdf_author[strlen(optarg)]=0;
+				strncpy(t2p->pdf_author, optarg, sizeof(t2p->pdf_author) - 1);
+				t2p->pdf_author[sizeof(t2p->pdf_author) - 1] = '\0';
 				break;
 			case 't': 
-				t2p->pdf_title = (unsigned char*)
-					_TIFFmalloc(strlen(optarg)+1);
-				if(t2p->pdf_title==NULL){
-					TIFFError(
-						TIFF2PDF_MODULE, 
-				"Can't allocate %lu bytes of memory for main", 
-						(long)strlen(optarg) + 1); 
-					goto fail;
-				}
-				strcpy((char *)t2p->pdf_title, optarg);
-				t2p->pdf_title[strlen(optarg)] = 0;
+				strncpy(t2p->pdf_title, optarg, sizeof(t2p->pdf_title) - 1);
+				t2p->pdf_title[sizeof(t2p->pdf_title) - 1] = '\0';
 				break;
 			case 's': 
-				t2p->pdf_subject = (unsigned char*)
-					_TIFFmalloc(strlen(optarg) + 1);
-				if(t2p->pdf_subject==NULL){
-					TIFFError(
-						TIFF2PDF_MODULE, 
-				"Can't allocate %lu bytes of memory for main", 
-						(long)strlen(optarg)+1); 
-					goto fail;
-				}
-				strcpy((char *)t2p->pdf_subject, optarg);
-				t2p->pdf_subject[strlen(optarg)]=0;
+				strncpy(t2p->pdf_subject, optarg, sizeof(t2p->pdf_subject) - 1);
+				t2p->pdf_subject[sizeof(t2p->pdf_subject) - 1] = '\0';
 				break;
 			case 'k': 
-				t2p->pdf_keywords = (unsigned char*)
-					_TIFFmalloc(strlen(optarg) + 1);
-				if(t2p->pdf_keywords==NULL){
-					TIFFError(
-						TIFF2PDF_MODULE, 
-				"Can't allocate %lu bytes of memory for main", 
-						(long)strlen(optarg) + 1); 
-					goto fail;
-				}
-				strcpy((char *)t2p->pdf_keywords, optarg);
-				t2p->pdf_keywords[strlen(optarg)] = 0;
-				break;		
+				strncpy(t2p->pdf_keywords, optarg, sizeof(t2p->pdf_keywords) - 1);
+				t2p->pdf_keywords[sizeof(t2p->pdf_keywords) - 1] = '\0';
+				break;
 			case 'b':
 				t2p->pdf_image_interpolate = 1;
 				break;
@@ -904,12 +959,13 @@ tiff2pdf(TIFF *input, FILE *outputfile,
 	 * Output
 	 */
 	t2p->outputdisable = 0;
-        t2p->outputfile = outputfile;
+	t2p->outputfile = outputfile;
 
 	output = TIFFClientOpen(outfilename, "w", (thandle_t) t2p,
 				t2p_readproc, t2p_writeproc, t2p_seekproc, 
 				t2p_closeproc, t2p_sizeproc, 
-				t2p_mapproc, t2p_unmapproc );
+				t2p_mapproc, t2p_unmapproc);
+
 	if (output == NULL) {
 		TIFFError(TIFF2PDF_MODULE,
 			  "Can't initialize output descriptor");
@@ -925,33 +981,28 @@ tiff2pdf(TIFF *input, FILE *outputfile,
 	/*
 	 * Write
 	 */
-	written = t2p_write_pdf(t2p, input, output);
+	t2p_write_pdf(t2p, input, output);
 	if (t2p->t2p_error != 0) {
 		TIFFError(TIFF2PDF_MODULE,
 			  "An error occurred creating output PDF file");
 		goto fail;
 	}
 
-/* success: */
-	if (output != NULL)
-		TIFFClose(output);
-	if (t2p != NULL)
-		t2p_free(t2p);
-	return(EXIT_SUCCESS);
-
+	goto success;
 fail:
-	if(input != NULL)
-		TIFFClose(input);
+	ret = EXIT_FAILURE;
+success:
 	if (output != NULL)
 		TIFFClose(output);
 	if (t2p != NULL)
 		t2p_free(t2p);
-	return(EXIT_FAILURE);
+	return ret;
   
 }
 
 
-static int tiff2pdf_match_paper_size(float* width, float* length, char* papersize){
+static
+int tiff2pdf_match_paper_size(float* width, float* length, char* papersize){
 
 	size_t i, len;
 	const char* sizes[]={
@@ -998,7 +1049,7 @@ static int tiff2pdf_match_paper_size(flo
 
 	len=strlen(papersize);
 	for(i=0;i<len;i++){
-		papersize[i]=toupper(papersize[i]);
+		papersize[i]=toupper((int) papersize[i]);
 	}
 	for(i=0;sizes[i]!=NULL; i++){
 		if (strcmp( (const char*)papersize, sizes[i])==0){
@@ -1012,17 +1063,18 @@ static int tiff2pdf_match_paper_size(flo
 }
 
 /*
-	This function allocates and initializes a T2P context struct pointer.
-*/
-
-static T2P* t2p_init(){
+ * This function allocates and initializes a T2P context struct pointer.
+ */
 
+static
+T2P* t2p_init()
+{
 	T2P* t2p = (T2P*) _TIFFmalloc(sizeof(T2P));
 	if(t2p==NULL){
 		TIFFError(
 			TIFF2PDF_MODULE, 
 			"Can't allocate %lu bytes of memory for t2p_init", 
-			(long)sizeof(T2P));
+			(unsigned long) sizeof(T2P));
 		return( (T2P*) NULL );
 	}
 	_TIFFmemset(t2p, 0x00, sizeof(T2P));
@@ -1038,14 +1090,15 @@ static T2P* t2p_init(){
 }
 
 /*
-	This function frees a T2P context struct pointer and any allocated data fields of it.
-*/
-
-static void t2p_free(T2P* t2p){
+ * This function frees a T2P context struct pointer and any allocated data fields of it.
+ */
 
-	int i=0;
+static
+void t2p_free(T2P* t2p)
+{
+	int i = 0;
 
-	if(t2p != NULL){
+	if (t2p != NULL) {
 		if(t2p->pdf_xrefoffsets != NULL){
 			_TIFFfree( (tdata_t) t2p->pdf_xrefoffsets);
 		}
@@ -1063,27 +1116,6 @@ static void t2p_free(T2P* t2p){
 		if(t2p->pdf_palette != NULL){
 			_TIFFfree( (tdata_t) t2p->pdf_palette);
 		}
-		if(t2p->pdf_fileid != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_fileid);
-		}
-		if(t2p->pdf_datetime != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_datetime);
-		}
-		if(t2p->pdf_creator != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_creator);
-		}
-		if(t2p->pdf_author != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_author);
-		}
-		if(t2p->pdf_title != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_title);
-		}
-		if(t2p->pdf_subject != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_subject);
-		}
-		if(t2p->pdf_keywords != NULL){
-			_TIFFfree( (tdata_t) t2p->pdf_keywords);
-		}
 #ifdef OJPEG_SUPPORT
 		if(t2p->pdf_ojpegdata != NULL){
 			_TIFFfree( (tdata_t) t2p->pdf_ojpegdata);
@@ -1100,7 +1132,8 @@ static void t2p_free(T2P* t2p){
         before calling t2p_write_pdf with it.
 */
 
-static void t2p_validate(T2P* t2p){
+static
+void t2p_validate(T2P* t2p){
 
 #ifdef JPEG_SUPPORT
 	if(t2p->pdf_defaultcompression==T2P_COMPRESS_JPEG){
@@ -1142,7 +1175,8 @@ static void t2p_validate(T2P* t2p){
         with the output of the PDF document as a whole.  
 */
 
-static void t2p_read_tiff_init(T2P* t2p, TIFF* input){
+static
+void t2p_read_tiff_init(T2P* t2p, TIFF* input){
 
 	tdir_t directorycount=0;
 	tdir_t i=0;
@@ -1151,23 +1185,23 @@ static void t2p_read_tiff_init(T2P* t2p,
 	uint16 xuint16=0;
 
 	directorycount=TIFFNumberOfDirectories(input);
-	t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(directorycount * sizeof(T2P_PAGE));
+	t2p->tiff_pages = (T2P_PAGE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_PAGE)));
 	if(t2p->tiff_pages==NULL){
 		TIFFError(
 			TIFF2PDF_MODULE, 
-			"Can't allocate %lu bytes of memory for tiff_pages array, %s", 
-			directorycount * (long)sizeof(T2P_PAGE), 
+			"Can't allocate " TIFF_SIZE_FORMAT " bytes of memory for tiff_pages array, %s", 
+			(TIFF_SIZE_T) directorycount * sizeof(T2P_PAGE), 
 			TIFFFileName(input));
 		t2p->t2p_error = T2P_ERR_ERROR;
 		return;
 	}
 	_TIFFmemset( t2p->tiff_pages, 0x00, directorycount * sizeof(T2P_PAGE));
-	t2p->tiff_tiles = (T2P_TILES*) _TIFFmalloc(directorycount * sizeof(T2P_TILES));
+	t2p->tiff_tiles = (T2P_TILES*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,directorycount,sizeof(T2P_TILES)));
 	if(t2p->tiff_tiles==NULL){
 		TIFFError(
 			TIFF2PDF_MODULE, 
-			"Can't allocate %lu bytes of memory for tiff_tiles array, %s", 
-			directorycount * (long)sizeof(T2P_TILES), 
+			"Can't allocate " TIFF_SIZE_FORMAT " bytes of memory for tiff_tiles array, %s", 
+			(TIFF_SIZE_T) directorycount * sizeof(T2P_TILES), 
 			TIFFFileName(input));
 		t2p->t2p_error = T2P_ERR_ERROR;
 		return;
@@ -1252,8 +1286,10 @@ static void t2p_read_tiff_init(T2P* t2p,
                                  &(t2p->tiff_transferfunction[0]),
                                  &(t2p->tiff_transferfunction[1]),
                                  &(t2p->tiff_transferfunction[2]))) {
-			if(t2p->tiff_transferfunction[1] !=
-			   t2p->tiff_transferfunction[0]) {
+			if((t2p->tiff_transferfunction[1] != (float*) NULL) &&
+                           (t2p->tiff_transferfunction[2] != (float*) NULL) &&
+                           (t2p->tiff_transferfunction[1] !=
+                            t2p->tiff_transferfunction[0])) {
 				t2p->tiff_transferfunctioncount = 3;
 				t2p->tiff_pages[i].page_extra += 4;
 				t2p->pdf_xrefcount += 4;
@@ -1280,7 +1316,24 @@ static void t2p_read_tiff_init(T2P* t2p,
 			t2p->tiff_pages[i].page_tilecount;
 		if( (TIFFGetField(input, TIFFTAG_PLANARCONFIG, &xuint16) != 0)
 			&& (xuint16 == PLANARCONFIG_SEPARATE ) ){
-				TIFFGetField(input, TIFFTAG_SAMPLESPERPIXEL, &xuint16);
+				if( !TIFFGetField(input, TIFFTAG_SAMPLESPERPIXEL, &xuint16) )
+				{
+					TIFFError(
+                        TIFF2PDF_MODULE, 
+                        "Missing SamplesPerPixel, %s", 
+                        TIFFFileName(input));
+                    t2p->t2p_error = T2P_ERR_ERROR;
+                    return;
+				}
+                if( (t2p->tiff_tiles[i].tiles_tilecount % xuint16) != 0 )
+                {
+                    TIFFError(
+                        TIFF2PDF_MODULE, 
+                        "Invalid tile count, %s", 
+                        TIFFFileName(input));
+                    t2p->t2p_error = T2P_ERR_ERROR;
+                    return;
+                }
 				t2p->tiff_tiles[i].tiles_tilecount/= xuint16;
 		}
 		if( t2p->tiff_tiles[i].tiles_tilecount > 0){
@@ -1293,14 +1346,13 @@ static void t2p_read_tiff_init(T2P* t2p,
 				TIFFTAG_TILELENGTH, 
 				&( t2p->tiff_tiles[i].tiles_tilelength) );
 			t2p->tiff_tiles[i].tiles_tiles = 
-			(T2P_TILE*) _TIFFmalloc(
-				t2p->tiff_tiles[i].tiles_tilecount 
-				* sizeof(T2P_TILE) );
+			(T2P_TILE*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,t2p->tiff_tiles[i].tiles_tilecount,
+                                                                 sizeof(T2P_TILE)) );
 			if( t2p->tiff_tiles[i].tiles_tiles == NULL){
 				TIFFError(
 					TIFF2PDF_MODULE, 
-					"Can't allocate %lu bytes of memory for t2p_read_tiff_init, %s", 
-					t2p->tiff_tiles[i].tiles_tilecount * (long)sizeof(T2P_TILE), 
+					"Can't allocate " TIFF_SIZE_FORMAT " bytes of memory for t2p_read_tiff_init, %s", 
+					(TIFF_SIZE_T) t2p->tiff_tiles[i].tiles_tilecount * sizeof(T2P_TILE), 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return;
@@ -1313,12 +1365,19 @@ static void t2p_read_tiff_init(T2P* t2p,
 
 /*
  * This function is used by qsort to sort a T2P_PAGE* array of page structures
- * by page number.
+ * by page number. If the page numbers are the same, we fall back to comparing
+ * directory numbers to preserve the order of the input file.
  */
 
-static int t2p_cmp_t2p_page(const void* e1, const void* e2){
+static
+int t2p_cmp_t2p_page(const void* e1, const void* e2){
 
-	return( ((T2P_PAGE*)e1)->page_number - ((T2P_PAGE*)e2)->page_number );
+	int d;
+	d = (int32)(((T2P_PAGE*)e1)->page_number) - (int32)(((T2P_PAGE*)e2)->page_number);
+	if(d == 0){
+		d = (int32)(((T2P_PAGE*)e1)->page_directory) - (int32)(((T2P_PAGE*)e2)->page_directory);
+	}
+	return d;
 }
 
 /*
@@ -1333,7 +1392,8 @@ static int t2p_cmp_t2p_page(const void*
 	requiring transcoding of the image data.
 */
 
-static void t2p_read_tiff_data(T2P* t2p, TIFF* input){
+static
+void t2p_read_tiff_data(T2P* t2p, TIFF* input){
 
 	int i=0;
 	uint16* r;
@@ -1496,10 +1556,28 @@ static void t2p_read_tiff_data(T2P* t2p,
 							&xuint16, &xuint16p)
 					   && xuint16 == 1) {
 						if(xuint16p[0] == EXTRASAMPLE_ASSOCALPHA){
+							if( t2p->tiff_bitspersample != 8 )
+							{
+							    TIFFError(
+								    TIFF2PDF_MODULE, 
+								    "No support for BitsPerSample=%d for RGBA",
+								    t2p->tiff_bitspersample);
+							    t2p->t2p_error = T2P_ERR_ERROR;
+							    return;
+							}
 							t2p->pdf_sample=T2P_SAMPLE_RGBAA_TO_RGB;
 							break;
 						}
 						if(xuint16p[0] == EXTRASAMPLE_UNASSALPHA){
+							if( t2p->tiff_bitspersample != 8 )
+							{
+							    TIFFError(
+								    TIFF2PDF_MODULE, 
+								    "No support for BitsPerSample=%d for RGBA",
+								    t2p->tiff_bitspersample);
+							    t2p->t2p_error = T2P_ERR_ERROR;
+							    return;
+							}
 							t2p->pdf_sample=T2P_SAMPLE_RGBA_TO_RGB;
 							break;
 						}
@@ -1559,7 +1637,7 @@ static void t2p_read_tiff_data(T2P* t2p,
 				t2p->pdf_palette=NULL;
 			}
 			t2p->pdf_palette = (unsigned char*)
-				_TIFFmalloc(t2p->pdf_palettesize*3);
+				_TIFFmalloc(TIFFSafeMultiply(tmsize_t,t2p->pdf_palettesize,3));
 			if(t2p->pdf_palette==NULL){
 				TIFFError(
 					TIFF2PDF_MODULE, 
@@ -1628,7 +1706,7 @@ static void t2p_read_tiff_data(T2P* t2p,
 				t2p->pdf_palette=NULL;
 			}
 			t2p->pdf_palette = (unsigned char*) 
-				_TIFFmalloc(t2p->pdf_palettesize*4);
+				_TIFFmalloc(TIFFSafeMultiply(tmsize_t,t2p->pdf_palettesize,4));
 			if(t2p->pdf_palette==NULL){
 				TIFFError(
 					TIFF2PDF_MODULE, 
@@ -1661,6 +1739,22 @@ static void t2p_read_tiff_data(T2P* t2p,
 #endif
 			break;
 		case PHOTOMETRIC_CIELAB:
+            if( t2p->tiff_samplesperpixel != 3){
+                TIFFError(
+                    TIFF2PDF_MODULE, 
+                    "Unsupported samplesperpixel = %d for CIELAB", 
+                    t2p->tiff_samplesperpixel);
+                t2p->t2p_error = T2P_ERR_ERROR;
+                return;
+            }
+            if( t2p->tiff_bitspersample != 8){
+                TIFFError(
+                    TIFF2PDF_MODULE, 
+                    "Invalid bitspersample = %d for CIELAB", 
+                    t2p->tiff_bitspersample);
+                t2p->t2p_error = T2P_ERR_ERROR;
+                return;
+            }
 			t2p->pdf_labrange[0]= -127;
 			t2p->pdf_labrange[1]= 127;
 			t2p->pdf_labrange[2]= -127;
@@ -1676,6 +1770,22 @@ static void t2p_read_tiff_data(T2P* t2p,
 			t2p->pdf_colorspace=T2P_CS_LAB;
 			break;
 		case PHOTOMETRIC_ITULAB:
+            if( t2p->tiff_samplesperpixel != 3){
+                TIFFError(
+                    TIFF2PDF_MODULE, 
+                    "Unsupported samplesperpixel = %d for ITULAB", 
+                    t2p->tiff_samplesperpixel);
+                t2p->t2p_error = T2P_ERR_ERROR;
+                return;
+            }
+            if( t2p->tiff_bitspersample != 8){
+                TIFFError(
+                    TIFF2PDF_MODULE, 
+                    "Invalid bitspersample = %d for ITULAB", 
+                    t2p->tiff_bitspersample);
+                t2p->t2p_error = T2P_ERR_ERROR;
+                return;
+            }
 			t2p->pdf_labrange[0]=-85;
 			t2p->pdf_labrange[1]=85;
 			t2p->pdf_labrange[2]=-75;
@@ -1761,9 +1871,16 @@ static void t2p_read_tiff_data(T2P* t2p,
 	}
 
 	t2p_compose_pdf_page(t2p);
+        if( t2p->t2p_error == T2P_ERR_ERROR )
+	    return;
 
 	t2p->pdf_transcode = T2P_TRANSCODE_ENCODE;
-	if(t2p->pdf_nopassthrough==0){
+        /* It seems that T2P_TRANSCODE_RAW mode doesn't support separate->contig */
+        /* conversion. At least t2p_read_tiff_size and t2p_read_tiff_size_tile */
+        /* do not take into account the number of samples, and thus */
+        /* that can cause heap buffer overflows such as in */
+        /* http://bugzilla.maptools.org/show_bug.cgi?id=2715 */
+	if(t2p->pdf_nopassthrough==0 && t2p->tiff_planar!=PLANARCONFIG_SEPARATE){
 #ifdef CCITT_SUPPORT
 		if(t2p->tiff_compression==COMPRESSION_CCITTFAX4  
 			){
@@ -1848,8 +1965,10 @@ static void t2p_read_tiff_data(T2P* t2p,
 			 &(t2p->tiff_transferfunction[0]),
 			 &(t2p->tiff_transferfunction[1]),
 			 &(t2p->tiff_transferfunction[2]))) {
-		if(t2p->tiff_transferfunction[1] !=
-		   t2p->tiff_transferfunction[0]) {
+		if((t2p->tiff_transferfunction[1] != (float*) NULL) &&
+                   (t2p->tiff_transferfunction[2] != (float*) NULL) &&
+                   (t2p->tiff_transferfunction[1] !=
+                    t2p->tiff_transferfunction[0])) {
 			t2p->tiff_transferfunctioncount=3;
 		} else {
 			t2p->tiff_transferfunctioncount=1;
@@ -1913,9 +2032,10 @@ static void t2p_read_tiff_data(T2P* t2p,
 	uncompressed image data from the input TIFF for a page.
 */
 
-static void t2p_read_tiff_size(T2P* t2p, TIFF* input){
+static
+void t2p_read_tiff_size(T2P* t2p, TIFF* input){
 
-	uint32* sbc=NULL;
+	uint64* sbc=NULL;
 #if defined(JPEG_SUPPORT) || defined (OJPEG_SUPPORT)
 	unsigned char* jpt=NULL;
 	tstrip_t i=0;
@@ -1927,14 +2047,22 @@ static void t2p_read_tiff_size(T2P* t2p,
 #ifdef CCITT_SUPPORT
 		if(t2p->pdf_compression == T2P_COMPRESS_G4 ){
 			TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc);
-			t2p->tiff_datasize=sbc[0];
+            if (sbc[0] != (uint64)(tmsize_t)sbc[0]) {
+                TIFFError(TIFF2PDF_MODULE, "Integer overflow");
+                t2p->t2p_error = T2P_ERR_ERROR;
+            }
+			t2p->tiff_datasize=(tmsize_t)sbc[0];
 			return;
 		}
 #endif
 #ifdef ZIP_SUPPORT
 		if(t2p->pdf_compression == T2P_COMPRESS_ZIP){
 			TIFFGetField(input, TIFFTAG_STRIPBYTECOUNTS, &sbc);
-			t2p->tiff_datasize=sbc[0];
+            if (sbc[0] != (uint64)(tmsize_t)sbc[0]) {
+                TIFFError(TIFF2PDF_MODULE, "Integer overflow");
+                t2p->t2p_error = T2P_ERR_ERROR;
+            }
+			t2p->tiff_datasize=(tmsize_t)sbc[0];
 			return;
 		}
 #endif
@@ -1954,7 +2082,7 @@ static void t2p_read_tiff_size(T2P* t2p,
 			if(TIFFGetField(input, TIFFTAG_JPEGIFOFFSET, &(t2p->tiff_dataoffset))){
 				if(t2p->tiff_dataoffset != 0){
 					if(TIFFGetField(input, TIFFTAG_JPEGIFBYTECOUNT, &(t2p->tiff_datasize))!=0){
-                                          if((uint64)t2p->tiff_datasize < k) {
+						if((uint64)t2p->tiff_datasize < k) {
 							TIFFWarning(TIFF2PDF_MODULE, 
 								"Input file %s has short JPEG interchange file byte count", 
 								TIFFFileName(input));
@@ -2012,14 +2140,17 @@ static void t2p_read_tiff_size(T2P* t2p,
 			}
 			for(i=0;i<stripcount;i++){
 				k = checkAdd64(k, sbc[i], t2p);
-				k -=4; /* don't use SOI or EOI of strip */
+				k -=2; /* don't use EOI of strip */
+				k +=2; /* add space for restart marker */
 			}
 			k = checkAdd64(k, 2, t2p); /* use EOI of last strip */
+			k = checkAdd64(k, 6, t2p); /* for DRI marker of first strip */
 			t2p->tiff_datasize = (tsize_t) k;
 			if ((uint64) t2p->tiff_datasize != k) {
 				TIFFError(TIFF2PDF_MODULE, "Integer overflow");
 				t2p->t2p_error = T2P_ERR_ERROR;
 			}
+			return;
 		}
 #endif
 		(void) 0;
@@ -2047,9 +2178,10 @@ static void t2p_read_tiff_size(T2P* t2p,
 	uncompressed image data from the input TIFF for a tile of a page.
 */
 
-static void t2p_read_tiff_size_tile(T2P* t2p, TIFF* input, ttile_t tile){
+static
+void t2p_read_tiff_size_tile(T2P* t2p, TIFF* input, ttile_t tile){
 
-	uint32* tbc = NULL;
+	uint64* tbc = NULL;
 	uint16 edge=0;
 #ifdef JPEG_SUPPORT
 	unsigned char* jpt;
@@ -2085,9 +2217,7 @@ static void t2p_read_tiff_size_tile(T2P*
 				if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt)!=0){
 					if(count > 4){
 						k = checkAdd64(k, count, t2p);
-						k -= 4; /* don't use EOI of header or SOI of tile */
-
-
+						k -= 2; /* don't use EOI of header or SOI of tile */
 					}
 				}
 			}
@@ -2123,7 +2253,8 @@ static void t2p_read_tiff_size_tile(T2P*
  * and does not have full imaged tile width.
  */
 
-static int t2p_tile_is_right_edge(T2P_TILES tiles, ttile_t tile){
+static
+int t2p_tile_is_right_edge(T2P_TILES tiles, ttile_t tile){
 
 	if( ((tile+1) % tiles.tiles_tilecountx == 0) 
 		&& (tiles.tiles_edgetilewidth != 0) ){
@@ -2138,7 +2269,8 @@ static int t2p_tile_is_right_edge(T2P_TI
  * and does not have full imaged tile length.
  */
 
-static int t2p_tile_is_bottom_edge(T2P_TILES tiles, ttile_t tile){
+static
+int t2p_tile_is_bottom_edge(T2P_TILES tiles, ttile_t tile){
 
 	if( ((tile+1) > (tiles.tiles_tilecount-tiles.tiles_tilecountx) )
 		&& (tiles.tiles_edgetilelength != 0) ){
@@ -2154,7 +2286,8 @@ static int t2p_tile_is_bottom_edge(T2P_T
 	or zero on error.
 */
 
-static tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){
+static
+tsize_t t2p_readwrite_pdf_image(T2P* t2p, TIFF* input, TIFF* output){
 
 	tsize_t written=0;
 	unsigned char* buffer=NULL;
@@ -2174,15 +2307,15 @@ static tsize_t t2p_readwrite_pdf_image(T
 	uint16 v_samp=1;
 	uint16 ri=1;
 	uint32 rows=0;
-#endif
+#endif /* ifdef OJPEG_SUPPORT */
 #ifdef JPEG_SUPPORT
 	unsigned char* jpt;
 	float* xfloatp;
-	uint32* sbc;
+	uint64* sbc;
 	unsigned char* stripbuffer;
 	tsize_t striplength=0;
 	uint32 max_striplength=0;
-#endif
+#endif /* ifdef JPEG_SUPPORT */
 
 	/* Fail if prior error (in particular, can't trust tiff_datasize) */
 	if (t2p->t2p_error != T2P_ERR_OK)
@@ -2195,8 +2328,9 @@ static tsize_t t2p_readwrite_pdf_image(T
 				_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, 
+                                          "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);
@@ -2216,20 +2350,20 @@ static tsize_t t2p_readwrite_pdf_image(T
 			_TIFFfree(buffer);
 			return(t2p->tiff_datasize);
 		}
-#endif
+#endif /* ifdef CCITT_SUPPORT */
 #ifdef ZIP_SUPPORT
 		if (t2p->pdf_compression == T2P_COMPRESS_ZIP) {
 			buffer = (unsigned char*)
 				_TIFFmalloc(t2p->tiff_datasize);
-                        memset(buffer, 0, 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, 
+					(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);
 			if (t2p->tiff_fillorder==FILLORDER_LSB2MSB) {
@@ -2241,22 +2375,22 @@ static tsize_t t2p_readwrite_pdf_image(T
 			_TIFFfree(buffer);
 			return(t2p->tiff_datasize);
 		}
-#endif
+#endif /* ifdef ZIP_SUPPORT */
 #ifdef OJPEG_SUPPORT
 		if(t2p->tiff_compression == COMPRESSION_OJPEG) {
 
 			if(t2p->tiff_dataoffset != 0) {
 				buffer = (unsigned char*)
 					_TIFFmalloc(t2p->tiff_datasize);
-                                memset(buffer, 0, 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, 
+						(unsigned long) t2p->tiff_datasize, 
 						TIFFFileName(input));
 					t2p->t2p_error = T2P_ERR_ERROR;
 					return(0);
 				}
+                                memset(buffer, 0, t2p->tiff_datasize);
 				if(t2p->pdf_ojpegiflength==0){
 					inputoffset=t2pSeekFile(input, 0,
 								 SEEK_CUR);
@@ -2324,15 +2458,15 @@ static tsize_t t2p_readwrite_pdf_image(T
 				}
 				buffer = (unsigned char*)
 					_TIFFmalloc(t2p->tiff_datasize);
-                                memset(buffer, 0, 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, 
+						(unsigned long) t2p->tiff_datasize, 
 						TIFFFileName(input));
 					t2p->t2p_error = T2P_ERR_ERROR;
 					return(0);
 				}
+                                memset(buffer, 0, t2p->tiff_datasize);
 				_TIFFmemcpy(buffer, t2p->pdf_ojpegdata, t2p->pdf_ojpegdatalength);
 				bufferoffset=t2p->pdf_ojpegdatalength;
 				stripcount=TIFFNumberOfStrips(input);
@@ -2353,29 +2487,35 @@ static tsize_t t2p_readwrite_pdf_image(T
 				t2pWriteFile(output, (tdata_t) buffer, bufferoffset);
 				_TIFFfree(buffer);
 				return(bufferoffset);
+#if 0
+                                /*
+                                  This hunk of code removed code is clearly
+                                  mis-placed and we are not sure where it
+                                  should be (if anywhere)
+                                */
 				TIFFError(TIFF2PDF_MODULE, 
 	"No support for OJPEG image %s with no JPEG File Interchange offset", 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
+#endif
 			}
-			return(t2p->tiff_datasize);
 		}
-#endif
+#endif /* ifdef OJPEG_SUPPORT */
 #ifdef JPEG_SUPPORT
 		if(t2p->tiff_compression == COMPRESSION_JPEG) {
 			uint32 count = 0;
 			buffer = (unsigned char*)
 				_TIFFmalloc(t2p->tiff_datasize);
-                        memset(buffer, 0, 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, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				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) {
 					_TIFFmemcpy(buffer, jpt, count);
@@ -2403,7 +2543,8 @@ static tsize_t t2p_readwrite_pdf_image(T
 				if(!t2p_process_jpeg_strip(
 					stripbuffer, 
 					&striplength, 
-					buffer, 
+					buffer,
+					t2p->tiff_datasize,
 					&bufferoffset, 
 					i, 
 					t2p->tiff_length)){
@@ -2423,21 +2564,21 @@ static tsize_t t2p_readwrite_pdf_image(T
 			_TIFFfree(buffer);
 			return(bufferoffset);
 		}
-#endif
+#endif /* ifdef JPEG_SUPPORT */
 		(void)0;
 	}
 
 	if(t2p->pdf_sample==T2P_SAMPLE_NOTHING){
 		buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
-                memset(buffer, 0, 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, 
+				(unsigned long) t2p->tiff_datasize, 
 				TIFFFileName(input));
 			t2p->t2p_error = T2P_ERR_ERROR;
 			return(0);
 		}
+                memset(buffer, 0, t2p->tiff_datasize);
 		stripsize=TIFFStripSize(input);
 		stripcount=TIFFNumberOfStrips(input);
 		for(i=0;i<stripcount;i++){
@@ -2445,7 +2586,7 @@ static tsize_t t2p_readwrite_pdf_image(T
 				TIFFReadEncodedStrip(input, 
 				i, 
 				(tdata_t) &buffer[bufferoffset], 
-				stripsize);
+				TIFFmin(stripsize, t2p->tiff_datasize - bufferoffset));
 			if(read==-1){
 				TIFFError(TIFF2PDF_MODULE, 
 					"Error on decoding strip %u of %s", 
@@ -2467,22 +2608,23 @@ static tsize_t t2p_readwrite_pdf_image(T
 			stripcount=sepstripcount/t2p->tiff_samplesperpixel;
 			
 			buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
-                        memset(buffer, 0, 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, 
+					(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(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, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
+                                _TIFFfree(buffer);
 				return(0);
 			}
 			for(i=0;i<stripcount;i++){
@@ -2492,7 +2634,7 @@ static tsize_t t2p_readwrite_pdf_image(T
 						TIFFReadEncodedStrip(input, 
 							i + j*stripcount, 
 							(tdata_t) &(samplebuffer[samplebufferoffset]), 
-							sepstripsize);
+							TIFFmin(sepstripsize, stripsize - samplebufferoffset));
 					if(read==-1){
 						TIFFError(TIFF2PDF_MODULE, 
 					"Error on decoding strip %u of %s", 
@@ -2516,15 +2658,15 @@ static tsize_t t2p_readwrite_pdf_image(T
 		}
 
 		buffer = (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
-                memset(buffer, 0, 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, 
+				(unsigned long) t2p->tiff_datasize, 
 				TIFFFileName(input));
 			t2p->t2p_error = T2P_ERR_ERROR;
 			return(0);
 		}
+                memset(buffer, 0, t2p->tiff_datasize);
 		stripsize=TIFFStripSize(input);
 		stripcount=TIFFNumberOfStrips(input);
 		for(i=0;i<stripcount;i++){
@@ -2532,7 +2674,7 @@ static tsize_t t2p_readwrite_pdf_image(T
 				TIFFReadEncodedStrip(input, 
 				i, 
 				(tdata_t) &buffer[bufferoffset], 
-				stripsize);
+				TIFFmin(stripsize, t2p->tiff_datasize - bufferoffset));
 			if(read==-1){
 				TIFFError(TIFF2PDF_MODULE, 
 					"Error on decoding strip %u of %s", 
@@ -2547,16 +2689,18 @@ static tsize_t t2p_readwrite_pdf_image(T
 		}
 
 		if(t2p->pdf_sample & T2P_SAMPLE_REALIZE_PALETTE){
+			// FIXME: overflow?
 			samplebuffer=(unsigned char*)_TIFFrealloc( 
 				(tdata_t) buffer, 
 				t2p->tiff_datasize * t2p->tiff_samplesperpixel);
 			if(samplebuffer==NULL){
 				TIFFError(TIFF2PDF_MODULE, 
 	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
-			  _TIFFfree(buffer);
+				_TIFFfree(buffer);
+				return(0);
 			} else {
 				buffer=samplebuffer;
 				t2p->tiff_datasize *= t2p->tiff_samplesperpixel;
@@ -2583,7 +2727,7 @@ static tsize_t t2p_readwrite_pdf_image(T
 			if(samplebuffer==NULL){
 				TIFFError(TIFF2PDF_MODULE, 
 	"Can't allocate %lu bytes of memory for t2p_readwrite_pdf_image, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				_TIFFfree(buffer);
@@ -2637,7 +2781,7 @@ dataready:
 	case T2P_COMPRESS_G4:
 		TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4);
 		break;
-#endif
+#endif /* ifdef CCITT_SUPPORT */
 #ifdef JPEG_SUPPORT
 	case T2P_COMPRESS_JPEG:
 		if(t2p->tiff_photometric==PHOTOMETRIC_YCBCR) {
@@ -2683,7 +2827,7 @@ dataready:
 		}
 	
 		break;
-#endif
+#endif /* ifdef JPEG_SUPPORT */
 #ifdef ZIP_SUPPORT
 	case T2P_COMPRESS_ZIP:
 		TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
@@ -2698,7 +2842,7 @@ dataready:
 				(t2p->pdf_defaultcompressionquality / 100));
 		}
 		break;
-#endif
+#endif /* ifdef ZIP_SUPPORT */
 	default:
 		break;
 	}
@@ -2712,8 +2856,8 @@ dataready:
 						     buffer,
 						     stripsize * stripcount); 
 	} else
-#endif
-	{
+#endif /* ifdef JPEG_SUPPORT */
+        {
 		bufferoffset = TIFFWriteEncodedStrip(output, (tstrip_t)0,
 						     buffer,
 						     t2p->tiff_datasize); 
@@ -2741,7 +2885,8 @@ dataready:
  * for the tile.  It returns the amount written or zero on error.
  */
 
-static tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_t tile){
+static
+tsize_t t2p_readwrite_pdf_image_tile(T2P* t2p, TIFF* input, TIFF* output, ttile_t tile){
 
 	uint16 edge=0;
 	tsize_t written=0;
@@ -2752,7 +2897,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 	tsize_t read=0;
 	uint16 i=0;
 	ttile_t tilecount=0;
-	tsize_t tilesize=0;
+	/* tsize_t tilesize=0; */
 	ttile_t septilecount=0;
 	tsize_t septilesize=0;
 #ifdef JPEG_SUPPORT
@@ -2760,7 +2905,6 @@ static tsize_t t2p_readwrite_pdf_image_t
 	float* xfloatp;
 	uint32 xuint32=0;
 #endif
-        (void)tilesize;
 
 	/* Fail if prior error (in particular, can't trust tiff_datasize) */
 	if (t2p->t2p_error != T2P_ERR_OK)
@@ -2782,7 +2926,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 				TIFFError(TIFF2PDF_MODULE, 
 					"Can't allocate %lu bytes of memory "
                                         "for t2p_readwrite_pdf_image_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -2803,7 +2947,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 				TIFFError(TIFF2PDF_MODULE, 
 					"Can't allocate %lu bytes of memory "
                                         "for t2p_readwrite_pdf_image_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -2832,7 +2976,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 				TIFFError(TIFF2PDF_MODULE, 
 					"Can't allocate %lu bytes of memory "
                                         "for t2p_readwrite_pdf_image, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -2871,35 +3015,40 @@ static tsize_t t2p_readwrite_pdf_image_t
 			buffer= (unsigned char*) _TIFFmalloc(t2p->tiff_datasize);
 			if(buffer==NULL){
 				TIFFError(TIFF2PDF_MODULE, 
-					"Can't allocate %lu bytes of memory "
+					"Can't allocate " TIFF_SIZE_FORMAT " bytes of memory "
                                         "for t2p_readwrite_pdf_image_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+                                          (TIFF_SIZE_T) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
 			}
 			if(TIFFGetField(input, TIFFTAG_JPEGTABLES, &count, &jpt) != 0) {
-				if (count > 0) {
-					_TIFFmemcpy(buffer, jpt, count);
+				if (count > 4) {
+                                        int retTIFFReadRawTile;
+                    /* Ignore EOI marker of JpegTables */
+					_TIFFmemcpy(buffer, jpt, count - 2);
 					bufferoffset += count - 2;
+                    /* Store last 2 bytes of the JpegTables */
 					table_end[0] = buffer[bufferoffset-2];
 					table_end[1] = buffer[bufferoffset-1];
-				}
-				if (count > 0) {
 					xuint32 = bufferoffset;
-					bufferoffset += TIFFReadRawTile(
-						input, 
-						tile, 
-						(tdata_t) &(((unsigned char*)buffer)[bufferoffset-2]), 
-						-1);
-						buffer[xuint32-2]=table_end[0];
-						buffer[xuint32-1]=table_end[1];
-				} else {
-					bufferoffset += TIFFReadRawTile(
+                                        bufferoffset -= 2;
+                                        retTIFFReadRawTile= TIFFReadRawTile(
 						input, 
 						tile, 
 						(tdata_t) &(((unsigned char*)buffer)[bufferoffset]), 
 						-1);
+                                        if( retTIFFReadRawTile < 0 )
+                                        {
+                                            _TIFFfree(buffer);
+                                            t2p->t2p_error = T2P_ERR_ERROR;
+                                            return(0);
+                                        }
+					bufferoffset += retTIFFReadRawTile;
+                    /* Overwrite SOI marker of image scan with previously */
+                    /* saved end of JpegTables */
+					buffer[xuint32-2]=table_end[0];
+					buffer[xuint32-1]=table_end[1];
 				}
 			}
 			t2pWriteFile(output, (tdata_t) buffer, bufferoffset);
@@ -2916,7 +3065,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 			TIFFError(TIFF2PDF_MODULE, 
 				"Can't allocate %lu bytes of memory for "
                                 "t2p_readwrite_pdf_image_tile, %s", 
-				(unsigned long)t2p->tiff_datasize, 
+				(unsigned long) t2p->tiff_datasize, 
 				TIFFFileName(input));
 			t2p->t2p_error = T2P_ERR_ERROR;
 			return(0);
@@ -2942,14 +3091,14 @@ static tsize_t t2p_readwrite_pdf_image_t
 		if(t2p->pdf_sample == T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG){
 			septilesize=TIFFTileSize(input);
 			septilecount=TIFFNumberOfTiles(input);
-			tilesize=septilesize*t2p->tiff_samplesperpixel;
+			/* tilesize=septilesize*t2p->tiff_samplesperpixel; */
 			tilecount=septilecount/t2p->tiff_samplesperpixel;
 			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_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -2959,7 +3108,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 				TIFFError(TIFF2PDF_MODULE, 
 					"Can't allocate %lu bytes of memory "
                                         "for t2p_readwrite_pdf_image_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -2998,7 +3147,7 @@ static tsize_t t2p_readwrite_pdf_image_t
 				TIFFError(TIFF2PDF_MODULE, 
 					"Can't allocate %lu bytes of memory "
                                         "for t2p_readwrite_pdf_image_tile, %s", 
-					(unsigned long)t2p->tiff_datasize, 
+					(unsigned long) t2p->tiff_datasize, 
 					TIFFFileName(input));
 				t2p->t2p_error = T2P_ERR_ERROR;
 				return(0);
@@ -3183,7 +3332,8 @@ static tsize_t t2p_readwrite_pdf_image_t
 }
 
 #ifdef OJPEG_SUPPORT
-static int t2p_process_ojpeg_tables(T2P* t2p, TIFF* input){
+static
+int t2p_process_ojpeg_tables(T2P* t2p, TIFF* input){
 	uint16 proc=0;
 	void* q;
 	uint32 q_length=0;
@@ -3278,6 +3428,7 @@ static int t2p_process_ojpeg_tables(T2P*
 			"Can't allocate %u bytes of memory for t2p_process_ojpeg_tables, %s", 
 			2048, 
 			TIFFFileName(input));
+		t2p->t2p_error = T2P_ERR_ERROR;
 		return(0);
 	}
 	_TIFFmemset(t2p->pdf_ojpegdata, 0x00, 2048);
@@ -3427,39 +3578,75 @@ static int t2p_process_ojpeg_tables(T2P*
 #endif
 
 #ifdef JPEG_SUPPORT
-static int t2p_process_jpeg_strip(
+static
+int t2p_process_jpeg_strip(
 	unsigned char* strip, 
 	tsize_t* striplength, 
 	unsigned char* buffer, 
+	tsize_t buffersize,
 	tsize_t* bufferoffset, 
 	tstrip_t no, 
 	uint32 height){
 
 	tsize_t i=0;
-	uint16 ri =0;
-	uint16 v_samp=1;
-	uint16 h_samp=1;
-	int j=0;
-	
-	i++;
-	
-	while(i<(*striplength)){
+
+	while (i < *striplength) {
+		tsize_t datalen;
+		uint16 ri;
+		uint16 v_samp;
+		uint16 h_samp;
+		int j;
+		int ncomp;
+
+		/* marker header: one or more FFs */
+		if (strip[i] != 0xff)
+			return(0);
+		i++;
+		while (i < *striplength && strip[i] == 0xff)
+			i++;
+		if (i >= *striplength)
+			return(0);
+		/* SOI is the only pre-SOS marker without a length word */
+		if (strip[i] == 0xd8)
+			datalen = 0;
+		else {
+			if ((*striplength - i) <= 2)
+				return(0);
+			datalen = (strip[i+1] << 8) | strip[i+2];
+			if (datalen < 2 || datalen >= (*striplength - i))
+				return(0);
+		}
 		switch( strip[i] ){
-			case 0xd8:
-				i+=2;
+			case 0xd8:	/* SOI - start of image */
+                if( *bufferoffset + 2 > buffersize )
+                    return(0);
+				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), 2);
+				*bufferoffset+=2;
 				break;
-			case 0xc0:
-			case 0xc1:
-			case 0xc3:
-			case 0xc9:
-			case 0xca:
+			case 0xc0:	/* SOF0 */
+			case 0xc1:	/* SOF1 */
+			case 0xc3:	/* SOF3 */
+			case 0xc9:	/* SOF9 */
+			case 0xca:	/* SOF10 */
 				if(no==0){
-					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
-					for(j=0;j<buffer[*bufferoffset+9];j++){
-						if( (buffer[*bufferoffset+11+(2*j)]>>4) > h_samp) 
-							h_samp = (buffer[*bufferoffset+11+(2*j)]>>4);
-						if( (buffer[*bufferoffset+11+(2*j)] & 0x0f) > v_samp) 
-							v_samp = (buffer[*bufferoffset+11+(2*j)] & 0x0f);
+                    if( *bufferoffset + datalen + 2 + 6 > buffersize )
+                        return(0);
+					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
+                    if( *bufferoffset + 9 >= buffersize )
+                        return(0);
+					ncomp = buffer[*bufferoffset+9];
+					if (ncomp < 1 || ncomp > 4)
+						return(0);
+					v_samp=1;
+					h_samp=1;
+                    if( *bufferoffset + 11 + 3*(ncomp-1) >= buffersize )
+                        return(0);
+					for(j=0;j<ncomp;j++){
+						uint16 samp = buffer[*bufferoffset+11+(3*j)];
+						if( (samp>>4) > h_samp) 
+							h_samp = (samp>>4);
+						if( (samp & 0x0f) > v_samp) 
+							v_samp = (samp & 0x0f);
 					}
 					v_samp*=8;
 					h_samp*=8;
@@ -3473,45 +3660,51 @@ static int t2p_process_jpeg_strip(
                                           (unsigned char) ((height>>8) & 0xff);
 					buffer[*bufferoffset+6]=
                                             (unsigned char) (height & 0xff);
-					*bufferoffset+=strip[i+2]+2;
-					i+=strip[i+2]+2;
-
+					*bufferoffset+=datalen+2;
+					/* insert a DRI marker */
 					buffer[(*bufferoffset)++]=0xff;
 					buffer[(*bufferoffset)++]=0xdd;
 					buffer[(*bufferoffset)++]=0x00;
 					buffer[(*bufferoffset)++]=0x04;
 					buffer[(*bufferoffset)++]=(ri >> 8) & 0xff;
 					buffer[(*bufferoffset)++]= ri & 0xff;
-				} else {
-					i+=strip[i+2]+2;
 				}
 				break;
-			case 0xc4:
-			case 0xdb:
-				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
-				*bufferoffset+=strip[i+2]+2;
-				i+=strip[i+2]+2;
+			case 0xc4: /* DHT */
+			case 0xdb: /* DQT */
+                if( *bufferoffset + datalen + 2 > buffersize )
+                    return(0);
+				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
+				*bufferoffset+=datalen+2;
 				break;
-			case 0xda:
+			case 0xda: /* SOS */
 				if(no==0){
-					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), strip[i+2]+2);
-					*bufferoffset+=strip[i+2]+2;
-					i+=strip[i+2]+2;
+                    if( *bufferoffset + datalen + 2 > buffersize )
+                        return(0);
+					_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), datalen+2);
+					*bufferoffset+=datalen+2;
 				} else {
+                    if( *bufferoffset + 2 > buffersize )
+                        return(0);
 					buffer[(*bufferoffset)++]=0xff;
 					buffer[(*bufferoffset)++]=
                                             (unsigned char)(0xd0 | ((no-1)%8));
-					i+=strip[i+2]+2;
 				}
-				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i-1]), (*striplength)-i-1);
-				*bufferoffset+=(*striplength)-i-1;
+				i += datalen + 1;
+				/* copy remainder of strip */
+                if( *bufferoffset + *striplength - i > buffersize )
+                    return(0);
+				_TIFFmemcpy(&(buffer[*bufferoffset]), &(strip[i]), *striplength - i);
+				*bufferoffset+= *striplength - i;
 				return(1);
 			default:
-				i+=strip[i+2]+2;
+				/* ignore any other marker */
+				break;
 		}
+		i += datalen + 1;
 	}
-	
 
+	/* failed to find SOS marker */
 	return(0);
 }
 #endif
@@ -3520,19 +3713,21 @@ static int t2p_process_jpeg_strip(
 	This functions converts a tilewidth x tilelength buffer of samples into an edgetilewidth x 
 	tilelength buffer of samples.
 */
-static void t2p_tile_collapse_left(
+static
+void t2p_tile_collapse_left(
 	tdata_t buffer, 
 	tsize_t scanwidth, 
 	uint32 tilewidth, 
 	uint32 edgetilewidth, 
 	uint32 tilelength){
 	
-	uint32 i=0;
+	uint32 i;
 	tsize_t edgescanwidth=0;
 	
 	edgescanwidth = (scanwidth * edgetilewidth + (tilewidth - 1))/ tilewidth;
 	for(i=0;i<tilelength;i++){
-		_TIFFmemcpy( 
+                /* We use memmove() since there can be overlaps in src and dst buffers for the first items */
+		memmove( 
 			&(((char*)buffer)[edgescanwidth*i]), 
 			&(((char*)buffer)[scanwidth*i]), 
 			edgescanwidth);
@@ -3548,7 +3743,8 @@ static void t2p_tile_collapse_left(
  * implementations, then it replaces the original implementations.
  */
 
-static void
+static
+void
 t2p_write_advance_directory(T2P* t2p, TIFF* output)
 {
 	t2p_disable(output);
@@ -3563,10 +3759,12 @@ t2p_write_advance_directory(T2P* t2p, TI
 	return;
 }
 
-static tsize_t t2p_sample_planar_separate_to_contig(T2P* t2p, 
-                                                    unsigned char* buffer, 
-                                                    unsigned char* samplebuffer, 
-                                                    tsize_t samplebuffersize){
+static
+tsize_t t2p_sample_planar_separate_to_contig(
+											T2P* t2p, 
+											unsigned char* buffer, 
+											unsigned char* samplebuffer, 
+											tsize_t samplebuffersize){
 
 	tsize_t stride=0;
 	tsize_t i=0;
@@ -3582,7 +3780,8 @@ static tsize_t t2p_sample_planar_separat
 	return(samplebuffersize);
 }
 
-static tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){
+static
+tsize_t t2p_sample_realize_palette(T2P* t2p, unsigned char* buffer){
 
 	uint32 sample_count=0;
 	uint16 component_count=0;
@@ -3590,8 +3789,18 @@ static tsize_t t2p_sample_realize_palett
 	uint32 sample_offset=0;
 	uint32 i=0;
 	uint32 j=0;
+        size_t data_size;
 	sample_count=t2p->tiff_width*t2p->tiff_length;
 	component_count=t2p->tiff_samplesperpixel;
+        data_size=TIFFSafeMultiply(size_t,sample_count,component_count);
+        if( (data_size == 0U) || (t2p->tiff_datasize < 0) ||
+            (data_size > (size_t) t2p->tiff_datasize) )
+        {
+            TIFFError(TIFF2PDF_MODULE,
+                      "Error: sample_count * component_count > t2p->tiff_datasize");
+            t2p->t2p_error = T2P_ERR_ERROR;
+            return 1;
+        }
 	
 	for(i=sample_count;i>0;i--){
 		palette_offset=buffer[i-1] * component_count;
@@ -3609,7 +3818,8 @@ static tsize_t t2p_sample_realize_palett
 	into RGB interleaved data, discarding A.
 */
 
-static tsize_t t2p_sample_abgr_to_rgb(tdata_t data, uint32 samplecount)
+static
+tsize_t t2p_sample_abgr_to_rgb(tdata_t data, uint32 samplecount)
 {
 	uint32 i=0;
 	uint32 sample=0;
@@ -3629,12 +3839,18 @@ static tsize_t t2p_sample_abgr_to_rgb(td
  * into RGB interleaved data, discarding A.
  */
 
-static tsize_t
+static
+tsize_t
 t2p_sample_rgbaa_to_rgb(tdata_t data, uint32 samplecount)
 {
 	uint32 i;
 	
-	for(i = 0; i < samplecount; i++)
+    /* For the 3 first samples, there is overlapping between souce and
+       destination, so use memmove().
+       See http://bugzilla.maptools.org/show_bug.cgi?id=2577 */
+    for(i = 0; i < 3 && i < samplecount; i++)
+        memmove((uint8*)data + i * 3, (uint8*)data + i * 4, 3);
+	for(; i < samplecount; i++)
 		memcpy((uint8*)data + i * 3, (uint8*)data + i * 4, 3);
 
 	return(i * 3);
@@ -3645,20 +3861,20 @@ t2p_sample_rgbaa_to_rgb(tdata_t data, ui
  * into RGB interleaved data, adding 255-A to each component sample.
  */
 
-static tsize_t
+static
+tsize_t
 t2p_sample_rgba_to_rgb(tdata_t data, uint32 samplecount)
 {
 	uint32 i = 0;
 	uint32 sample = 0;
 	uint8 alpha = 0;
-	
+
 	for (i = 0; i < samplecount; i++) {
 		sample=((uint32*)data)[i];
-		alpha=(uint8)((255 - (sample & 0xff)));
-		((uint8 *)data)[i * 3] = (uint8) ((sample >> 24) & 0xff) + alpha;
-		((uint8 *)data)[i * 3 + 1] = (uint8) ((sample >> 16) & 0xff) + alpha;
-		((uint8 *)data)[i * 3 + 2] = (uint8) ((sample >> 8) & 0xff) + alpha;
-		
+		alpha=(uint8)((255 - ((sample >> 24) & 0xff)));
+		((uint8 *)data)[i * 3] = (uint8) ((sample >> 16) & 0xff) + alpha;
+		((uint8 *)data)[i * 3 + 1] = (uint8) ((sample >> 8) & 0xff) + alpha;
+		((uint8 *)data)[i * 3 + 2] = (uint8) (sample & 0xff) + alpha;
 	}
 
 	return (i * 3);
@@ -3669,7 +3885,8 @@ t2p_sample_rgba_to_rgb(tdata_t data, uin
 	to unsigned.
 */
 
-static tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t buffer, uint32 samplecount){
+static
+tsize_t t2p_sample_lab_signed_to_unsigned(tdata_t buffer, uint32 samplecount){
 
 	uint32 i=0;
 
@@ -3695,13 +3912,17 @@ static tsize_t t2p_sample_lab_signed_to_
 	This function writes the PDF header to output.
 */
 
-static tsize_t t2p_write_pdf_header(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_header(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 	char buffer[16];
 	int buflen=0;
 	
-	buflen=sprintf(buffer, "%%PDF-%u.%u ", t2p->pdf_majorversion&0xff, t2p->pdf_minorversion&0xff);
+	buflen = snprintf(buffer, sizeof(buffer), "%%PDF-%u.%u ",
+			  t2p->pdf_majorversion&0xff,
+			  t2p->pdf_minorversion&0xff);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t)"\n%\342\343\317\323\n", 7);
 
@@ -3712,13 +3933,15 @@ static tsize_t t2p_write_pdf_header(T2P*
 	This function writes the beginning of a PDF object to output.
 */
 
-static tsize_t t2p_write_pdf_obj_start(uint32 number, TIFF* output){
+static
+tsize_t t2p_write_pdf_obj_start(uint32 number, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
-	buflen=sprintf(buffer, "%lu", (unsigned long)number);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)number);
+	check_snprintf_ret((T2P*)NULL, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen );
 	written += t2pWriteFile(output, (tdata_t) " 0 obj\n", 7);
 
@@ -3729,7 +3952,8 @@ static tsize_t t2p_write_pdf_obj_start(u
 	This function writes the end of a PDF object to output.
 */
 
-static tsize_t t2p_write_pdf_obj_end(TIFF* output){
+static
+tsize_t t2p_write_pdf_obj_end(TIFF* output){
 
 	tsize_t written=0;
 
@@ -3739,23 +3963,23 @@ static tsize_t t2p_write_pdf_obj_end(TIF
 }
 
 /*
-	This function writes a PDF string object to output.
-*/
+ * This function writes a PDF string object to output.
+ */
 	
-static tsize_t t2p_write_pdf_string(unsigned char* pdfstr, TIFF* output){
-
+static
+tsize_t t2p_write_pdf_string(char* pdfstr, TIFF* output)
+{
 	tsize_t written = 0;
 	uint32 i = 0;
 	char buffer[64];
-	uint32 len = 0;
+	size_t len = 0;
 	
-	len = strlen((char *)pdfstr);
+	len = strlen(pdfstr);
 	written += t2pWriteFile(output, (tdata_t) "(", 1);
 	for (i=0; i<len; i++) {
 		if((pdfstr[i]&0x80) || (pdfstr[i]==127) || (pdfstr[i]<32)){
-			sprintf(buffer, "\\%.3hho", pdfstr[i]);
-			buffer[sizeof(buffer) - 1] = '\0';
-			written += t2pWriteFile(output, (tdata_t) buffer, 4);
+			snprintf(buffer, sizeof(buffer), "\\%.3o", ((unsigned char)pdfstr[i]));
+			written += t2pWriteFile(output, (tdata_t)buffer, 4);
 		} else {
 			switch (pdfstr[i]){
 				case 0x08:
@@ -3797,7 +4021,8 @@ static tsize_t t2p_write_pdf_string(unsi
 	This function writes a buffer of data to output.
 */
 
-static tsize_t t2p_write_pdf_stream(tdata_t buffer, tsize_t len, TIFF* output){
+static
+tsize_t t2p_write_pdf_stream(tdata_t buffer, tsize_t len, TIFF* output){
 
 	tsize_t written=0;
 
@@ -3810,7 +4035,8 @@ static tsize_t t2p_write_pdf_stream(tdat
 	This functions writes the beginning of a PDF stream to output.
 */
 
-static tsize_t t2p_write_pdf_stream_start(TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_start(TIFF* output){
 
 	tsize_t written=0;
 
@@ -3823,7 +4049,8 @@ static tsize_t t2p_write_pdf_stream_star
 	This function writes the end of a PDF stream to output. 
 */
 
-static tsize_t t2p_write_pdf_stream_end(TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_end(TIFF* output){
 
 	tsize_t written=0;
 
@@ -3836,17 +4063,19 @@ static tsize_t t2p_write_pdf_stream_end(
 	This function writes a stream dictionary for a PDF stream to output.
 */
 
-static tsize_t t2p_write_pdf_stream_dict(tsize_t len, uint32 number, TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_dict(tsize_t len, uint32 number, TIFF* output){
 	
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 	
 	written += t2pWriteFile(output, (tdata_t) "/Length ", 8);
 	if(len!=0){
 		written += t2p_write_pdf_stream_length(len, output);
 	} else {
-		buflen=sprintf(buffer, "%lu", (unsigned long)number);
+		buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)number);
+		check_snprintf_ret((T2P*)NULL, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6);
 	}
@@ -3858,7 +4087,8 @@ static tsize_t t2p_write_pdf_stream_dict
 	This functions writes the beginning of a PDF stream dictionary to output.
 */
 
-static tsize_t t2p_write_pdf_stream_dict_start(TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_dict_start(TIFF* output){
 
 	tsize_t written=0;
 
@@ -3871,7 +4101,8 @@ static tsize_t t2p_write_pdf_stream_dict
 	This function writes the end of a PDF stream dictionary to output. 
 */
 
-static tsize_t t2p_write_pdf_stream_dict_end(TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_dict_end(TIFF* output){
 
 	tsize_t written=0;
 
@@ -3884,13 +4115,15 @@ static tsize_t t2p_write_pdf_stream_dict
 	This function writes a number to output.
 */
 
-static tsize_t t2p_write_pdf_stream_length(tsize_t len, TIFF* output){
+static
+tsize_t t2p_write_pdf_stream_length(tsize_t len, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
-	buflen=sprintf(buffer, "%lu", (unsigned long)len);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)len);
+	check_snprintf_ret((T2P*)NULL, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "\n", 1);
 
@@ -3898,20 +4131,23 @@ static tsize_t t2p_write_pdf_stream_leng
 }
 
 /*
-	This function writes the PDF Catalog structure to output.
-*/
-
-static tsize_t t2p_write_pdf_catalog(T2P* t2p, TIFF* output){
+ * This function writes the PDF Catalog structure to output.
+ */
 
-	tsize_t written=0;
-	char buffer[16];
-	int buflen=0;
+static
+tsize_t t2p_write_pdf_catalog(T2P* t2p, TIFF* output)
+{
+	tsize_t written = 0;
+	char buffer[32];
+	int buflen = 0;
 
 	written += t2pWriteFile(output, 
 		(tdata_t)"<< \n/Type /Catalog \n/Pages ", 
 		27);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_pages);
-	written += t2pWriteFile(output, (tdata_t) buffer, buflen );
+	buflen = snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_pages);
+	check_snprintf_ret(t2p, buflen, buffer);
+	written += t2pWriteFile(output, (tdata_t) buffer,
+				TIFFmin((size_t)buflen, sizeof(buffer) - 1));
 	written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6);
 	if(t2p->pdf_fitwindow){
 		written += t2pWriteFile(output, 
@@ -3927,86 +4163,60 @@ static tsize_t t2p_write_pdf_catalog(T2P
 	This function writes the PDF Info structure to output.
 */
 
-static tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output){
-
+static
+tsize_t t2p_write_pdf_info(T2P* t2p, TIFF* input, TIFF* output)
+{
 	tsize_t written = 0;
-	unsigned char* info;
+	char* info;
 	char buffer[512];
-	int buflen = 0;
 
-        (void) buflen;
-
-	if(t2p->pdf_datetime==NULL){
+	if(t2p->pdf_datetime[0] == '\0')
 		t2p_pdf_tifftime(t2p, input);
-	}
-	if(strlen((char *)t2p->pdf_datetime) > 0){
+	if (strlen(t2p->pdf_datetime) > 0) {
 		written += t2pWriteFile(output, (tdata_t) "<< \n/CreationDate ", 18);
 		written += t2p_write_pdf_string(t2p->pdf_datetime, output);
 		written += t2pWriteFile(output, (tdata_t) "\n/ModDate ", 10);
 		written += t2p_write_pdf_string(t2p->pdf_datetime, output);
 	}
 	written += t2pWriteFile(output, (tdata_t) "\n/Producer ", 11);
-	_TIFFmemset((tdata_t)buffer, 0x00, sizeof(buffer));
-	buflen = sprintf(buffer, "libtiff / tiff2pdf - %d", TIFFLIB_VERSION);
-	written += t2p_write_pdf_string((unsigned char*)buffer, 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 != NULL){ 
-		if(strlen((char *)t2p->pdf_creator)>0){
-			if(strlen((char *)t2p->pdf_creator) > 511) {
-				t2p->pdf_creator[512] = '\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){
-			if(strlen((char *)info) > 511) {
-				info[512] = '\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 != NULL) { 
-		if(strlen((char *)t2p->pdf_author) > 0) {
-			if(strlen((char *)t2p->pdf_author) > 511) {
-				t2p->pdf_author[512] = '\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){
-			if(strlen((char *)info) > 511) {
-				info[512] = '\0';
-			}
-			written += t2pWriteFile(output, (tdata_t) "/Author ", 8);
-			written += t2p_write_pdf_string(info, output);
-			written += t2pWriteFile(output, (tdata_t) "\n", 1);
-		} else if ( TIFFGetField(input, TIFFTAG_COPYRIGHT, &info) != 0){
-			if(strlen((char *)info) > 511) {
-				info[512] = '\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 != NULL) {
-		if(strlen((char *)t2p->pdf_title) > 0) {
-			if(strlen((char *)t2p->pdf_title) > 511) {
-				t2p->pdf_title[512] = '\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((char *)info) > 511) {
+	}
+	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);
@@ -4014,36 +4224,25 @@ static tsize_t t2p_write_pdf_info(T2P* t
 			written += t2pWriteFile(output, (tdata_t) "\n", 1);
 		}
 	}
-	if(t2p->pdf_subject != NULL) {
-		if(strlen((char *)t2p->pdf_subject) > 0) {
-			if(strlen((char *)t2p->pdf_subject) > 511) {
-				t2p->pdf_subject[512] = '\0';
-			}
-			written += t2pWriteFile(output, (tdata_t) "/Subject ", 9);
-			written += t2p_write_pdf_string(t2p->pdf_subject, output);
-			written += t2pWriteFile(output, (tdata_t) "\n", 1);
-		}
+	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) {
-			if(strlen((char *)info) > 511) {
-				info[512] = '\0';
-			}
+		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 != NULL) { 
-		if(strlen((char *)t2p->pdf_keywords) > 0) {
-			if(strlen((char *)t2p->pdf_keywords) > 511) {
-				t2p->pdf_keywords[512] = '\0';
-			}
-			written += t2pWriteFile(output, (tdata_t) "/Keywords ", 10);
-			written += t2p_write_pdf_string(t2p->pdf_keywords, output);
-			written += t2pWriteFile(output, (tdata_t) "\n", 1);
-		}
+	if (t2p->pdf_keywords[0] != '\0') {
+		written += t2pWriteFile(output, (tdata_t) "/Keywords ", 10);
+		written += t2p_write_pdf_string(t2p->pdf_keywords, output);
+		written += t2pWriteFile(output, (tdata_t) "\n", 1);
 	}
-	written += t2pWriteFile(output, (tdata_t) ">> \n", 4);	
+	written += t2pWriteFile(output, (tdata_t) ">> \n", 4);
 
 	return(written);
 }
@@ -4053,21 +4252,27 @@ static tsize_t t2p_write_pdf_info(T2P* t
  * date string, it is called by t2p_pdf_tifftime.
  */
 
-static void t2p_pdf_currenttime(T2P* t2p)
+static
+void t2p_pdf_currenttime(T2P* t2p)
 {
-
 	struct tm* currenttime;
 	time_t timenow;
 
-	timenow=time(0);
-	currenttime=localtime(&timenow);
-	sprintf((char *)t2p->pdf_datetime, "D:%.4d%.2d%.2d%.2d%.2d%.2d",
-		(currenttime->tm_year+1900) % 65536, 
-		(currenttime->tm_mon+1) % 256, 
-		(currenttime->tm_mday) % 256, 
-		(currenttime->tm_hour) % 256, 
-		(currenttime->tm_min) % 256, 
-		(currenttime->tm_sec) % 256);
+	if (time(&timenow) == (time_t) -1) {
+		TIFFError(TIFF2PDF_MODULE,
+			  "Can't get the current time: %s", strerror(errno));
+		timenow = (time_t) 0;
+	}
+
+	currenttime = localtime(&timenow);
+	snprintf(t2p->pdf_datetime, sizeof(t2p->pdf_datetime),
+		 "D:%.4d%.2d%.2d%.2d%.2d%.2d",
+		 (currenttime->tm_year + 1900) % 65536,
+		 (currenttime->tm_mon + 1) % 256,
+		 (currenttime->tm_mday) % 256,
+		 (currenttime->tm_hour) % 256,
+		 (currenttime->tm_min) % 256,
+		 (currenttime->tm_sec) % 256);
 
 	return;
 }
@@ -4077,19 +4282,11 @@ static void t2p_pdf_currenttime(T2P* t2p
  * TIFF file if it exists or the current time as a PDF date string.
  */
 
-static void t2p_pdf_tifftime(T2P* t2p, TIFF* input){
-
+void t2p_pdf_tifftime(T2P* t2p, TIFF* input)
+{
 	char* datetime;
 
-	t2p->pdf_datetime = (unsigned char*) _TIFFmalloc(19);
-	if(t2p->pdf_datetime == NULL){
-		TIFFError(TIFF2PDF_MODULE, 
-		"Can't allocate %u bytes of memory for t2p_pdf_tiff_time", 17); 
-		t2p->t2p_error = T2P_ERR_ERROR;
-		return;
-	}
-	t2p->pdf_datetime[16] = '\0';
-	if( TIFFGetField(input, TIFFTAG_DATETIME, &datetime) != 0 
+	if (TIFFGetField(input, TIFFTAG_DATETIME, &datetime) != 0
 	    && (strlen(datetime) >= 19) ){
 		t2p->pdf_datetime[0]='D';
 		t2p->pdf_datetime[1]=':';
@@ -4107,6 +4304,7 @@ static void t2p_pdf_tifftime(T2P* t2p, T
 		t2p->pdf_datetime[13]=datetime[15];
 		t2p->pdf_datetime[14]=datetime[17];
 		t2p->pdf_datetime[15]=datetime[18];
+		t2p->pdf_datetime[16] = '\0';
 	} else {
 		t2p_pdf_currenttime(t2p);
 	}
@@ -4118,19 +4316,21 @@ static void t2p_pdf_tifftime(T2P* t2p, T
  * This function writes a PDF Pages Tree structure to output.
  */
 
-static tsize_t t2p_write_pdf_pages(T2P* t2p, TIFF* output)
+static
+tsize_t t2p_write_pdf_pages(T2P* t2p, TIFF* output)
 {
 	tsize_t written=0;
 	tdir_t i=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
 	int page=0;
-	written += t2pWriteFile(output, 
+	written += t2pWriteFile(output,
 		(tdata_t) "<< \n/Type /Pages \n/Kids [ ", 26);
 	page = t2p->pdf_pages+1;
 	for (i=0;i<t2p->tiff_pagecount;i++){
-		buflen=sprintf(buffer, "%d", page);
+		buflen=snprintf(buffer, sizeof(buffer), "%d", page);
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 		if ( ((i+1)%8)==0 ) {
@@ -4145,8 +4345,8 @@ static tsize_t t2p_write_pdf_pages(T2P*
 		}
 	}
 	written += t2pWriteFile(output, (tdata_t) "] \n/Count ", 10);
-	_TIFFmemset(buffer, 0x00, 16);
-	buflen=sprintf(buffer, "%d", t2p->tiff_pagecount);
+	buflen=snprintf(buffer, sizeof(buffer), "%d", t2p->tiff_pagecount);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " \n>> \n", 6);
 
@@ -4157,32 +4357,39 @@ static tsize_t t2p_write_pdf_pages(T2P*
 	This function writes a PDF Page structure to output.
 */
 
-static tsize_t t2p_write_pdf_page(uint32 object, T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_page(uint32 object, T2P* t2p, TIFF* output){
 
 	unsigned int i=0;
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[256];
 	int buflen=0;
-	
+
 	written += t2pWriteFile(output, (tdata_t) "<<\n/Type /Page \n/Parent ", 24);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_pages);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_pages);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6);
 	written += t2pWriteFile(output, (tdata_t) "/MediaBox [", 11); 
-	buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x1);
+	buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.x1);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " ", 1); 
-	buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y1);
+	buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.y1);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " ", 1); 
-	buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.x2);
+	buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.x2);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " ", 1); 
-	buflen=sprintf(buffer, "%.4f",t2p->pdf_mediabox.y2);
+	buflen=snprintf(buffer, sizeof(buffer), "%.4f",t2p->pdf_mediabox.y2);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "] \n", 3); 
 	written += t2pWriteFile(output, (tdata_t) "/Contents ", 10);
-	buflen=sprintf(buffer, "%lu", (unsigned long)(object + 1));
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(object + 1));
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " 0 R \n", 6);
 	written += t2pWriteFile(output, (tdata_t) "/Resources << \n", 15);
@@ -4190,16 +4397,17 @@ static tsize_t t2p_write_pdf_page(uint32
 		written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12);
 		for(i=0;i<t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount;i++){
 			written += t2pWriteFile(output, (tdata_t) "/Im", 3);
-			buflen = sprintf(buffer, "%u", t2p->pdf_page+1);
+			buflen = snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1);
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) "_", 1);
-			buflen = sprintf(buffer, "%u", i+1);
+			buflen = snprintf(buffer, sizeof(buffer), "%u", i+1);
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) " ", 1);
-			buflen = sprintf(
-				buffer, 
-				"%lu", 
+			buflen = snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); 
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 			if(i%4==3){
@@ -4210,13 +4418,13 @@ static tsize_t t2p_write_pdf_page(uint32
 	} else {
 			written += t2pWriteFile(output, (tdata_t) "/XObject <<\n", 12);
 			written += t2pWriteFile(output, (tdata_t) "/Im", 3);
-			buflen = sprintf(buffer, "%u", t2p->pdf_page+1);
+			buflen = snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1);
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) " ", 1);
-			buflen = sprintf(
-				buffer, 
-				"%lu", 
+			buflen = snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)(object+3+(2*i)+t2p->tiff_pages[t2p->pdf_page].page_extra)); 
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 		written += t2pWriteFile(output, (tdata_t) ">>\n", 3);
@@ -4224,17 +4432,16 @@ static tsize_t t2p_write_pdf_page(uint32
 	if(t2p->tiff_transferfunctioncount != 0) {
 		written += t2pWriteFile(output, (tdata_t) "/ExtGState <<", 13);
 		t2pWriteFile(output, (tdata_t) "/GS1 ", 5);
-		buflen = sprintf(
-			buffer, 
-			"%lu", 
+		buflen = snprintf(buffer, sizeof(buffer), "%lu",
 			(unsigned long)(object + 3)); 
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 		written += t2pWriteFile(output, (tdata_t) ">> \n", 4);
 	}
 	written += t2pWriteFile(output, (tdata_t) "/ProcSet [ ", 11);
-	if(t2p->pdf_colorspace == T2P_CS_BILEVEL 
-		|| t2p->pdf_colorspace == T2P_CS_GRAY
+	if(t2p->pdf_colorspace & T2P_CS_BILEVEL 
+		|| t2p->pdf_colorspace & T2P_CS_GRAY
 		){
 		written += t2pWriteFile(output, (tdata_t) "/ImageB ", 8);
 	} else {
@@ -4252,7 +4459,8 @@ static tsize_t t2p_write_pdf_page(uint32
 	This function composes the page size and image and tile locations on a page.
 */
 
-static void t2p_compose_pdf_page(T2P* t2p){
+static
+void t2p_compose_pdf_page(T2P* t2p){
 
 	uint32 i=0;
 	uint32 i2=0;
@@ -4264,6 +4472,8 @@ static void t2p_compose_pdf_page(T2P* t2
 	uint32 tilelength=0;
 	int istiled=0;
 	float f=0;
+	float width_ratio=0;
+	float length_ratio=0;
 	
 	t2p->pdf_xres = t2p->tiff_xres;
 	t2p->pdf_yres = t2p->tiff_yres;
@@ -4275,8 +4485,18 @@ static void t2p_compose_pdf_page(T2P* t2
 		t2p->pdf_xres = t2p->pdf_defaultxres;
 	if(t2p->pdf_yres == 0.0)
 		t2p->pdf_yres = t2p->pdf_defaultyres;
-	if (t2p->tiff_resunit != RESUNIT_CENTIMETER	/* RESUNIT_NONE and */
-	    && t2p->tiff_resunit != RESUNIT_INCH) {	/* other cases */
+	if (t2p->pdf_image_fillpage) {
+		width_ratio = t2p->pdf_defaultpagewidth/t2p->tiff_width;
+		length_ratio = t2p->pdf_defaultpagelength/t2p->tiff_length;
+		if (width_ratio < length_ratio ) {
+			t2p->pdf_imagewidth = t2p->pdf_defaultpagewidth;
+			t2p->pdf_imagelength = t2p->tiff_length * width_ratio;
+		} else {
+			t2p->pdf_imagewidth = t2p->tiff_width * length_ratio;
+			t2p->pdf_imagelength = t2p->pdf_defaultpagelength;
+		}
+	} else if (t2p->tiff_resunit != RESUNIT_CENTIMETER	/* RESUNIT_NONE and */
+		&& t2p->tiff_resunit != RESUNIT_INCH) {	/* other cases */
 		t2p->pdf_imagewidth = ((float)(t2p->tiff_width))/t2p->pdf_xres;
 		t2p->pdf_imagelength = ((float)(t2p->tiff_length))/t2p->pdf_yres;
 	} else {
@@ -4318,6 +4538,15 @@ static void t2p_compose_pdf_page(T2P* t2
 	} else {
 		tilewidth=(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilewidth;
 		tilelength=(t2p->tiff_tiles[t2p->pdf_page]).tiles_tilelength;
+		if( tilewidth > INT_MAX ||
+		    tilelength > INT_MAX ||
+		    t2p->tiff_width > INT_MAX - tilewidth ||
+		    t2p->tiff_length > INT_MAX - tilelength )
+		{
+		    TIFFError(TIFF2PDF_MODULE, "Integer overflow");
+		    t2p->t2p_error = T2P_ERR_ERROR;
+		    return;
+		}
 		tilecountx=(t2p->tiff_width + 
 			tilewidth -1)/ 
 			tilewidth;
@@ -4439,7 +4668,8 @@ static void t2p_compose_pdf_page(T2P* t2
 	return;
 }
 
-static void t2p_compose_pdf_page_orient(T2P_BOX* boxp, uint16 orientation){
+static
+void t2p_compose_pdf_page_orient(T2P_BOX* boxp, uint16 orientation){
 
 	float m1[9];
 	float f=0.0;
@@ -4514,7 +4744,8 @@ static void t2p_compose_pdf_page_orient(
 	return;
 }
 
-static void t2p_compose_pdf_page_orient_flip(T2P_BOX* boxp, uint16 orientation){
+static
+void t2p_compose_pdf_page_orient_flip(T2P_BOX* boxp, uint16 orientation){
 
 	float m1[9];
 	float f=0.0;
@@ -4576,7 +4807,8 @@ static void t2p_compose_pdf_page_orient_
 	This function writes a PDF Contents stream to output.
 */
 
-static tsize_t t2p_write_pdf_page_content_stream(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_page_content_stream(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 	ttile_t i=0;
@@ -4587,7 +4819,7 @@ static tsize_t t2p_write_pdf_page_conten
 	if(t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount>0){ 
 		for(i=0;i<t2p->tiff_tiles[t2p->pdf_page].tiles_tilecount; i++){
 			box=t2p->tiff_tiles[t2p->pdf_page].tiles_tiles[i].tile_box;
-			buflen=sprintf(buffer, 
+			buflen=snprintf(buffer, sizeof(buffer), 
 				"q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d_%ld Do Q\n", 
 				t2p->tiff_transferfunctioncount?"/GS1 gs ":"",
 				box.mat[0],
@@ -4598,11 +4830,12 @@ static tsize_t t2p_write_pdf_page_conten
 				box.mat[7],
 				t2p->pdf_page + 1, 
 				(long)(i + 1));
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2p_write_pdf_stream(buffer, buflen, output);
 		}
 	} else {
 		box=t2p->pdf_imagebox;
-		buflen=sprintf(buffer, 
+		buflen=snprintf(buffer, sizeof(buffer), 
 			"q %s %.4f %.4f %.4f %.4f %.4f %.4f cm /Im%d Do Q\n", 
 			t2p->tiff_transferfunctioncount?"/GS1 gs ":"",
 			box.mat[0],
@@ -4612,6 +4845,7 @@ static tsize_t t2p_write_pdf_page_conten
 			box.mat[6],
 			box.mat[7],
 			t2p->pdf_page+1);
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2p_write_pdf_stream(buffer, buflen, output);
 	}
 
@@ -4622,64 +4856,59 @@ static tsize_t t2p_write_pdf_page_conten
 	This function writes a PDF Image XObject stream dictionary to output. 
 */
 
-static tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t tile, 
-                                                 T2P* t2p, 
-                                                 TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_stream_dict(ttile_t tile, 
+												T2P* t2p, 
+												TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
 	written += t2p_write_pdf_stream_dict(0, t2p->pdf_xrefcount+1, output); 
 	written += t2pWriteFile(output, 
 		(tdata_t) "/Type /XObject \n/Subtype /Image \n/Name /Im", 
 		42);
-	buflen=sprintf(buffer, "%u", t2p->pdf_page+1);
+	buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_page+1);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	if(tile != 0){
 		written += t2pWriteFile(output, (tdata_t) "_", 1);
-		buflen=sprintf(buffer, "%lu", (unsigned long)tile);
+		buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)tile);
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	}
 	written += t2pWriteFile(output, (tdata_t) "\n/Width ", 8);
-	_TIFFmemset((tdata_t)buffer, 0x00, 16);
 	if(tile==0){
-		buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_width);
+		buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->tiff_width);
 	} else {
 		if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){
-			buflen=sprintf(
-				buffer, 
-				"%lu", 
+			buflen=snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth);
 		} else {
-			buflen=sprintf(
-				buffer, 
-				"%lu", 
+			buflen=snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth);
 		}
 	}
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "\n/Height ", 9);
-	_TIFFmemset((tdata_t)buffer, 0x00, 16);
 	if(tile==0){
-		buflen=sprintf(buffer, "%lu", (unsigned long)t2p->tiff_length);
+		buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->tiff_length);
 	} else {
 		if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)!=0){
-			buflen=sprintf(
-				buffer, 
-				"%lu", 
+			buflen=snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength);
 		} else {
-			buflen=sprintf(
-				buffer, 
-				"%lu", 
+			buflen=snprintf(buffer, sizeof(buffer), "%lu",
 				(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength);
 		}
 	}
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "\n/BitsPerComponent ", 19);
-	_TIFFmemset((tdata_t)buffer, 0x00, 16);
-	buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample);
+	buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_bitspersample);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "\n/ColorSpace ", 13);
 	written += t2p_write_pdf_xobject_cs(t2p, output);
@@ -4688,7 +4917,7 @@ static tsize_t t2p_write_pdf_xobject_str
 					 (tdata_t) "\n/Interpolate true", 18);
 	if( (t2p->pdf_switchdecode != 0)
 #ifdef CCITT_SUPPORT
-		&& ! (t2p->pdf_colorspace == T2P_CS_BILEVEL 
+		&& ! (t2p->pdf_colorspace & T2P_CS_BILEVEL 
 		&& t2p->pdf_compression == T2P_COMPRESS_G4)
 #endif
 		){
@@ -4704,7 +4933,8 @@ static tsize_t t2p_write_pdf_xobject_str
  */
 
 
-static tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_cs(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 	char buffer[128];
@@ -4723,11 +4953,12 @@ static tsize_t t2p_write_pdf_xobject_cs(
 		t2p->pdf_colorspace ^= T2P_CS_PALETTE;
 		written += t2p_write_pdf_xobject_cs(t2p, output);
 		t2p->pdf_colorspace |= T2P_CS_PALETTE;
-		buflen=sprintf(buffer, "%u", (0x0001 << t2p->tiff_bitspersample)-1 );
+		buflen=snprintf(buffer, sizeof(buffer), "%u", (0x0001 << t2p->tiff_bitspersample)-1 );
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " ", 1);
-		_TIFFmemset(buffer, 0x00, 16);
-		buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_palettecs ); 
+		buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_palettecs ); 
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ]\n", 7);
 		return(written);
@@ -4761,22 +4992,16 @@ static tsize_t t2p_write_pdf_xobject_cs(
 			X_W /= Y_W;
 			Z_W /= Y_W;
 			Y_W = 1.0F;
-			buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", X_W, Y_W, Z_W);
-			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
-			X_W = 0.3457F; /* 0.3127F; */ /* D50, commented D65 */
-			Y_W = 0.3585F; /* 0.3290F; */
-			Z_W = 1.0F - (X_W + Y_W);
-			X_W /= Y_W;
-			Z_W /= Y_W;
-			Y_W = 1.0F;
-			buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", 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);
 			written += t2pWriteFile(output, (tdata_t) "/Range ", 7);
-			buflen=sprintf(buffer, "[%d %d %d %d] \n", 
+			buflen=snprintf(buffer, sizeof(buffer), "[%d %d %d %d] \n", 
 				t2p->pdf_labrange[0], 
 				t2p->pdf_labrange[1], 
 				t2p->pdf_labrange[2], 
 				t2p->pdf_labrange[3]);
+			check_snprintf_ret(t2p, buflen, buffer);
 			written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			written += t2pWriteFile(output, (tdata_t) ">>] \n", 5);
 			
@@ -4785,30 +5010,35 @@ static tsize_t t2p_write_pdf_xobject_cs(
 	return(written);
 }
 
-static tsize_t t2p_write_pdf_transfer(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_transfer(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
 	written += t2pWriteFile(output, (tdata_t) "<< /Type /ExtGState \n/TR ", 25);
 	if(t2p->tiff_transferfunctioncount == 1){
-		buflen=sprintf(buffer, "%lu",
+		buflen=snprintf(buffer, sizeof(buffer), "%lu",
 			       (unsigned long)(t2p->pdf_xrefcount + 1));
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 	} else {
 		written += t2pWriteFile(output, (tdata_t) "[ ", 2);
-		buflen=sprintf(buffer, "%lu",
+		buflen=snprintf(buffer, sizeof(buffer), "%lu",
 			       (unsigned long)(t2p->pdf_xrefcount + 1));
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
-		buflen=sprintf(buffer, "%lu",
+		buflen=snprintf(buffer, sizeof(buffer), "%lu",
 			       (unsigned long)(t2p->pdf_xrefcount + 2));
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
-		buflen=sprintf(buffer, "%lu",
+		buflen=snprintf(buffer, sizeof(buffer), "%lu",
 			       (unsigned long)(t2p->pdf_xrefcount + 3));
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) " 0 R ", 5);
 		written += t2pWriteFile(output, (tdata_t) "/Identity ] ", 12);
@@ -4819,31 +5049,34 @@ static tsize_t t2p_write_pdf_transfer(T2
 	return(written);
 }
 
-static tsize_t t2p_write_pdf_transfer_dict(T2P* t2p, TIFF* output, uint16 i){
+static
+tsize_t t2p_write_pdf_transfer_dict(T2P* t2p, TIFF* output, uint16 i){
 
 	tsize_t written=0;
 	char buffer[32];
 	int buflen=0;
-	(void)i; // XXX
+	(void)i; /* XXX */
 
 	written += t2pWriteFile(output, (tdata_t) "/FunctionType 0 \n", 17);
 	written += t2pWriteFile(output, (tdata_t) "/Domain [0.0 1.0] \n", 19);
 	written += t2pWriteFile(output, (tdata_t) "/Range [0.0 1.0] \n", 18);
-	buflen=sprintf(buffer, "/Size [%u] \n", (1<<t2p->tiff_bitspersample));
+	buflen=snprintf(buffer, sizeof(buffer), "/Size [%u] \n", (1<<t2p->tiff_bitspersample));
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "/BitsPerSample 16 \n", 19);
-	written += t2p_write_pdf_stream_dict(1<<(t2p->tiff_bitspersample+1), 0, output);
+	written += t2p_write_pdf_stream_dict(((tsize_t)1)<<(t2p->tiff_bitspersample+1), 0, output);
 
 	return(written);
 }
 
-static tsize_t t2p_write_pdf_transfer_stream(T2P* t2p, TIFF* output, uint16 i){
+static
+tsize_t t2p_write_pdf_transfer_stream(T2P* t2p, TIFF* output, uint16 i){
 
 	tsize_t written=0;
 
 	written += t2p_write_pdf_stream(
 		t2p->tiff_transferfunction[i], 
-		(1<<(t2p->tiff_bitspersample+1)), 
+		(((tsize_t)1)<<(t2p->tiff_bitspersample+1)), 
 		output);
 
 	return(written);
@@ -4853,10 +5086,11 @@ static tsize_t t2p_write_pdf_transfer_st
 	This function writes a PDF Image XObject Colorspace array to output.
 */
 
-static tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_calcs(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[128];
+	char buffer[256];
 	int buflen=0;
 	
 	float X_W=0.0;
@@ -4924,19 +5158,22 @@ static tsize_t t2p_write_pdf_xobject_cal
 	written += t2pWriteFile(output, (tdata_t) "<< \n", 4);
 	if(t2p->pdf_colorspace & T2P_CS_CALGRAY){
 		written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12);
-		buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", 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);
 		written += t2pWriteFile(output, (tdata_t) "/Gamma 2.2 \n", 12);
 	}
 	if(t2p->pdf_colorspace & T2P_CS_CALRGB){
 		written += t2pWriteFile(output, (tdata_t) "/WhitePoint ", 12);
-		buflen=sprintf(buffer, "[%.4f %.4f %.4f] \n", 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);
 		written += t2pWriteFile(output, (tdata_t) "/Matrix ", 8);
-		buflen=sprintf(buffer, "[%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f] \n", 
+		buflen=snprintf(buffer, sizeof(buffer), "[%.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f] \n", 
 			X_R, Y_R, Z_R, 
 			X_G, Y_G, Z_G, 
 			X_B, Y_B, Z_B); 
+		check_snprintf_ret(t2p, buflen, buffer);
 		written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 		written += t2pWriteFile(output, (tdata_t) "/Gamma [2.2 2.2 2.2] \n", 22);
 	}
@@ -4949,28 +5186,32 @@ static tsize_t t2p_write_pdf_xobject_cal
 	This function writes a PDF Image XObject Colorspace array to output.
 */
 
-static tsize_t t2p_write_pdf_xobject_icccs(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_icccs(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 	
 	written += t2pWriteFile(output, (tdata_t) "[/ICCBased ", 11);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_icccs);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_icccs);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " 0 R] \n", 7);
 
 	return(written);
 }
 
-static tsize_t t2p_write_pdf_xobject_icccs_dict(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_icccs_dict(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 	
 	written += t2pWriteFile(output, (tdata_t) "/N ", 3);
-	buflen=sprintf(buffer, "%u \n", t2p->tiff_samplesperpixel);
+	buflen=snprintf(buffer, sizeof(buffer), "%u \n", t2p->tiff_samplesperpixel);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) "/Alternate ", 11);
 	t2p->pdf_colorspace ^= T2P_CS_ICCBASED;
@@ -4981,7 +5222,8 @@ static tsize_t t2p_write_pdf_xobject_icc
 	return(written);
 }
 
-static tsize_t t2p_write_pdf_xobject_icccs_stream(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_icccs_stream(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 
@@ -4997,7 +5239,8 @@ static tsize_t t2p_write_pdf_xobject_icc
 	This function writes a palette stream for an indexed color space to output.
 */
 
-static tsize_t t2p_write_pdf_xobject_palettecs_stream(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_palettecs_stream(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 
@@ -5013,7 +5256,8 @@ static tsize_t t2p_write_pdf_xobject_pal
 	This function writes a PDF Image XObject Decode array to output.
 */
 
-static tsize_t t2p_write_pdf_xobject_decode(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_decode(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
 	int i=0;
@@ -5032,10 +5276,11 @@ static tsize_t t2p_write_pdf_xobject_dec
 	output.
 */
 
-static tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t tile, T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xobject_stream_filter(ttile_t tile, T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[16];
+	char buffer[32];
 	int buflen=0;
 
 	if(t2p->pdf_compression==T2P_COMPRESS_NONE){
@@ -5050,42 +5295,40 @@ static tsize_t t2p_write_pdf_xobject_str
 			written += t2pWriteFile(output, (tdata_t) "<< /K -1 ", 9);
 			if(tile==0){
 				written += t2pWriteFile(output, (tdata_t) "/Columns ", 9);
-				buflen=sprintf(buffer, "%lu",
+				buflen=snprintf(buffer, sizeof(buffer), "%lu",
 					       (unsigned long)t2p->tiff_width);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				written += t2pWriteFile(output, (tdata_t) " /Rows ", 7);
-				buflen=sprintf(buffer, "%lu",
+				buflen=snprintf(buffer, sizeof(buffer), "%lu",
 					       (unsigned long)t2p->tiff_length);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 			} else {
 				if(t2p_tile_is_right_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){
 					written += t2pWriteFile(output, (tdata_t) "/Columns ", 9);
-					buflen=sprintf(
-						buffer, 
-						"%lu", 
+					buflen=snprintf(buffer, sizeof(buffer), "%lu",
 						(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilewidth);
+					check_snprintf_ret(t2p, buflen, buffer);
 					written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				} else {
 					written += t2pWriteFile(output, (tdata_t) "/Columns ", 9);
-					buflen=sprintf(
-						buffer, 
-						"%lu", 
+					buflen=snprintf(buffer, sizeof(buffer), "%lu",
 						(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilewidth);
+					check_snprintf_ret(t2p, buflen, buffer);
 					written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				}
 				if(t2p_tile_is_bottom_edge(t2p->tiff_tiles[t2p->pdf_page], tile-1)==0){
 					written += t2pWriteFile(output, (tdata_t) " /Rows ", 7);
-					buflen=sprintf(
-						buffer, 
-						"%lu", 
+					buflen=snprintf(buffer, sizeof(buffer), "%lu",
 						(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_tilelength);
+					check_snprintf_ret(t2p, buflen, buffer);
 					written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				} else {
 					written += t2pWriteFile(output, (tdata_t) " /Rows ", 7);
-					buflen=sprintf(
-						buffer, 
-						"%lu", 
+					buflen=snprintf(buffer, sizeof(buffer), "%lu",
 						(unsigned long)t2p->tiff_tiles[t2p->pdf_page].tiles_edgetilelength);
+					check_snprintf_ret(t2p, buflen, buffer);
 					written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				}
 			}
@@ -5101,7 +5344,7 @@ static tsize_t t2p_write_pdf_xobject_str
 
 			if(t2p->tiff_photometric != PHOTOMETRIC_YCBCR) {
 				written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13);
-				written += t2pWriteFile(output, (tdata_t) "<< /ColorTransform 0 >>\n", 24);
+				written += t2pWriteFile(output, (tdata_t) "<< /ColorTransform 1 >>\n", 24);
 			}
 			break;
 #endif
@@ -5111,21 +5354,21 @@ static tsize_t t2p_write_pdf_xobject_str
 			if(t2p->pdf_compressionquality%100){
 				written += t2pWriteFile(output, (tdata_t) "/DecodeParms ", 13);
 				written += t2pWriteFile(output, (tdata_t) "<< /Predictor ", 14);
-				_TIFFmemset(buffer, 0x00, 16);
-				buflen=sprintf(buffer, "%u", t2p->pdf_compressionquality%100);
+				buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->pdf_compressionquality%100);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				written += t2pWriteFile(output, (tdata_t) " /Columns ", 10);
-				_TIFFmemset(buffer, 0x00, 16);
-				buflen = sprintf(buffer, "%lu",
+				buflen = snprintf(buffer, sizeof(buffer), "%lu",
 						 (unsigned long)t2p->tiff_width);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				written += t2pWriteFile(output, (tdata_t) " /Colors ", 9);
-				_TIFFmemset(buffer, 0x00, 16);
-				buflen=sprintf(buffer, "%u", t2p->tiff_samplesperpixel);
+				buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_samplesperpixel);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				written += t2pWriteFile(output, (tdata_t) " /BitsPerComponent ", 19);
-				_TIFFmemset(buffer, 0x00, 16);
-				buflen=sprintf(buffer, "%u", t2p->tiff_bitspersample);
+				buflen=snprintf(buffer, sizeof(buffer), "%u", t2p->tiff_bitspersample);
+				check_snprintf_ret(t2p, buflen, buffer);
 				written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 				written += t2pWriteFile(output, (tdata_t) ">>\n", 3);
 			}
@@ -5142,19 +5385,21 @@ static tsize_t t2p_write_pdf_xobject_str
 	This function writes a PDF xref table to output.
 */
 
-static tsize_t t2p_write_pdf_xreftable(T2P* t2p, TIFF* output){
+static
+tsize_t t2p_write_pdf_xreftable(T2P* t2p, TIFF* output){
 
 	tsize_t written=0;
-	char buffer[21];
+	char buffer[64];
 	int buflen=0;
 	uint32 i=0;
 
 	written += t2pWriteFile(output, (tdata_t) "xref\n0 ", 7);
-	buflen=sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount + 1));
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(t2p->pdf_xrefcount + 1));
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
 	written += t2pWriteFile(output, (tdata_t) " \n0000000000 65535 f \n", 22);
 	for (i=0;i<t2p->pdf_xrefcount;i++){
-		sprintf(buffer, "%.10lu 00000 n \n",
+		snprintf(buffer, sizeof(buffer), "%.10lu 00000 n \n",
 			(unsigned long)t2p->pdf_xrefoffsets[i]);
 		written += t2pWriteFile(output, (tdata_t) buffer, 20);
 	}
@@ -5166,52 +5411,40 @@ static tsize_t t2p_write_pdf_xreftable(T
  * This function writes a PDF trailer to output.
  */
 
-static tsize_t t2p_write_pdf_trailer(T2P* t2p, TIFF* output)
+static
+tsize_t t2p_write_pdf_trailer(T2P* t2p, TIFF* output)
 {
 
 	tsize_t written = 0;
 	char buffer[32];
 	int buflen = 0;
-	char fileidbuf[16];
-	int i = 0;
+	size_t i = 0;
 
-        for (i=0; i<(int)sizeof(fileidbuf); i++)
-          fileidbuf[i] = (char) rand();
+	for (i = 0; i < sizeof(t2p->pdf_fileid) - 8; i += 8)
+		snprintf(t2p->pdf_fileid + i, 9, "%.8X", rand());
 
-	t2p->pdf_fileid = (unsigned char*)_TIFFmalloc(33);
-	if(t2p->pdf_fileid == NULL) {
-		TIFFError(
-			TIFF2PDF_MODULE, 
-		"Can't allocate %u bytes of memory for t2p_write_pdf_trailer", 
-			33 );
-		t2p->t2p_error = T2P_ERR_ERROR;
-		return(0);
-	}
-	_TIFFmemset(t2p->pdf_fileid, 0x00, 33);
-	for (i = 0; i < 16; i++) {
-		sprintf((char *)t2p->pdf_fileid + 2 * i,
-			"%.2hhX", fileidbuf[i]);
-	}
 	written += t2pWriteFile(output, (tdata_t) "trailer\n<<\n/Size ", 17);
-	buflen = sprintf(buffer, "%lu", (unsigned long)(t2p->pdf_xrefcount+1));
+	buflen = snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)(t2p->pdf_xrefcount+1));
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
-	_TIFFmemset(buffer, 0x00, 32);	
 	written += t2pWriteFile(output, (tdata_t) "\n/Root ", 7);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_catalog);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_catalog);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
-	_TIFFmemset(buffer, 0x00, 32);	
 	written += t2pWriteFile(output, (tdata_t) " 0 R \n/Info ", 12);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_info);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_info);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
-	_TIFFmemset(buffer, 0x00, 32);	
 	written += t2pWriteFile(output, (tdata_t) " 0 R \n/ID[<", 11);
-	written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32);
+	written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid,
+				sizeof(t2p->pdf_fileid) - 1);
 	written += t2pWriteFile(output, (tdata_t) "><", 2);
-	written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid, 32);
+	written += t2pWriteFile(output, (tdata_t) t2p->pdf_fileid,
+				sizeof(t2p->pdf_fileid) - 1);
 	written += t2pWriteFile(output, (tdata_t) ">]\n>>\nstartxref\n", 16);
-	buflen=sprintf(buffer, "%lu", (unsigned long)t2p->pdf_startxref);
+	buflen=snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)t2p->pdf_startxref);
+	check_snprintf_ret(t2p, buflen, buffer);
 	written += t2pWriteFile(output, (tdata_t) buffer, buflen);
-	_TIFFmemset(buffer, 0x00, 32);	
 	written += t2pWriteFile(output, (tdata_t) "\n%%EOF\n", 7);
 
 	return(written);
@@ -5257,7 +5490,8 @@ static tsize_t t2p_write_pdf_trailer(T2P
   and TIFFClose on output.
 */
 
-static tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){
+static
+tsize_t t2p_write_pdf(T2P* t2p, TIFF* input, TIFF* output){
 
 	tsize_t written=0;
 	ttile_t i2=0;
@@ -5266,12 +5500,13 @@ static tsize_t t2p_write_pdf(T2P* t2p, T
 
 	t2p_read_tiff_init(t2p, input);
 	if(t2p->t2p_error!=T2P_ERR_OK){return(0);}
-	t2p->pdf_xrefoffsets= (uint32*) _TIFFmalloc(t2p->pdf_xrefcount * sizeof(uint32) );
+	t2p->pdf_xrefoffsets= (uint32*) _TIFFmalloc(TIFFSafeMultiply(tmsize_t,t2p->pdf_xrefcount,sizeof(uint32)) );
 	if(t2p->pdf_xrefoffsets==NULL){
 		TIFFError(
 			TIFF2PDF_MODULE, 
-			"Can't allocate %lu bytes of memory for t2p_write_pdf", 
-			t2p->pdf_xrefcount * (long)sizeof(uint32) );
+			"Can't allocate %u bytes of memory for t2p_write_pdf", 
+			(unsigned int) (t2p->pdf_xrefcount * sizeof(uint32)) );
+		t2p->t2p_error = T2P_ERR_ERROR;
 		return(written);
 	}
 	t2p->pdf_xrefcount=0;
@@ -5328,9 +5563,9 @@ static tsize_t t2p_write_pdf(T2P* t2p, T
 				written += t2p_write_pdf_transfer_dict(t2p, output, i);
 				written += t2p_write_pdf_stream_dict_end(output);
 				written += t2p_write_pdf_stream_start(output);
-				streamlen=written;
+				/* streamlen=written; */ /* value not used */
 				written += t2p_write_pdf_transfer_stream(t2p, output, i);
-				streamlen=written-streamlen;
+				/* streamlen=written-streamlen; */ /* value not used */
 				written += t2p_write_pdf_stream_end(output);
 				written += t2p_write_pdf_obj_end(output);
 			}
@@ -5343,9 +5578,9 @@ static tsize_t t2p_write_pdf(T2P* t2p, T
 			written += t2p_write_pdf_stream_dict(t2p->pdf_palettesize, 0, output);
 			written += t2p_write_pdf_stream_dict_end(output);
 			written += t2p_write_pdf_stream_start(output);
-			streamlen=written;
+			/* streamlen=written; */ /* value not used */
 			written += t2p_write_pdf_xobject_palettecs_stream(t2p, output);
-			streamlen=written-streamlen;
+			/* streamlen=written-streamlen; */ /* value not used */
 			written += t2p_write_pdf_stream_end(output);
 			written += t2p_write_pdf_obj_end(output);
 		}
@@ -5357,9 +5592,9 @@ static tsize_t t2p_write_pdf(T2P* t2p, T
 			written += t2p_write_pdf_xobject_icccs_dict(t2p, output);
 			written += t2p_write_pdf_stream_dict_end(output);
 			written += t2p_write_pdf_stream_start(output);
-			streamlen=written;
+			/* streamlen=written; */ /* value not used */
 			written += t2p_write_pdf_xobject_icccs_stream(t2p, output);
-			streamlen=written-streamlen;
+			/* streamlen=written-streamlen; */ /* value not used */
 			written += t2p_write_pdf_stream_end(output);
 			written += t2p_write_pdf_obj_end(output);
 		}
@@ -5420,5 +5655,13 @@ static tsize_t t2p_write_pdf(T2P* t2p, T
 }
 
 /* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
 
 #endif
+
