| | 165 | //----------------------------------------------------------------------------- |
| | 166 | // |
| | 167 | // Bitwise functions |
| | 168 | // |
| | 169 | //----------------------------------------------------------------------------- |
| | 170 | |
| | 171 | /** \brief packs octets with one bit of information into a byte |
| | 172 | |
| | 173 | */ |
| | 174 | void pack_bytes( |
| | 175 | char * input, |
| | 176 | unsigned int input_length, |
| | 177 | char * output, |
| | 178 | unsigned int output_length, |
| | 179 | unsigned int * num_written) |
| | 180 | { |
| | 181 | div_t d = div(input_length,8); |
| | 182 | unsigned int req_output_length = d.quot; |
| | 183 | req_output_length += ( d.rem > 0 ) ? 1 : 0; |
| | 184 | if ( output_length < req_output_length ) { |
| | 185 | perror("ERROR: sigprocc_pack_bytes: output too short\n"); |
| | 186 | return; |
| | 187 | } |
| | 188 | |
| | 189 | unsigned int i; |
| | 190 | unsigned int N = 0; // number of bytes written to output |
| | 191 | char byte = 0; |
| | 192 | |
| | 193 | for (i=0; i<input_length; i++) { |
| | 194 | byte |= input[i] & 0x01; |
| | 195 | |
| | 196 | if ( (i+1)%8 == 0 ) { |
| | 197 | output[N++] = byte; |
| | 198 | byte = 0; |
| | 199 | } else { |
| | 200 | byte <<= 1; |
| | 201 | } |
| | 202 | } |
| | 203 | |
| | 204 | if ( i%8 != 0 ) |
| | 205 | output[N++] = byte >> 1; |
| | 206 | |
| | 207 | *num_written = N; |
| | 208 | } |
| | 209 | |
| | 210 | |
| | 211 | |
| | 212 | void unpack_bytes( |
| | 213 | char * input, |
| | 214 | unsigned int input_length, |
| | 215 | char * output, |
| | 216 | unsigned int output_length, |
| | 217 | unsigned int * num_written) |
| | 218 | { |
| | 219 | unsigned int i; |
| | 220 | unsigned int N = 0; |
| | 221 | char byte; |
| | 222 | |
| | 223 | if ( output_length < 8*input_length ) { |
| | 224 | perror("ERROR: sigprocc_unpack_bytes: output too short\n"); |
| | 225 | return; |
| | 226 | } |
| | 227 | |
| | 228 | for (i=0; i<input_length; i++) { |
| | 229 | byte = input[i]; |
| | 230 | output[N++] = (byte >> 7) & 0x01; |
| | 231 | output[N++] = (byte >> 6) & 0x01; |
| | 232 | output[N++] = (byte >> 5) & 0x01; |
| | 233 | output[N++] = (byte >> 4) & 0x01; |
| | 234 | output[N++] = (byte >> 3) & 0x01; |
| | 235 | output[N++] = (byte >> 2) & 0x01; |
| | 236 | output[N++] = (byte >> 1) & 0x01; |
| | 237 | output[N++] = byte & 0x01; |
| | 238 | } |
| | 239 | |
| | 240 | *num_written = N; |
| | 241 | } |
| | 242 | |
| | 243 | void repack_bytes( |
| | 244 | char * input, |
| | 245 | unsigned int input_sym_size, |
| | 246 | unsigned int input_length, |
| | 247 | char * output, |
| | 248 | unsigned int output_sym_size, |
| | 249 | unsigned int output_length, |
| | 250 | unsigned int * num_written) |
| | 251 | { |
| | 252 | div_t d = div(input_length*input_sym_size,output_sym_size); |
| | 253 | unsigned int req_output_length = d.quot; |
| | 254 | req_output_length += ( d.rem > 0 ) ? 1 : 0; |
| | 255 | if ( output_length < req_output_length ) { |
| | 256 | perror("ERROR: sigprocc_repack_bytes: output too short\n"); |
| | 257 | return; |
| | 258 | } |
| | 259 | |
| | 260 | unsigned int i; |
| | 261 | char sym_in = 0; |
| | 262 | char sym_out = 0; |
| | 263 | |
| | 264 | // there is probably a more efficient way to do this, but... |
| | 265 | unsigned int total_bits = input_length*input_sym_size; |
| | 266 | unsigned int i_in = 0; // input index |
| | 267 | unsigned int i_out = 0; // output index |
| | 268 | unsigned int k=0; // input symbol enable |
| | 269 | unsigned int n=0; // output symbol enable |
| | 270 | unsigned int v; // bit mask |
| | 271 | |
| | 272 | for (i=0; i<total_bits; i++) { |
| | 273 | sym_out <<= 1; |
| | 274 | |
| | 275 | // push input if necessary |
| | 276 | if ( k == 0 ) |
| | 277 | sym_in = input[i_in++]; |
| | 278 | |
| | 279 | v = input_sym_size - k - 1; |
| | 280 | sym_out |= (sym_in >> v) & 0x01; |
| | 281 | |
| | 282 | // push output if available |
| | 283 | if ( n == output_sym_size-1 ) { |
| | 284 | output[i_out++] = sym_out; |
| | 285 | sym_out = 0; |
| | 286 | } |
| | 287 | |
| | 288 | k = (k+1) % input_sym_size; |
| | 289 | n = (n+1) % output_sym_size; |
| | 290 | } |
| | 291 | |
| | 292 | *num_written = i_out; |
| | 293 | } |
| | 294 | |