]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Spandspi's FAX engine now gives separate size and resolution information about
authorSteve Underwood <steveu@coppice.org>
Sun, 10 Mar 2013 12:55:21 +0000 (20:55 +0800)
committerSteve Underwood <steveu@coppice.org>
Sun, 10 Mar 2013 12:55:21 +0000 (20:55 +0800)
the images on the line and the images in the file. The ties in with the recent
addition of image resizing and flattenign for colur images.
mod_spandsp has been changed to make use of the additional information.

14 files changed:
libs/spandsp/src/spandsp/private/t30.h
libs/spandsp/src/spandsp/private/t4_tx.h
libs/spandsp/src/spandsp/saturated.h
libs/spandsp/src/spandsp/t30.h
libs/spandsp/src/spandsp/t4_rx.h
libs/spandsp/src/t30.c
libs/spandsp/src/t4_rx.c
libs/spandsp/src/t4_tx.c
libs/spandsp/tests/dtmf_tx_tests.c
libs/spandsp/tests/fax_tester.h
libs/spandsp/tests/fax_tests.c
libs/spandsp/tests/fax_utils.c
libs/spandsp/tests/t4_tests.c
src/mod/applications/mod_spandsp/mod_spandsp_fax.c

index 9b70a7a73be8c723c0bf05f91a9a787e7d4e2951..47574360ec76c6bcac5f61b68b40e05d9d5a8895 100644 (file)
@@ -218,6 +218,8 @@ struct t30_state_s
 
     /*! \brief TRUE if a local T.30 interrupt is pending. */
     int local_interrupt_pending;
+    /*! \brief The image coding to be used on the line for non-bilevel images. */
+    int multilevel_line_encoding;
     /*! \brief The image coding being used on the line. */
     int line_encoding;
     /*! \brief The image coding being used for output files. */
index 078ac97b8ad59a2307628f61462c68376dda3a7b..afc44fcf53eb585fd425acc03f0f25dc659c7478 100644 (file)
@@ -57,9 +57,15 @@ typedef struct
     /*! \brief Row counter for playing out the rows of the image. */
     int row;
 
-    /*! \brief Image length of the image in the file. This is used when the
-               image is resized or dithered flat. */
+    /*! \brief Width of the image in the file. */
+    int image_width;
+    /*! \brief Length of the image in the file. */
     int image_length;
+    /*! \brief Column-to-column (X) resolution in pixels per metre of the image in the file. */
+    int image_x_resolution;
+    /*! \brief Row-to-row (Y) resolution in pixels per metre of the image in the file. */
+    int image_y_resolution;
+
     /*! \brief Row counter used when the image is resized or dithered flat. */
     int raw_row;
 } t4_tx_tiff_state_t;
@@ -72,9 +78,9 @@ typedef struct
 */
 typedef struct
 {
-    /*! \brief Column-to-column (X) resolution in pixels per metre. */
+    /*! \brief Column-to-column (X) resolution in pixels per metre on the wire. */
     int x_resolution;
-    /*! \brief Row-to-row (Y) resolution in pixels per metre. */
+    /*! \brief Row-to-row (Y) resolution in pixels per metre on the wire. */
     int y_resolution;
 } t4_tx_metadata_t;
 
index aaa760a7adcc06c77d9c1f58ea68fbe80b86e81a..d8872f9c3b03222f5c26d779541ae93cb139ce78 100644 (file)
@@ -369,7 +369,7 @@ static __inline__ int16_t saturated_mul16(int16_t a, int16_t b)
     if (product == 0x40000000)
         return INT16_MAX;
     /*endif*/
-    return (int16_t)(product >> 15);
+    return (int16_t) (product >> 15);
 }
 /*- End of function --------------------------------------------------------*/
 
index a954be1c364e727bede43001fefb0ed34a7a4e77..7606f42d753624ce1bb25a5c2b1b2d3d08e5c9e3 100644 (file)
@@ -531,13 +531,25 @@ typedef struct
     int pages_rx;
     /*! \brief The number of pages in the file (<0 if not known). */
     int pages_in_file;
