Spandsp tweaks
This commit is contained in:
parent
8d005a4138
commit
c741332dcd
|
@ -76,16 +76,6 @@ SPAN_DECLARE(void) set_lab_gamut2(lab_params_t *s, int L_P, int L_Q, int a_P, in
|
|||
|
||||
SPAN_DECLARE(void) get_lab_gamut2(lab_params_t *s, int *L_P, int *L_Q, int *a_P, int *a_Q, int *b_P, int *b_Q);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_itulab(logging_state_t *logging, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_jpeg(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen);
|
||||
|
||||
SPAN_DECLARE(int) t42_jpeg_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen);
|
||||
|
||||
SPAN_DECLARE(int) t42_srgb_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_srgb(logging_state_t *logging, lab_params_t *s, tdata_t dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t *width, uint32_t *height);
|
||||
|
||||
SPAN_DECLARE(void) t42_encode_set_options(t42_encode_state_t *s, uint32_t l0, int quality, int options);
|
||||
|
||||
SPAN_DECLARE(int) t42_encode_set_image_width(t42_encode_state_t *s, uint32_t image_width);
|
||||
|
|
|
@ -40,7 +40,7 @@ enum
|
|||
{
|
||||
V18_MODE_NONE = 0,
|
||||
/* V.18 Annex A - Weitbrecht TDD at 45.45bps (US TTY), half-duplex, 5 bit baudot (USA). */
|
||||
V18_MODE_5BIT_45 = 1,
|
||||
V18_MODE_5BIT_4545 = 1,
|
||||
/* V.18 Annex A - Weitbrecht TDD at 50bps (International TTY), half-duplex, 5 bit baudot (UK, Australia and others). */
|
||||
V18_MODE_5BIT_50 = 2,
|
||||
/* V.18 Annex B - DTMF encoding of ASCII (Denmark, Holland and others). */
|
||||
|
@ -55,6 +55,7 @@ enum
|
|||
V18_MODE_V21TEXTPHONE = 7,
|
||||
/* V.18 Annex G - V.18 text telephone mode. */
|
||||
V18_MODE_V18TEXTPHONE = 8,
|
||||
V18_MODE_5BIT_476 = 9,
|
||||
/* Use repetitive shift characters where character set shifts are used */
|
||||
V18_MODE_REPETITIVE_SHIFTS_OPTION = 0x1000
|
||||
};
|
||||
|
@ -171,28 +172,6 @@ SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len);
|
|||
invalid, this function will return -1. */
|
||||
SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len);
|
||||
|
||||
/*! Convert a text string to a V.18 DTMF string.
|
||||
\brief Convert a text string to a V.18 DTMF string.
|
||||
\param s The V.18 context.
|
||||
\param dtmf The resulting DTMF string.
|
||||
\param msg The text string to be converted.
|
||||
\return The length of the DTMF string.
|
||||
*/
|
||||
SPAN_DECLARE(int) v18_encode_dtmf(v18_state_t *s, char dtmf[], const char msg[]);
|
||||
|
||||
/*! Convert a V.18 DTMF string to a text string.
|
||||
\brief Convert a V.18 DTMF string to a text string.
|
||||
\param s The V.18 context.
|
||||
\param msg The resulting test string.
|
||||
\param dtmf The DTMF string to be converted.
|
||||
\return The length of the text string.
|
||||
*/
|
||||
SPAN_DECLARE(int) v18_decode_dtmf(v18_state_t *s, char msg[], const char dtmf[]);
|
||||
|
||||
SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch);
|
||||
|
||||
SPAN_DECLARE(uint8_t) v18_decode_baudot(v18_state_t *s, uint8_t ch);
|
||||
|
||||
/*! \brief Return a short name for an V.18 mode
|
||||
\param mode The code for the V.18 mode.
|
||||
\return A pointer to the name.
|
||||
|
|
|
@ -132,18 +132,19 @@ static const res_table_t y_res_table[] =
|
|||
{ -1.00f, -1}
|
||||
};
|
||||
|
||||
static const int resolution_map[10][10] =
|
||||
static const int resolution_map[10][9] =
|
||||
{
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_STANDARD, 0, 0, 0, 0, 0, 0},
|
||||
{T4_RESOLUTION_100_100, 0, T4_RESOLUTION_200_100, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_FINE, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, T4_RESOLUTION_200_200, 0, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, T4_RESOLUTION_300_300, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_SUPERFINE, 0, 0, T4_RESOLUTION_R16_SUPERFINE, 0, 0, 0},
|
||||
{ 0, 0, T4_RESOLUTION_200_400, 0, 0, T4_RESOLUTION_400_400, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, T4_RESOLUTION_300_600, 0, 0, T4_RESOLUTION_600_600, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, T4_RESOLUTION_400_800, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, 0, T4_RESOLUTION_600_1200, 0, T4_RESOLUTION_1200_1200},
|
||||
/* x = 100 102 200 204 300 400 408 600 1200 */
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_STANDARD, 0, 0, 0, 0, 0}, /* y = 3.85/mm */
|
||||
{T4_RESOLUTION_100_100, 0, T4_RESOLUTION_200_100, 0, 0, 0, 0, 0, 0}, /* y = 100 */
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_FINE, 0, 0, 0, 0, 0}, /* y = 7.7/mm */
|
||||
{ 0, 0, T4_RESOLUTION_200_200, 0, 0, 0, 0, 0, 0}, /* y = 200 */
|
||||
{ 0, 0, 0, 0, T4_RESOLUTION_300_300, 0, 0, 0, 0}, /* y = 300 */
|
||||
{ 0, 0, 0, T4_RESOLUTION_R8_SUPERFINE, 0, 0, T4_RESOLUTION_R16_SUPERFINE, 0, 0}, /* y = 154/mm */
|
||||
{ 0, 0, T4_RESOLUTION_200_400, 0, 0, T4_RESOLUTION_400_400, 0, 0, 0}, /* y = 400 */
|
||||
{ 0, 0, 0, 0, T4_RESOLUTION_300_600, 0, 0, T4_RESOLUTION_600_600, 0}, /* y = 600 */
|
||||
{ 0, 0, 0, 0, 0, T4_RESOLUTION_400_800, 0, 0, 0}, /* y = 800 */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, T4_RESOLUTION_600_1200, T4_RESOLUTION_1200_1200} /* y = 1200 */
|
||||
};
|
||||
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
|
@ -1354,12 +1355,14 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
|
|||
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.x_resolution;
|
||||
t->image_y_resolution = s->tiff.y_resolution;
|
||||
|
||||
t->x_resolution = s->metadata.x_resolution;
|
||||
t->y_resolution = s->metadata.y_resolution/s->row_squashing_ratio;
|
||||
|
||||
t->compression = s->metadata.compression;
|
||||
|
||||
switch (s->metadata.compression)
|
||||
{
|
||||
case T4_COMPRESSION_T4_1D:
|
||||
|
@ -1417,7 +1420,7 @@ SPAN_DECLARE(int) t4_tx_image_complete(t4_tx_state_t *s)
|
|||
return t85_encode_image_complete(&s->encoder.t85);
|
||||
#if defined(SPANDSP_SUPPORT_T88)
|
||||
case T4_COMPRESSION_T88:
|
||||
break;
|
||||
return t88_encode_image_complete(&s->encoder.t88);
|
||||
#endif
|
||||
case T4_COMPRESSION_T42_T81:
|
||||
case T4_COMPRESSION_SYCC_T81:
|
||||
|
@ -1428,7 +1431,7 @@ SPAN_DECLARE(int) t4_tx_image_complete(t4_tx_state_t *s)
|
|||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T45)
|
||||
case T4_COMPRESSION_T45:
|
||||
break;
|
||||
return t45_encode_image_complete(&s->encoder.t45);
|
||||
#endif
|
||||
}
|
||||
return SIG_STATUS_END_OF_DATA;
|
||||
|
@ -1444,6 +1447,19 @@ SPAN_DECLARE(int) t4_tx_get_bit(t4_tx_state_t *s)
|
|||
|
||||
SPAN_DECLARE(int) t4_tx_get(t4_tx_state_t *s, uint8_t buf[], size_t max_len)
|
||||
{
|
||||
#if 0
|
||||
if (s->pre_encoded_len > 0)
|
||||
{
|
||||
if (max_len > (s->pre_encoded_len - s->pre_encoded_ptr))
|
||||
max_len = s->pre_encoded_len - s->pre_encoded_ptr;
|
||||
memcpy(buf, &s->pre_encoded_buf[s->pre_encoded_ptr], max_len);
|
||||
s->pre_encoded_ptr += max_len;
|
||||
return max_len;
|
||||
}
|
||||
|
||||
if (s->image_get_handler)
|
||||
return s->image_get_handler((void *) &s->encoder, buf, max_len);
|
||||
#else
|
||||
switch (s->metadata.compression)
|
||||
{
|
||||
case T4_COMPRESSION_T4_1D:
|
||||
|
@ -1469,6 +1485,7 @@ SPAN_DECLARE(int) t4_tx_get(t4_tx_state_t *s, uint8_t buf[], size_t max_len)
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1497,31 +1514,44 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
|
|||
case T4_COMPRESSION_T4_2D:
|
||||
case T4_COMPRESSION_T6:
|
||||
t4_t6_encode_restart(&s->encoder.t4_t6, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t4_t6_encode_get;
|
||||
break;
|
||||
case T4_COMPRESSION_T85:
|
||||
case T4_COMPRESSION_T85_L0:
|
||||
t85_encode_restart(&s->encoder.t85, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t85_encode_get;
|
||||
break;
|
||||
#if defined(SPANDSP_SUPPORT_T88)
|
||||
case T4_COMPRESSION_T88:
|
||||
t88_encode_restart(&s->encoder.t88, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t88_encode_get;
|
||||
break;
|
||||
#endif
|
||||
case T4_COMPRESSION_T42_T81:
|
||||
case T4_COMPRESSION_SYCC_T81:
|
||||
t42_encode_restart(&s->encoder.t42, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t42_encode_get;
|
||||
break;
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
case T4_COMPRESSION_T43:
|
||||
t43_encode_restart(&s->encoder.t43, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t43_encode_get;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T45)
|
||||
case T4_COMPRESSION_T45:
|
||||
t45_encode_restart(&s->encoder.t45, s->metadata.image_width, s->metadata.image_length);
|
||||
s->image_get_handler = (t4_image_get_handler_t) t45_encode_get;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
s->image_get_handler = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If there is a page header, create that first */
|
||||
if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL && s->header_info && s->header_info[0] && make_header(s) == 0)
|
||||
if (s->metadata.image_type == T4_IMAGE_TYPE_BILEVEL && s->header_info && s->header_info[0] && make_header(s) == 0)
|
||||
//if (s->header_info && s->header_info[0] && make_header(s) == 0)
|
||||
{
|
||||
s->header_row = 0;
|
||||
set_row_read_handler(s, header_row_read_handler, (void *) s);
|
||||
|
@ -1634,7 +1664,7 @@ SPAN_DECLARE(int) t4_tx_release(t4_tx_state_t *s)
|
|||
return t85_encode_release(&s->encoder.t85);
|
||||
#if defined(SPANDSP_SUPPORT_T88)
|
||||
case T4_COMPRESSION_T88:
|
||||
break;
|
||||
return t88_encode_release(&s->encoder.t88);
|
||||
#endif
|
||||
case T4_COMPRESSION_T42_T81:
|
||||
case T4_COMPRESSION_SYCC_T81:
|
||||
|
@ -1645,7 +1675,7 @@ SPAN_DECLARE(int) t4_tx_release(t4_tx_state_t *s)
|
|||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T45)
|
||||
case T4_COMPRESSION_T45:
|
||||
break;
|
||||
return t45_encode_release(&s->encoder.t45);
|
||||
#endif
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -78,13 +78,13 @@
|
|||
Silence for 0.5s then send TXP
|
||||
DTMF
|
||||
Proceed as Annex B
|
||||
1650Hz (V21 ch 2 low)
|
||||
1650Hz (V21 ch 2 low) [1650Hz +-12Hz]
|
||||
Proceed as Annex F in call mode
|
||||
1300Hz (Calling tone)
|
||||
1300Hz (Calling tone) [1300Hz +-16Hz]
|
||||
Proceed as Annex E in call mode
|
||||
1400Hz/1800Hz (Weitbrecht)
|
||||
1400Hz/1800Hz (Weitbrecht) [1400Hz +-5% and 1800Hz +-5%]
|
||||
Detect rate and proceed as Annex A
|
||||
980Hz/1180Hz (V21 ch 1)
|
||||
980Hz/1180Hz (V21 ch 1) [980Hz +-12Hz, 1180Hz +-12Hz]
|
||||
Start timer Tr
|
||||
2225Hz (Bell ANS)
|
||||
Proceed as Annex D call mode
|
||||
|
@ -98,21 +98,21 @@
|
|||
Monitor as caller for 980Hz or 1300Hz
|
||||
CI/XCI
|
||||
Respond with ANSam
|
||||
1300Hz
|
||||
1300Hz [1300Hz +-16Hz]
|
||||
Probe
|
||||
Timer Ta (3s)
|
||||
Probe
|
||||
1400Hz/1800Hz (Weitbrecht)
|
||||
1400Hz/1800Hz (Weitbrecht) [1400Hz +-5% and 1800Hz +-5%]
|
||||
Detect rate and proceed as Annex A
|
||||
DTMF
|
||||
Proceed as Annex B
|
||||
980Hz (V21 ch 1 low)
|
||||
980Hz (V21 ch 1 low) [980Hz +-12Hz]
|
||||
Start timer Te
|
||||
1270Hz (Bell103 ch 2 high)
|
||||
Proceed as Annex D answer mode
|
||||
2225Hz (Bell ANS)
|
||||
Proceed as Annex D call mode
|
||||
1650Hz (V21 ch 2 low)
|
||||
1650Hz (V21 ch 2 low) [1650Hz +-12Hz]
|
||||
Proceed as Annex F answer mode
|
||||
ANSam
|
||||
Proceed as V.8 caller Annex G
|
||||
|
@ -131,6 +131,7 @@ struct dtmf_to_ascii_s
|
|||
|
||||
static const struct dtmf_to_ascii_s dtmf_to_ascii[] =
|
||||
{
|
||||
{"###0", '!'},
|
||||
{"###1", 'C'},
|
||||
{"###2", 'F'},
|
||||
{"###3", 'I'},
|
||||
|
@ -140,7 +141,6 @@ static const struct dtmf_to_ascii_s dtmf_to_ascii[] =
|
|||
{"###7", 'U'},
|
||||
{"###8", 'X'},
|
||||
{"###9", ';'},
|
||||
{"###0", '!'},
|
||||
{"##*1", 'A'},
|
||||
{"##*2", 'D'},
|
||||
{"##*3", 'G'},
|
||||
|
@ -373,71 +373,174 @@ static const uint8_t txp[] = "1111111111000101011100001101110000010101";
|
|||
100 ms mark. */
|
||||
static const uint8_t xci[] = "01111111110111111111";
|
||||
|
||||
static int cmp(const void *s, const void *t)
|
||||
/* The entries here must match the order in which the related names are defined in v18.h */
|
||||
static const int automoding_sequences[][6] =
|
||||
{
|
||||
const char *ss;
|
||||
struct dtmf_to_ascii_s *tt;
|
||||
|
||||
ss = (const char *) s;
|
||||
tt = (struct dtmf_to_ascii_s *) t;
|
||||
return strncmp(ss, tt->dtmf, strlen(tt->dtmf));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) v18_encode_dtmf(v18_state_t *s, char dtmf[], const char msg[])
|
||||
{
|
||||
const char *t;
|
||||
const char *v;
|
||||
char *u;
|
||||
|
||||
t = msg;
|
||||
u = dtmf;
|
||||
while (*t)
|
||||
{
|
||||
v = ascii_to_dtmf[*t & 0x7F];
|
||||
while (*v)
|
||||
*u++ = *v++;
|
||||
t++;
|
||||
}
|
||||
*u = '\0';
|
||||
|
||||
return u - dtmf;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) v18_decode_dtmf(v18_state_t *s, char msg[], const char dtmf[])
|
||||
{
|
||||
int entries;
|
||||
const char *t;
|
||||
char *u;
|
||||
struct dtmf_to_ascii_s *ss;
|
||||
|
||||
entries = sizeof(dtmf_to_ascii)/sizeof(dtmf_to_ascii[0]) - 1;
|
||||
t = dtmf;
|
||||
u = msg;
|
||||
while (*t)
|
||||
/* Dummy entry 0 */
|
||||
V18_MODE_5BIT_4545,
|
||||
V18_MODE_BELL103,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF
|
||||
},
|
||||
{
|
||||
ss = bsearch(t, dtmf_to_ascii, entries, sizeof(dtmf_to_ascii[0]), cmp);
|
||||
if (ss)
|
||||
{
|
||||
t += strlen(ss->dtmf);
|
||||
*u++ = ss->ascii;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Can't match the code. Let's assume this is a code we just don't know, and skip over it */
|
||||
while (*t == '#' || *t == '*')
|
||||
t++;
|
||||
if (*t)
|
||||
t++;
|
||||
}
|
||||
/* Australia */
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Ireland */
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Germany */
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Switzerland */
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Italy */
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Spain */
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Austria */
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Netherlands */
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Iceland */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Norway */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Sweden */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Finland */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Denmark */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* UK */
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* USA */
|
||||
V18_MODE_5BIT_4545,
|
||||
V18_MODE_BELL103,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF
|
||||
},
|
||||
{
|
||||
/* France */
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_BELL103
|
||||
},
|
||||
{
|
||||
/* Belgium */
|
||||
V18_MODE_V23VIDEOTEX,
|
||||
V18_MODE_EDT,
|
||||
V18_MODE_DTMF,
|
||||
V18_MODE_5BIT_50,
|
||||
V18_MODE_V21TEXTPHONE,
|
||||
V18_MODE_BELL103
|
||||
}
|
||||
*u = '\0';
|
||||
return u - msg;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
};
|
||||
|
||||
SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
|
||||
static uint16_t encode_baudot(v18_state_t *s, uint8_t ch)
|
||||
{
|
||||
static const uint8_t conv[128] =
|
||||
{
|
||||
|
@ -449,7 +552,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
|
|||
0xFF, /* ENQ */
|
||||
0xFF, /* ACK */
|
||||
0xFF, /* BEL */
|
||||
0x00, /* BS */
|
||||
0x40, /* BS */
|
||||
0x44, /* HT >> SPACE */
|
||||
0x42, /* LF */
|
||||
0x42, /* VT >> LF */
|
||||
|
@ -572,14 +675,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
|
|||
};
|
||||
uint16_t shift;
|
||||
|
||||
if (ch == 0x7F)
|
||||
{
|
||||
/* DLE is a special character meaning "force a
|
||||
change to the letter character set */
|
||||
shift = BAUDOT_LETTER_SHIFT;
|
||||
return 0;
|
||||
}
|
||||
ch = conv[ch];
|
||||
ch = conv[ch & 0x7F];
|
||||
/* Is it a non-existant code? */
|
||||
if (ch == 0xFF)
|
||||
return 0;
|
||||
|
@ -605,7 +701,7 @@ SPAN_DECLARE(uint16_t) v18_encode_baudot(v18_state_t *s, uint8_t ch)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(uint8_t) v18_decode_baudot(v18_state_t *s, uint8_t ch)
|
||||
static uint8_t decode_baudot(v18_state_t *s, uint8_t ch)
|
||||
{
|
||||
static const uint8_t conv[2][32] =
|
||||
{
|
||||
|
@ -624,8 +720,8 @@ SPAN_DECLARE(uint8_t) v18_decode_baudot(v18_state_t *s, uint8_t ch)
|
|||
default:
|
||||
return conv[s->baudot_rx_shift][ch];
|
||||
}
|
||||
/* return 0 if we did not produce a character */
|
||||
return 0;
|
||||
/* Return 0xFF if we did not produce a character */
|
||||
return 0xFF;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -649,7 +745,7 @@ static int v18_tdd_get_async_byte(void *user_data)
|
|||
if (s->tx_signal_on)
|
||||
{
|
||||
/* The FSK should now be switched off. */
|
||||
s->tx_signal_on = FALSE;
|
||||
s->tx_signal_on = 0;
|
||||
}
|
||||
return 0x1F;
|
||||
}
|
||||
|
@ -659,14 +755,16 @@ static void v18_dtmf_get(void *user_data)
|
|||
{
|
||||
v18_state_t *s;
|
||||
int ch;
|
||||
const char *v;
|
||||
int len;
|
||||
const char *t;
|
||||
|
||||
s = (v18_state_t *) user_data;
|
||||
if ((ch = queue_read_byte(&s->queue.queue)) >= 0)
|
||||
{
|
||||
v = ascii_to_dtmf[ch & 0x7F];
|
||||
dtmf_tx_put(&s->dtmf_tx, v, strlen(v));
|
||||
s->rx_suppression = ((300 + 100*strlen(v))*SAMPLE_RATE)/1000;
|
||||
t = ascii_to_dtmf[ch & 0x7F];
|
||||
len = strlen(t);
|
||||
dtmf_tx_put(&s->dtmf_tx, t, len);
|
||||
s->rx_suppression = ((300 + 100*len)*SAMPLE_RATE)/1000;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -685,7 +783,7 @@ static int v18_edt_get_async_byte(void *user_data)
|
|||
if (s->tx_signal_on)
|
||||
{
|
||||
/* The FSK should now be switched off. */
|
||||
s->tx_signal_on = FALSE;
|
||||
s->tx_signal_on = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -726,7 +824,7 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
|
|||
return;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Rx byte %x\n", byte);
|
||||
if ((octet = v18_decode_baudot(s, byte)))
|
||||
if ((octet = decode_baudot(s, byte)) != 0xFF)
|
||||
s->rx_msg[s->rx_msg_len++] = octet;
|
||||
if (s->rx_msg_len >= 256)
|
||||
{
|
||||
|
@ -738,11 +836,55 @@ static void v18_tdd_put_async_byte(void *user_data, int byte)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int decode_dtmf_cmp(const void *s, const void *t)
|
||||
{
|
||||
const char *ss;
|
||||
struct dtmf_to_ascii_s *tt;
|
||||
|
||||
ss = (const char *) s;
|
||||
tt = (struct dtmf_to_ascii_s *) t;
|
||||
return strncmp(ss, tt->dtmf, strlen(tt->dtmf));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int decode_dtmf(v18_state_t *s, char msg[], const char dtmf[])
|
||||
{
|
||||
int entries;
|
||||
int len;
|
||||
const char *t;
|
||||
char *u;
|
||||
struct dtmf_to_ascii_s *ss;
|
||||
|
||||
entries = sizeof(dtmf_to_ascii)/sizeof(dtmf_to_ascii[0]) - 1;
|
||||
t = dtmf;
|
||||
u = msg;
|
||||
while (*t)
|
||||
{
|
||||
ss = bsearch(t, dtmf_to_ascii, entries, sizeof(dtmf_to_ascii[0]), decode_dtmf_cmp);
|
||||
if (ss)
|
||||
{
|
||||
len = strlen(ss->dtmf);
|
||||
t += len;
|
||||
*u++ = ss->ascii;
|
||||
return len;
|
||||
}
|
||||
/* Can't match the code. Let's assume this is a code we just don't know, and skip over it */
|
||||
while (*t == '#' || *t == '*')
|
||||
t++;
|
||||
if (*t)
|
||||
t++;
|
||||
}
|
||||
*u = '\0';
|
||||
return u - msg;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void v18_dtmf_put(void *user_data, const char dtmf[], int len)
|
||||
{
|
||||
v18_state_t *s;
|
||||
char buf[128];
|
||||
int i;
|
||||
int matched;
|
||||
|
||||
s = (v18_state_t *) user_data;
|
||||
if (s->rx_suppression > 0)
|
||||
|
@ -753,11 +895,17 @@ static void v18_dtmf_put(void *user_data, const char dtmf[], int len)
|
|||
if (dtmf[i] >= '0' && dtmf[i] <= '9')
|
||||
{
|
||||
s->rx_msg[s->rx_msg_len] = '\0';
|
||||
if (v18_decode_dtmf(s, buf, (const char *) s->rx_msg) > 0)
|
||||
if ((matched = decode_dtmf(s, buf, (const char *) s->rx_msg)) > 0)
|
||||
{
|
||||
buf[1] = '\0';
|
||||
s->put_msg(s->user_data, (const uint8_t *) buf, 1);
|
||||
s->rx_msg_len = 0;
|
||||
}
|
||||
if (s->rx_msg_len > matched)
|
||||
memcpy(&s->rx_msg[0], &s->rx_msg[matched], s->rx_msg_len - matched);
|
||||
s->rx_msg_len -= matched;
|
||||
}
|
||||
}
|
||||
s->in_progress = 5*SAMPLE_RATE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -815,7 +963,7 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len)
|
|||
if (len < max_len)
|
||||
{
|
||||
if ((lenx = fsk_tx(&s->fsk_tx, amp + len, max_len - len)) <= 0)
|
||||
s->tx_signal_on = FALSE;
|
||||
s->tx_signal_on = 0;
|
||||
len += lenx;
|
||||
}
|
||||
break;
|
||||
|
@ -894,12 +1042,12 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
|
|||
}
|
||||
switch (s->mode)
|
||||
{
|
||||
case V18_MODE_5BIT_45:
|
||||
case V18_MODE_5BIT_4545:
|
||||
case V18_MODE_5BIT_50:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
n = 0;
|
||||
if ((x = v18_encode_baudot(s, msg[i])))
|
||||
if ((x = encode_baudot(s, msg[i])))
|
||||
{
|
||||
if ((x & 0x3E0))
|
||||
buf[n++] = (uint8_t) ((x >> 5) & 0x1F);
|
||||
|
@ -907,7 +1055,7 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
|
|||
/* TODO: Deal with out of space condition */
|
||||
if (queue_write(&s->queue.queue, (const uint8_t *) buf, n) < 0)
|
||||
return i;
|
||||
s->tx_signal_on = TRUE;
|
||||
s->tx_signal_on = 1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
|
@ -920,12 +1068,14 @@ SPAN_DECLARE(int) v18_put(v18_state_t *s, const char msg[], int len)
|
|||
|
||||
SPAN_DECLARE(const char *) v18_mode_to_str(int mode)
|
||||
{
|
||||
switch ((mode & 0xFF))
|
||||
switch ((mode & 0xFFF))
|
||||
{
|
||||
case V18_MODE_NONE:
|
||||
return "None";
|
||||
case V18_MODE_5BIT_45:
|
||||
case V18_MODE_5BIT_4545:
|
||||
return "Weitbrecht TDD (45.45bps)";
|
||||
case V18_MODE_5BIT_476:
|
||||
return "Weitbrecht TDD (47.6bps)";
|
||||
case V18_MODE_5BIT_50:
|
||||
return "Weitbrecht TDD (50bps)";
|
||||
case V18_MODE_DTMF:
|
||||
|
@ -958,6 +1108,9 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
|||
put_msg_func_t put_msg,
|
||||
void *user_data)
|
||||
{
|
||||
if (nation < 0 || nation >= V18_AUTOMODING_END)
|
||||
return NULL;
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
if ((s = (v18_state_t *) malloc(sizeof(*s))) == NULL)
|
||||
|
@ -965,14 +1118,14 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
|||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->calling_party = calling_party;
|
||||
s->mode = mode & 0xFF;
|
||||
s->mode = mode & ~V18_MODE_REPETITIVE_SHIFTS_OPTION;
|
||||
s->put_msg = put_msg;
|
||||
s->user_data = user_data;
|
||||
|
||||
switch (s->mode)
|
||||
{
|
||||
case V18_MODE_5BIT_45:
|
||||
s->repeat_shifts = mode & 0x100;
|
||||
case V18_MODE_5BIT_4545:
|
||||
s->repeat_shifts = mode & V18_MODE_REPETITIVE_SHIFTS_OPTION;
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT_4545], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
/* Schedule an explicit shift at the start of baudot transmission */
|
||||
|
@ -983,8 +1136,20 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
|
|||
s->baudot_rx_shift = 0;
|
||||
s->next_byte = (uint8_t) 0xFF;
|
||||
break;
|
||||
case V18_MODE_5BIT_476:
|
||||
s->repeat_shifts = mode & V18_MODE_REPETITIVE_SHIFTS_OPTION;
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT_476], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
/* Schedule an explicit shift at the start of baudot transmission */
|
||||
s->baudot_tx_shift = 2;
|
||||
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
|
||||
ride over the fraction. */
|
||||
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_WEITBRECHT_476], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
|
||||
s->baudot_rx_shift = 0;
|
||||
s->next_byte = (uint8_t) 0xFF;
|
||||
break;
|
||||
case V18_MODE_5BIT_50:
|
||||
s->repeat_shifts = mode & 0x100;
|
||||
s->repeat_shifts = mode & V18_MODE_REPETITIVE_SHIFTS_OPTION;
|
||||
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT_50], async_tx_get_bit, &s->async_tx);
|
||||
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
|
||||
/* Schedule an explicit shift at the start of baudot transmission */
|
||||
|
|
|
@ -70,49 +70,55 @@ LOCALTESTS_DIR=../test-data/local
|
|||
# Colour/gray -> bilevel by not allowing ECM
|
||||
for OPTS in "-p AA" "-p TT" "-p GG" "-p TG" "-p GT"
|
||||
do
|
||||
IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
OUT_FILE="${LOCALTESTS_DIR}/lenna-colour-bilevel.tif"
|
||||
run_colour_fax_test
|
||||
echo Colour to bi-level tests disabled
|
||||
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
# OUT_FILE="${LOCALTESTS_DIR}/lenna-colour-bilevel.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
OUT_FILE="${LOCALTESTS_DIR}/lenna-bw-bilevel.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw-bilevel.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw-bilevel.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
# IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
done
|
||||
|
||||
# Colour/gray -> colour/gray by allowing ECM
|
||||
for OPTS in "-p AA -C -e" "-p TT -C -e" "-p GG -C -e" "-p TG -C -e" "-p GT -C -e"
|
||||
do
|
||||
IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
OUT_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
run_colour_fax_test
|
||||
echo Colour to colour tests disabled
|
||||
# IN_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
# OUT_FILE="${LOCALTESTS_DIR}/lenna-colour.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
OUT_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
# OUT_FILE="${LOCALTESTS_DIR}/lenna-bw.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/c03x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/l02x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
|
||||
IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
run_colour_fax_test
|
||||
# IN_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
# OUT_FILE="${TIFFFX_DIR}/l04x_02x.tif"
|
||||
# run_colour_fax_test
|
||||
done
|
||||
|
||||
# Bi-level tests
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -150,11 +150,11 @@ static int get_v18_mode(switch_core_session_t *session)
|
|||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *var;
|
||||
int r = V18_MODE_5BIT_45;
|
||||
int r = V18_MODE_5BIT_4545;
|
||||
|
||||
if ((var = switch_channel_get_variable(channel, "v18_mode"))) {
|
||||
if (!strcasecmp(var, "5BIT_45") || !strcasecmp(var, "baudot")) {
|
||||
r = V18_MODE_5BIT_45;
|
||||
r = V18_MODE_5BIT_4545;
|
||||
} else if (!strcasecmp(var, "5BIT_50")) {
|
||||
r = V18_MODE_5BIT_50;
|
||||
} else if (!strcasecmp(var, "DTMF")) {
|
||||
|
|
Loading…
Reference in New Issue