int exomizer(unsigned char *srcbuf, int len, int load, int start, unsigned char *destbuf) { int destlen; int max_offset = 65536; int max_passes = 65536; static match_ctx ctx; encode_match_data emd; encode_match_priv optimal_priv; search_nodep snp; match_ctx_init(ctx, srcbuf, len, max_offset); emd->out = NULL; emd->priv = optimal_priv; optimal_init(emd); snp = do_compress(ctx, emd, max_passes); destlen = generate_output(ctx, snp, sfx_c64ne, optimal_encode, emd, load, len, start, destbuf); optimal_free(emd); #if 0 /* RH */ search_node_free(snp); #endif /* RH */ match_ctx_free(ctx); return destlen; }
void crunch_backwards(struct membuf *inbuf, struct membuf *outbuf, struct crunch_options *options, /* IN */ struct crunch_info *info) /* OUT */ { static match_ctx ctx; encode_match_data emd; search_nodep snp; int outlen; int safety; int copy_used; if(options == NULL) { options = default_options; } outlen = membuf_memlen(outbuf); emd->out = NULL; optimal_init(emd); LOG(LOG_NORMAL, ("\nPhase 1: Instrumenting file" "\n-----------------------------\n")); LOG(LOG_NORMAL, (" Length of indata: %d bytes.\n", membuf_memlen(inbuf))); match_ctx_init(ctx, inbuf, options->max_len, options->max_offset, options->use_imprecise_rle); LOG(LOG_NORMAL, (" Instrumenting file, done.\n")); emd->out = NULL; optimal_init(emd); LOG(LOG_NORMAL, ("\nPhase 2: Calculating encoding" "\n-----------------------------\n")); snp = do_compress(ctx, emd, options->exported_encoding, options->max_passes, options->use_literal_sequences); LOG(LOG_NORMAL, (" Calculating encoding, done.\n")); LOG(LOG_NORMAL, ("\nPhase 3: Generating output file" "\n------------------------------\n")); LOG(LOG_NORMAL, (" Encoding: %s\n", optimal_encoding_export(emd))); safety = do_output(ctx, snp, emd, optimal_encode, outbuf, ©_used); LOG(LOG_NORMAL, (" Length of crunched data: %d bytes.\n", membuf_memlen(outbuf) - outlen)); optimal_free(emd); search_node_free(snp); match_ctx_free(ctx); if(info != NULL) { info->literal_sequences_used = copy_used; info->needed_safety_offset = safety; } }
search_nodep do_compress(match_ctx ctx, encode_match_data emd, const char *exported_encoding, int max_passes, int use_literal_sequences) { matchp_cache_enum mpce; matchp_snp_enum snpe; search_nodep snp; search_nodep best_snp; int pass; float size; float old_size; char prev_enc[100]; const char *curr_enc; pass = 1; prev_enc[0] = '\0'; LOG(LOG_NORMAL, (" pass %d: ", pass)); if(exported_encoding != NULL) { LOG(LOG_NORMAL, ("importing %s\n", exported_encoding)); optimal_encoding_import(emd, exported_encoding); } else { LOG(LOG_NORMAL, ("optimizing ..\n")); matchp_cache_get_enum(ctx, mpce); optimal_optimize(emd, matchp_cache_enum_get_next, mpce); } best_snp = NULL; old_size = 100000000.0; for (;;) { snp = search_buffer(ctx, optimal_encode, emd, use_literal_sequences); if (snp == NULL) { LOG(LOG_ERROR, ("error: search_buffer() returned NULL\n")); exit(-1); } size = snp->total_score; LOG(LOG_NORMAL, (" size %0.1f bits ~%d bytes\n", size, (((int) size) + 7) >> 3)); if (size >= old_size) { search_node_free(snp); break; } if (best_snp != NULL) { search_node_free(best_snp); } best_snp = snp; old_size = size; ++pass; if(pass > max_passes) { break; } optimal_free(emd); optimal_init(emd); LOG(LOG_NORMAL, (" pass %d: optimizing ..\n", pass)); matchp_snp_get_enum(snp, snpe); optimal_optimize(emd, matchp_snp_enum_get_next, snpe); curr_enc = optimal_encoding_export(emd); if (strcmp(curr_enc, prev_enc) == 0) { break; } strcpy(prev_enc, curr_enc); } return best_snp; }
static search_nodep do_compress(match_ctx ctx, encode_match_data emd, int max_passes) { matchp_cache_enum mpce; matchp_snp_enum snpe; search_nodep snp; search_nodep best_snp; int pass; float old_size; pass = 1; matchp_cache_get_enum(ctx, mpce); optimal_optimize(emd, matchp_cache_enum_get_next, mpce); best_snp = NULL; old_size = 1000000.0; for (;;) { snp = search_buffer(ctx, optimal_encode, emd); if (snp == NULL) { fprintf(stderr, "error: search_buffer() returned NULL\n"); exit(-1); } float size = snp->total_score; if (size >= old_size) { #if 0 /* RH */ search_node_free(snp); #endif /* RH */ break; } #if 0 /* RH */ if (best_snp != NULL) { search_node_free(best_snp); } #endif /* RH */ best_snp = snp; old_size = size; ++pass; if (pass > max_passes) { break; } optimal_free(emd); optimal_init(emd); matchp_snp_get_enum(snp, snpe); optimal_optimize(emd, matchp_snp_enum_get_next, snpe); } return best_snp; }