-    /*! \brief The horizontal column-to-column resolution of the most recent page, in pixels per metre */
+    /*! \brief The type of image of the most recent file page */
+    int image_type;
+    /*! \brief The horizontal column-to-column resolution of the most recent file page, in pixels per metre */
+    int image_x_resolution;
+    /*! \brief The vertical row-to-row resolution of the most recent file page, in pixels per metre */
+    int image_y_resolution;
+    /*! \brief The number of horizontal pixels in the most recent file page. */
+    int image_width;
+    /*! \brief The number of vertical pixels in the most recent file page. */
+    int image_length;
+    /*! \brief The type of image of the most recent exchanged page */
+    int type;
+    /*! \brief The horizontal column-to-column resolution of the most recent exchanged page, in pixels per metre */
     int x_resolution;
-    /*! \brief The vertical row-to-row resolution of the most recent page, in pixels per metre */
+    /*! \brief The vertical row-to-row resolution of the most recent exchanged page, in pixels per metre */
     int y_resolution;
-    /*! \brief The number of horizontal pixels in the most recent page. */
+    /*! \brief The number of horizontal pixels in the most recent exchanged page. */
     int width;
-    /*! \brief The number of vertical pixels in the most recent page. */
+    /*! \brief The number of vertical pixels in the most recent exchanged page. */
     int length;
     /*! \brief The size of the image, in bytes */
     int image_size;
index ba7dedb23fb86d4e1322c70f9be6a80d4b5d2a9d..f2ff4fa0eec7681e8ed52745006868b28f7af211 100644 (file)
@@ -232,18 +232,30 @@ typedef struct
     int pages_transferred;
     /*! \brief The number of pages in the file (<0 if unknown). */
     int pages_in_file;
-    /*! \brief The number of horizontal pixels in the most recent page. */
-    int width;
-    /*! \brief The number of vertical pixels in the most recent page. */
-    int length;
     /*! \brief The number of bad pixel rows in the most recent page. */
     int bad_rows;
     /*! \brief The largest number of bad pixel rows in a block in the most recent page. */
     int longest_bad_row_run;
-    /*! \brief The horizontal resolution of the page in pixels per metre */
+    /*! \brief The type of image in the file page */
+    int image_type;
+    /*! \brief The horizontal resolution of the file page in pixels per metre */
+    int image_x_resolution;
+    /*! \brief The vertical resolution of the file page in pixels per metre */
+    int image_y_resolution;
+    /*! \brief The number of horizontal pixels in the file page. */
+    int image_width;
+    /*! \brief The number of vertical pixels in the file page. */
+    int image_length;
+    /*! \brief The type of image in the exchanged page */
+    int type;
+    /*! \brief The horizontal resolution of the exchanged page in pixels per metre */
     int x_resolution;
-    /*! \brief The vertical resolution of the page in pixels per metre */
+    /*! \brief The vertical resolution of the exchanged page in pixels per metre */
     int y_resolution;
+    /*! \brief The number of horizontal pixels in the exchanged page. */
+    int width;
+    /*! \brief The number of vertical pixels in the exchanged page. */
+    int length;
     /*! \brief The type of compression used between the FAX machines */
     int encoding;
     /*! \brief The size of the image on the line, in bytes */
@@ -369,6 +381,12 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
     \return A pointer to the string. */
 SPAN_DECLARE(const char *) t4_encoding_to_str(int encoding);
 
+/*! Get the short text name of an image format. 
+    \brief Get the short text name of an image format.
+    \param encoding The image format.
+    \return A pointer to the string. */
+SPAN_DECLARE(const char *) t4_image_type_to_str(int type);
+
 #if defined(__cplusplus)
 }
 #endif
index 5c495dbb81b50ca3efc9db9f5f4f178688585d11..ddb03378342b6ce2c160051fe56b57a5f55a7701 100644 (file)
@@ -6313,12 +6313,21 @@ SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t)
     t->pages_tx = s->tx_page_number;
     t->pages_rx = s->rx_page_number;
     t->pages_in_file = stats.pages_in_file;
-    t->width = stats.width;
-    t->length = stats.length;
     t->bad_rows = stats.bad_rows;
     t->longest_bad_row_run = stats.longest_bad_row_run;
+
+    t->image_type = stats.image_type;
+    t->image_x_resolution = stats.image_x_resolution;
+    t->image_y_resolution = stats.image_y_resolution;
+    t->image_width = stats.image_width;
+    t->image_length = stats.image_length;
+
+    t->type = stats.type;
     t->x_resolution = stats.x_resolution;
     t->y_resolution = stats.y_resolution;
+    t->width = stats.width;
+    t->length = stats.length;
+
     t->encoding = stats.encoding;
     t->image_size = stats.line_image_size;
     t->current_status = s->current_status;
