私はLibTiffのTIFFGetField関数を使って文字列TIFFフィールド(TIFFTAG_MODELなど)を読み込もうとしていましたが、そこから戻ってくるのはゼロメモリへのポインタです。 TIFFGetField man pageはあまり役に立ちません。文字列フィールドの引数がchar**
と予想されています。暗黙のうちにメモリを割り当て、そのメモリに文字列を書き込み、ポインタを返します。しかし、それはその記憶を解放する責任を話しません。TIFF文字列フィールドは、LibTIFFのTIFFGetFieldを使用してどのように取得されますか?
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=''
そして、ちょうどこれらのフィールドことを実証しますchar_ptr
にアクセスする前に、おそらくTIFFClose()
ない
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..
これは本当に問題でした。ありがとうございます。それはまた、文字列がどのように解放されているかの質問に答えるものです。 –