Hi Oliver,

I have rewritten libtiffOStreamSeekProc so that it extends the stream
if the required file position is beyond the current extents of the
stream.  I've tested with the attached test program based on your
suggested test.  The solution I went for is similar in effect to what
you implemented but shorter and with less separate cases, making it
easier to follow and understand.

The code now looks like:

toff_t libtiffOStreamSeekProc(thandle_t fd, toff_t off, int i)
{
    std::ostream *fout = (std::ostream*)fd;

    toff_t pos_required = 0;
    toff_t stream_end = 0;
    switch(i)
    {
        case SEEK_SET:
        {
            pos_required = off;

            fout->seekp(0, std::ios::end);
            stream_end = fout->tellp();
            break;
        }
        case SEEK_CUR:
        {
            toff_t stream_curr = fout->tellp();
            pos_required = stream_curr + off;

            fout->seekp(0, std::ios::end);
            stream_end = fout->tellp();
            break;
        }
        case SEEK_END:
        {
            fout->seekp(0, std::ios::end);
            stream_end = fout->tellp();
            pos_required = stream_end + off;
            break;
        }
        default:
            break;
    }

    if (pos_required>stream_end)
    {
        // position required past the end of the stream so we need to
insert extra characters to
        // ensure the stream is big enough to encompass the new the position.
        fout->seekp(0, std::ios::end);
        for(toff_t i=stream_end; i<pos_required; ++i)
        {
            fout->put(char(0));
        }
    }

    fout->seekp(pos_required,std::ios::beg);
    toff_t ret = fout->tellp();
    if (fout->bad())
    {
        ret = 0;
    }
    return ret;
}

I've tesed with the attached test.cpp and before the change it failed
as per your description it works fine and the resulting tif file is
indentical to the one written directly to the file.

Could you please test with your application to see if everything is
work fine for you.
Robert.
cmake_minimum_required(VERSION 2.6)

SET(PROJECT_NAME tiffbug)
PROJECT(${PROJECT_NAME})

FIND_PACKAGE(OpenThreads)
FIND_PACKAGE(osg)
FIND_PACKAGE(osgDB)
FIND_PACKAGE(osgViewer)
FIND_PACKAGE(osgShadow)
FIND_PACKAGE(osgSim)
FIND_PACKAGE(osgParticle)

SET(SOURCES
    test.cpp
)

INCLUDE_DIRECTORIES(${OPENTHREADS_INCLUDE_DIR} ${OSG_INCLUDE_DIR})

LINK_DIRECTORIES(${OSG_LIB_DIR})

ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCES})

TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OSG_LIBRARY} ${OSGDB_LIBRARY} 
${OPENTHREADS_LIBRARY})
#include <osgDB/Registry>

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments(&argc, argv);
    
    osg::Image* img = new osg::Image();
    img->allocateImage(32,32,1,GL_RGB, GL_UNSIGNED_BYTE);
    osgDB::ReaderWriter* _rw = osgDB::Registry::instance()->getReaderWriterForExtension("tiff");
    osgDB::ReaderWriter::Options* _rwOptions = new osgDB::ReaderWriter::Options();

    std::stringstream outStream;
    std::ofstream outfile("outp.tif", std::ios::out | std::ios::binary);

    if (arguments.read("-d"))
    {
        _rw->writeImage( *img, outfile, _rwOptions); //Line A
    }
    else
    {
        _rw->writeImage( *img, outStream, _rwOptions); //Line B
        std::string outBuf = outStream.str();
        outfile << outBuf;
    }
    outfile.close();

    return 0;

}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to