2 Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.
3 Permission is granted to make verbatim copies of this file for private
4 use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.
6 This file is: "unppmc.c" (exclusion)
7 Email: arturo@arturocampos.com
8 Web: http://www.arturocampos.com
10 Part of the ppmc decoder.
12 This module is the main module and calls the different modules to do
13 the decoding of a file. When done prints kbyps.
17 // Bibliotecas necesarias
20 #include "range.h" //the range coder functions and data
24 // Declaracion de funciones del ppmcmain.c
25 long filesize(FILE *stream);
31 void main (int argc, char *argv[])
33 unsigned long counter, //temporal counter for loops like for or while
34 counter2, //another temporal counter for sub loops
35 size_file_output, //the size of the output file
36 main_counter; //used in main
37 char expected_flush=0; //used for checking flushing which can't be done
40 // Print title and version.
41 printf("UNPPMC using range coder.\n");
42 printf("Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.\n");
43 printf("Permission is granted to make verbatim copies of this program for private\n");
44 printf("use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.\n");
47 // Check for correct number of parameters
50 printf("Bad number of arguments.\n");
55 // Try to open input and output files
56 if((file_input=fopen(argv[1],"r+b"))==NULL)
58 printf("Couldn't open %s.\n",argv[1]);
62 if((file_output=fopen(argv[2],"w+b"))==NULL)
64 printf("Couldn't create %s.\n",argv[2]);
70 fread(&size_file_output,1,4,file_input);
73 // Initialize ppmc decoder
75 ppmc_initialize_contexts();
76 ppmc_decoder_initialize();
81 range_decoder_init(&rc_decoder,file_input);
84 // Start main loop which decodes the file
85 main_counter=size_file_output-4; //take in account the bytes already written
86 expected_flush=0; //we don't expect a flush yet
88 while(main_counter!=0)
91 // Clear exclusion table
92 for(counter=0;counter!=256;++counter)
95 // Try to decode current byte in order-4 if possible, else in lower ones
101 ppmc_decode_order2();
104 ppmc_decode_order1();
107 ppmc_decode_order0();
108 if(byte==-1) //check if it was an escape code
110 // Decode in order-(-1)
111 ppmc_get_totf_ordern1();
112 symb_cump=range_decoder_decode(&rc_decoder,total_cump);
113 byte=ppmc_get_symbol_ordern1();
114 ppmc_get_prob_ordern1();
115 range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
116 coded_in_order=0; //update all orders
118 // Now see if it's the code of flushing
122 printf("Flushing.\n");
123 ppmc_flush_mem_dec();
125 continue; //do not output byte nor update
133 // Output byte and update model
135 fputc(byte,file_output);
137 switch(coded_in_order) //update exclusion
139 case 0: ppmc_update_order0(); //update only order-0
140 case 1: ppmc_update_order1(); //update order-0 and order-1
141 case 2: ppmc_update_dec_order2(); //update order-0 1 and 2
142 case 3: ppmc_update_dec_order3();
143 case 4: ppmc_update_dec_order4();
148 // Check if flushing has to be done and has not been done.
149 // This is optional, in case you limit the memory usage, you don't
150 // need to include this
152 if(expected_flush==1) // If flushing didn't happen, we can't decode
154 printf("Can't decompress file. Not enough memory.\nTry in a machine with more memory.\n");
157 if(ppmc_out_of_memory==1)
159 expected_flush=1; // Next code must be a flush code, otherwise we don't
160 // have enough memory, and therefore we can't decode
164 // Update order variables
169 o1_byte=byte; //current one, is next time order-1
171 // Byte decoded and model updated, loop
174 //printf("\n%d",size_file_output-main_counter);
181 // Close file handles and free memory
193 // Ruotines not used by ppmc but rather by main.
194 // Not including the range coder.
197 // Returns the file size of a given file.
198 long filesize(FILE *stream)
202 curpos = ftell(stream);
203 fseek(stream, 0L, SEEK_END);
204 length = ftell(stream);
205 fseek(stream, curpos, SEEK_SET);