index 293ea72b415922c4ab4d56f5a02e12ed759ab860..a331225ddf97feb8ba8512cd0050c0431d9c284d 100644 (file)
@@ -114,6 +114,27 @@ SPAN_DECLARE(const char *) t4_encoding_to_str(int encoding)
 }
 /*- End of function --------------------------------------------------------*/
 
+SPAN_DECLARE(const char *) t4_image_type_to_str(int type)
+{
+    switch (type)
+    {
+    case T4_IMAGE_TYPE_BILEVEL:
+        return "bi-level";
+    case T4_IMAGE_TYPE_COLOUR_BILEVEL:
+        return "bi-level colour";
+    case T4_IMAGE_TYPE_GRAY_8BIT:
+        return "8-bit gray scale";
+    case T4_IMAGE_TYPE_GRAY_12BIT:
+        return "12-bit gray scale";
+    case T4_IMAGE_TYPE_COLOUR_8BIT:
+        return "8-bit colour";
+    case T4_IMAGE_TYPE_COLOUR_12BIT:
+        return "12-bit colour";
+    }
+    return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
 static int set_tiff_directory_info(t4_rx_state_t *s)
 {
     time_t now;
@@ -573,6 +594,8 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
     memset(t, 0, sizeof(*t));
     t->pages_transferred = s->current_page;
     t->pages_in_file = s->tiff.pages_in_file;
+    t->image_x_resolution = s->metadata.x_resolution;
+    t->image_y_resolution = s->metadata.y_resolution;
     t->x_resolution = s->metadata.x_resolution;
     t->y_resolution = s->metadata.y_resolution;
     t->encoding = s->line_encoding;
@@ -581,28 +604,44 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
     case T4_COMPRESSION_ITU_T4_1D:
     case T4_COMPRESSION_ITU_T4_2D:
     case T4_COMPRESSION_ITU_T6:
+        t->type = T4_IMAGE_TYPE_BILEVEL;
         t->width = t4_t6_decode_get_image_width(&s->decoder.t4_t6);
         t->length = t4_t6_decode_get_image_length(&s->decoder.t4_t6);
+        t->image_type = t->type;
+        t->image_width = t->width;
+        t->image_length = t->length;
         t->line_image_size = t4_t6_decode_get_compressed_image_size(&s->decoder.t4_t6)/8;
         t->bad_rows = s->decoder.t4_t6.bad_rows;
         t->longest_bad_row_run = s->decoder.t4_t6.longest_bad_row_run;
         break;
     case T4_COMPRESSION_ITU_T42:
+        t->type = 0;
         t->width = t42_decode_get_image_width(&s->decoder.t42);
         t->length = t42_decode_get_image_length(&s->decoder.t42);
+        t->image_type = t->type;
+        t->image_width = t->width;
+        t->image_length = t->length;
         t->line_image_size = t42_decode_get_compressed_image_size(&s->decoder.t42)/8;
         break;
 #if defined(SPANDSP_SUPPORT_T43)
     case T4_COMPRESSION_ITU_T43:
+        t->type = 0;
         t->width = t43_decode_get_image_width(&s->decoder.t43);
         t->length = t43_decode_get_image_length(&s->decoder.t43);
+        t->image_type = t->type;
+        t->image_width = t->width;
+        t->image_length = t->length;
         t->line_image_size = t43_decode_get_compressed_image_size(&s->decoder.t43)/8;
         break;
 #endif
     case T4_COMPRESSION_ITU_T85:
     case T4_COMPRESSION_ITU_T85_L0:
+        t->type = T4_IMAGE_TYPE_BILEVEL;
         t->width = t85_decode_get_image_width(&s->decoder.t85);
         t->length = t85_decode_get_image_length(&s->decoder.t85);
+        t->image_type = t->type;
+        t->image_width = t->width;
+        t->image_length = t->length;
         t->line_image_size = t85_decode_get_compressed_image_size(&s->decoder.t85)/8;
         break;
     }
index 82cf97026e1217e63436c744ee2459564cba992c..840b27a2f2e98c1e8b216cc7ad98773a871f8005 100644 (file)
@@ -289,10 +289,11 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
 #endif
     parm32 = 0;
     TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
+    t->image_width =
     s->image_width = parm32;
     parm32 = 0;
     TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm32);
-    s->tiff.image_length =
+    t->image_length =
     s->image_length = parm32;
     x_resolution = 0.0f;
     TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
@@ -322,6 +323,10 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
             break;
         }
     }
