]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Improvements to dithering down colour and gray scale images to bi-level
authorSteve Underwood <steveu@coppice.org>
Tue, 7 Aug 2012 14:34:32 +0000 (22:34 +0800)
committerSteve Underwood <steveu@coppice.org>
Tue, 7 Aug 2012 14:34:32 +0000 (22:34 +0800)
images, for images with different illuminants.

18 files changed:
libs/spandsp/src/fax.c
libs/spandsp/src/image_translate.c
libs/spandsp/src/spandsp/image_translate.h
libs/spandsp/src/spandsp/private/image_translate.h
libs/spandsp/src/spandsp/private/t4_tx.h
libs/spandsp/src/spandsp/t30.h
libs/spandsp/src/spandsp/t30_fcf.h
libs/spandsp/src/t30.c
libs/spandsp/src/t30_api.c
libs/spandsp/src/t30_logging.c
libs/spandsp/src/t38_gateway.c
libs/spandsp/src/t38_terminal.c
libs/spandsp/src/t4_rx.c
libs/spandsp/src/t4_t6_decode.c
libs/spandsp/src/t4_t6_encode.c
libs/spandsp/src/t4_tx.c
libs/spandsp/tests/image_translate_tests.c
libs/spandsp/tests/t42_tests.c

index 19bf4cf5e6f28e27fa72152c0cd591a9fe04dcf9..1edba28eea1e2a325f46d3927274bc53f08f5a5b 100644 (file)
@@ -77,9 +77,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index db6a7adc0e8bba90426c773dccbf0b4efc95d44c..785997def5e95a31635b51f9f74d87382b9bd914 100644 (file)
@@ -59,9 +59,7 @@
 #include "spandsp/t4_tx.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -72,9 +70,7 @@
 #include "spandsp/private/logging.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
@@ -132,13 +128,13 @@ static int get_and_scrunch_row(image_translate_state_t *s, uint8_t buf[], size_t
     /* Scrunch colour down to gray, and scrunch 16 bit pixels down to 8 bit pixels */
     switch (s->input_format)
     {
-    case IMAGE_TRANSLATE_FROM_GRAY_16:
+    case T4_IMAGE_TYPE_GRAY_12BIT:
         image_gray16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
         break;
-    case IMAGE_TRANSLATE_FROM_COLOUR_16:
+    case T4_IMAGE_TYPE_COLOUR_12BIT:
         image_colour16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
         break;
-    case IMAGE_TRANSLATE_FROM_COLOUR_8:
+    case T4_IMAGE_TYPE_COLOUR_8BIT:
         image_colour8_to_gray8_row(buf, buf, s->input_width);
         break;
     }
@@ -235,47 +231,17 @@ static __inline__ uint8_t find_closest_palette_color(int in)
 }
 /*- End of function --------------------------------------------------------*/
 
-SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], size_t len)
+static int floyd_steinberg_dither_row(image_translate_state_t *s, uint8_t buf[], int y)
 {
     int x;
-    int y;
     int i;
     int j;
     int limit;
     int old_pixel;
     int new_pixel;
     int quant_error;
-    uint8_t *p;
     uint8_t xx;
 
-    if (s->output_row < 0)
-        return 0;
-    y = s->output_row++;
-    /* This algorithm works over two rows, and outputs the earlier of the two. To
-       make this work:
-           - At row 0 we grab and scrunch two rows.
-           - From row 1 up to the last row we grab one new additional row each time.
-           - At the last row we dither and output, without getting an extra row in. */
-    for (i = (y == 0)  ?  0  :  1;  i < 2;  i++)
-    {
-        p = s->pixel_row[0];
-        s->pixel_row[0] = s->pixel_row[1];
-        s->pixel_row[1] = p;
-
-        /* If this is the end of the image just ignore that there is now rubbish in pixel_row[1].
-           Mark that the end has occurred. This row will be properly output, and the next one
-           will fail, with the end of image condition (i.e. returning zero length) */
-        if (s->resize)
-        {
-            if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
-                s->output_row = -1;
-        }
-        else
-        {
-            if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
-                s->output_row = -1;
-        }
-    }
     /* Apply Floyd-Steinberg dithering to the 8 bit pixels, using a bustrophodontic
        scan, to reduce the grayscale image to pure black and white */
     /* The first and last pixels in each row need special treatment, so we do not
@@ -353,6 +319,46 @@ SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[],
 }
 /*- End of function --------------------------------------------------------*/
 
+SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], size_t len)
+{
+    int y;
+    int i;
+    uint8_t *p;
+
+    if (s->output_row < 0)
+        return 0;
+    y = s->output_row++;
+    /* This algorithm works over two rows, and outputs the earlier of the two. To
+       make this work:
+           - At row 0 we grab and scrunch two rows.
+           - From row 1 up to the last row we grab one new additional row each time.
+           - At the last row we dither and output, without getting an extra row in. */
+    for (i = (y == 0)  ?  0  :  1;  i < 2;  i++)
+    {
+        p = s->pixel_row[0];
+        s->pixel_row[0] = s->pixel_row[1];
+        s->pixel_row[1] = p;
+
+        /* If this is the end of the image just ignore that there is now rubbish in pixel_row[1].
+           Mark that the end has occurred. This row will be properly output, and the next one
+           will fail, with the end of image condition (i.e. returning zero length) */
+        if (s->resize)
+        {
+            if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
+                s->output_row = -1;
+        }
+        else
+        {
+            if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
+                s->output_row = -1;
+        }
+    }
+    if (s->output_format == T4_IMAGE_TYPE_BILEVEL)
+        i = floyd_steinberg_dither_row(s, buf, y);
+    return i;
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE(int) image_translate_get_output_width(image_translate_state_t *s)
 {
     return s->output_width;
@@ -369,6 +375,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
                                                              int input_format,
                                                              int input_width,
                                                              int input_length,
+                                                             int output_format,
                                                              int output_width,
                                                              int output_length,
                                                              t4_row_read_handler_t row_read_handler,
@@ -384,10 +391,11 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
     memset(s, 0, sizeof(*s));
 
     s->input_format = input_format;
-
     s->input_width = input_width;
     s->input_length = input_length;
 
+    s->output_format = output_format;
+
     if ((s->resize = (output_width > 0)))
     {
         s->output_width = output_width;
@@ -404,16 +412,16 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
 
     switch (s->input_format)
     {
-    case IMAGE_TRANSLATE_FROM_GRAY_8:
+    case T4_IMAGE_TYPE_GRAY_8BIT:
         s->bytes_per_pixel = 1;
         break;
-    case IMAGE_TRANSLATE_FROM_GRAY_16:
+    case T4_IMAGE_TYPE_GRAY_12BIT:
         s->bytes_per_pixel = 2;
         break;
-    case IMAGE_TRANSLATE_FROM_COLOUR_8:
+    case T4_IMAGE_TYPE_COLOUR_8BIT:
         s->bytes_per_pixel = 3;
         break;
-    case IMAGE_TRANSLATE_FROM_COLOUR_16:
+    case T4_IMAGE_TYPE_COLOUR_12BIT:
         s->bytes_per_pixel = 6;
         break;
     default:
index 80f29f04712d96460d0efef734514dc2ca4b9bc1..31f13d28458c668284b159666367f4114f4f6560 100644 (file)
 
 typedef struct image_translate_state_s image_translate_state_t;
 
-enum
-{
-    IMAGE_TRANSLATE_FROM_MONO = 1,
-    IMAGE_TRANSLATE_FROM_GRAY_8 = 2,
-    IMAGE_TRANSLATE_FROM_GRAY_16 = 3,
-    IMAGE_TRANSLATE_FROM_COLOUR_8 = 4,
-    IMAGE_TRANSLATE_FROM_COLOUR_16 = 5
-};
-
 #if defined(__cplusplus)
 extern "C"
 {
@@ -75,6 +66,7 @@ SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s);
     \param input_format x
     \param input_width The width of the source image, in pixels.
     \param input_length The length of the source image, in pixels.
+    \param output_format x
     \param output_width The width of the output image, in pixels. If this is set <= 0 the image
            will not be resized.
     \param output_length The length of the output image, in pixels. If this is set to <= 0 the
@@ -88,6 +80,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
                                                              int input_format,
                                                              int input_width,
                                                              int input_length,
+                                                             int output_format,
                                                              int output_width,
                                                              int output_length,
                                                              t4_row_read_handler_t row_read_handler,
index a4f7daa81fdcd0de9daae4b82a94b9a6fa75bf4c..e473a0f644ca13a6c1609e779f015e02202b0292 100644 (file)
@@ -33,6 +33,7 @@ struct image_translate_state_s
     int input_format;
     int input_width;
     int input_length;
+    int output_format;
     int output_width;
     int output_length;
     int resize;
index b7b5d11eff667d05fdf1199687dfc3a7d6509e9b..9f4bf463be06aee77aae4676a3f793e750a06990 100644 (file)
@@ -90,6 +90,10 @@ struct t4_tx_state_s
     /*! \brief The type of compression used between the FAX machines. */
     int line_encoding;
 
+    int line_encoding_bilevel;
+    int line_encoding_gray;
+    int line_encoding_colour;
+
     /*! \brief The width of the current page, in pixels. */
     uint32_t image_width;
     /*! \brief The length of the current page, in pixels. */
@@ -140,6 +144,9 @@ struct t4_tx_state_s
 
     image_translate_state_t translator;
 
+    int apply_lab;
+    lab_params_t lab_params;
+
     /* Supporting information, like resolutions, which the backend may want. */
     t4_tx_metadata_t metadata;
 
index 8c0edffd83f8202295fbf9c4728fabadac8bedf5..88dd94be900ae29efb05fbc858990d8bbcedf98d 100644 (file)
@@ -373,7 +373,11 @@ enum
     /*! T.81 + T.30 Annex K colour sYCC-JPEG compression */
     T30_SUPPORT_SYCC_T81_COMPRESSION = 0x200,
     /*! T.88 monochrome JBIG2 compression */
-    T30_SUPPORT_T88_COMPRESSION = 0x400
+    T30_SUPPORT_T88_COMPRESSION = 0x400,
+    /*! Dither a gray scale image down a simple bilevel image, with rescaling to fit a FAX page */
+    T30_SUPPORT_GRAY_TO_BILEVEL = 0x40000000,
+    /*! Dither a colour image down a simple bilevel image, with rescaling to fit a FAX page */
+    T30_SUPPORT_COLOUR_TO_BILEVEL = 0x80000000
 };
 
 enum
index 7414497247ad49fa2b2eaae6599933cb33201409..763627e435aeafb3fffa7dc35b4274d62e725fdd 100644 (file)
@@ -114,6 +114,7 @@ enum
 
     /*! Information frame types used for error correction mode, in T.4 */
     T4_FCD = 0x06,          /*! [0110 0000] Facsimile coded data */
+    T4_CCD = 0x46,          /*! [0110 0010] Character coded data */
     T4_RCP = 0x86           /*! [0110 0001] Return to control for partial page */
 };
 
index ec2852ef42df609b4b9d20551e421db4d184959a..cf073b9049a565c57793488ccdf2d2d6d465fb82 100644 (file)
@@ -64,9 +64,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -82,9 +80,7 @@
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
@@ -2072,7 +2068,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
     s->error_correcting_mode = (s->ecm_allowed  &&  (s->far_dis_dtc_frame[6] & DISBIT3) != 0);
     /* 256 octets per ECM frame */
     s->octets_per_ecm_frame = 256;
-    /* Select the compression to use. */
+    /* Now we know if we are going to use ECM, select the compression to use. */
     if (!s->error_correcting_mode)
     {
         /* Without error correction our choices are very limited */
@@ -2091,7 +2087,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
     {
 #if defined(SPANDSP_SUPPORT_T42x)  ||  defined(SPANDSP_SUPPORT_T43)
         /* With error correction colour may be possible/required */
-        if (0)
+        if ((0 & (T30_SUPPORT_T43_COMPRESSION | T30_SUPPORT_T45_COMPRESSION | T30_SUPPORT_T81_COMPRESSION | T30_SUPPORT_SYCC_T81_COMPRESSION)))
         {
             s->line_encoding = T4_COMPRESSION_ITU_T85_L0;
         }
@@ -2382,7 +2378,7 @@ static int process_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
     s->image_width = widths[i][dcs_frame[5] & (DISBIT2 | DISBIT1)];
 
     /* Check which compression the far end has decided to use. */
-#if defined(SPANDSP_SUPPORT_T42x)
+#if defined(SPANDSP_SUPPORT_T42)
     if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE))
     {
         s->line_encoding = T4_COMPRESSION_ITU_T42;
index ad7cb0e71c93c090be986dc44e82e712a313f88a..86972c0fee7a4e9f3fc24fa8c24f9272e8b97607 100644 (file)
@@ -64,9 +64,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -82,9 +80,7 @@
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index 9328c9b8f38be53089ed412e96500d9299f2394b..8347a2615d5deedaac1c10772a43b38cfff95afd 100644 (file)
@@ -64,9 +64,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -81,9 +79,7 @@
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
@@ -410,6 +406,8 @@ SPAN_DECLARE(const char *) t30_frametype(uint8_t x)
         return "NULL";
     case T4_FCD:
         return "FCD";
+    case T4_CCD:
+        return "CCD";
     case T4_RCP:
         return "RCP";
     }
index e3c99a634a028665c1f28667de3090492a3269a2..11b653face5908f08d8ce7dc5c7816258738849b 100644 (file)
@@ -77,9 +77,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index d16e3cd5697ff9983b28858257ed4f8fae9b812d..d947d139062b09a9ca82323eac5f395271262e02 100644 (file)
@@ -67,9 +67,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -87,9 +85,7 @@
 #include "spandsp/private/timezone.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index 4e096e637136f85b026ebf2af7c064e15d620b9a..7de952b890b495c475ce4ba9af4f1ecb5e28d250 100644 (file)
@@ -57,9 +57,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -70,9 +68,7 @@
 #include "spandsp/private/logging.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index b3c96222b871a1f7edddc3bf755ff488ba5a4917..ac528a6a891e9cf3687ffa7b779d576ab67f5a92 100644 (file)
@@ -88,9 +88,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
 #include "spandsp/private/logging.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index 59dbd251e9983a51a1a41d837f241967df60fa9f..c8c0c2f5bb44d303756aa76da9d18e14f5388f0e 100644 (file)
@@ -85,9 +85,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -97,9 +95,7 @@
 #include "spandsp/private/logging.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
index d1060f8a82eae6b5f6a452fb09bb8e92f5401dc0..17c832ecf57d0d78ae018574c9213f1ba2ae96f0 100644 (file)
@@ -57,9 +57,7 @@
 #include "spandsp/image_translate.h"
 #include "spandsp/t81_t82_arith_coding.h"
 #include "spandsp/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/t43.h"
 #endif
@@ -69,9 +67,7 @@
 #include "spandsp/private/logging.h"
 #include "spandsp/private/t81_t82_arith_coding.h"
 #include "spandsp/private/t85.h"
-#if defined(SPANDSP_SUPPORT_T42)
 #include "spandsp/private/t42.h"
-#endif
 #if defined(SPANDSP_SUPPORT_T43)
 #include "spandsp/private/t43.h"
 #endif
@@ -104,6 +100,8 @@ static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
     {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, FIELD_CUSTOM, FALSE, FALSE, (char *) "ImageLayer"},
 };
 
+static void t4_tx_set_image_length(t4_tx_state_t *s, int image_length);
+
 static TIFFExtendProc _ParentExtender = NULL;
 
 static void TIFFFXDefaultDirectory(TIFF *tif)
@@ -251,31 +249,14 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
         }
     }
     t4_tx_set_image_width(s, s->image_width);
