libtiff: Merge branch 'tiffcp_tiffcrop_228' into 'master'

From 251395dd28dcc8504fddc979e1535f33b4afa376 Mon Sep 17 00:00:00 2001
From: Lee Howard <[EMAIL REDACTED]>
Date: Fri, 15 Mar 2024 10:54:43 -0700
Subject: [PATCH 1/3] Fix tiffcp and tiffcrop issue 228 - step 1

---
 tools/tiffcp.c   | 6 +++---
 tools/tiffcrop.c | 9 +++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/tools/tiffcp.c b/tools/tiffcp.c
index 650544e3..a8c0dfcb 100644
--- a/tools/tiffcp.c
+++ b/tools/tiffcp.c
@@ -641,9 +641,9 @@ static const char usage_info[] =
     " -c jpeg[:opts]  compress output with JPEG encoding\n"
     /* "    JPEG options:", */
     "    #            set compression quality level (0-100, default 75)\n"
-    "    r            output color image as RGB rather than YCbCr\n"
-    "    For example, -c jpeg:r:50 for JPEG-encoded RGB with 50% comp. "
-    "quality\n"
+    "    r            do not change colorspace (raw)\n"
+    "    For example, -c jpeg:r:50 for JPEG-encoded with 50% comp. "
+    "quality and same colorspace\n"
 #endif
 #ifdef JBIG_SUPPORT
     " -c jbig         compress output with ISO JBIG encoding\n"
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index 95983479..44677a7d 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -755,10 +755,9 @@ static const char usage_info[] =
     " -c jpeg[:opts] Compress output with JPEG encoding\n"
     /* "    JPEG options:\n" */
     "    #        Set compression quality level (0-100, default 100)\n"
-    "    raw      Output color image as raw YCbCr (default)\n"
-    "    rgb      Output color image as RGB\n"
-    "    For example, -c jpeg:rgb:50 for JPEG-encoded RGB with 50% comp. "
-    "quality\n"
+    "    raw      Output same colorspace image as input (default)\n"
+    "    For example, -c jpeg:raw:50 for JPEG-encoded with 50% comp. "
+    "quality and the same colorspace\n"
 #endif
 #ifdef PACKBITS_SUPPORT
     " -c packbits Compress output with packbits encoding\n"
@@ -1653,8 +1652,10 @@ static int processCompressOptions(char *opt)
                 quality = atoi(cp + 1);
             else if (strneq(cp + 1, "raw", 3))
                 jpegcolormode = JPEGCOLORMODE_RAW;
+/* libjpeg does not support colorspace conversion to RGB
             else if (strneq(cp + 1, "rgb", 3))
                 jpegcolormode = JPEGCOLORMODE_RGB;
+*/
             else
                 usage(EXIT_FAILURE);
             cp = strchr(cp + 1, ':');

From dee5bda6c082d8e3f203a203447682dc7e5fbd92 Mon Sep 17 00:00:00 2001
From: Lee Howard <faxguy@howardsilvan.com>
Date: Tue, 26 Mar 2024 18:04:04 -0700
Subject: [PATCH 2/3] Correct tiffcrop output of RGB JPEG and tiffcp/tiffcrop
 documentation - issue #228

---
 tools/tiffcp.c   |  6 +++---
 tools/tiffcrop.c | 31 +++++++++++++++++++++----------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/tools/tiffcp.c b/tools/tiffcp.c
index a8c0dfcb..91049bd7 100644
--- a/tools/tiffcp.c
+++ b/tools/tiffcp.c
@@ -641,9 +641,9 @@ static const char usage_info[] =
     " -c jpeg[:opts]  compress output with JPEG encoding\n"
     /* "    JPEG options:", */
     "    #            set compression quality level (0-100, default 75)\n"
-    "    r            do not change colorspace (raw)\n"
-    "    For example, -c jpeg:r:50 for JPEG-encoded with 50% comp. "
-    "quality and same colorspace\n"
+    "    r            outupt color image as RGB rather than YCbCr\n"
+    "    For example, -c jpeg:r:50 for JPEG-encoded RGB with 50% comp. "
+    "quality\n"
 #endif
 #ifdef JBIG_SUPPORT
     " -c jbig         compress output with ISO JBIG encoding\n"
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
index 44677a7d..8bc84e63 100644
--- a/tools/tiffcrop.c
+++ b/tools/tiffcrop.c
@@ -487,8 +487,7 @@ static uint32_t g3opts = 0;
 static int ignore = FALSE; /* if true, ignore read errors */
 static uint32_t defg3opts = (uint32_t)-1;
 static int quality = 100; /* JPEG quality */