+    if (res_unit == RESUNIT_INCH)
+        t->image_x_resolution = x_resolution*100.0f/CM_PER_INCH;
+    else
+        t->image_x_resolution = x_resolution*100.0f;
 
     s->metadata.y_resolution = T4_Y_RESOLUTION_STANDARD;
     for (i = 0;  y_res_table[i].code > 0;  i++)
@@ -332,6 +337,11 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
             break;
         }
     }
+    if (res_unit == RESUNIT_INCH)
+        t->image_y_resolution = y_resolution*100.0f/CM_PER_INCH;
+    else
+        t->image_y_resolution = y_resolution*100.0f;
+
     t4_tx_set_image_width(s, s->image_width);
     t4_tx_set_image_length(s, s->image_length);
     t4_tx_set_max_2d_rows_per_1d_row(s, -s->metadata.y_resolution);
@@ -421,7 +431,7 @@ static int test_tiff_directory_info(t4_tx_state_t *s)
     if (t->image_type != T4_IMAGE_TYPE_BILEVEL)
         return -1;
 #endif
-    if (s->tiff.image_type != image_type)
+    if (t->image_type != image_type)
         return 1;
 
     parm32 = 0;
@@ -984,6 +994,13 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
     memset(t, 0, sizeof(*t));
     t->pages_transferred = s->current_page - s->start_page;
     t->pages_in_file = s->tiff.pages_in_file;
+
+    t->image_type = s->tiff.image_type;
+    t->image_width = s->tiff.image_width;
+    t->image_length = s->tiff.image_length;
+    t->image_x_resolution = s->tiff.image_x_resolution;
+    t->image_y_resolution = s->tiff.image_y_resolution;
+
     t->x_resolution = s->metadata.x_resolution;
     t->y_resolution = s->metadata.y_resolution/s->row_squashing_ratio;
     t->encoding = s->line_encoding;
@@ -992,26 +1009,30 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
     case T4_COMPRESSION_ITU_T4_1D:
     case T4_COMPRESSION_ITU_T4_2D:
     case T4_COMPRESSION_ITU_T6:
+        t->type = T4_IMAGE_TYPE_BILEVEL;
         t->width = t4_t6_encode_get_image_width(&s->encoder.t4_t6);
-        t->length = t4_t6_encode_get_image_length(&s->encoder.t4_t6);
+        t->length = t4_t6_encode_get_image_length(&s->encoder.t4_t6)/s->row_squashing_ratio;
         t->line_image_size = t4_t6_encode_get_compressed_image_size(&s->encoder.t4_t6)/8;
         break;
     case T4_COMPRESSION_ITU_T42:
+        t->type = 0;
         t->width = t42_encode_get_image_width(&s->encoder.t42);
-        t->length = t42_encode_get_image_length(&s->encoder.t42);
+        t->length = t42_encode_get_image_length(&s->encoder.t42)/s->row_squashing_ratio;
         t->line_image_size = t42_encode_get_compressed_image_size(&s->encoder.t42)/8;
         break;
 #if defined(SPANDSP_SUPPORT_T43)
     case T4_COMPRESSION_ITU_T43:
+        t->type = 0;
         t->width = t43_encode_get_image_width(&s->encoder.t43);
-        t->length = t43_encode_get_image_length(&s->encoder.t43);
+        t->length = t43_encode_get_image_length(&s->encoder.t43)/s->row_squashing_ratio;
         t->line_image_size = t43_encode_get_compressed_image_size(&s->encoder.t43)/8;
         break;
 #endif
     case T4_COMPRESSION_ITU_T85:
     case T4_COMPRESSION_ITU_T85_L0:
+        t->type = T4_IMAGE_TYPE_BILEVEL;
         t->width = t85_encode_get_image_width(&s->encoder.t85);
-        t->length = t85_encode_get_image_length(&s->encoder.t85);
+        t->length = t85_encode_get_image_length(&s->encoder.t85)/s->row_squashing_ratio;
         t->line_image_size = t85_encode_get_compressed_image_size(&s->encoder.t85)/8;
         break;
     }
index 75151129a01fc1f3a6394dd8afa2d9699edc55ba..176cf1783bc2783464ffd2742fd3281979492277 100644 (file)
@@ -63,7 +63,7 @@ int main(int argc, char *argv[])
         exit(2);
     }
 