+    t4_tx_set_image_length(s, s->image_length);
     switch (s->line_encoding)
     {
     case T4_COMPRESSION_ITU_T4_1D:
     case T4_COMPRESSION_ITU_T4_2D:
     case T4_COMPRESSION_ITU_T6:
-        t4_t6_encode_set_image_width(&s->encoder.t4_t6, s->image_width);
         t4_t6_encode_set_max_2d_rows_per_1d_row(&s->encoder.t4_t6, -s->metadata.y_resolution);
         break;
-#if defined(SPANDSP_SUPPORT_T42)
-    case T4_COMPRESSION_ITU_T42:
-        t42_encode_set_image_width(&s->encoder.t42, s->image_width);
-        t42_encode_set_image_length(&s->encoder.t42, s->image_length);
-        break;
-#endif
-#if defined(SPANDSP_SUPPORT_T43)
-    case T4_COMPRESSION_ITU_T43:
-        t43_encode_set_image_width(&s->encoder.t43, s->image_width);
-        t43_encode_set_image_length(&s->encoder.t43, s->image_length);
-        break;
-#endif
-    case T4_COMPRESSION_ITU_T85:
-    case T4_COMPRESSION_ITU_T85_L0:
-        t85_encode_set_image_width(&s->encoder.t85, s->image_width);
-        t85_encode_set_image_length(&s->encoder.t85, s->image_length);
-        break;
     }
 #if defined(SPANDSP_SUPPORT_TIFF_FX)
     if (TIFFGetField(t->tiff_file, TIFFTAG_PROFILETYPE, &parm32))