-/* static int    jpegcolormode = -1;        was JPEGCOLORMODE_RGB;  */
-static int jpegcolormode = JPEGCOLORMODE_RGB;
+static int jpegcolormode = -1;        /* means YCbCr or to not convert */
 static uint16_t defcompression = (uint16_t)-1;
 static uint16_t defpredictor = (uint16_t)-1;
 static int pageNum = 0;
@@ -755,7 +754,8 @@ static const char usage_info[] =
     " -c jpeg[:opts] Compress output with JPEG encoding\n"
     /* "    JPEG options:\n" */
     "    #        Set compression quality level (0-100, default 100)\n"
-    "    raw      Output same colorspace image as input (default)\n"
+    "    raw      Output same colorspace image as input\n"
+    "    rgb      Output color image as RGB (default is YCbCr)\n"
     "    For example, -c jpeg:raw:50 for JPEG-encoded with 50% comp. "
     "quality and the same colorspace\n"
 #endif
@@ -1652,10 +1652,8 @@ static int processCompressOptions(char *opt)
                 quality = atoi(cp + 1);
             else if (strneq(cp + 1, "raw", 3))
                 jpegcolormode = JPEGCOLORMODE_RAW;
-/* libjpeg does not support colorspace conversion to RGB
             else if (strneq(cp + 1, "rgb", 3))
                 jpegcolormode = JPEGCOLORMODE_RGB;
-*/
             else
                 usage(EXIT_FAILURE);
             cp = strchr(cp + 1, ':');
@@ -7068,7 +7066,6 @@ static int loadImage(TIFF *in, struct image_data *image, struct dump_opts *dump,
 
     if (input_compression == COMPRESSION_JPEG)
     { /* Force conversion to RGB */
-        jpegcolormode = JPEGCOLORMODE_RGB;
         TIFFSetField(in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
     }
     /* The clause up to the read statement is taken from Tom Lane's tiffcp patch
@@ -8202,11 +8199,18 @@ static int writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
                                                                  : "mask");
             return (-1);
         }
-        if ((input_photometric == PHOTOMETRIC_RGB) &&
-            (jpegcolormode == JPEGCOLORMODE_RGB))
+        if (jpegcolormode == JPEGCOLORMODE_RGB && input_photometric == PHOTOMETRIC_YCBCR)
+        {
+            TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+        }
+        else if (jpegcolormode == -1 && input_photometric == PHOTOMETRIC_RGB)
+        {
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
+        }
         else
+        {
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
+        }
     }
     else
     {
@@ -8969,11 +8973,18 @@ static int writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image,
                                                                  : "mask");
             return (-1);
         }
-        if ((input_photometric == PHOTOMETRIC_RGB) &&
-            (jpegcolormode == JPEGCOLORMODE_RGB))
+        if (jpegcolormode == JPEGCOLORMODE_RGB && input_photometric == PHOTOMETRIC_YCBCR)
+        {
+            TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+        }
+        else if (jpegcolormode == -1 && input_photometric == PHOTOMETRIC_RGB)
+        {
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR);
+        }
         else
+        {
             TIFFSetField(out, TIFFTAG_PHOTOMETRIC, input_photometric);
+        }
     }
     else
     {

From 41bb7c3a8523f5c8cf594bc684633c6493fdd33b Mon Sep 17 00:00:00 2001
From: Lee Howard <faxguy@howardsilvan.com>
Date: Thu, 16 May 2024 19:26:59 +0000
Subject: [PATCH 3/3] Update tiffcp.c

---
 tools/tiffcp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/tiffcp.c b/tools/tiffcp.c
index 91049bd7..650544e3 100644
--- a/tools/tiffcp.c
+++ b/tools/tiffcp.c
@@ -641,7 +641,7 @@ static const char usage_info[] =
     " -c jpeg[:opts]  compress output with JPEG encoding\n"
     /* "    JPEG options:", */
     "    #            set compression quality level (0-100, default 75)\n"
-    "    r            outupt color image as RGB rather than YCbCr\n"
+    "    r            output color image as RGB rather than YCbCr\n"
     "    For example, -c jpeg:r:50 for JPEG-encoded RGB with 50% comp. "
     "quality\n"
 #endif