Чтобы использовать буфер в памяти:

ли способ в LibTiff, как я могу прочитать файл из памяти и сохранить его в памяти?

Я не хочу сначала сохранять изображение на диск, прежде чем открывать его в другой библиотеке ...

Спасибо!

Ответы на вопрос(3)

и и передать ихTIFFClientOpen (неTIFFOpen) функция при создании вашегоTIFF.

Пример:

TIFF* tif = TIFFClientOpen(
    "Memory", "w", (thandle_t)something_you_will_use_later,
    tiff_Read, tiff_Write, tiff_Seek, tiff_Close, tiff_Size,
    tiff_Map, tiff_Unmap);

И вы должны также реализовать следующие функции (st перешел к этим функциямsomething_you_will_use_later перешел кTIFFClientOpen :

tsize_t tiff_Read(thandle_t st,tdata_t buffer,tsize_t size)
{
    ...
};

tsize_t tiff_Write(thandle_t st,tdata_t buffer,tsize_t size)
{
    ...
};

int tiff_Close(thandle_t)
{
    return 0;
};

toff_t tiff_Seek(thandle_t st,toff_t pos, int whence)
{
    if (pos == 0xFFFFFFFF)
       return 0xFFFFFFFF;
    ...
};

toff_t tiff_Size(thandle_t st)
{
    ...
};

int tiff_Map(thandle_t, tdata_t*, toff_t*)
{
    return 0;
};

void tiff_Unmap(thandle_t, tdata_t, toff_t)
{
    return;
};
 Van Coding18 янв. 2011 г., 17:16
Извините, что спрашиваю снова, но я не понимаю, как заставить эти функции работать. Я пытаюсь прочитать из строки и положить результат в строку. Не могли бы вы дать пример кода для этого? Это было бы здорово!
 Bobrovsky19 янв. 2011 г., 05:53
Вот (svn.exactcode.de/exact-image/trunk/codecs/tiff.cc) пример TIFFClientOpen, используемый для чтения / записи в потоки. Может быть, это будет полезно для вас.

Что я использую ...:

#define MALLOC(ptr,type,number,action) {\
if (((ptr) = (type*) malloc ((number)*sizeof(type))) == NULL) {\
    (void) fprintf (stderr, "[%s: #%04d] ERROR : malloc of %lu bytes failed !\n", __FILE__, __LINE__, number*sizeof(type));\
    perror ("Operating system message");\
    action;}}

#define REALLOC(ptr,type,number,action) {\
if (((ptr) = (type*) realloc ((ptr), (number)*sizeof(type))) == NULL) {\
    (void) fprintf (stderr, "[%s: #%04d] ERROR : realloc of %lu bytes failed!\n", __FILE__, __LINE__, number*sizeof(type));\
    perror ("Operating system message");\
    action;}}

#define FREE(ptr) { if (ptr != NULL) free (ptr); ptr = NULL; }


extern "C" {

    typedef struct _memtiff {
        unsigned char *data;
        tsize_t size;
        tsize_t incsiz;
        tsize_t flen;
        toff_t fptr;
    } MEMTIFF;

    static MEMTIFF *memTiffOpen(tsize_t incsiz = 10240, tsize_t initsiz = 10240)
    {
        MEMTIFF *memtif;
        MALLOC(memtif, MEMTIFF, 1, exit(-1));
        memtif->incsiz = incsiz;
        if (initsiz == 0) initsiz = incsiz;
        MALLOC(memtif->data, unsigned char, initsiz, exit(-1));
        memtif->size = initsiz;
        memtif->flen = 0;
        memtif->fptr = 0;
        return memtif;
    }
    /*===========================================================================*/

    static tsize_t memTiffReadProc(thandle_t handle, tdata_t buf, tsize_t size)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        tsize_t n;
        if (((tsize_t) memtif->fptr + size) <= memtif->flen) {
            n = size;
        }
        else {
            n = memtif->flen - memtif->fptr;
        }
        memcpy(buf, memtif->data + memtif->fptr, n);
        memtif->fptr += n;

        return n;
    }
    /*===========================================================================*/

    static tsize_t memTiffWriteProc(thandle_t handle, tdata_t buf, tsize_t size)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        if (((tsize_t) memtif->fptr + size) > memtif->size) {
            memtif->data = (unsigned char *) realloc(memtif->data, memtif->fptr + memtif->incsiz + size);
            memtif->size = memtif->fptr + memtif->incsiz + size;
        }
        memcpy (memtif->data + memtif->fptr, buf, size);
        memtif->fptr += size;
        if (memtif->fptr > memtif->flen) memtif->flen = memtif->fptr;

        return size;
    }
    /*===========================================================================*/

    static toff_t memTiffSeekProc(thandle_t handle, toff_t off, int whence)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        switch (whence) {
            case SEEK_SET: {
                if ((tsize_t) off > memtif->size) {
                    memtif->data = (unsigned char *) realloc(memtif->data, memtif->size + memtif->incsiz + off);
                    memtif->size = memtif->size + memtif->incsiz + off;
                }
                memtif->fptr = off;
                break;
            }
            case SEEK_CUR: {
                if ((tsize_t)(memtif->fptr + off) > memtif->size) {
                    memtif->data = (unsigned char *) realloc(memtif->data, memtif->fptr + memtif->incsiz + off);
                    memtif->size = memtif->fptr + memtif->incsiz + off;
                }
                memtif->fptr += off;
                break;
            }
            case SEEK_END: {
                if ((tsize_t) (memtif->size + off) > memtif->size) {
                    memtif->data = (unsigned char *) realloc(memtif->data, memtif->size + memtif->incsiz + off);
                    memtif->size = memtif->size + memtif->incsiz + off;
                }
                memtif->fptr = memtif->size + off;
                break;
            }
        }
        if (memtif->fptr > memtif->flen) memtif->flen = memtif->fptr;
        return memtif->fptr;
    }
    /*===========================================================================*/

    static int memTiffCloseProc(thandle_t handle)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        memtif->fptr = 0;
        return 0;
    }
    /*===========================================================================*/


    static toff_t memTiffSizeProc(thandle_t handle)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        return memtif->flen;
    }
    /*===========================================================================*/


    static int memTiffMapProc(thandle_t handle, tdata_t* base, toff_t* psize)
    {
        MEMTIFF *memtif = (MEMTIFF *) handle;
        *base = memtif->data;
        *psize = memtif->flen;
        return (1);
    }
    /*===========================================================================*/

    static void memTiffUnmapProc(thandle_t handle, tdata_t base, toff_t size)
    {
        return;
    }
    /*===========================================================================*/

    static void memTiffFree(MEMTIFF *memtif)
    {
        FREE(memtif->data);
        FREE(memtif);
        return;
    }
    /*===========================================================================*/

}

