]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - examples/ppmc/unppmc.c
leak
[z.facultad/75.06/jacu.git] / examples / ppmc / unppmc.c
1 /*
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.
5
6    This file is: "unppmc.c"
7 Email: arturo@arturocampos.com
8 Web: http://www.arturocampos.com
9
10
11 Part of the ppmc decoder.
12
13 This module is the main module and calls the different modules to do
14 the decoding of a file. When done prints kbyps.
15 */
16
17
18 // Bibliotecas necesarias
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include "range.h"      //the range coder functions and data
22 #include "ppmcdata.h"
23
24
25 // Declaracion de funciones del ppmcmain.c
26 long filesize(FILE *stream);
27
28
29
30
31 //Main
32 void main (int argc, char *argv[])
33 {
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
39
40
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");
46
47
48
49         // Check for correct number of parameters
50         if(argc!=3)
51         {
52                 printf("Bad number of arguments.\n");
53                 exit(1);
54         }
55
56
57         // Try to open input and output files
58         if((file_input=fopen(argv[1],"r+b"))==NULL)
59         {
60                 printf("Couldn't open %s.\n",argv[1]);
61                 exit(1);
62         }
63
64         if((file_output=fopen(argv[2],"w+b"))==NULL)
65         {
66                 printf("Couldn't create %s.\n",argv[2]);
67                 exit(1);
68         }
69
70
71         // Get output length
72         fread(&size_file_output,1,4,file_input);
73
74
75         // Initialize ppmc decoder
76         ppmc_alloc_memory();
77         ppmc_initialize_contexts();
78         ppmc_decoder_initialize();
79
80
81
82         // Initialize decoder
83         range_decoder_init(&rc_decoder,file_input);
84
85
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
89
90         while(main_counter!=0)
91         {
92
93                 // Try to decode current byte in order-4 if possible, else in lower ones
94                 ppmc_decode_order4();
95                 if(byte==-1)
96                         ppmc_decode_order3();
97                 if(byte==-1)
98                 {
99                         ppmc_decode_order2();
100                         if(byte==-1)
101                         {
102                                 ppmc_decode_order1();
103                                 if(byte==-1)
104                                 {
105                                         ppmc_decode_order0();
106                                         if(byte==-1)         //check if it was an escape code
107                                         {
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
115
116                                                 // Now see if it's the code of flushing
117
118                                                 if(symb_cump==256)
119                                                 {
120                                                         printf("Flushing.\n");
121                                                         ppmc_flush_mem_dec();
122                                                         expected_flush=0;
123                                                         continue;            //do not output byte nor update
124                                                 }
125
126                                         }
127                                 }
128                         }
129                 }
130
131                 // Output byte and update model
132
133                 fputc(byte,file_output);
134
135                 switch(coded_in_order) //update exclusion
136                 {
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();
142                         default: break;
143                 };
144
145
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
149
150                 if(expected_flush==1)  // If flushing didn't happen, we can't decode
151                 {
152                         printf("Can't decompress file. Not enough memory.\nTry in a machine with more memory.\n");
153                         exit(1);
154                 }
155                 if(ppmc_out_of_memory==1)
156                 {
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
159                 }
160
161
162                 // Update order variables
163
164                 o4_byte=o3_byte;
165                 o3_byte=o2_byte;
166                 o2_byte=o1_byte;
167                 o1_byte=byte;  //current one, is next time order-1
168
169                 // Byte decoded and model updated, loop
170                 main_counter--;
171
172
173         }
174
175
176         ppmc_free_memory();
177
178         // Close file handles and free memory
179         fclose(file_input);
180         fclose(file_output);
181
182
183         // Nicely exit
184         exit(0);
185 }
186
187
188 // Ruotines not used by ppmc but rather by main.
189 // Not including the range coder.
190
191
192 // Returns the file size of a given file.
193 long filesize(FILE *stream)
194 {
195         long curpos, length;
196
197         curpos = ftell(stream);
198         fseek(stream, 0L, SEEK_END);
199         length = ftell(stream);
200         fseek(stream, curpos, SEEK_SET);
201         return length;
202 }
203
204