]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - src/ppmc/unppmc.c
Se agrega documentación y una implementación de prueba de PPMC.
[z.facultad/75.06/jacu.git] / src / 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