@@ -426,6 +407,8 @@ static int row_read(void *user_data, uint8_t buf[], size_t len)
         return 0;
     if (TIFFReadScanline(s->tiff.tiff_file, buf, s->tiff.raw_row, 0) < 0)
         return 0;
+    if (s->apply_lab)
+        lab_to_srgb(&s->lab_params, buf, buf, len/3);
     s->tiff.raw_row++;
     return len;
 }
@@ -438,23 +421,12 @@ static int read_tiff_image(t4_tx_state_t *s)
     int i;
     uint8_t *t;
     image_translate_state_t *translator;
-    int mode;
 
     if (s->tiff.image_type != T4_IMAGE_TYPE_BILEVEL)
     {
         /* We need to dither this image down to pure black and white, possibly resizing it
            along the way. */
-        if (s->tiff.image_type == T4_IMAGE_TYPE_GRAY_8BIT)
-            mode = IMAGE_TRANSLATE_FROM_GRAY_8;
-        else if (s->tiff.image_type == T4_IMAGE_TYPE_GRAY_12BIT)
-            mode = IMAGE_TRANSLATE_FROM_GRAY_16;
-        else if (s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_8BIT)
-            mode = IMAGE_TRANSLATE_FROM_COLOUR_8;
-        else if (s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_12BIT)
-            mode = IMAGE_TRANSLATE_FROM_COLOUR_16;
-        else
-            return -1;
-        if ((translator = image_translate_init(NULL, mode, s->image_width, s->image_length, 1728, -1, row_read, s)) == NULL)
+        if ((translator = image_translate_init(NULL, s->tiff.image_type, s->image_width, s->image_length, T4_IMAGE_TYPE_BILEVEL, 1728, -1, row_read, s)) == NULL)
             return -1;
         s->image_width = image_translate_get_output_width(translator);
         s->image_length = image_translate_get_output_length(translator);
@@ -469,6 +441,23 @@ static int read_tiff_image(t4_tx_state_t *s)
             s->tiff.image_buffer = t;
         }
         s->tiff.raw_row = 0;
