2012.11.24 00:09 "[Tiff] help writing thumbnails to TIFF file?", by Paul Heckbert

2012.11.23 23:49 "Re: [Tiff] Write Exif data to Tiff file", by Paul Heckbert

DonM-2 wrote:
>

> I would like to write Exif data (such as exposure time) to a tiff file I > am creating. Is this possible with libtiff,...

>

Yes, it's possible. Here's a sample C++ program that does it. This code works with libtiff version 4.0.3.

wtiff.cpp
---

// write a test picture to a TIFF file using libtiff, setting some optional EXIF tags

#include <assert.h>

#include <tiffio.h>

#include <tif_dir.h> // libtiff internals; for TIFFFieldArray

typedef unsigned char uint8;

int main() {
  int nx = 640, ny = 480;
  char *filename = "t.tif"; // file to write

TIFF *tif = TIFFOpen(filename, "w");
assert(tif);

  assert(TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx) != 0);
  assert(TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny) != 0);
  assert(TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8) != 0);
  assert(TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) != 0);
  assert(TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, ny/2) != 0); // two big
strips
  assert(TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW) != 0);
  assert(TIFFSetField(tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL) != 0);
  assert(TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT) != 0);
  assert(TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) != 0);
  assert(TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3) != 0);

  // add EXIF tags to the set of tags that libtiff knows about
  // necessary if we want to set EXIFTAG_DATETIMEORIGINAL, for example
  const TIFFFieldArray *exif_fields = _TIFFGetExifFields();
  _TIFFMergeFields(tif, exif_fields->fields, exif_fields->count);

  // the following two tags are optional
  assert(TIFFSetField(tif, TIFFTAG_SOFTWARE, "WhizBang 1.2.3") != 0);
  assert(TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, "2011:08:01 18:28:47")
!= 0);

  // the following line is optional. it causes IFD to be written at
beginning of file.
  // otherwise it would be written at end of file (after the pixels)
  assert(TIFFCheckpointDirectory(tif) != 0);

  uint8 *buf = (uint8 *)_TIFFmalloc(nx*3);

assert(buf);
picture has horizontal ramp in red, vertical ramp in green //

  for (int y=0; y<ny; y++) {

  uint8 *p = buf;

    for (int x=0; x<nx; x++) {
      *p++ = x*255/(nx-1);  // r
      *p++ = y*255/(ny-1);  // g
      *p++ = 0;             // b

  }
  assert(TIFFWriteScanline(tif, buf, y, 0) != -1);
}
_TIFFfree(buf);

 TIFFClose(tif);

}
---

Here's a makefile fragment for Mac OSX or Linux that takes care of providing the include path to the tif_dir.h file, which is not part of the build, but is in the libtiff source directory $TIFFSRC.

TOP = whatever
TIFF = $(TOP)/tiff-4.0.3/build
TIFFSRC = $(TOP)/tiff-4.0.3/libtiff
.cpp.o:
        g++ -c $(COPTS) -I$(TIFF)/include -I$(TIFFSRC) $<

If your version of libtiff is older, try the following small changes to the source code, which work with version 3.8.2, at least:

replace #include <tif_dir.h> line with

  extern "C" { extern const TIFFFieldInfo *_TIFFGetExifFieldInfo(size_t *);
}

and replace the two lines that call _TIFFGetExifFields and _TIFFMergeFields with these three lines:

  size_t exif_field_count;
  const TIFFFieldInfo *exif_field_info =
_TIFFGetExifFieldInfo(&exif_field_count);
  TIFFMergeFieldInfo(tif, exif_field_info, exif_field_count);

If you work in C and not C++, it would not be difficult to translate the above code to C.

--

View this message in context: http://old.nabble.com/Write-Exif-data-to-Tiff-file-tp32482486p34716158.html

Sent from the Tiff / LibTiff mailing list archive at Nabble.com.