00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * v42bis.h 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2005 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU Lesser General Public License version 2.1, 00014 * as published by the Free Software Foundation. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00024 * 00025 * $Id: v42bis.h,v 1.22 2008/04/17 14:27:01 steveu Exp $ 00026 */ 00027 00028 /*! \page v42bis_page V.42bis modem data compression 00029 \section v42bis_page_sec_1 What does it do? 00030 The v.42bis specification defines a data compression scheme, to work in 00031 conjunction with the error correction scheme defined in V.42. 00032 00033 \section v42bis_page_sec_2 How does it work? 00034 */ 00035 00036 #if !defined(_SPANDSP_V42BIS_H_) 00037 #define _SPANDSP_V42BIS_H_ 00038 00039 #define V42BIS_MAX_BITS 12 00040 #define V42BIS_MAX_CODEWORDS 4096 /* 2^V42BIS_MAX_BITS */ 00041 #define V42BIS_TABLE_SIZE 5021 /* This should be a prime >(2^V42BIS_MAX_BITS) */ 00042 #define V42BIS_MAX_STRING_SIZE 250 00043 00044 enum 00045 { 00046 V42BIS_P0_NEITHER_DIRECTION = 0, 00047 V42BIS_P0_INITIATOR_RESPONDER, 00048 V42BIS_P0_RESPONDER_INITIATOR, 00049 V42BIS_P0_BOTH_DIRECTIONS 00050 }; 00051 00052 enum 00053 { 00054 V42BIS_COMPRESSION_MODE_DYNAMIC = 0, 00055 V42BIS_COMPRESSION_MODE_ALWAYS, 00056 V42BIS_COMPRESSION_MODE_NEVER 00057 }; 00058 00059 typedef void (*v42bis_frame_handler_t)(void *user_data, const uint8_t *pkt, int len); 00060 typedef void (*v42bis_data_handler_t)(void *user_data, const uint8_t *buf, int len); 00061 00062 /*! 00063 V.42bis dictionary node. 00064 */ 00065 typedef struct 00066 { 00067 /*! \brief The prior code for each defined code. */ 00068 uint16_t parent_code; 00069 /*! \brief The number of leaf nodes this node has */ 00070 int16_t leaves; 00071 /*! \brief This leaf octet for each defined code. */ 00072 uint8_t node_octet; 00073 /*! \brief Bit map of the children which exist */ 00074 uint32_t children[8]; 00075 } v42bis_dict_node_t; 00076 00077 /*! 00078 V.42bis compression. This defines the working state for a single instance 00079 of V.42bis compression. 00080 */ 00081 typedef struct 00082 { 00083 /*! \brief Compression mode. */ 00084 int compression_mode; 00085 /*! \brief Callback function to handle received frames. */ 00086 v42bis_frame_handler_t handler; 00087 /*! \brief An opaque pointer passed in calls to frame_handler. */ 00088 void *user_data; 00089 /*! \brief The maximum frame length allowed */ 00090 int max_len; 00091 00092 uint32_t string_code; 00093 uint32_t latest_code; 00094 int string_length; 00095 uint32_t output_bit_buffer; 00096 int output_bit_count; 00097 int output_octet_count; 00098 uint8_t output_buf[1024]; 00099 v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; 00100 /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ 00101 int transparent; 00102 int change_transparency; 00103 /*! \brief IIR filter state, used in assessing compressibility. */ 00104 int compressibility_filter; 00105 int compressibility_persistence; 00106 00107 /*! \brief Next empty dictionary entry */ 00108 uint32_t v42bis_parm_c1; 00109 /*! \brief Current codeword size */ 00110 int v42bis_parm_c2; 00111 /*! \brief Threshold for codeword size change */ 00112 uint32_t v42bis_parm_c3; 00113 00114 /*! \brief Mark that this is the first octet/code to be processed */ 00115 int first; 00116 uint8_t escape_code; 00117 } v42bis_compress_state_t; 00118 00119 /*! 00120 V.42bis decompression. This defines the working state for a single instance 00121 of V.42bis decompression. 00122 */ 00123 typedef struct 00124 { 00125 /*! \brief Callback function to handle decompressed data. */ 00126 v42bis_data_handler_t handler; 00127 /*! \brief An opaque pointer passed in calls to data_handler. */ 00128 void *user_data; 00129 /*! \brief The maximum decompressed data block length allowed */ 00130 int max_len; 00131 00132 uint32_t old_code; 00133 uint32_t last_old_code; 00134 uint32_t input_bit_buffer; 00135 int input_bit_count; 00136 int octet; 00137 int last_length; 00138 int output_octet_count; 00139 uint8_t output_buf[1024]; 00140 v42bis_dict_node_t dict[V42BIS_MAX_CODEWORDS]; 00141 /*! \brief TRUE if we are in transparent (i.e. uncompressable) mode */ 00142 int transparent; 00143 00144 int last_extra_octet; 00145 00146 /*! \brief Next empty dictionary entry */ 00147 uint32_t v42bis_parm_c1; 00148 /*! \brief Current codeword size */ 00149 int v42bis_parm_c2; 00150 /*! \brief Threshold for codeword size change */ 00151 uint32_t v42bis_parm_c3; 00152 00153 /*! \brief Mark that this is the first octet/code to be processed */ 00154 int first; 00155 uint8_t escape_code; 00156 int escaped; 00157 } v42bis_decompress_state_t; 00158 00159 /*! 00160 V.42bis compression/decompression descriptor. This defines the working state for a 00161 single instance of V.42bis compress/decompression. 00162 */ 00163 typedef struct 00164 { 00165 /*! \brief V.42bis data compression directions. */ 00166 int v42bis_parm_p0; 00167 00168 /*! \brief Compression state. */ 00169 v42bis_compress_state_t compress; 00170 /*! \brief Decompression state. */ 00171 v42bis_decompress_state_t decompress; 00172 00173 /*! \brief Maximum codeword size (bits) */ 00174 int v42bis_parm_n1; 00175 /*! \brief Total number of codewords */ 00176 uint32_t v42bis_parm_n2; 00177 /*! \brief Maximum string length */ 00178 int v42bis_parm_n7; 00179 } v42bis_state_t; 00180 00181 #if defined(__cplusplus) 00182 extern "C" 00183 { 00184 #endif 00185 00186 /*! Compress a block of octets. 00187 \param s The V.42bis context. 00188 \param buf The data to be compressed. 00189 \param len The length of the data buffer. 00190 \return 0 */ 00191 int v42bis_compress(v42bis_state_t *s, const uint8_t *buf, int len); 00192 00193 /*! Flush out any data remaining in a compression buffer. 00194 \param s The V.42bis context. 00195 \return 0 */ 00196 int v42bis_compress_flush(v42bis_state_t *s); 00197 00198 /*! Decompress a block of octets. 00199 \param s The V.42bis context. 00200 \param buf The data to be decompressed. 00201 \param len The length of the data buffer. 00202 \return 0 */ 00203 int v42bis_decompress(v42bis_state_t *s, const uint8_t *buf, int len); 00204 00205 /*! Flush out any data remaining in the decompression buffer. 00206 \param s The V.42bis context. 00207 \return 0 */ 00208 int v42bis_decompress_flush(v42bis_state_t *s); 00209 00210 /*! Initialise a V.42bis context. 00211 \param s The V.42bis context. 00212 \param negotiated_p0 The negotiated P0 parameter, from the V.42bis spec. 00213 \param negotiated_p1 The negotiated P1 parameter, from the V.42bis spec. 00214 \param negotiated_p2 The negotiated P2 parameter, from the V.42bis spec. 00215 \param frame_handler . 00216 \param frame_user_data . 00217 \param max_frame_len The maximum length that should be passed to the frame handler. 00218 \param data_handler . 00219 \param data_user_data . 00220 \param max_data_len The maximum length that should be passed to the data handler. 00221 \return The V.42bis context. */ 00222 v42bis_state_t *v42bis_init(v42bis_state_t *s, 00223 int negotiated_p0, 00224 int negotiated_p1, 00225 int negotiated_p2, 00226 v42bis_frame_handler_t frame_handler, 00227 void *frame_user_data, 00228 int max_frame_len, 00229 v42bis_data_handler_t data_handler, 00230 void *data_user_data, 00231 int max_data_len); 00232 00233 /*! Set the compression mode. 00234 \param s The V.42bis context. 00235 \param mode One of the V.42bis compression modes - 00236 V42BIS_COMPRESSION_MODE_DYNAMIC, 00237 V42BIS_COMPRESSION_MODE_ALWAYS, 00238 V42BIS_COMPRESSION_MODE_NEVER */ 00239 void v42bis_compression_control(v42bis_state_t *s, int mode); 00240 00241 /*! Release a V.42bis context. 00242 \param s The V.42bis context. 00243 \return 0 if OK */ 00244 int v42bis_release(v42bis_state_t *s); 00245 00246 #if defined(__cplusplus) 00247 } 00248 #endif 00249 00250 #endif 00251 /*- End of file ------------------------------------------------------------*/