+        switch (s->tiff.photo_metric)
+        {
+        case PHOTOMETRIC_CIELAB:
+            /* The default luminant is D50 */
+            set_lab_illuminant(&s->lab_params, 0.96422f, 1.0f,  0.82521f);
+            set_lab_gamut(&s->lab_params, 0, 100, -128, 127, -128, 127, TRUE);
+            s->apply_lab = TRUE;
+            break;
+        case PHOTOMETRIC_ITULAB:
+            set_lab_illuminant(&s->lab_params, 0.9638f, 1.0f, 0.8245f);
+            set_lab_gamut(&s->lab_params, 0, 100, -85, 85, -75, 125, FALSE);
+            s->apply_lab = TRUE;
+            break;
+        default:
+            s->apply_lab = FALSE;
+            break;
+        }
         total_len = 0;
         for (i = 0;  i < s->image_length;  i++)
             total_len += image_translate_row(translator, &s->tiff.image_buffer[total_len], s->image_width/8);
@@ -782,6 +771,29 @@ SPAN_DECLARE(void) t4_tx_set_image_width(t4_tx_state_t *s, int image_width)
 }
 /*- End of function --------------------------------------------------------*/
 
+static void t4_tx_set_image_length(t4_tx_state_t *s, int image_length)
+{
+    s->image_length = image_length;
+    switch (s->line_encoding)
+    {
+#if defined(SPANDSP_SUPPORT_T42)
+    case T4_COMPRESSION_ITU_T42:
+        t42_encode_set_image_length(&s->encoder.t42, image_length);
+        break;
+#endif
+#if defined(SPANDSP_SUPPORT_T43)
+    case T4_COMPRESSION_ITU_T43:
+        t43_encode_set_image_length(&s->encoder.t43, image_length);
+        break;
+#endif
+    case T4_COMPRESSION_ITU_T85:
+    case T4_COMPRESSION_ITU_T85_L0:
+        t85_encode_set_image_length(&s->encoder.t85, image_length);
+        break;
+    }
+}
+/*- End of function --------------------------------------------------------*/
+
 SPAN_DECLARE(void) t4_tx_set_max_2d_rows_per_1d_row(t4_tx_state_t *s, int max)
 {
     switch (s->line_encoding)
index 8c3f55f0776c5f0d90942948b15141afc3a2fb1c..b57fe3965b8a7c62d43a4014ef2bcf54100e9bdf 100644 (file)
@@ -213,7 +213,7 @@ static void dither_tests_gray16(void)
             image[i*im.width + j] = j*1200;
     }
 
