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