2016-11-09 3 views
1

J'ai essayé de lire des champs TIFF de chaîne (tels que TIFFTAG_MODEL) en utilisant la fonction TIFFGetField de LibTiff, mais tout ce que je récupère est des pointeurs vers la mémoire mise à zéro. Le TIFFGetField man page n'est pas beaucoup d'aide, indiquant simplement qu'il attend un argument char** pour les champs de chaîne, ce qui suggère implicitement qu'il va allouer de la mémoire, écrire la chaîne dans cette mémoire et lui renvoyer un pointeur. Mais ensuite, il ne discute pas des responsabilités pour libérer cette mémoire.Comment les champs de chaîne TIFF sont-ils récupérés à l'aide de TIFFGetField de LibTIFF?

Lorsque je définis un char* et l'initialise à NULL, puis passez l'adresse de cette variable à TIFFGetField, elle le définit sur une adresse non NULL, mais la mémoire pointée par cette adresse est tous des zéros. Dans le cas où c'est pertinent, j'utilise LibTiff 4.0.2 sur MacOS.

Voici un MCVE avec ce que j'ai essayé jusqu'ici. (Le code est commenté où je faisais des expériences avec le passage dans un tampon déjà alloué à la place qui ne fonctionnait pas non plus..)

#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; 
} 

Sortie:

(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='' 

Et juste pour démontrer que ces champs sont correctement écrites, voici le fichier TIFF résultant:

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.. 

Répondre

2

peut-être ne pas TIFFClose() avant d'accéder à char_ptr. Il vous renvoie probablement une adresse dans une structure de données créée/remplie par TIFFOpen() et détruite par TIFFClose().

+0

C'était en effet le problème, merci. Cela répond également à la question de savoir comment la chaîne est libérée. –