А потом:

if ((filepath == "-") || (filepath == "HTTP")) {
    memtif = memTiffOpen();
    tif = TIFFClientOpen("MEMTIFF", "wb", (thandle_t) memtif,
        memTiffReadProc,
        memTiffWriteProc,
        memTiffSeekProc,
        memTiffCloseProc,
        memTiffSizeProc,
        memTiffMapProc,
        memTiffUnmapProc
    );
}
else {
    if ((tif = TIFFOpen (filepath.c_str(), "wb")) == NULL) {
        if (memtif != NULL) memTiffFree(memtif);
        string msg = "TIFFopen of \"" + filepath + "\" failed!";
        throw SipiError(__file__, __LINE__, msg);
    }
}

Чтобы использовать буфер в памяти:

    if (filepath == "-") {
        size_t n = 0;
        while (n < memtif->flen) {
            n += fwrite (&(memtif->data[n]), 1, memtif->flen - n > 10240 ? 10240 : memtif->flen - n, stdout);
        }
        fflush(stdout);
        memTiffFree(memtif);
    }

что это старый вопрос, но я собираюсь опубликовать более простой и актуальный ответ для тех, кто, как я, нуждается в этой информации для более поздних версий libtiff. В самой последней версии libtiff (4.0.2) и даже в нескольких последних версиях, которые я считаю (проверьте ваш конкретный номер версии), есть включаемый файл с именем tiffio.hxx. Он имеет две внешние функции для чтения / записи в потоки в памяти:

extern TIFF* TIFFStreamOpen(const char*, std::ostream *);
extern TIFF* TIFFStreamOpen(const char*, std::istream *);

Вы можете просто включить этот файл и читать или записывать в память.

Написание примера:

#include <tiffio.h>
#include <tiffio.hxx>
#include <sstream>    

std::ostringstream output_TIFF_stream;

//Note: because this is an in memory TIFF, just use whatever you want for the name - we 
//aren't using it to read from a file
TIFF* mem_TIFF = TIFFStreamOpen("MemTIFF", &output_TIFF_stream);

//perform normal operations on mem_TIFF here like setting fields
//...

//Write image data to the TIFF 
//..

TIFFClose(mem_TIFF);   

//Now output_TIFF_stream has all of my image data. I can do whatever I need to with it.

Чтение очень похоже:

#include <tiffio.h>
#include <tiffio.hxx>
#include <sstream>

std::istringstream input_TIFF_stream;
//Populate input_TIFF_stream with TIFF image data
//...

TIFF* mem_TIFF = TIFFStreamOpen("MemTIFF", &input_TIFF_stream);

//perform normal operations on mem_TIFF here reading fields
//...

TIFFClose(mem_TIFF);

Это очень простые примеры, но вы можете видеть, что при использовании TIFFStreamOpen вам не нужно переопределять эти функции и передавать их в TIFFClientOpen.

 BoazGarty09 мар. 2015 г., 08:29
Хорошо, как я могу получить #include <tiffio.hxx> для устранения ошибки сборки?
 KSletmoe12 мар. 2015 г., 17:15
@david В чем ошибка? Заголовок не найден? Если это так, убедитесь, что у вас достаточно свежая версия libtiff
 FarK10 сент. 2018 г., 13:56
Могут быть некоторые проблемы с этим решением, проверьте это:maptools-org.996276.n3.nabble.com/In-memory-tiffs-td13305.html

Ваш ответ на вопрос