libtiff: Add background gradient option for tiff2rgba alpha compositing.

From 5da038136c54b3a298b79f6c850547d928f70a99 Mon Sep 17 00:00:00 2001
From: Lee Howard <[EMAIL REDACTED]>
Date: Fri, 17 May 2024 16:26:07 +0000
Subject: [PATCH] Add background gradient option for tiff2rgba alpha
 compositing.

---
 doc/tools/tiff2rgba.rst |  5 +++++
 tools/tiff2rgba.c       | 17 +++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/doc/tools/tiff2rgba.rst b/doc/tools/tiff2rgba.rst
index d547dc3e..9c067800 100644
--- a/doc/tools/tiff2rgba.rst
+++ b/doc/tools/tiff2rgba.rst
@@ -59,6 +59,11 @@ Options
   Drop the alpha component from the output file, producing a pure RGB file.
   Currently this does not work if the :option:`-b` flag is also in effect.
 
+.. option:: -B
+
+  Use this value as the background when doing alpha compositing (dropping the
+  alpha component).
+
 .. option:: -M size
 
   Set maximum memory allocation size (in MiB). The default is 256MiB.
diff --git a/tools/tiff2rgba.c b/tools/tiff2rgba.c
index 693fc814..61400500 100644
--- a/tools/tiff2rgba.c
+++ b/tools/tiff2rgba.c
@@ -57,6 +57,7 @@ static uint16_t compression = COMPRESSION_PACKBITS;
 static uint32_t rowsperstrip = (uint32_t)-1;
 static int process_by_block = 0; /* default is whole image at once */
 static int no_alpha = 0;
+static int background = 0;
 static int bigtiff_output = 0;
 #define DEFAULT_MAX_MALLOC (256 * 1024 * 1024)
 /* malloc size limit (in bytes)
@@ -75,7 +76,7 @@ int main(int argc, char *argv[])
     extern char *optarg;
 #endif
 
-    while ((c = getopt(argc, argv, "c:r:t:bn8hM:")) != -1)
+    while ((c = getopt(argc, argv, "c:r:t:B:bn8hM:")) != -1)
         switch (c)
         {
             case 'M':
@@ -108,6 +109,10 @@ int main(int argc, char *argv[])
                 rowsperstrip = atoi(optarg);
                 break;
 
+            case 'B':
+                background = atoi(optarg) & 0xFF;
+                break;
+
             case 'n':
                 no_alpha = 1;
                 break;
@@ -486,9 +491,12 @@ static int cvt_whole_image(TIFF *in, TIFF *out)
         src = dst = (unsigned char *)raster;
         while (count > 0)
         {
-            *(dst++) = *(src++);
-            *(dst++) = *(src++);
-            *(dst++) = *(src++);
+            /* do alpha compositing */
+            const int src_alpha = src[3];
+            const int background_contribution = background * (0xFF - src_alpha);
+            *(dst++) = (*(src) * src_alpha + background_contribution) / 0xFF; src++;
+            *(dst++) = (*(src) * src_alpha + background_contribution) / 0xFF; src++;
+            *(dst++) = (*(src) * src_alpha + background_contribution) / 0xFF; src++;
             src++;
             count--;
         }
@@ -619,6 +627,7 @@ static const char usage_info[] =
     " -r rows/strip\n"
     " -b (progress by block rather than as a whole image)\n"
     " -n don't emit alpha component.\n"
+    " -B use this value as the background when doing alpha compositing\n"
     " -8 write BigTIFF file instead of ClassicTIFF\n"
     " -M set the memory allocation limit in MiB. 0 to disable limit\n";