📄 main.c
字号:
"but the data file was compressed with F_bits=%i, B_bits=%i.\n", F_bits, B_bits, f1, b1); exit(1); } }#endif if (B_bits - F_bits < 2) { fprintf(stderr,"Corrupt input file; B_bits - F_bits < 2\n"); exit(1); } if (model[method].needs_mem) { /* read memory limit to be used and store in mbytes */ mbytes = INPUT_BYTE(); } if (verbose) describe_setup(method); model[method].decode(); /* Call DECODER */ } /* statistics section if using verbose flag */ if (verbose) { print_results(selected, method); } return 0; /* exited cleanly */}/* * Ensure encoding options are only specifed after a '-e' on the command * line, more to point, ensure they are only used for encoding */static void encode_only(char *str1, int selected, char **argv){ if (selected!=ENCODE) { fprintf(stderr, "%s is defined by the encoder,\n" "and can not be specified by the decoder.\n" "('-e' is required on command line before any encode options)\n", str1); usage(argv[0]); } }/* * If argv[0] matches one of the methods in the list, return it, else * return -1. Used so that the program name name can determine the * default compression model. */static int determine_model(char *arg0){ char *progname; int i; progname = arg0; /* Ignore pathname */ if (strrchr(progname, '/') != NULL) progname = strrchr(progname, '/') + 1; i = 0; while (model[i].name != NULL && strcmp(progname, model[i].name) != 0) i++; /* If no names in list match progname, see if they are * contained within progname, eg: 'bits1' would match 'bits' */ if (model[i].name == NULL) { for (i=0; model[i].name != NULL; i++) if (strstr(progname, model[i].name) != NULL) break; } /* Return -1 if no matching model */ if (model[i].name == NULL) return -1; return i;}/* * decode_magic(str1) * Search through the magic numbers for the coding methods, trying to * match with str1. Return coding method if found, else exit program. */static int decode_magic(unsigned char *str1){ int i = 0; while (model[i].name != NULL && memcmp(str1, model[i].magic, MAGICNO_LENGTH) != 0) i++; if (model[i].name == NULL) { fprintf(stderr, "Bad Magic Number\n"); exit(1); } return i;}/* * usage(argv[0]) */static void usage(char *str1){ int default_method; char model_list[1024]; char freq_string[127]; char code_string[127]; int i; /* Build up a list of models. Ie: "char, bits, word" */ model_list[0]='\0'; strcpy(model_list, model[0].name); for (i = 1; model[i].name!=NULL; i++) { strcat(model_list, ", "); strcat(model_list, model[i].name); }#if defined(VARY_NBITS) sprintf(freq_string,"%i..%i, default = %i",1, MAX_F_BITS, F_bits); sprintf(code_string,"%i..%i, default = %i",3, MAX_B_BITS, B_bits);#else sprintf(freq_string,"%i, fixed at compile time", F_bits); sprintf(code_string,"%i, fixed at compile time", B_bits);#endif /* Determine which is the default method, so can tell user */ default_method = determine_model(str1); if (default_method == -1) default_method = determine_model(DEFAULT_MODEL); if (default_method == -1) default_method = 0; fprintf(stderr, "\nUsage: " "%s [-e [-t s] [-f n] [-b n] [-m n] [-c n] | -d] [-v] [file]\n\n", str1); fprintf(stderr, "-e: Encode\n" " -t s Encoding method (%s, default = %s)\n" " -b n Code bits to use (%s)\n" " -f n Frequency bits to use (%s)\n" " -m n Memory size to use (Mbytes) (%i..%i, default = %i)" " bits & word\n" " -c n Bits of context to use (%i..%i, default = %i)" " bits only\n" "-d: Decode\n" "-v: Verbose Give timing, compression, and memory " "usage information.\n\n", model_list, model[default_method].name, code_string, freq_string, MIN_MBYTES, MAX_MBYTES, DEFAULT_MEM, MIN_CONTEXT_BITS, MAX_CONTEXT_BITS, DEFAULT_BITS_CONTEXT ); if (verbose) { fprintf(stderr,"Version: %s\n\n",VERSION); describe_setup(-1); } exit(1);}/* * Describe setup for 'method', or in general if method < 0 */static void describe_setup(int method){ if (method>=0) fprintf(stderr,"Model : %s\n",model[method].desc); fprintf(stderr,"Stats : %s\n",stats_desc); fprintf(stderr,"Coder : %s\n",coder_desc);#if defined(VARY_NBITS) if (method >= 0) { fprintf(stderr,"Code bits : %10i\n", B_bits); fprintf(stderr,"Frequency bits : %10i\n", F_bits); }#else fprintf(stderr,"Code bits : %10i (Fixed)\n", B_bits); fprintf(stderr,"Frequency bits : %10i (Fixed)\n", F_bits);#endif if (method >= 0 && model[method].needs_mem) fprintf(stderr,"Memory limit : %10i Mb\n",mbytes);}/* * * print the results of compressing/decompressing a file * */static void print_results(int operation, int method){ int bytes_compressed, bytes_uncompressed; if (operation == ENCODE) { bytes_compressed = bitio_bytes_out(); bytes_uncompressed = bitio_bytes_in(); } else { bytes_compressed = bitio_bytes_in(); bytes_uncompressed = bitio_bytes_out(); } fprintf(stderr,"Uncompressed : %10u bytes\n", bytes_uncompressed); fprintf(stderr,"Compressed : %10u bytes\n", bytes_compressed); if (bytes_uncompressed > 0) fprintf(stderr, "Compression rate : %10.3f bpc (%0.2f%%) \n", 8.0 * bytes_compressed / bytes_uncompressed, (float)bytes_compressed/bytes_uncompressed*100); /* only provide timing details if "times()" function is available */ /* Give kb/s in terms of uncompressed data */#ifdef SYSV { struct tms cpu_usage; float cpu_used, comp_rate; times(&cpu_usage); /* determine the cpu time used */ cpu_used = ((float) cpu_usage.tms_utime) / sysconf(_SC_CLK_TCK); if (cpu_used == 0) comp_rate = 0; else { comp_rate = ((float) bytes_uncompressed) / (1024 * cpu_used); } fprintf(stderr, "Compression time : %10.2f seconds (%0.2f Kb/s)\n", cpu_used, comp_rate); }#endif if (model[method].needs_mem) { if (model[method].purge_mem) { fprintf(stderr, "Memory purges : %10d time%s\n", purge_counter, (purge_counter == 1 ? "" : "s") ); } /* Count peak memory usage, even if later purged */ if (peak_memory > total_memory) total_memory = peak_memory; fprintf(stderr, "Peak memory used : %10.1f Kbytes\n", total_memory*1.0/1024); } /* Call per model method results if they exist */ if (model[method].results != NULL) model[method].results(operation);}/************************************************************************//* * Memory Routines. Used by word.c and bits.c. They malloc, realloc, purge * and reserve memory as required, while staying within the specified * memory limit (artificially returns NULL if would exceed memory * limit). *//* * * call the standard C function realloc after checking that the memory * limit isn't exceeded. If limit is exceeded return NULL * */void *do_realloc(void *ptr, size_t size){ if (((total_memory+size) / MEGABYTE) >= mbytes) return NULL; total_memory += size; return (realloc(ptr, size));}/* * * call the standard C function malloc after checking against the memory * limit. If the limit is exceeded return NULL * */void *do_malloc(size_t size){ if (((total_memory+size) / MEGABYTE) >= mbytes) return NULL; total_memory += size; return (malloc(size));}/* * * adds specified memory to current memory count * returns total bytes now allocated if successful, NOMEMLEFT if memory limit * is reached */int get_memory(size_t size){ if (((total_memory+size) / MEGABYTE) >= mbytes) return NOMEMLEFT; total_memory += size; return total_memory;}/* * Clear memory counter (assume free() already done by calling routine) * */void purge_memory(void){ if (total_memory > peak_memory) peak_memory = total_memory; total_memory = 0; purge_counter++;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -