int main(int argc, char *argv[]) { int len; v42bis_state_t state_a; v42bis_state_t state_b; uint8_t buf[1024]; int in_fd; int v42bis_fd; int out_fd; int do_compression; int do_decompression; time_t now; do_compression = TRUE; do_decompression = TRUE; if (argc < 2) { fprintf(stderr, "Usage: %s <file>\n", argv[0]); exit(2); } if (do_compression) { if ((in_fd = open(argv[1], O_RDONLY)) < 0) { fprintf(stderr, "Error opening file '%s'.\n", argv[1]); exit(2); } if ((v42bis_fd = open(COMPRESSED_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { fprintf(stderr, "Error opening file '%s'.\n", COMPRESSED_FILE_NAME); exit(2); } time(&now); v42bis_init(&state_a, 3, 512, 6, frame_handler, (void *) (intptr_t) v42bis_fd, 512, data_handler, NULL, 512); v42bis_compression_control(&state_a, V42BIS_COMPRESSION_MODE_ALWAYS); in_octets_to_date = 0; out_octets_to_date = 0; while ((len = read(in_fd, buf, 1024)) > 0) { if (v42bis_compress(&state_a, buf, len)) { fprintf(stderr, "Bad return code from compression\n"); exit(2); } in_octets_to_date += len; } v42bis_compress_flush(&state_a); printf("%d bytes compressed to %d bytes in %lds\n", in_octets_to_date, out_octets_to_date, time(NULL) - now); close(in_fd); close(v42bis_fd); } if (do_decompression) { /* Now open the files for the decompression. */ if ((v42bis_fd = open(COMPRESSED_FILE_NAME, O_RDONLY)) < 0) { fprintf(stderr, "Error opening file '%s'.\n", COMPRESSED_FILE_NAME); exit(2); } if ((out_fd = open(OUTPUT_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { fprintf(stderr, "Error opening file '%s'.\n", OUTPUT_FILE_NAME); exit(2); } time(&now); v42bis_init(&state_b, 3, 512, 6, frame_handler, (void *) (intptr_t) v42bis_fd, 512, data_handler, (void *) (intptr_t) out_fd, 512); in_octets_to_date = 0; out_octets_to_date = 0; while ((len = read(v42bis_fd, buf, 1024)) > 0) { if (v42bis_decompress(&state_b, buf, len)) { fprintf(stderr, "Bad return code from decompression\n"); exit(2); } in_octets_to_date += len; } v42bis_decompress_flush(&state_b); printf("%d bytes decompressed to %d bytes in %lds\n", in_octets_to_date, out_octets_to_date, time(NULL) - now); close(v42bis_fd); close(out_fd); } return 0; }
/* Compress a packet using V.42bis data compression */ static int v42bis_compress_unitdata(uint8_t *pcomp_index, uint8_t *data, unsigned int len, v42bis_state_t *comp) { /* Note: This implementation may only be used to compress SN_UNITDATA * packets, since it resets the compression state for each NPDU. */ uint8_t *data_o; int rc; int skip = 0; struct v42bis_output_buffer compressed_data; /* Don't bother with short packets */ if (len < MIN_COMPR_PAYLOAD) skip = 1; /* Skip if compression is not enabled for TX direction */ if (!comp->compress.v42bis_parm_p0) skip = 1; /* Skip compression */ if (skip) { *pcomp_index = 0; return len; } /* Reset V.42bis compression state */ v42bis_reset(comp); /* Run compressor */ data_o = talloc_zero_size(comp, len * MAX_DATADECOMPR_FAC); compressed_data.buf = data_o; compressed_data.buf_pointer = data_o; compressed_data.len = 0; comp->compress.user_data = (&compressed_data); rc = v42bis_compress(comp, data, len); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "Data compression failed, skipping...\n"); skip = 1; } rc = v42bis_compress_flush(comp); if (rc < 0) { LOGP(DSNDCP, LOGL_ERROR, "Data compression failed, skipping...\n"); skip = 1; } /* The compressor might yield negative compression gain, in * this case, we just decide to send the packat as normal, * uncompressed payload => skip compresssion */ if (compressed_data.len >= len) { LOGP(DSNDCP, LOGL_ERROR, "Data compression ineffective, skipping...\n"); skip = 1; } /* Skip compression */ if (skip) { *pcomp_index = 0; talloc_free(data_o); return len; } *pcomp_index = 1; memcpy(data, data_o, compressed_data.len); talloc_free(data_o); return compressed_data.len; }