-    s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_16, im.width, im.length, -1, -1, row_read, &im);
+    s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
     get_flattened_image(s, TRUE);
 }
 /*- End of function --------------------------------------------------------*/
@@ -239,7 +239,7 @@ static void dither_tests_gray8(void)
         for (j = 0;  j < im.width;  j++)
             image[i*im.width + j] = j*1200/256;
     }
-    s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_8, im.width, im.length, -1, -1, row_read, &im);
+    s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
     get_flattened_image(s, TRUE);
 }
 /*- End of function --------------------------------------------------------*/
@@ -269,7 +269,7 @@ static void dither_tests_colour16(void)
             image[i*3*im.width + 3*j + 2] = j*1200;
         }
     }
-    s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_16, im.width, im.length, -1, -1, row_read, &im);
+    s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
     get_flattened_image(s, TRUE);
 }
 /*- End of function --------------------------------------------------------*/
@@ -300,7 +300,7 @@ static void dither_tests_colour8(void)
         }
     }
 
-    s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, -1, -1, row_read, &im);
+    s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
     get_flattened_image(s, TRUE);
 }
 /*- End of function --------------------------------------------------------*/
@@ -331,7 +331,7 @@ static void grow_tests_colour8(void)
         }
     }
 
-    s1 = image_translate_init(s1, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, 200, -1, row_read, &im);
+    s1 = image_translate_init(s1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, 200, -1, row_read, &im);
 
     get_flattened_image(s1, FALSE);
 }
@@ -409,7 +409,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char
     im.current_row = 0;
     im.bytes_per_pixel = samples_per_pixel;
 
-    s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, image_width, image_length, output_width, output_length, row_read, &im);
+    s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, row_read, &im);
     output_width = image_translate_get_output_width(s);
     output_length = image_translate_get_output_length(s);
 
index c0d494c8ce9380709a2842635cf4bc4faa3e59b5..b00dac0707b9e466efcfe197a56d18a6c19a8257 100644 (file)
@@ -476,8 +476,8 @@ int main(int argc, char *argv[])
     }
     TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);
-    // libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
-    // or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values
+    /* libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
+       or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values */
     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);
     TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);