t81_t82_arith_coding_tests.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * t81_t82_arith_coding_tests.c - Tests for the ITU T.81 and T.82 arithmetic
  5. * encoder/decoder, based on the test description
  6. * in T.82
  7. *
  8. * Written by Steve Underwood <steveu@coppice.org>
  9. *
  10. * Copyright (C) 2009 Steve Underwood
  11. *
  12. * All rights reserved.
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License version 2, as
  16. * published by the Free Software Foundation.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26. */
  27. /*! \file */
  28. /*! \page t81_t82_arith_coding_tests_page T.81 and T.82 Arithmetic encoder/decoder tests
  29. \section t81_t82_arith_coding_tests_pagesec_1 What does it do
  30. These tests exercise the arithmetic encoder and decoder for T.81 and T.82. As T.85 is based
  31. on T.82, this is also the arithmetic coder for T.85.
  32. These tests are based on T.82 section 7. Nothing beyond the prescibed tests is performed at
  33. the present time.
  34. */
  35. #if defined(HAVE_CONFIG_H)
  36. #include "config.h"
  37. #endif
  38. #include <inttypes.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <stddef.h>
  42. #include <string.h>
  43. #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
  44. #include "spandsp.h"
  45. #define MSG_SIZE 10000
  46. uint8_t msg[MSG_SIZE];
  47. int32_t msg_len;
  48. static void write_byte(void *user_data, int byte)
  49. {
  50. if (msg_len < MSG_SIZE)
  51. msg[msg_len++] = byte;
  52. }
  53. /*- End of function --------------------------------------------------------*/
  54. int main(int argc, char *argv[])
  55. {
  56. t81_t82_arith_encode_state_t *se;
  57. t81_t82_arith_decode_state_t *sd;
  58. int i;
  59. int j;
  60. int test_failed;
  61. int pix;
  62. const uint8_t *pp;
  63. /* Test data from T.82 7.1 */
  64. static const uint16_t pix_7_1[16] =
  65. {
  66. 0x05E0, 0x0000, 0x8B00, 0x01C4, 0x1700, 0x0034, 0x7FFF, 0x1A3F,
  67. 0x951B, 0x05D8, 0x1D17, 0xE770, 0x0000, 0x0000, 0x0656, 0x0E6A
  68. };
  69. /* Test data from T.82 7.1 */
  70. static const uint16_t cx_7_1[16] =
  71. {
  72. 0x0FE0, 0x0000, 0x0F00, 0x00F0, 0xFF00, 0x0000, 0x0000, 0x0000,
  73. 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
  74. };
  75. /* Test data from T.82 7.1 - scd with stuffing and SDNORM termination */
  76. static const uint8_t sde_7_1[32] =
  77. {
  78. 0x69, 0x89, 0x99, 0x5C, 0x32, 0xEA, 0xFA, 0xA0,
  79. 0xD5, 0xFF, 0x00, 0x52, 0x7F, 0xFF, 0x00, 0xFF,
  80. 0x00, 0xFF, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x3F,
  81. 0xFF, 0x00, 0x2D, 0x20, 0x82, 0x91, 0xFF, 0x02
  82. };
  83. #define SDE_7_1_LEN 30 /* Don't include the termination SDNORM */
  84. #define SDE_7_1_FULL_LEN 32 /* Include the termination SDNORM */
  85. printf("T.81/T.82 arithmetic encoder tests, from ITU-T T.82\n\n");
  86. printf("Arithmetic encoder tests from ITU-T T.82/7.1\n");
  87. if ((se = t81_t82_arith_encode_init(NULL, write_byte, NULL)) == NULL)
  88. {
  89. fprintf(stderr, "Failed to allocate arithmetic encoder!\n");
  90. exit(2);
  91. }
  92. msg_len = 0;
  93. for (i = 0; i < 16; i++)
  94. {
  95. for (j = 0; j < 16; j++)
  96. {
  97. t81_t82_arith_encode(se,
  98. (cx_7_1[i] >> (15 - j)) & 1,
  99. (pix_7_1[i] >> (15 - j)) & 1);
  100. }
  101. }
  102. t81_t82_arith_encode_flush(se);
  103. if (msg_len != SDE_7_1_LEN || memcmp(msg, sde_7_1, SDE_7_1_LEN))
  104. {
  105. printf("Encoded data: ");
  106. for (i = 0; i < msg_len; i++)
  107. printf("%02X", msg[i]);
  108. printf("\n");
  109. printf("Expected data: ");
  110. for (i = 0; i < SDE_7_1_LEN; i++)
  111. printf("%02X", sde_7_1[i]);
  112. printf("\n");
  113. printf("Test failed\n");
  114. exit(2);
  115. }
  116. printf("Test passed\n");
  117. printf("Arithmetic decoder tests from ITU-T T.82/7.1\n");
  118. printf("Decoding byte by byte...\n");
  119. test_failed = false;
  120. if ((sd = t81_t82_arith_decode_init(NULL)) == NULL)
  121. {
  122. fprintf(stderr, "Failed to allocate arithmetic decoder!\n");
  123. exit(2);
  124. }
  125. pp = sde_7_1;
  126. sd->pscd_ptr = pp;
  127. sd->pscd_end = pp + 1;
  128. for (i = 0; i < 16; i++)
  129. {
  130. for (j = 0; j < 16; j++)
  131. {
  132. for (;;)
  133. {
  134. pix = t81_t82_arith_decode(sd, (cx_7_1[i] >> (15 - j)) & 1);
  135. if ((pix >= 0 || sd->pscd_end >= sde_7_1 + SDE_7_1_FULL_LEN))
  136. break;
  137. pp++;
  138. if (sd->pscd_ptr != pp - 1)
  139. sd->pscd_ptr = pp;
  140. sd->pscd_end = pp + 1;
  141. }
  142. if (pix < 0)
  143. {
  144. printf("Bad pixel %d, byte %" PRIdPTR ".\n\n",
  145. i*16 + j + 1,
  146. sd->pscd_ptr - sd->pscd_end);
  147. test_failed = true;
  148. break;
  149. }
  150. if (pix != ((pix_7_1[i] >> (15 - j)) & 1))
  151. {
  152. printf("Bad PIX (%d) at pixel %d.\n\n",
  153. pix,
  154. i*16 + j + 1);
  155. test_failed = true;
  156. break;
  157. }
  158. }
  159. }
  160. if (sd->pscd_ptr != sd->pscd_end - 2)
  161. {
  162. printf("%" PRIdPTR " bytes left after decoder finished.\n\n",
  163. sd->pscd_end - sd->pscd_ptr - 2);
  164. test_failed = true;
  165. }
  166. if (test_failed)
  167. {
  168. printf("Test failed\n");
  169. exit(2);
  170. }
  171. printf("Test passed\n");
  172. printf("Decoding chunk by chunk...\n");
  173. test_failed = false;
  174. t81_t82_arith_decode_init(sd);
  175. sd->pscd_ptr = sde_7_1;
  176. sd->pscd_end = sde_7_1 + SDE_7_1_FULL_LEN;
  177. for (i = 0; i < 16; i++)
  178. {
  179. for (j = 0; j < 16; j++)
  180. {
  181. pix = t81_t82_arith_decode(sd, (cx_7_1[i] >> (15 - j)) & 1);
  182. if (pix < 0)
  183. {
  184. printf("Bad pixel %d, byte %" PRIdPTR ".\n\n",
  185. i*16 + j + 1,
  186. sd->pscd_ptr - sd->pscd_end);
  187. test_failed = true;
  188. break;
  189. }
  190. if (pix != ((pix_7_1[i] >> (15 - j)) & 1))
  191. {
  192. printf("Bad PIX (%d) at pixel %d.\n\n",
  193. pix,
  194. i*16 + j + 1);
  195. test_failed = true;
  196. break;
  197. }
  198. }
  199. }
  200. if (sd->pscd_ptr != sd->pscd_end - 2)
  201. {
  202. printf("%" PRIdPTR " bytes left after decoder finished.\n\n",
  203. sd->pscd_end - sd->pscd_ptr - 2);
  204. test_failed = true;
  205. }
  206. if (test_failed)
  207. {
  208. printf("Test failed\n");
  209. exit(2);
  210. }
  211. printf("Test passed\n");
  212. t81_t82_arith_encode_free(se);
  213. t81_t82_arith_decode_free(sd);
  214. printf("Tests passed\n");
  215. return 0;
  216. }
  217. /*- End of function --------------------------------------------------------*/
  218. /*- End of file ------------------------------------------------------------*/