2 Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.
3 Permission is granted to make verbatim copies of this program for private
4 use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.
6 This file is: "unppmc.c"
7 Email: arturo@arturocampos.com
8 Web: http://www.arturocampos.com
11 Part of the ppmc decoder.
13 This module is the main module and calls the different modules to do
14 the decoding of a file. When done prints kbyps.
18 // Bibliotecas necesarias
21 #include "range.h" //the range coder functions and data
25 // Declaracion de funciones del ppmcmain.c
26 long filesize(FILE *stream);
32 void main (int argc, char *argv[])
34 unsigned long counter, //temporal counter for loops like for or while
35 counter2, //another temporal counter for sub loops
36 size_file_output, //the size of the output file
37 main_counter; //used in main
38 char expected_flush=0; //used for checking flushing which can't be done
41 // Print title, version and copyright
42 printf("UNPPMC using range coder.\n");
43 printf("Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.\n");
44 printf("Permission is granted to make verbatim copies of this program for private\n");
45 printf("use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.\n");
49 // Check for correct number of parameters
52 printf("Bad number of arguments.\n");
57 // Try to open input and output files
58 if((file_input=fopen(argv[1],"r+b"))==NULL)
60 printf("Couldn't open %s.\n",argv[1]);
64 if((file_output=fopen(argv[2],"w+b"))==NULL)
66 printf("Couldn't create %s.\n",argv[2]);
72 fread(&size_file_output,1,4,file_input);
75 // Initialize ppmc decoder
77 ppmc_initialize_contexts();
78 ppmc_decoder_initialize();
83 range_decoder_init(&rc_decoder,file_input);
86 // Start main loop which decodes the file
87 main_counter=size_file_output-4; //take in account the bytes already written
88 expected_flush=0; //we don't expect a flush yet
90 while(main_counter!=0)
93 // Try to decode current byte in order-4 if possible, else in lower ones
102 ppmc_decode_order1();
105 ppmc_decode_order0();
106 if(byte==-1) //check if it was an escape code
108 // Decode in order-(-1)
109 ppmc_get_totf_ordern1();
110 symb_cump=range_decoder_decode(&rc_decoder,total_cump);
111 byte=ppmc_get_symbol_ordern1();
112 ppmc_get_prob_ordern1();
113 range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
114 coded_in_order=0; //update all orders
116 // Now see if it's the code of flushing
120 printf("Flushing.\n");
121 ppmc_flush_mem_dec();
123 continue; //do not output byte nor update
131 // Output byte and update model
133 fputc(byte,file_output);
135 switch(coded_in_order) //update exclusion
137 case 0: ppmc_update_order0(); //update only order-0
138 case 1: ppmc_update_order1(); //update order-0 and order-1
139 case 2: ppmc_update_dec_order2(); //update order-0 1 and 2
140 case 3: ppmc_update_dec_order3();
141 case 4: ppmc_update_dec_order4();
146 // Check if flushing has to be done and has not been done.
147 // This is optional, in case you limit the memory usage, you don't
148 // need to include this
150 if(expected_flush==1) // If flushing didn't happen, we can't decode
152 printf("Can't decompress file. Not enough memory.\nTry in a machine with more memory.\n");
155 if(ppmc_out_of_memory==1)
157 expected_flush=1; // Next code must be a flush code, otherwise we don't
158 // have enough memory, and therefore we can't decode
162 // Update order variables
167 o1_byte=byte; //current one, is next time order-1
169 // Byte decoded and model updated, loop
178 // Close file handles and free memory
188 // Ruotines not used by ppmc but rather by main.
189 // Not including the range coder.
192 // Returns the file size of a given file.
193 long filesize(FILE *stream)
197 curpos = ftell(stream);
198 fseek(stream, 0L, SEEK_END);
199 length = ftell(stream);
200 fseek(stream, curpos, SEEK_SET);