TIFFSetField() is a brain-dead interface which works over very type-unsafe
C ellipses feature. So one can easily invoke UB and worse.
In your case it probably comes down to that you need to pass a pointer to
data to the TIFFSetField() ellipses. If you pass a struct or class
instead, the behaviour is UB, but might work accidentally in some cases as
you have discovered, if the compiler decides to pass the struct as a
pointer instead of by value or whatever.
Also, the man page for TIFFSetField does not contain the word
EXIFTAG_CFAPATTERN. This means this is a custom tag which actually should
be first defined by TIFFMergeFieldInfo() to avoid libTIFF warnings or
worse, and then TIFFSetField() should be called according to this
definition. It looks like EXIFTAG_CFAPATTERN should be defined as a
byte-vector, taking an explicit count plus a pointer to the binary data.
This might be some kind of default, which explains why this worked for you
in the first place, but it is better to be explicit.
unsigned int tag = EXIFTAG_CFAPATTERN;
short count=-1; //variable length
unsigned char passCount = 1; // pass count separately into
TIFFSetField().
TIFFFieldInfo customTag = { tag, count,
count, TIFF_BYTE, FIELD_CUSTOM, TRUE, passCount, (char*) "Custom Tag" };
if (TIFFMergeFieldInfo(tif, &customTag, 1) != 0) {
// handle error
}
int len = ...; // actual length of the array
auto ptr = reinterpret_cast<uint8_t *>(&cfaDimPat);
TIFFSetField(tif, tag, len, ptr);
HTH. I am not too sure if what I wrote actually makes any sense, but
at least these lines are extracted from our codebase which works
successfully with custom TIFF tags.
Cheers
Paavo
On Sun, 22 Jun 2025, David C. Partridge via Tiff wrote:
Date: Sun, 22 Jun 2025 07:38:57 +0100
From: David C. Partridge via Tiff <[email protected]>
Reply-To: David C. Partridge <[email protected]>
To: [email protected]
Subject: Re: [Tiff] Problem with SIGSEGV on Linux with TIFFSetField for
EXIFTAG_CFAPATTERN
An update:
I changed the code to read:
TIFFSetField(m_tiff, EXIFTAG_CFAPATTERN, count, reinterpret_cast<uint8_t
*>(&cfaDimPat));
Which appears to have fixed the problem though I’m unclear why it would change
anything much …
D.
From: Tiff <[email protected]> On Behalf Of David C. Partridge via
Tiff
Sent: 22 June 2025 06:17
To: [email protected]
Subject: [Tiff] Problem with SIGSEGV on Linux with TIFFSetField for
EXIFTAG_CFAPATTERN
I have the following code:
//
// Now write EXIFTAG_CFAPATTERN
which is basically what we put into cfaDimPat
// when the other (non-EXIF) CFA
related tags were written.
//
if (cfa)
{
constexpr uint16_t
count = sizeof(cfaDimPat.dim) + sizeof(cfaDimPat.cfa.cfa4);
TIFFSetField(m_tiff, EXIFTAG_CFAPATTERN, count, cfaDimPat);
}
Which works just fine on Windows. However, on Linux I get a SIGSEGV and my
signal handler prints a backtrace as follows:
00002431 2025-06-22 04:43:00.002 005575 7f8a2f604100 >In
signalHandler(SIGSEGV)
00002432 2025-06-22 04:43:00.064 005575 7f8a2f604100
>__GI___sigaction at :?
00002432 2025-06-22 04:43:00.064 005575 7f8a2f604100 >
00002433 2025-06-22 04:43:00.110 005575 7f8a2f604100
>__memcpy_avx_unaligned_erms at
./string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:399
00002433 2025-06-22 04:43:00.110 005575 7f8a2f604100 >
00002434 2025-06-22 04:43:00.147 005575 7f8a2f604100
>_TIFFVSetField at tif_dir.c:?
00002434 2025-06-22 04:43:00.147 005575 7f8a2f604100 >
00002435 2025-06-22 04:43:00.186 005575 7f8a2f604100 >TIFFSetField
at ??:?
00002435 2025-06-22 04:43:00.186 005575 7f8a2f604100 >
00002436 2025-06-22 04:43:00.743 005575 7f8a2f604100
>CTIFFWriter::Open() at
/home/amonra/.vs/DSS/DeepSkyStackerKernel/TIFFUtil.cpp:1077
Where line 1077 is the TIFFSetField call above.
tif_dirinfo.c says this about that tag:
{EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, FIELD_CUSTOM, 1,
1, "CFAPattern", NULL}
Have I got the type for the count value incorrect or got that value wrong
(should I provide the count of uint16_t values rather than count of bytes)?
The cfaDimPat structure is defined as follows:
struct
{
uint16_t dim[2]{ 0 };
union
{
uint8_t cfa4[4];
uint8_t cfa9[9];
uint8_t cfa16[16];
} cfa { 0 };
} cfaDimPat;
Thank you, David
_______________________________________________
Tiff mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/tiff