#include <tiffio.h> #include <pthread.h> // Function prototypes static tsize_t libtiffDummyReadProc (thandle_t fd, tdata_t buf, tsize_t size); static tsize_t libtiffDummyWriteProc (thandle_t fd, tdata_t buf, tsize_t size); static toff_t libtiffDummySeekProc (thandle_t fd, toff_t off, int i); static int libtiffDummyCloseProc (thandle_t fd); // We need globals because of the callbacks (they don't allow us to pass state) char *globalImageBuffer; unsigned long globalImageBufferOffset; // This mutex keeps the globals safe by ensuring only one user at a time pthread_mutex_t convMutex = PTHREAD_MUTEX_INITIALIZER; ... TIFF *conv; // Lock the mutex pthread_mutex_lock (&convMutex); globalImageBuffer = NULL; globalImageBufferOffset = 0; // Open the dummy document (which actually only exists in memory) conv = TIFFClientOpen ("dummy", "w", (thandle_t) - 1, libtiffDummyReadProc, libtiffDummyWriteProc, libtiffDummySeekProc, libtiffDummyCloseProc, NULL, NULL, NULL); // Setup the image as if it was any other tiff image here, including setting tags ... // Actually do the client open TIFFWriteEncodedStrip (conv, 0, stripBuffer, imageOffset); // Unlock the mutex pthread_mutex_unlock (&convMutex); ... /////////////////// Callbacks to libtiff ... static tsize_t libtiffDummyReadProc (thandle_t fd, tdata_t buf, tsize_t size) { // Return the amount of data read, which we will always set as 0 because // we only need to be able to write to these in-memory tiffs return 0; } static tsize_t libtiffDummyWriteProc (thandle_t fd, tdata_t buf, tsize_t size) { // libtiff will try to write an 8 byte header into the tiff file. We need // to ignore this because PDF does not use it... if ((size == 8) && (((char *) buf)[0] == 'I') && (((char *) buf)[1] == 'I') && (((char *) buf)[2] == 42)) { // Skip the header -- little endian } else if ((size == 8) && (((char *) buf)[0] == 'M') && (((char *) buf)[1] == 'M') && (((char *) buf)[2] == 42)) { // Skip the header -- big endian } else { // Have we done anything yet? if (globalImageBuffer == NULL) if((globalImageBuffer = (char *) malloc (size * sizeof (char))) == NULL) { fprintf(stderr, "Memory allocation error\n"); exit(42); } // Otherwise, we need to grow the memory buffer else { if ((globalImageBuffer = (char *) realloc (globalImageBuffer, (size * sizeof (char)) + globalImageBufferOffset)) == NULL) fprintf(stderr, "Could not grow the tiff conversion memory buffer\n"); exit(42); } // Now move the image data into the buffer memcpy (globalImageBuffer + globalImageBufferOffset, buf, size); globalImageBufferOffset += size; } return (size); } static toff_t libtiffDummySeekProc (thandle_t fd, toff_t off, int i) { // This appears to return the location that it went to return off; } static int libtiffDummyCloseProc (thandle_t fd) { // Return a zero meaning all is well return 0; }