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

Reply via email to