2016-11-09 34 views
1

我一直在尝试使用LibTiff的TIFFGetField函数读取字符串TIFF字段(例如TIFFTAG_MODEL),但是我从中获得的所有信息都是指向归零内存的指针。 TIFFGetField man page没有什么帮助,只是说它需要一个字符串字段的char**参数,我认为这暗示了它将分配内存,将字符串写入该内存并返回一个指向它的指针。但是,它没有讨论释放内存的责任。如何使用LibTIFF的TIFFGetField检索TIFF字符串字段?

当我定义char*并将其初始化为NULL时,将该变量的地址传递给TIFFGetField,它将其设置为非NULL地址,但该地址指向的内存全为零。

如果相关,我在MacOS上使用LibTiff 4.0.2。

这是我迄今为止尝试过的一个MCVE。 (注释掉的代码是我与在已分配的缓冲区,而不是通过尝试这也不能工作。)

#include "tiffio.h" 
#include <stdio.h> 

const char* img_filename = "temp.tif"; 

void WriteTestTIFF() 
{ 
    TIFF* tiff = TIFFOpen(img_filename, "w"); 

    const size_t width = 2; 
    const size_t height = 2; 
    unsigned char image[width * height] = { 0 }; 

    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width); 
    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height); 
    TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, height); // Single strip image 
    TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE); 
    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8); 
    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1); 
    TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); 
    TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); 
    TIFFSetField(tiff, TIFFTAG_MINSAMPLEVALUE, 0); 
    TIFFSetField(tiff, TIFFTAG_MAXSAMPLEVALUE, 255); 

    TIFFSetField(tiff, TIFFTAG_SOFTWARE, "TestingTIFFStringFields"); 
    TIFFSetField(tiff, TIFFTAG_MODEL, "FakeCamera"); 

    TIFFWriteEncodedStrip(tiff, 0, image, height * width); 
    TIFFClose(tiff); 
} 

void ReadTestTIFF() 
{ 
    TIFF* tiff = TIFFOpen(img_filename, "r"); 
    //char buffer[256] = ""; 
    char* char_ptr = NULL; 
    uint32 width = 0; 
    uint32 height = 0; 
    printf("(void*)char_ptr=0x%016lX\n", (unsigned long)char_ptr); 
    //printf("buffer='%s'\n", buffer); 
    if (/*TIFFGetField(tiff, TIFFTAG_MODEL, buffer) != 1 
     ||*/ TIFFGetField(tiff, TIFFTAG_MODEL, &char_ptr) != 1 
     || TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) != 1 
     || TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height) != 1) 
    { 
     puts("One or more TIFFGetField calls failed."); 
    } 
    printf("width=%u\n", width); 
    printf("height=%u\n", height); 
    TIFFClose(tiff); 
    printf("(void*)char_ptr=0x%016lX\n", (unsigned long)char_ptr); 
    for (int n=0; n<5; n++) 
    { 
     printf("char_ptr[%d]=0x%02X\n", n, (unsigned int)(char_ptr[n])); 
    } 
    //printf("buffer='%s'\n", buffer); 
    printf("char_ptr='%s'\n", char_ptr); 
} 

int main() 
{ 
    WriteTestTIFF(); 
    ReadTestTIFF(); 
    return 0; 
} 

输出:

(void*)char_ptr=0x0000000000000000 
width=2 
height=2 
(void*)char_ptr=0x00007FA5B3400310 
char_ptr[0]=0x00 
char_ptr[1]=0x00 
char_ptr[2]=0x00 
char_ptr[3]=0x00 
char_ptr[4]=0x00 
char_ptr='' 

而只是为了证明这些领域正在编写正确,这里产生的TIFF文件:

0000000: 4949 2a00 0c00 0000 0000 0000 0e00 0001 II*............. 
0000010: 0300 0100 0000 0200 0000 0101 0300 0100 ................ 
0000020: 0000 0200 0000 0201 0300 0100 0000 0800 ................ 
0000030: 0000 0301 0300 0100 0000 0100 0000 0601 ................ 
0000040: 0300 0100 0000 0100 0000 1001 0200 0b00 ................ 
0000050: 0000 d200 0000 1101 0400 0100 0000 0800 ................ 
0000060: 0000 1501 0300 0100 0000 0100 0000 1601 ................ 
0000070: 0300 0100 0000 0200 0000 1701 0400 0100 ................ 
0000080: 0000 0400 0000 1801 0300 0100 0000 0000 ................ 
0000090: 0000 1901 0300 0100 0000 ff00 0000 3101 ..............1. 
00000a0: 0200 1800 0000 ba00 0000 5301 0300 0100 ..........S..... 
00000b0: 0000 0100 0000 0000 0000 5465 7374 696e ..........Testin 
00000c0: 6754 4946 4653 7472 696e 6746 6965 6c64 gTIFFStringField 
00000d0: 7300 4661 6b65 4361 6d65 7261 000a  s.FakeCamera.. 

回答

2

也许不TIFFClose()访问char_ptr之前。这可能会让你回到一个由TIFFOpen()创建/填充的数据结构的地址,并被TIFFClose()销毁。

+0

确实是这个问题,谢谢。这也回答了字符串如何被释放的问题。 –

相关问题