2009.03.27 22:42 "[Tiff] TIFFOpen throws access error", by

2009.04.08 20:56 "[Tiff] writing in-memory tiffs", by Christian Henning

Hi there, I have big problems writing in-memory tiffs. Depending on the libtiff version I'm using I get two different results and both aren't working. For reference, I'm using Visual Studio 2005.

1. Using libtiff3 ( 3.8.2.2278 )

Here, writing in-memory tiff finishes but the result is a lot different to when writing directly to the filesystem. The in-memory buffer is 3 bytes larger in my example and almost everything but the header is different as a binary compare tells me.

2. Using libtiff4 ( beta3 )

When writing the buffer libtiff breaks after writing the header ( 8 bytes ) with the following error:

"Maximum TIFF file size exceeded"

I'm running the same code as before but I'm linking to libtiff4.

Here is the whole test case code:

#include <stdio.h>

#include <cassert>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>

extern "C" {
#include "tiff.h"
#include "tiffio.h"
}

using namespace std;

static ostream* get_ostream( thandle_t handle )
{
    return reinterpret_cast< ostream* >( handle );
}

static tsize_t read_proc( thandle_t fd
                        , tdata_t   buf
                        , tsize_t   size

                        )
{
    return 0;
}

static tsize_t write_proc( thandle_t handle
                         , tdata_t   buf
                         , tsize_t   size

                         )
{
    cout << "write: " << size << endl;

    ostream* os = get_ostream( handle );

     os->write( reinterpret_cast<char const*>( buf )

             , static_cast<streamsize>( size )
             );

    assert( os->good() );

     return size;
}

static toff_t seek_proc( thandle_t handle
                       , toff_t off

                       , int way
                       )
{
    return off;
}

static int close_proc( thandle_t handle )
{
    ostream* os = get_ostream( handle );
    os->operator<< ( flush );

    return 0;
}

static toff_t size_proc( thandle_t handle )
{
    return 0;
}

static void tiff_error( const char* module, const char* fmt, va_list ap )
{
    char buf[1000];
    sprintf(buf, fmt, ap);
    cout << "error: " << buf << endl;
}

static void tiff_warning( char const *module, char const *fmt, va_list ap )
{
    char buf[1000];
    sprintf(buf, fmt, ap);
    cout << "warning: " << fmt << endl;
}

int main()
{
    {

 stringstream ss( ios_base::in | ios_base::out | ios_base::binary );

        TIFFSetErrorHandler  ( tiff_error   );
        TIFFSetWarningHandler( tiff_warning );

     TIFF* t

                                   , &ss

                            , read_proc
                            , write_proc
                            , seek_proc
                            , close_proc
                            , size_proc
                            , NULL
                            , NULL
                            );

        TIFFSetField( tiff, TIFFTAG_IMAGEWIDTH  , 1 );
        TIFFSetField( tiff, TIFFTAG_IMAGELENGTH , 1 );
        TIFFSetField( tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
        TIFFSetField( tiff, TIFFTAG_SAMPLESPERPIXEL, 1 );
        TIFFSetField( tiff, TIFFTAG_BITSPERSAMPLE, 8 );
        TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, PHOTOMETRIC_RGB );
        TIFFSetField( tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE );
        TIFFSetField( tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
        TIFFSetField( tiff, TIFFTAG_ROWSPERSTRIP,

TIFFDefaultStripSize( tiff, 0 ));

        vector< unsigned char > buffer( 100 );
        fill( buffer.begin(), buffer.end(), 0 );

        for( int i = 0; i < 1; ++ i )
        {
            TIFFWriteScanline( tiff, &buffer.front(), 0, 0 );
        }

        TIFFClose( tiff );

        // write to filesystem
        ofstream out( "c:\\in-memory.tiff", ios_base::binary );
        out << ss.rdbuf();
    }

    {
        TIFF* tiff = TIFFOpen( "c:\\direct.tiff", "w" );

        TIFFSetField( tiff, TIFFTAG_IMAGEWIDTH  , 1 );
        TIFFSetField( tiff, TIFFTAG_IMAGELENGTH , 1 );
        TIFFSetField( tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
        TIFFSetField( tiff, TIFFTAG_SAMPLESPERPIXEL, 1 );
        TIFFSetField( tiff, TIFFTAG_BITSPERSAMPLE, 8 );
        TIFFSetField( tiff, TIFFTAG_SAMPLEFORMAT, PHOTOMETRIC_RGB );
        TIFFSetField( tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE );
        TIFFSetField( tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
        TIFFSetField( tiff, TIFFTAG_ROWSPERSTRIP,

TIFFDefaultStripSize( tiff, 0 ));

        vector< unsigned char > buffer( 100 );
        fill( buffer.begin(), buffer.end(), 0 );

        for( int i = 0; i < 1; ++ i )
        {
            TIFFWriteScanline( tiff, &buffer.front(), 0, 0 );
        }

        TIFFClose( tiff );
    }

    return 0;
}

Thanks in advance for any help.

Christian