AWARE [SYSTEMS]
AWare Systems, , Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
November 2012

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
Archive maintained by AWare Systems



New Datamatrix section



Valid HTML 4.01!



2012.11.23 23:49 "Re: 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.