]> git.imager.perl.org - imager.git/blobdiff - tiff.c
- set i_format to tiff when reading tiff images and test for it
[imager.git] / tiff.c
diff --git a/tiff.c b/tiff.c
index 317c599ea5d74d0ab08b04806b244a0cecafc295..89eb4a143a3f06c87fccd5ef782eb0cfe08c89d7 100644 (file)
--- a/tiff.c
+++ b/tiff.c
@@ -61,6 +61,12 @@ static void error_handler(char const *module, char const *fmt, va_list ap) {
   i_push_errorvf(0, fmt, ap);
 }
 
+static void warn_handler(char const *module, char const *fmt, va_list ap) {
+  /* for now do nothing, perhaps we could warn(), though that should be
+     done in the XS code, not in the code which isn't mean to know perl 
+     exists ;) */
+}
+
 static int save_tiff_tags(TIFF *tif, i_img *im);
 
 static void expand_4bit_hl(unsigned char *buf, int count);
@@ -92,6 +98,37 @@ comp_seek(thandle_t h, toff_t o, int w) {
   return (toff_t) ig->seekcb(ig, o, w);
 }
 
+/*
+=item comp_mmap(thandle_t, tdata_t*, toff_t*)
+
+Dummy mmap stub.
+
+This shouldn't ever be called but newer tifflibs want it anyway.
+
+=cut
+*/
+
+static 
+int
+comp_mmap(thandle_t h, tdata_t*p, toff_t*off) {
+  return -1;
+}
+
+/*
+=item comp_munmap(thandle_t h, tdata_t p, toff_t off)
+
+Dummy munmap stub.
+
+This shouldn't ever be called but newer tifflibs want it anyway.
+
+=cut
+*/
+
+static void
+comp_munmap(thandle_t h, tdata_t p, toff_t off) {
+  /* do nothing */
+}
+
 static i_img *read_one_tiff(TIFF *tif) {
   i_img *im;
   uint32 width, height;
@@ -126,6 +163,9 @@ static i_img *read_one_tiff(TIFF *tif) {
   else {
     im = i_img_empty_ch(NULL, width, height, channels);
   }
+
+  if (!im)
+    return NULL;
     
   /* resolution tags */
   TIFFGetFieldDefaulted(tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
@@ -158,6 +198,8 @@ static i_img *read_one_tiff(TIFF *tif) {
                 strlen(data), 0);
     }
   }
+
+  i_tags_add(&im->tags, "i_format", 0, "tiff", -1, 0);
   
   /*   TIFFPrintDirectory(tif, stdout, 0); good for debugging */
 
@@ -260,9 +302,13 @@ static i_img *read_one_tiff(TIFF *tif) {
       }
     } else {
       uint32 rowsperstrip, row;
-      TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
-      mm_log((1, "i_readtiff_wiol: rowsperstrip=%d\n", rowsperstrip));
-      
+      int rc = TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+      mm_log((1, "i_readtiff_wiol: rowsperstrip=%d rc = %d\n", rowsperstrip, rc));
+  
+                       if (rc != 1 || rowsperstrip==-1) {
+                               rowsperstrip = height;
+                       }
+    
       raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
       if (!raster) {
         i_img_destroy(im);
@@ -315,10 +361,12 @@ i_img*
 i_readtiff_wiol(io_glue *ig, int length) {
   TIFF* tif;
   TIFFErrorHandler old_handler;
+  TIFFErrorHandler old_warn_handler;
   i_img *im;
 
   i_clear_error();
   old_handler = TIFFSetErrorHandler(error_handler);
+  old_warn_handler = TIFFSetWarningHandler(warn_handler);
 
   /* Add code to get the filename info from the iolayer */
   /* Also add code to check for mmapped code */
@@ -334,13 +382,14 @@ i_readtiff_wiol(io_glue *ig, int length) {
                       (TIFFSeekProc) comp_seek,
                       (TIFFCloseProc) ig->closecb,
                       ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
-                      (TIFFMapFileProc) NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      (TIFFMapFileProc) comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);
   
   if (!tif) {
     mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
     i_push_error(0, "opening file");
     TIFFSetErrorHandler(old_handler);
+    TIFFSetWarningHandler(old_warn_handler);
     return NULL;
   }
 
@@ -348,6 +397,7 @@ i_readtiff_wiol(io_glue *ig, int length) {
 
   if (TIFFLastDirectory(tif)) mm_log((1, "Last directory of tiff file\n"));
   TIFFSetErrorHandler(old_handler);
+  TIFFSetWarningHandler(old_warn_handler);
   TIFFClose(tif);
   return im;
 }
@@ -363,12 +413,14 @@ i_img**
 i_readtiff_multi_wiol(io_glue *ig, int length, int *count) {
   TIFF* tif;
   TIFFErrorHandler old_handler;
+  TIFFErrorHandler old_warn_handler;
   i_img **results = NULL;
   int result_alloc = 0;
   int dirnum = 0;
 
   i_clear_error();
   old_handler = TIFFSetErrorHandler(error_handler);
+  old_warn_handler = TIFFSetWarningHandler(warn_handler);
 
   /* Add code to get the filename info from the iolayer */
   /* Also add code to check for mmapped code */
@@ -383,14 +435,15 @@ i_readtiff_multi_wiol(io_glue *ig, int length, int *count) {
                       (TIFFReadWriteProc) ig->writecb,
                       (TIFFSeekProc) comp_seek,
                       (TIFFCloseProc) ig->closecb,
-                      (TIFFSizeProc) ig->sizecb,
-                      (TIFFMapFileProc) NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
+                      (TIFFMapFileProc) comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);
   
   if (!tif) {
     mm_log((1, "i_readtiff_wiol: Unable to open tif file\n"));
     i_push_error(0, "opening file");
     TIFFSetErrorHandler(old_handler);
+    TIFFSetWarningHandler(old_warn_handler);
     return NULL;
   }
 
@@ -408,11 +461,17 @@ i_readtiff_multi_wiol(io_glue *ig, int length, int *count) {
         i_img **newresults;
         result_alloc *= 2;
         newresults = myrealloc(results, result_alloc * sizeof(i_img *));
+       if (!newresults) {
+         i_img_destroy(im); /* don't leak it */
+         break;
+       }
+       results = newresults;
       }
     }
     results[*count-1] = im;
   } while (TIFFSetDirectory(tif, ++dirnum));
 
+  TIFFSetWarningHandler(old_warn_handler);
   TIFFSetErrorHandler(old_handler);
   TIFFClose(tif);
   return results;
@@ -802,9 +861,9 @@ i_writetiff_multi_wiol(io_glue *ig, i_img **imgs, int count) {
                       (TIFFReadWriteProc) ig->writecb,
                       (TIFFSeekProc)      comp_seek,
                       (TIFFCloseProc)     ig->closecb, 
-                      (TIFFSizeProc)      ig->sizecb,
-                      (TIFFMapFileProc)   NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
+                      (TIFFMapFileProc)   comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);
   
 
 
@@ -862,9 +921,9 @@ i_writetiff_multi_wiol_faxable(io_glue *ig, i_img **imgs, int count, int fine) {
                       (TIFFReadWriteProc) ig->writecb,
                       (TIFFSeekProc)      comp_seek,
                       (TIFFCloseProc)     ig->closecb, 
-                      (TIFFSizeProc)      ig->sizecb,
-                      (TIFFMapFileProc)   NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
+                      (TIFFMapFileProc)   comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);
   
 
 
@@ -918,9 +977,9 @@ i_writetiff_wiol(i_img *img, io_glue *ig) {
                       (TIFFReadWriteProc) ig->writecb,
                       (TIFFSeekProc)      comp_seek,
                       (TIFFCloseProc)     ig->closecb, 
-                      (TIFFSizeProc)      ig->sizecb,
-                      (TIFFMapFileProc)   NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
+                      (TIFFMapFileProc)   comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);
   
 
 
@@ -973,9 +1032,9 @@ i_writetiff_wiol_faxable(i_img *im, io_glue *ig, int fine) {
                       (TIFFReadWriteProc) ig->writecb,
                       (TIFFSeekProc)      comp_seek,
                       (TIFFCloseProc)     ig->closecb, 
-                      (TIFFSizeProc)      ig->sizecb,
-                      (TIFFMapFileProc)   NULL,
-                      (TIFFUnmapFileProc) NULL);
+                      ig->sizecb ? (TIFFSizeProc) ig->sizecb : (TIFFSizeProc) sizeproc,
+                      (TIFFMapFileProc)   comp_mmap,
+                      (TIFFUnmapFileProc) comp_munmap);