-    gen = dtmf_tx_init(NULL);
+    gen = dtmf_tx_init(NULL, NULL, NULL);
     len = dtmf_tx(gen, amp, 16384);
     printf("Generated %d samples\n", len);
     sf_writef_short(outhandle, amp, len);
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
     }
     while (len > 0);
 
-    dtmf_tx_init(gen);
+    dtmf_tx_init(gen, NULL, NULL);
     len = dtmf_tx(gen, amp, 16384);
     printf("Generated %d samples\n", len);
     sf_writef_short(outhandle, amp, len);
index 3d64e2e6b7e939c91b0baf32866ccd050b9fe057..0d1f77f0bb920c5c5b5d593a2d7bf2bc07030334 100644 (file)
@@ -83,14 +83,17 @@ struct faxtester_state_s
     int image_len;
     int image_ptr;
     int image_bit_ptr;
-    
+
     int ecm_frame_size;
     int corrupt_crc;
-    
+
     int final_delayed;
 
     fax_modems_state_t modems;
-    
+
+    /*! \brief CED or CNG detector */
+    modem_connect_tones_rx_state_t connect_rx;
+
     /*! If TRUE, transmission is in progress */
     int transmit;
 
index fc0e20988e564a65bae93749f66402fce864dca9..cf285009054e8d68a8bbd5810dc5f5edc0d1b8d6 100644 (file)
@@ -529,7 +529,7 @@ int main(int argc, char *argv[])
     decode_file_name = NULL;
     code_to_look_up = -1;
     t38_transport = T38_TRANSPORT_UDPTL;
-    while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:tT:u:v:z:")) != -1)
+    while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
     {
         switch (opt)
         {
@@ -865,7 +865,7 @@ int main(int argc, char *argv[])
                                            T30_SUPPORT_T4_1D_COMPRESSION
                                          | T30_SUPPORT_T4_2D_COMPRESSION
                                          | T30_SUPPORT_T6_COMPRESSION
-                                         | T30_SUPPORT_T81_COMPRESSION
+                                         //| T30_SUPPORT_T81_COMPRESSION
                                          | T30_SUPPORT_T85_COMPRESSION
                                          | T30_SUPPORT_T85_L0_COMPRESSION);
         }
index 9548808086773ff8a9ffa09a7920ba94c2852021..b3068559656a898df0527af25d23d7c207978824 100644 (file)
@@ -105,8 +105,9 @@ void fax_log_page_transfer_statistics(t30_state_t *s, const char *tag)
     printf("%s:   Bad ECM frames %d\n", tag, t.error_correcting_mode_retries);
     printf("%s:   Compression type %s (%d)\n", tag, t4_encoding_to_str(t.encoding), t.encoding);
     printf("%s:   Compressed image size %d bytes\n", tag, t.image_size);
-    printf("%s:   Image size %d pels x %d pels\n", tag, t.width, t.length);
-    printf("%s:   Image resolution %d pels/m x %d pels/m\n", tag, t.x_resolution, t.y_resolution);
+    printf("%s:   Image type %s (%s in the file)\n", tag, t4_image_type_to_str(t.type), t4_image_type_to_str(t.image_type));
+    printf("%s:   Image size %d pels x %d pels (%d pels x %d pels in the file)\n", tag, t.width, t.length, t.image_width, t.image_length);
+    printf("%s:   Image resolution %d pels/m x %d pels/m (%d pels/m x %d pels/m in the file)\n", tag, t.x_resolution, t.y_resolution, t.image_x_resolution, t.image_y_resolution);
 #if defined(SPANDSP_EXPOSE_INTERNAL_STRUCTURES)
     printf("%s:   Bits per row - min %d, max %d\n", tag, s->t4.tx.encoder.t4_t6.min_row_bits, s->t4.tx.encoder.t4_t6.max_row_bits);
 #endif
index 0e2167513b5a3bcde475bc49058359e27845ff27..8b96f390f124ef1be283c8ed3d8b381fca0171f8 100644 (file)
@@ -130,7 +130,9 @@ static void display_page_stats(t4_rx_state_t *s)
     printf("Pages = %d\n", stats.pages_transferred);
     printf("Compression = %s\n", t4_encoding_to_str(stats.encoding));
     printf("Compressed size = %d\n", stats.line_image_size);
+    printf("Raw image size = %d pels x %d pels\n", stats.image_width, stats.image_length);
     printf("Image size = %d pels x %d pels\n", stats.width, stats.length);
+    printf("Raw image resolution = %d pels/m x %d pels/m\n", stats.image_x_resolution, stats.image_y_resolution);
     printf("Image resolution = %d pels/m x %d pels/m\n", stats.x_resolution, stats.y_resolution);
     printf("Bad rows = %d\n", stats.bad_rows);
     printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
index 0af26ce625692f6e0793c6bb630658b27b6be408..ff0b9a36f9be6913a10c8115f7dd5bd4a097b53f 100644 (file)
@@ -358,9 +358,11 @@ static int phase_b_handler(t30_state_t *s, void *user_data, int result)
 static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
 {
        t30_stats_t t30_stats;
-       char *fax_image_resolution = NULL;
+       char *fax_file_image_resolution = NULL;
+       char *fax_line_image_resolution = NULL;
+       char *fax_file_image_pixel_size = NULL;
+       char *fax_line_image_pixel_size = NULL;
        char *fax_image_size = NULL;
-       char *fax_image_pixel_size = NULL;
        char *fax_bad_rows = NULL;
        char *fax_encoding = NULL;
        char *fax_longest_bad_row_run = NULL;
@@ -383,14 +385,24 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
 
        /* Set Channel Variable */
 
-       fax_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.x_resolution, t30_stats.y_resolution);
-       if (fax_image_resolution) {
-               switch_channel_set_variable(channel, "fax_image_resolution", fax_image_resolution);
+       fax_line_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.x_resolution, t30_stats.y_resolution);
+       if (fax_line_image_resolution) {
+               switch_channel_set_variable(channel, "fax_image_resolution", fax_line_image_resolution);
+       }
+
+       fax_file_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.image_x_resolution, t30_stats.image_y_resolution);
+       if (fax_file_image_resolution) {
+               switch_channel_set_variable(channel, "fax_file_image_resolution", fax_file_image_resolution);
+       }
+
+       fax_line_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.width, t30_stats.length);
+       if (fax_line_image_pixel_size) {
+               switch_channel_set_variable(channel, "fax_image_pixel_size", fax_line_image_pixel_size);;
        }
 
-       fax_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.width, t30_stats.length);
-       if (fax_image_pixel_size) {
-               switch_channel_set_variable(channel, "fax_image_pixel_size", fax_image_pixel_size);;
+       fax_file_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.image_width, t30_stats.image_length);
+       if (fax_file_image_pixel_size) {
+               switch_channel_set_variable(channel, "fax_file_image_pixel_size", fax_file_image_pixel_size);;
        }
 
        fax_image_size = switch_core_session_sprintf(session, "%d", t30_stats.image_size);
@@ -423,8 +435,9 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
 
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==== Page %s===========================================================\n", pvt->app_mode == FUNCTION_TX ? "Sent ====": "Received ");
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Page no = %d\n", (pvt->app_mode == FUNCTION_TX)  ?  t30_stats.pages_tx  :  t30_stats.pages_rx);
-       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image size = %d x %d pixels\n", t30_stats.width, t30_stats.length);
-       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution = %d/m x %d/m\n", t30_stats.x_resolution, t30_stats.y_resolution);
+    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image type = %s (%s in the file)\n", t4_image_type_to_str(t30_stats.type), t4_image_type_to_str(t30_stats.image_type));
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image size = %d x %d pixels (%d x %d pixels in the file)\n", t30_stats.width, t30_stats.length, t30_stats.image_width, t30_stats.image_length);
+       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution = %d/m x %d/m (%d/m x %d/m in the file)\n", t30_stats.x_resolution, t30_stats.y_resolution, t30_stats.image_x_resolution, t30_stats.image_y_resolution);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compression = %s (%d)\n", t4_encoding_to_str(t30_stats.encoding), t30_stats.encoding);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compressed image size = %d bytes\n", t30_stats.image_size);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad rows = %d\n", t30_stats.bad_rows);
@@ -436,9 +449,11 @@ static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
        if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXPAGERESULT : SPANDSP_EVENT_RXFAXPAGERESULT) == SWITCH_STATUS_SUCCESS) {
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "uuid", switch_core_session_get_uuid(session));
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages);
-               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution);
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_line_image_resolution);
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-file-image-resolution", fax_file_image_resolution);
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size);
-               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-pixel-size", fax_image_pixel_size);
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-pixel-size", fax_line_image_pixel_size);
+               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-file-image-pixel-size", fax_file_image_pixel_size);
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows);
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-longest-bad-row-run", fax_longest_bad_row_run);
                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-encoding", fax_encoding);