// initialized now.
void ppmc_alloc_memory(void)
{
- unsigned long counter;
+ unsigned long counter;
- // Init mempool buffers
+ // Init mempool buffers
- for(counter=0;counter!=_mempool_max_index;++counter)
- {
- _bytes_pool_array[counter]=0;
- _context_pool_array[counter]=0;
- }
+ for(counter=0;counter!=_mempool_max_index;++counter)
+ {
+ _bytes_pool_array[counter]=0;
+ _context_pool_array[counter]=0;
+ }
- _bytes_pool_index=1; //first entry will be used now
- _context_pool_index=1;
+ _bytes_pool_index=1; //first entry will be used now
+ _context_pool_index=1;
- // Allocate memory for ppmc structures and adjust some variables
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ // Allocate memory for ppmc structures and adjust some variables
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- //save pointers in the array for freeing
- _bytes_pool_array[0]=_bytes_pool;
- _context_pool_array[0]=_context_pool;
+ //save pointers in the array for freeing
+ _bytes_pool_array[0]=_bytes_pool;
+ _context_pool_array[0]=_context_pool;
- //adjust variables
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements;
- _context_pool_max=_context_pool+_context_pool_elements;
+ //adjust variables
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements;
+ _context_pool_max=_context_pool+_context_pool_elements;
- ppmc_out_of_memory=0; //we still have memory
+ ppmc_out_of_memory=0; //we still have memory
}
// those who care about the number of bytes defined in a context.
void ppmc_initialize_contexts(void)
{
- unsigned long counter, counter2;
+ unsigned long counter, counter2;
- // Order-0
- for(counter=0;counter!=256;++counter) //clear table
- order0_array[counter]=0;
+ // Order-0
+ for(counter=0;counter!=256;++counter) //clear table
+ order0_array[counter]=0;
- order0_defined_bytes=0; //adjust variables
- order0_max_cump=0;
+ order0_defined_bytes=0; //adjust variables
+ order0_max_cump=0;
- // Order-1
- for(counter=0;counter!=256;++counter) //erase every table of every context
- for(counter2=0;counter2!=256;++counter2)
- order1_array[counter][counter2]=0;
+ // Order-1
+ for(counter=0;counter!=256;++counter) //erase every table of every context
+ for(counter2=0;counter2!=256;++counter2)
+ order1_array[counter][counter2]=0;
- for(counter=0;counter!=256;++counter) //adjust variables
- {
- order1_defined_bytes_array[counter]=0;
- order1_max_cump_array[counter]=0;
- }
+ for(counter=0;counter!=256;++counter) //adjust variables
+ {
+ order1_defined_bytes_array[counter]=0;
+ order1_max_cump_array[counter]=0;
+ }
- // Order-2
- for(counter=0;counter!=65536;++counter)
- {
- //order2_array[counter].prob=0; //clear pointer to bytes and frequencies
- //order2_array[counter].max_cump=0;
- order2_array[counter].defined_bytes=0;
- }
+ // Order-2
+ for(counter=0;counter!=65536;++counter)
+ {
+ //order2_array[counter].prob=0; //clear pointer to bytes and frequencies
+ //order2_array[counter].max_cump=0;
+ order2_array[counter].defined_bytes=0;
+ }
- // Order-4-3
- for(counter=0;counter!=65536;++counter) //order-4-3
- {
- order4_hasht[counter]=0;
- order3_hasht[counter]=0;
- }
+ // Order-4-3
+ for(counter=0;counter!=65536;++counter) //order-4-3
+ {
+ order4_hasht[counter]=0;
+ order3_hasht[counter]=0;
+ }
}
void ppmc_encoder_initialize(void)
{
- // Initialize order-0 and prepare different bytes for orders
- fputc((byte=fgetc(file_input)),file_output);
- o4_byte=byte; //order-4
+ // Initialize order-0 and prepare different bytes for orders
+ fputc((byte=fgetc(file_input)),file_output);
+ o4_byte=byte; //order-4
- fputc((byte=fgetc(file_input)),file_output);
- o3_byte=byte; //order-3
+ fputc((byte=fgetc(file_input)),file_output);
+ o3_byte=byte; //order-3
- fputc((byte=fgetc(file_input)),file_output);
- o2_byte=byte; //order-2
- ppmc_update_order0();
+ fputc((byte=fgetc(file_input)),file_output);
+ o2_byte=byte; //order-2
+ ppmc_update_order0();
- fputc((byte=fgetc(file_input)),file_output);
- o1_byte=byte;
+ fputc((byte=fgetc(file_input)),file_output);
+ o1_byte=byte;
}
void ppmc_decoder_initialize(void)
{
- // Initialize order-0 and context bytes
- byte=fgetc(file_input);
- o4_byte=byte; //order-4
- fputc(byte,file_output);
+ // Initialize order-0 and context bytes
+ byte=fgetc(file_input);
+ o4_byte=byte; //order-4
+ fputc(byte,file_output);
- byte=fgetc(file_input);
- o3_byte=byte; //order-3
- fputc(byte,file_output);
+ byte=fgetc(file_input);
+ o3_byte=byte; //order-3
+ fputc(byte,file_output);
- byte=fgetc(file_input);
- o2_byte=byte; //order-2
+ byte=fgetc(file_input);
+ o2_byte=byte; //order-2
- fputc(byte,file_output); //output first byte
- ppmc_update_order0();
+ fputc(byte,file_output); //output first byte
+ ppmc_update_order0();
- byte=fgetc(file_input);
- o1_byte=byte; //order-1
- fputc(byte,file_output);
+ byte=fgetc(file_input);
+ o1_byte=byte; //order-1
+ fputc(byte,file_output);
}
// It must be called when done.
void ppmc_free_memory(void)
{
- unsigned long counter;
+ unsigned long counter;
- // Free the memory buffers
+ // Free the memory buffers
- for(counter=0;counter!=_mempool_max_index;++counter)
- {
- if(_bytes_pool_array[counter]!=0)
- free(_bytes_pool_array[counter]);
+ for(counter=0;counter!=_mempool_max_index;++counter)
+ {
+ if(_bytes_pool_array[counter]!=0)
+ free(_bytes_pool_array[counter]);
- if(_context_pool_array[counter]!=0)
- free(_context_pool_array[counter]);
- }
+ if(_context_pool_array[counter]!=0)
+ free(_context_pool_array[counter]);
+ }
}
void ppmc_flush_mem_enc(void)
{
- // Code an escape code in order-4
- if(ppmc_get_totf_order4()!=0) //if 0 no need of escape code
- {
+ // Code an escape code in order-4
+ if(ppmc_get_totf_order4()!=0) //if 0 no need of escape code
+ {
- ppmc_get_escape_prob_order4(); //get prob and cump
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order4(); //get prob and cump
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- }
+ }
- // Code an escape code in order-3
- if(ppmc_get_totf_order3()!=0) //if 0 no need of escape code
- {
+ // Code an escape code in order-3
+ if(ppmc_get_totf_order3()!=0) //if 0 no need of escape code
+ {
- ppmc_get_escape_prob_order3(); //get prob and cump
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order3(); //get prob and cump
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- }
+ }
- // Code an escape code in order-2
+ // Code an escape code in order-2
- o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
+ o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
- // First check if current order-2 context is empty
- if(order2_array[o2_cntxt].defined_bytes!=0) //it's not empty
- {
- ppmc_get_totf_order2();
- ppmc_get_escape_prob_order2();
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- }
+ // First check if current order-2 context is empty
+ if(order2_array[o2_cntxt].defined_bytes!=0) //it's not empty
+ {
+ ppmc_get_totf_order2();
+ ppmc_get_escape_prob_order2();
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ }
- // Code an escape code in order-1
+ // Code an escape code in order-1
- // First check if current order-1 table is empty
- if(order1_defined_bytes_array[o1_byte]!=0) //it's not empty
- {
- ppmc_get_totf_order1();
- ppmc_get_escape_prob_order1();
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- }
+ // First check if current order-1 table is empty
+ if(order1_defined_bytes_array[o1_byte]!=0) //it's not empty
+ {
+ ppmc_get_totf_order1();
+ ppmc_get_escape_prob_order1();
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ }
- // Code an escape code in order-0. Order-0 always has at least one symbol
+ // Code an escape code in order-0. Order-0 always has at least one symbol
- ppmc_get_totf_order0();
- ppmc_get_escape_prob_order0();
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ ppmc_get_totf_order0();
+ ppmc_get_escape_prob_order0();
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- // Now we can code the code 256
+ // Now we can code the code 256
- symb_prob=1;
- symb_cump=256;
- total_cump=257;
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ symb_prob=1;
+ symb_cump=256;
+ total_cump=257;
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- // Now that decoder knows the flushing, free memory and reinit
+ // Now that decoder knows the flushing, free memory and reinit
- ppmc_free_memory();
- ppmc_alloc_memory();
- ppmc_initialize_contexts();
+ ppmc_free_memory();
+ ppmc_alloc_memory();
+ ppmc_initialize_contexts();
- // Be sure that order-0 has at least one probability
+ // Be sure that order-0 has at least one probability
- order0_array[o1_byte]++;
- order0_max_cump++;
- order0_defined_bytes++;
+ order0_array[o1_byte]++;
+ order0_max_cump++;
+ order0_defined_bytes++;
}
void ppmc_flush_mem_dec(void)
{
- // Free memory and reinit
+ // Free memory and reinit
- ppmc_free_memory();
- ppmc_alloc_memory();
- ppmc_initialize_contexts();
+ ppmc_free_memory();
+ ppmc_alloc_memory();
+ ppmc_initialize_contexts();
- // Be sure that order-0 has at least one probability
+ // Be sure that order-0 has at least one probability
- order0_array[o1_byte]++;
- order0_max_cump++;
- order0_defined_bytes++;
+ order0_array[o1_byte]++;
+ order0_max_cump++;
+ order0_defined_bytes++;
}
// Gets the probability for a given symbol in the order-(-1) (ordern1)
void ppmc_get_prob_ordern1(void)
{
- symb_cump=byte; //its value
- symb_prob=1; //flat probability
- total_cump=257; //total cump
+ symb_cump=byte; //its value
+ symb_prob=1; //flat probability
+ total_cump=257; //total cump
}
// order-(-1)
void ppmc_get_totf_ordern1(void)
{
- total_cump=257; //this is fixed
+ total_cump=257; //this is fixed
}
// Returns the symbol for a given cump under order-(-1)
unsigned long ppmc_get_symbol_ordern1 (void)
{
- return symb_cump;
+ return symb_cump;
}
// order-0
void ppmc_get_totf_order0(void)
{
- // Total cump is current total cump plus the escape for the escape code
- total_cump=order0_defined_bytes+order0_max_cump;
+ // Total cump is current total cump plus the escape for the escape code
+ total_cump=order0_defined_bytes+order0_max_cump;
}
// Returns: 1 in case a byte was coded. 0 in case of escape code.
char ppmc_code_byte_order0(void)
{
- unsigned long counter;
+ unsigned long counter;
- ppmc_get_totf_order0(); //get total cump
+ ppmc_get_totf_order0(); //get total cump
- // See if the byte is present
- if(order0_array[byte]==0) //a probability of 0
- {
+ // See if the byte is present
+ if(order0_array[byte]==0) //a probability of 0
+ {
- // Because it was not present, output an escape code, prepare variables
+ // Because it was not present, output an escape code, prepare variables
- symb_cump=order0_max_cump; //obviously its cump is current max_cump
- //without escape code's space
+ symb_cump=order0_max_cump; //obviously its cump is current max_cump
+ //without escape code's space
- symb_prob=order0_defined_bytes; //the number of defined bytes
+ symb_prob=order0_defined_bytes; //the number of defined bytes
- // Code the escape code
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the escape code
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 0; //byte not coded
- }
- else
- {
+ return 0; //byte not coded
+ }
+ else
+ {
- coded_in_order=0;
+ coded_in_order=0;
- // The symbol is present, code it under order-0
+ // The symbol is present, code it under order-0
- symb_prob=order0_array[byte]; //get probability directly
+ symb_prob=order0_array[byte]; //get probability directly
- // Make cump for current symbol
+ // Make cump for current symbol
- symb_cump=0; //for first symbol is 0
- for(counter=0; counter!=byte ; ++counter)
- symb_cump+=order0_array[counter]; //sum probabilities before our symbol
+ symb_cump=0; //for first symbol is 0
+ for(counter=0; counter!=byte ; ++counter)
+ symb_cump+=order0_array[counter]; //sum probabilities before our symbol
- // Code the symbol
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the symbol
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 1; //symbol coded under order-0
- }
+ return 1; //symbol coded under order-0
+ }
}
// care about updating variables, and renormalizing.
void ppmc_update_order0(void)
{
- if(order0_array[byte]==0)
- {
- // It had a zero probability
- order0_array[byte]++; //increment symbol probability
- ++order0_defined_bytes; //new byte defined
- ++order0_max_cump; //total cump
- return;
- }
- else
- {
- // It had a non-zero probability
-
- // Increment its probability
- order0_array[byte]++; //increment symbol probability
- ++order0_max_cump; //total cump
-
- // Check to see if its the maximum in this case renormalize
- if(order0_array[byte]==255)
- ppmc_renormalize_order0();
-
- return;
- }
+ if(order0_array[byte]==0)
+ {
+ // It had a zero probability
+ order0_array[byte]++; //increment symbol probability
+ ++order0_defined_bytes; //new byte defined
+ ++order0_max_cump; //total cump
+ return;
+ }
+ else
+ {
+ // It had a non-zero probability
+
+ // Increment its probability
+ order0_array[byte]++; //increment symbol probability
+ ++order0_max_cump; //total cump
+
+ // Check to see if its the maximum in this case renormalize
+ if(order0_array[byte]==255)
+ ppmc_renormalize_order0();
+
+ return;
+ }
}
// This functions renormalizes the probabilities at order-0 updating variables
void ppmc_renormalize_order0(void)
{
- unsigned long counter;
+ unsigned long counter;
- // Initialize variables
- order0_defined_bytes=0; //clear them
- order0_max_cump=0;
+ // Initialize variables
+ order0_defined_bytes=0; //clear them
+ order0_max_cump=0;
- // Loop over all probabilities, divide them by a factor of 2 and update variables
- for(counter=0 ; counter!=256 ; ++counter)
- {
- order0_array[counter]>>=1; //divide by a factor of 2
+ // Loop over all probabilities, divide them by a factor of 2 and update variables
+ for(counter=0 ; counter!=256 ; ++counter)
+ {
+ order0_array[counter]>>=1; //divide by a factor of 2
- if(order0_array[counter]!=0) //see if it has a non zero probability
- order0_defined_bytes++;
+ if(order0_array[counter]!=0) //see if it has a non zero probability
+ order0_defined_bytes++;
- order0_max_cump+=order0_array[counter]; //sum to the total cump
- }
+ order0_max_cump+=order0_array[counter]; //sum to the total cump
+ }
}
// or in case of a escape code it returns -1
void ppmc_decode_order0(void)
{
- unsigned long current_cump, counter;
+ unsigned long current_cump, counter;
- // Get the total cump needed for decoding symbol
- ppmc_get_totf_order0(); //total cump needed for decoding
- symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
+ // Get the total cump needed for decoding symbol
+ ppmc_get_totf_order0(); //total cump needed for decoding
+ symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
- // Now check if it's an escape code
- if(symb_cump>=order0_max_cump) //the defined code space for the escape code
- {
+ // Now check if it's an escape code
+ if(symb_cump>=order0_max_cump) //the defined code space for the escape code
+ {
- // Update coding values
+ // Update coding values
- ppmc_get_escape_prob_order0();
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order0();
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Mark as escape code
+ // Mark as escape code
- byte=-1;
+ byte=-1;
- return; //an escape code
- }
- else
- {
- // Now we have to check what symbol it is
+ return; //an escape code
+ }
+ else
+ {
+ // Now we have to check what symbol it is
- current_cump=0; //cump of the current symbol
+ current_cump=0; //cump of the current symbol
- for(counter=0 ; counter!= 256 ; ++counter)
- {
- if(symb_cump<current_cump)
- break; //symbol found, break search loop
- current_cump+=order0_array[counter]; //update cump
- }
+ for(counter=0 ; counter!= 256 ; ++counter)
+ {
+ if(symb_cump<current_cump)
+ break; //symbol found, break search loop
+ current_cump+=order0_array[counter]; //update cump
+ }
- counter--; //-1 (see ac_ppmc.html, searching for a given symbol)
+ counter--; //-1 (see ac_ppmc.html, searching for a given symbol)
- byte=counter; //update the variable with the found symbol
+ byte=counter; //update the variable with the found symbol
- // Get the cump and prob of byte
+ // Get the cump and prob of byte
- symb_prob=order0_array[byte]; //the probabilty
- symb_cump=current_cump-order0_array[byte]; //using the cump which was
- //already made
+ symb_prob=order0_array[byte]; //the probabilty
+ symb_cump=current_cump-order0_array[byte]; //using the cump which was
+ //already made
- // Update coding state
+ // Update coding state
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- coded_in_order=0; //decoded under order-0
+ coded_in_order=0; //decoded under order-0
- return;
- }
+ return;
+ }
}
// This function returns the probability for the escape codes in the variables
void ppmc_get_escape_prob_order0(void)
{
- // To understand that remember that the escape allocated for the escape code
- // is above the current maximum cump and that it has a probability determined
- // by the scheme C.
- symb_prob=order0_defined_bytes;
- symb_cump=order0_max_cump;
- total_cump=order0_defined_bytes+order0_max_cump;
+ // To understand that remember that the escape allocated for the escape code
+ // is above the current maximum cump and that it has a probability determined
+ // by the scheme C.
+ symb_prob=order0_defined_bytes;
+ symb_cump=order0_max_cump;
+ total_cump=order0_defined_bytes+order0_max_cump;
}
// order-1. o1_byte should contain the order-1
void ppmc_get_totf_order1(void)
{
- // Total cump is current total cump plus the escape for the escape code
- total_cump=order1_defined_bytes_array[o1_byte]+order1_max_cump_array[o1_byte];
+ // Total cump is current total cump plus the escape for the escape code
+ total_cump=order1_defined_bytes_array[o1_byte]+order1_max_cump_array[o1_byte];
}
// In case the byte is coded under this context, coded_in_order=1.
char ppmc_code_byte_order1(void)
{
- unsigned long counter;
+ unsigned long counter;
- // First check if current order-1 table is empty
- if(order1_defined_bytes_array[o1_byte]==0) //it's empty
- {
- return 0; //byte not coded, nothing done
- }
+ // First check if current order-1 table is empty
+ if(order1_defined_bytes_array[o1_byte]==0) //it's empty
+ {
+ return 0; //byte not coded, nothing done
+ }
- // Now try to code this byte under order-1
+ // Now try to code this byte under order-1
- ppmc_get_totf_order1(); //get total cump
+ ppmc_get_totf_order1(); //get total cump
- // See if the byte is present
- if(order1_array[o1_byte][byte]==0) //a probability of 0
- {
+ // See if the byte is present
+ if(order1_array[o1_byte][byte]==0) //a probability of 0
+ {
- // Because it was not present, output an escape code, prepare variables
+ // Because it was not present, output an escape code, prepare variables
- symb_cump=order1_max_cump_array[o1_byte];//obviously its cump is current max_cump
- //without escape code's space
+ symb_cump=order1_max_cump_array[o1_byte];//obviously its cump is current max_cump
+ //without escape code's space
- symb_prob=order1_defined_bytes_array[o1_byte];//the number of defined bytes
+ symb_prob=order1_defined_bytes_array[o1_byte];//the number of defined bytes
- // Code the escape code
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the escape code
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 0; //byte not coded, escape coded
- }
- else
- {
+ return 0; //byte not coded, escape coded
+ }
+ else
+ {
- coded_in_order=1; //because we coded it under order-1
+ coded_in_order=1; //because we coded it under order-1
- // The symbol is present, code it under order-1
+ // The symbol is present, code it under order-1
- symb_prob=order1_array[o1_byte][byte]; //get probability directly
+ symb_prob=order1_array[o1_byte][byte]; //get probability directly
- // Make cump for current symbol
+ // Make cump for current symbol
- symb_cump=0; //for first symbol is 0
- for(counter=0; counter!=byte ; ++counter)
- symb_cump+=order1_array[o1_byte][counter]; //sum probabilities before our symbol
+ symb_cump=0; //for first symbol is 0
+ for(counter=0; counter!=byte ; ++counter)
+ symb_cump+=order1_array[o1_byte][counter]; //sum probabilities before our symbol
- // Code the symbol
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the symbol
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 1; //symbol coded under order-1
- }
+ return 1; //symbol coded under order-1
+ }
}
// care about updating variables, and renormalizing. o1_byte must be filled.
void ppmc_update_order1(void)
{
- if(order1_array[o1_byte][byte]==0)
- {
- // It had a zero probability
- order1_array[o1_byte][byte]++; //increment symbol probability
- ++order1_defined_bytes_array[o1_byte]; //new byte defined
- ++order1_max_cump_array[o1_byte]; //total cump
- return;
- }
- else
- {
- // It had a non-zero probability
-
- // Increment its probability
- order1_array[o1_byte][byte]++; //increment symbol probability
- ++order1_max_cump_array[o1_byte]; //total cump
-
- // Check to see if its the maximum in this case renormalize
- if(order1_array[o1_byte][byte]==255)
- ppmc_renormalize_order1();
-
- return;
- }
+ if(order1_array[o1_byte][byte]==0)
+ {
+ // It had a zero probability
+ order1_array[o1_byte][byte]++; //increment symbol probability
+ ++order1_defined_bytes_array[o1_byte]; //new byte defined
+ ++order1_max_cump_array[o1_byte]; //total cump
+ return;
+ }
+ else
+ {
+ // It had a non-zero probability
+
+ // Increment its probability
+ order1_array[o1_byte][byte]++; //increment symbol probability
+ ++order1_max_cump_array[o1_byte]; //total cump
+
+ // Check to see if its the maximum in this case renormalize
+ if(order1_array[o1_byte][byte]==255)
+ ppmc_renormalize_order1();
+
+ return;
+ }
}
// This functions renormalizes the probabilities at order-1 updating variables
void ppmc_renormalize_order1(void)
{
- unsigned long counter;
+ unsigned long counter;
- // Initialize variables
- order1_defined_bytes_array[o1_byte]=0; //clear them
- order1_max_cump_array[o1_byte]=0;
+ // Initialize variables
+ order1_defined_bytes_array[o1_byte]=0; //clear them
+ order1_max_cump_array[o1_byte]=0;
- // Loop over all probabilities, divide them by a factor of 2 and update variables
- for(counter=0 ; counter!=256 ; ++counter)
- {
- order1_array[o1_byte][counter]>>=1; //divide by a factor of 2
+ // Loop over all probabilities, divide them by a factor of 2 and update variables
+ for(counter=0 ; counter!=256 ; ++counter)
+ {
+ order1_array[o1_byte][counter]>>=1; //divide by a factor of 2
- if(order1_array[o1_byte][counter]!=0) //see if it has a non zero probability
- order1_defined_bytes_array[o1_byte]++;
+ if(order1_array[o1_byte][counter]!=0) //see if it has a non zero probability
+ order1_defined_bytes_array[o1_byte]++;
- order1_max_cump_array[o1_byte]+=order1_array[o1_byte][counter]; //sum to the total cump
- }
+ order1_max_cump_array[o1_byte]+=order1_array[o1_byte][counter]; //sum to the total cump
+ }
}
// It updates "coded_in_order".
void ppmc_decode_order1(void)
{
- unsigned long current_cump, counter;
+ unsigned long current_cump, counter;
- // First check if current order-1 table is empty
- if(order1_defined_bytes_array[o1_byte]==0) //it's empty
- {
- byte=-1; //byte not coded, nothing done
- return;
- }
+ // First check if current order-1 table is empty
+ if(order1_defined_bytes_array[o1_byte]==0) //it's empty
+ {
+ byte=-1; //byte not coded, nothing done
+ return;
+ }
- // Get the total cump needed for decoding symbol
- ppmc_get_totf_order1(); //total cump needed for decoding
- symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
+ // Get the total cump needed for decoding symbol
+ ppmc_get_totf_order1(); //total cump needed for decoding
+ symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
- // Now check if it's an escape code
- if(symb_cump>=order1_max_cump_array[o1_byte]) //the defined code space for the escape code
- {
+ // Now check if it's an escape code
+ if(symb_cump>=order1_max_cump_array[o1_byte]) //the defined code space for the escape code
+ {
- // Update coding values
+ // Update coding values
- ppmc_get_escape_prob_order1();
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order1();
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Mark as escape code
+ // Mark as escape code
- byte=-1;
+ byte=-1;
- return; //an escape code
- }
- else
- {
- // Now we have to check what symbol it is
+ return; //an escape code
+ }
+ else
+ {
+ // Now we have to check what symbol it is
- current_cump=0; //cump of the current symbol
+ current_cump=0; //cump of the current symbol
- for(counter=0 ; counter!= 256 ; ++counter)
- {
- if(symb_cump<current_cump)
- break; //symbol found, break search loop
- current_cump+=order1_array[o1_byte][counter]; //update cump
- }
+ for(counter=0 ; counter!= 256 ; ++counter)
+ {
+ if(symb_cump<current_cump)
+ break; //symbol found, break search loop
+ current_cump+=order1_array[o1_byte][counter]; //update cump
+ }
- counter--; //-1 (see ac_ppmc.html, searching for a given symbol)
+ counter--; //-1 (see ac_ppmc.html, searching for a given symbol)
- byte=counter; //update the variable with the found symbol
+ byte=counter; //update the variable with the found symbol
- // Get the cump and prob of byte
+ // Get the cump and prob of byte
- symb_prob=order1_array[o1_byte][byte]; //the probabilty
- symb_cump=current_cump-order1_array[o1_byte][byte]; //using the cump which was
- //already made
+ symb_prob=order1_array[o1_byte][byte]; //the probabilty
+ symb_cump=current_cump-order1_array[o1_byte][byte]; //using the cump which was
+ //already made
- // Update coding state
+ // Update coding state
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Update coded_in_order used for update exclusion
+ // Update coded_in_order used for update exclusion
- coded_in_order=1;
+ coded_in_order=1;
- return;
- }
+ return;
+ }
}
// This function returns the probability for the escape codes in the variables
void ppmc_get_escape_prob_order1(void)
{
- // To understand that remember that the escape allocated for the escape code
- // is above the current maximum cump and that it has a probability determined
- // by the scheme C.
- symb_prob=order1_defined_bytes_array[o1_byte];
- symb_cump=order1_max_cump_array[o1_byte];
- total_cump=order1_defined_bytes_array[o1_byte]+order1_max_cump_array[o1_byte];
+ // To understand that remember that the escape allocated for the escape code
+ // is above the current maximum cump and that it has a probability determined
+ // by the scheme C.
+ symb_prob=order1_defined_bytes_array[o1_byte];
+ symb_cump=order1_max_cump_array[o1_byte];
+ total_cump=order1_defined_bytes_array[o1_byte]+order1_max_cump_array[o1_byte];
}
// for order-2.
void ppmc_get_totf_order2(void)
{
- // Total cump is current total cump plus the escape for the escape code
- total_cump=order2_array[o2_cntxt].defined_bytes+order2_array[o2_cntxt].max_cump;
+ // Total cump is current total cump plus the escape for the escape code
+ total_cump=order2_array[o2_cntxt].defined_bytes+order2_array[o2_cntxt].max_cump;
}
// In case the byte is coded under this context, coded_in_order=2.
char ppmc_code_byte_order2(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Initialize o2_cntxt
+ // Initialize o2_cntxt
- o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
+ o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
- // First check if current order-2 context is empty
- if(order2_array[o2_cntxt].defined_bytes==0) //it's empty
- {
- return 0; //byte not coded, nothing done
- }
+ // First check if current order-2 context is empty
+ if(order2_array[o2_cntxt].defined_bytes==0) //it's empty
+ {
+ return 0; //byte not coded, nothing done
+ }
- // Now try to code this byte under order-2
+ // Now try to code this byte under order-2
- ppmc_get_totf_order2(); //get total cump
+ ppmc_get_totf_order2(); //get total cump
- // See if the byte is present and compute its cump at the same time
+ // See if the byte is present and compute its cump at the same time
- node=order2_array[o2_cntxt].prob; //pointer to first element in the linked list
+ node=order2_array[o2_cntxt].prob; //pointer to first element in the linked list
- symb_cump=0; //the first symbol always has a 0 cump
+ symb_cump=0; //the first symbol always has a 0 cump
- // Now search the byte in the linked list
+ // Now search the byte in the linked list
- do{
- if(node->byte==byte)
- goto ppmc_o2_byte_found; //bad thing, I know, anyone has a better idea?
- symb_cump+=node->freq; //add the probability of this byte to the cump
- if(node->next==0)
- break;
- node=node->next; //next element in the linked list
- }while(1);
+ do{
+ if(node->byte==byte)
+ goto ppmc_o2_byte_found; //bad thing, I know, anyone has a better idea?
+ symb_cump+=node->freq; //add the probability of this byte to the cump
+ if(node->next==0)
+ break;
+ node=node->next; //next element in the linked list
+ }while(1);
- // If we reach that point, the byte was not found in the linked list
- // so we don't need the cump, we have to output an escape code, whose
- // probabilities are know using the context structure in the table.
+ // If we reach that point, the byte was not found in the linked list
+ // so we don't need the cump, we have to output an escape code, whose
+ // probabilities are know using the context structure in the table.
- // Byte was not present in the linked list, current node is the last one,
- // and that's the node needed for creating a new node, save it.
+ // Byte was not present in the linked list, current node is the last one,
+ // and that's the node needed for creating a new node, save it.
- o2_ll_node=node;
+ o2_ll_node=node;
- // Now get the probability and cump of the escape code
+ // Now get the probability and cump of the escape code
- symb_cump=order2_array[o2_cntxt].max_cump;
- symb_prob=order2_array[o2_cntxt].defined_bytes;
+ symb_cump=order2_array[o2_cntxt].max_cump;
+ symb_prob=order2_array[o2_cntxt].defined_bytes;
- // Code the escape code
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the escape code
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 0;
+ return 0;
- // That code is executed when the byte is found in the linked list
+ // That code is executed when the byte is found in the linked list
- ppmc_o2_byte_found:
+ppmc_o2_byte_found:
- // Everything has been tested, now we can feel free to code the byte,
- // the symb_cump is already computed, now get its probability and code
- // the byte, also save pointer to this element in the linked lists for
- // updating.
+ // Everything has been tested, now we can feel free to code the byte,
+ // the symb_cump is already computed, now get its probability and code
+ // the byte, also save pointer to this element in the linked lists for
+ // updating.
- coded_in_order=2; //successfully coded under order-2
+ coded_in_order=2; //successfully coded under order-2
- o2_ll_node=node; //save it for updating
+ o2_ll_node=node; //save it for updating
- symb_prob=node->freq; //get the probability of the byte
+ symb_prob=node->freq; //get the probability of the byte
- // Code it.
+ // Code it.
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 1; //byte coded under order-2
+ return 1; //byte coded under order-2
}
void ppmc_update_order2(void)
{
- // First of all check if that's the first byte in this context, in that case
- // we have to initialize some variables in the context structure.
+ // First of all check if that's the first byte in this context, in that case
+ // we have to initialize some variables in the context structure.
- if(order2_array[o2_cntxt].defined_bytes==0) //no byte defined yet
- {
+ if(order2_array[o2_cntxt].defined_bytes==0) //no byte defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- order2_array[o2_cntxt].defined_bytes=1;
- order2_array[o2_cntxt].max_cump=1;
- order2_array[o2_cntxt].prob=_bytes_pool;
+ order2_array[o2_cntxt].defined_bytes=1;
+ order2_array[o2_cntxt].max_cump=1;
+ order2_array[o2_cntxt].prob=_bytes_pool;
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // The byte was coded under order two, otherwise it was coded under a
- // lower order (never higher ones, remember that we are using update
- // exclusion) in this case we have to create a new node in the list.
+ // The byte was coded under order two, otherwise it was coded under a
+ // lower order (never higher ones, remember that we are using update
+ // exclusion) in this case we have to create a new node in the list.
- if(coded_in_order==2) //coded under order-2
- {
+ if(coded_in_order==2) //coded under order-2
+ {
- // Update its count and variables of this context and check for renormalization
+ // Update its count and variables of this context and check for renormalization
- o2_ll_node->freq++; //increment its frequency (rather probability)
+ o2_ll_node->freq++; //increment its frequency (rather probability)
- order2_array[o2_cntxt].max_cump++; //total cump
+ order2_array[o2_cntxt].max_cump++; //total cump
- if(o2_ll_node->freq==255) //do we have to renormalize?
- ppmc_renormalize_order2(); //renormalize
+ if(o2_ll_node->freq==255) //do we have to renormalize?
+ ppmc_renormalize_order2(); //renormalize
- }
- else
- {
+ }
+ else
+ {
- // Once every paranoid check has been done we are sure that this byte
- // did not existed and so we have to create a new node in the linked
- // list. Also we have to take care of memory issues.
+ // Once every paranoid check has been done we are sure that this byte
+ // did not existed and so we have to create a new node in the linked
+ // list. Also we have to take care of memory issues.
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- o2_ll_node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ o2_ll_node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- order2_array[o2_cntxt].max_cump++; //total cump
- order2_array[o2_cntxt].defined_bytes++; //total cump
+ order2_array[o2_cntxt].max_cump++; //total cump
+ order2_array[o2_cntxt].defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- }
+ }
}
// variables.
void ppmc_renormalize_order2(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Initialize variables. Defined bytes remain the same.
- order2_array[o2_cntxt].max_cump=0; //clear them
+ // Initialize variables. Defined bytes remain the same.
+ order2_array[o2_cntxt].max_cump=0; //clear them
- node=order2_array[o2_cntxt].prob; //get pointer to lined lists
+ node=order2_array[o2_cntxt].prob; //get pointer to lined lists
- // Divide all the probabilities by 2 and update context variables
- while(1)
- {
- node->freq>>=1; //divide by a factor of 2
+ // Divide all the probabilities by 2 and update context variables
+ while(1)
+ {
+ node->freq>>=1; //divide by a factor of 2
- if(node->freq==0) //don't allow a probability to be 0
- node->freq=1;
+ if(node->freq==0) //don't allow a probability to be 0
+ node->freq=1;
- order2_array[o2_cntxt].max_cump+=node->freq; //sum to the total cump
+ order2_array[o2_cntxt].max_cump+=node->freq; //sum to the total cump
- if(node->next==0) //last element
- break;
- node=node->next;
- }
+ if(node->next==0) //last element
+ break;
+ node=node->next;
+ }
- //printf("\nRenormalization, context:%c%c",o2_byte,o1_byte);
+ //printf("\nRenormalization, context:%c%c",o2_byte,o1_byte);
}
// "o2_ll_node" the pointer to its node. (so updating is faster)
void ppmc_decode_order2(void)
{
- unsigned long current_cump, counter;
- struct _byte_and_freq *node;
+ unsigned long current_cump, counter;
+ struct _byte_and_freq *node;
- // Initialize o2_cntxt
+ // Initialize o2_cntxt
- o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
+ o2_cntxt=ppmc_order2_hash_key(o1_byte,o2_byte);
- // First check if current order-2 context is empty
- if(order2_array[o2_cntxt].defined_bytes==0) //it's empty
- {
- byte=-1; //byte not coded, nothing done
- return;
- }
+ // First check if current order-2 context is empty
+ if(order2_array[o2_cntxt].defined_bytes==0) //it's empty
+ {
+ byte=-1; //byte not coded, nothing done
+ return;
+ }
- // Get the total cump needed for decoding symbol
- ppmc_get_totf_order2(); //total cump needed for decoding
- symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
+ // Get the total cump needed for decoding symbol
+ ppmc_get_totf_order2(); //total cump needed for decoding
+ symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
- // Now check if it's an escape code
- if(symb_cump>=order2_array[o2_cntxt].max_cump) //the defined code space for the escape code
- {
+ // Now check if it's an escape code
+ if(symb_cump>=order2_array[o2_cntxt].max_cump) //the defined code space for the escape code
+ {
- // Update coding values
+ // Update coding values
- ppmc_get_escape_prob_order2();
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order2();
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Mark as escape code
+ // Mark as escape code
- byte=-1;
+ byte=-1;
- return; //an escape code
- }
- else
- {
- // Now we have to check what symbol it is
+ return; //an escape code
+ }
+ else
+ {
+ // Now we have to check what symbol it is
- current_cump=0; //cump of the current symbol
+ current_cump=0; //cump of the current symbol
- node=order2_array[o2_cntxt].prob; //get pointer to linked lists
+ node=order2_array[o2_cntxt].prob; //get pointer to linked lists
- while(1)
- {
- current_cump+=node->freq; //update cump
- if(symb_cump<current_cump)
- break; //symbol found, break search loop
+ while(1)
+ {
+ current_cump+=node->freq; //update cump
+ if(symb_cump<current_cump)
+ break; //symbol found, break search loop
- node=node->next; //next element
- //we have no need to check for the last symbol, we'll never read further
- //the end of the linked lists, before we'll found the last byte.
- }
+ node=node->next; //next element
+ //we have no need to check for the last symbol, we'll never read further
+ //the end of the linked lists, before we'll found the last byte.
+ }
- //read byte value and probability
+ //read byte value and probability
- symb_prob=node->freq; //get the probability for updating the state
- byte=node->byte; //get byte
- o2_ll_node=node; //used for updating
+ symb_prob=node->freq; //get the probability for updating the state
+ byte=node->byte; //get byte
+ o2_ll_node=node; //used for updating
- // Get the cump of byte
+ // Get the cump of byte
- symb_cump=current_cump-symb_prob;
+ symb_cump=current_cump-symb_prob;
- // Update coding state
+ // Update coding state
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Update coded_in_order used for update exclusion
+ // Update coded_in_order used for update exclusion
- coded_in_order=2;
+ coded_in_order=2;
- return;
- }
+ return;
+ }
}
// when the context has not been initalized yet.
void ppmc_update_dec_order2(void)
{
- struct _byte_and_freq *node;
+ struct _byte_and_freq *node;
- // Handle the case when the context is not initialized
- // This code is the same as the one for the encoding.
+ // Handle the case when the context is not initialized
+ // This code is the same as the one for the encoding.
- if(order2_array[o2_cntxt].defined_bytes==0) //no byte defined yet
- {
+ if(order2_array[o2_cntxt].defined_bytes==0) //no byte defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- order2_array[o2_cntxt].defined_bytes=1;
- order2_array[o2_cntxt].max_cump=1;
- order2_array[o2_cntxt].prob=_bytes_pool;
+ order2_array[o2_cntxt].defined_bytes=1;
+ order2_array[o2_cntxt].max_cump=1;
+ order2_array[o2_cntxt].prob=_bytes_pool;
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // Current context is initalized, proceed
+ // Current context is initalized, proceed
- if(coded_in_order==2) //check if it was decoded under order-2
- {
+ if(coded_in_order==2) //check if it was decoded under order-2
+ {
- // We can be sure that the pointer "o2_ll_node" points to its entry, and
- // it has a non 0 probability (otherwise it couldn't be coded) so just
- // update its probability and max_cump
+ // We can be sure that the pointer "o2_ll_node" points to its entry, and
+ // it has a non 0 probability (otherwise it couldn't be coded) so just
+ // update its probability and max_cump
- o2_ll_node->freq++; //the probability of the byte
- order2_array[o2_cntxt].max_cump++; //the max_cump
+ o2_ll_node->freq++; //the probability of the byte
+ order2_array[o2_cntxt].max_cump++; //the max_cump
- if(o2_ll_node->freq==255) //check for renormalization
- ppmc_renormalize_order2();
+ if(o2_ll_node->freq==255) //check for renormalization
+ ppmc_renormalize_order2();
- }
- else
- {
+ }
+ else
+ {
- // An escape code was decoded under order-2, we have to read till the
- // end of the linked list so we can add a new node for this new byte.
+ // An escape code was decoded under order-2, we have to read till the
+ // end of the linked list so we can add a new node for this new byte.
- node=order2_array[o2_cntxt].prob; //get pointer to linked list
+ node=order2_array[o2_cntxt].prob; //get pointer to linked list
- while(1)
- {
- if(node->next==0) //check for the end of the linked list
- break;
- node=node->next; //next node
- }
+ while(1)
+ {
+ if(node->next==0) //check for the end of the linked list
+ break;
+ node=node->next; //next node
+ }
- // We reached the end of the linked list, add a new node if possible,
- // we are using the same code of "ppmc_update_order2()" with the
- // difference that the pointer to the linked list is "node"
+ // We reached the end of the linked list, add a new node if possible,
+ // we are using the same code of "ppmc_update_order2()" with the
+ // difference that the pointer to the linked list is "node"
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- order2_array[o2_cntxt].max_cump++; //total cump
- order2_array[o2_cntxt].defined_bytes++; //total cump
+ order2_array[o2_cntxt].max_cump++; //total cump
+ order2_array[o2_cntxt].defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //we are finished updating
+ return; //we are finished updating
- }
+ }
}
// This function returns the probability for the escape codes in the variables
void ppmc_get_escape_prob_order2(void)
{
- // To understand that remember that the escape allocated for the escape code
- // is above the current maximum cump and that it has a probability determined
- // by the scheme C.
+ // To understand that remember that the escape allocated for the escape code
+ // is above the current maximum cump and that it has a probability determined
+ // by the scheme C.
- symb_prob=order2_array[o2_cntxt].defined_bytes;
- symb_cump=order2_array[o2_cntxt].max_cump;
+ symb_prob=order2_array[o2_cntxt].defined_bytes;
+ symb_cump=order2_array[o2_cntxt].max_cump;
}
// have to code under this context.
char ppmc_get_totf_order3(void)
{
- struct context *cntxt_node;
+ struct context *cntxt_node;
- // First make the hash key for order-3
+ // First make the hash key for order-3
- o3_cntxt=ppmc_order3_hash_key(o1_byte,o2_byte,o3_byte);
- full_o3_cntxt=(o1_byte)+(o2_byte<<8)+(o3_byte<<16); //order-3
+ o3_cntxt=ppmc_order3_hash_key(o1_byte,o2_byte,o3_byte);
+ full_o3_cntxt=(o1_byte)+(o2_byte<<8)+(o3_byte<<16); //order-3
- // Now check the hash entry in the table
+ // Now check the hash entry in the table
- if(order3_hasht[o3_cntxt]==0) //if 0, not initialized
- {
+ if(order3_hasht[o3_cntxt]==0) //if 0, not initialized
+ {
- o3_context=0; //no hash entry
+ o3_context=0; //no hash entry
- return 0; //hash entry not initialized
- }
+ return 0; //hash entry not initialized
+ }
- // Now read trough the linked list of context searching current one
+ // Now read trough the linked list of context searching current one
- cntxt_node=order3_hasht[o3_cntxt];
+ cntxt_node=order3_hasht[o3_cntxt];
- while(1)
- {
+ while(1)
+ {
- if(cntxt_node->order4321==full_o3_cntxt) //compare context
- goto ppmc_gtf_cntxt_found;
+ if(cntxt_node->order4321==full_o3_cntxt) //compare context
+ goto ppmc_gtf_cntxt_found;
- if(cntxt_node->next==0) //end of context's linked list
- break;
+ if(cntxt_node->next==0) //end of context's linked list
+ break;
- cntxt_node=cntxt_node->next; //next element
+ cntxt_node=cntxt_node->next; //next element
- }
+ }
- // Once there the context was not found
- o3_context=cntxt_node; //pointer to last element in the linked list
+ // Once there the context was not found
+ o3_context=cntxt_node; //pointer to last element in the linked list
- return 0; //it was not present
+ return 0; //it was not present
- // The context is found, so return pointer and cump
+ // The context is found, so return pointer and cump
- ppmc_gtf_cntxt_found:
+ppmc_gtf_cntxt_found:
- o3_context=cntxt_node;
+ o3_context=cntxt_node;
- // Total cump is current total cump plus the escape for the escape code
+ // Total cump is current total cump plus the escape for the escape code
- total_cump=o3_context->defined_bytes+o3_context->max_cump;
+ total_cump=o3_context->defined_bytes+o3_context->max_cump;
- return 1; //context found
+ return 1; //context found
}
// In case the byte is coded under this context, coded_in_order=3.
char ppmc_code_byte_order3(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Get current context (if present) and total cump.
+ // Get current context (if present) and total cump.
- if(ppmc_get_totf_order3()==0)
- return 0;
+ if(ppmc_get_totf_order3()==0)
+ return 0;
- // See if the byte is present and compute its cump at the same time
+ // See if the byte is present and compute its cump at the same time
- node=o3_context->prob; //pointer to first element in the linked list
+ node=o3_context->prob; //pointer to first element in the linked list
- symb_cump=0; //the first symbol always has a 0 cump
+ symb_cump=0; //the first symbol always has a 0 cump
- // Now search the byte in the linked list
+ // Now search the byte in the linked list
- do{
- if(node->byte==byte)
- goto ppmc_o3_byte_found; //bad thing, I know, anyone has a better idea?
- symb_cump+=node->freq; //add the probability of this byte to the cump
- if(node->next==0)
- break;
- node=node->next; //next element in the linked list
- }while(1);
+ do{
+ if(node->byte==byte)
+ goto ppmc_o3_byte_found; //bad thing, I know, anyone has a better idea?
+ symb_cump+=node->freq; //add the probability of this byte to the cump
+ if(node->next==0)
+ break;
+ node=node->next; //next element in the linked list
+ }while(1);
- // If we reach that point, the byte was not found in the linked list
- // so we don't need the cump, we have to output an escape code, whose
- // probabilities are know using the context structure in the table.
+ // If we reach that point, the byte was not found in the linked list
+ // so we don't need the cump, we have to output an escape code, whose
+ // probabilities are know using the context structure in the table.
- // Byte was not present in the linked list, current node is the last one,
- // and that's the node needed for creating a new node, save it.
+ // Byte was not present in the linked list, current node is the last one,
+ // and that's the node needed for creating a new node, save it.
- o3_ll_node=node;
+ o3_ll_node=node;
- // Now get the probability and cump of the escape code
+ // Now get the probability and cump of the escape code
- symb_cump=o3_context->max_cump;
- symb_prob=o3_context->defined_bytes;
+ symb_cump=o3_context->max_cump;
+ symb_prob=o3_context->defined_bytes;
- // Code the escape code
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the escape code
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 0;
+ return 0;
- // That code is executed when the byte is found in the linked list
+ // That code is executed when the byte is found in the linked list
- ppmc_o3_byte_found:
+ppmc_o3_byte_found:
- // Everything has been tested, now we can feel free to code the byte,
- // the symb_cump is already computed, now get its probability and code
- // the byte, also save pointer to this element in the linked lists for
- // updating.
+ // Everything has been tested, now we can feel free to code the byte,
+ // the symb_cump is already computed, now get its probability and code
+ // the byte, also save pointer to this element in the linked lists for
+ // updating.
- coded_in_order=3; //successfully coded under order-3
+ coded_in_order=3; //successfully coded under order-3
- o3_ll_node=node; //save it for updating
+ o3_ll_node=node; //save it for updating
- symb_prob=node->freq; //get the probability of the byte
+ symb_prob=node->freq; //get the probability of the byte
- // Code it.
+ // Code it.
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 1; //byte coded under order-3
+ return 1; //byte coded under order-3
}
void ppmc_update_order3(void)
{
- // First thing first, check if the hash entry is initialized
+ // First thing first, check if the hash entry is initialized
- if(order3_hasht[o3_cntxt]==0) //no pointer to linked list defined yet
- {
+ if(order3_hasht[o3_cntxt]==0) //no pointer to linked list defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- order3_hasht[o3_cntxt]=_context_pool;
+ order3_hasht[o3_cntxt]=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o3_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o3_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // The byte was coded under order three, otherwise it was coded under a
- // lower order (never higher ones, remember that we are using update
- // exclusion) in this case we have to create a new node in the list.
+ // The byte was coded under order three, otherwise it was coded under a
+ // lower order (never higher ones, remember that we are using update
+ // exclusion) in this case we have to create a new node in the list.
- if(coded_in_order==3) //coded under order-3
- {
+ if(coded_in_order==3) //coded under order-3
+ {
- // Update its count and variables of this context and check for renormalization
+ // Update its count and variables of this context and check for renormalization
- o3_ll_node->freq++; //increment its frequency (rather probability)
+ o3_ll_node->freq++; //increment its frequency (rather probability)
- o3_context->max_cump++; //total cump
+ o3_context->max_cump++; //total cump
- if(o3_ll_node->freq==255) //do we have to renormalize?
- ppmc_renormalize_order3(); //renormalize
+ if(o3_ll_node->freq==255) //do we have to renormalize?
+ ppmc_renormalize_order3(); //renormalize
- }
- else
- {
+ }
+ else
+ {
- // Now we have two cases, under a given context (which we actually found)
- // we coded an escape coded, in that case just create a new node in the
- // linked list of bytes and probabilities. Otherwise we didn't find the
- // same node so we have to create it in the linked list for context.
- // And we can be sure that it at least has one element and that
- // "o3_context" points to the last element, so we can put the new element.
+ // Now we have two cases, under a given context (which we actually found)
+ // we coded an escape coded, in that case just create a new node in the
+ // linked list of bytes and probabilities. Otherwise we didn't find the
+ // same node so we have to create it in the linked list for context.
+ // And we can be sure that it at least has one element and that
+ // "o3_context" points to the last element, so we can put the new element.
- if(o3_context->order4321==full_o3_cntxt) //chech if that's the last
- { //element or the a context found
+ if(o3_context->order4321==full_o3_cntxt) //chech if that's the last
+ { //element or the a context found
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- o3_ll_node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ o3_ll_node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- o3_context->max_cump++; //total cump
- o3_context->defined_bytes++; //total cump
+ o3_context->max_cump++; //total cump
+ o3_context->defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
- }
- else
- {
+ }
+ }
+ else
+ {
- // We have to create a new context node
+ // We have to create a new context node
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- o3_context->next=_context_pool;
+ o3_context->next=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o3_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o3_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- }
+ }
- }
+ }
}
// variables.
void ppmc_renormalize_order3(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Initialize variables. Defined bytes remain the same.
- o3_context->max_cump=0; //clear them
+ // Initialize variables. Defined bytes remain the same.
+ o3_context->max_cump=0; //clear them
- node=o3_context->prob; //get pointer to lined lists
+ node=o3_context->prob; //get pointer to lined lists
- // Divide all the probabilities by 2 and update context variables
- while(1)
- {
- node->freq>>=1; //divide by a factor of 2
+ // Divide all the probabilities by 2 and update context variables
+ while(1)
+ {
+ node->freq>>=1; //divide by a factor of 2
- if(node->freq==0) //don't allow a probability to be 0
- node->freq=1;
+ if(node->freq==0) //don't allow a probability to be 0
+ node->freq=1;
- o3_context->max_cump+=node->freq; //sum to the total cump
+ o3_context->max_cump+=node->freq; //sum to the total cump
- if(node->next==0) //last element
- break;
- node=node->next;
- }
+ if(node->next==0) //last element
+ break;
+ node=node->next;
+ }
}
// "o3_ll_node" the pointer to its node. (so updating is faster)
void ppmc_decode_order3(void)
{
- unsigned long current_cump, counter;
- struct _byte_and_freq *node;
+ unsigned long current_cump, counter;
+ struct _byte_and_freq *node;
- // Get current context (if present) and total cump.
+ // Get current context (if present) and total cump.
- if(ppmc_get_totf_order3()==0)
- {
- byte=-1;
- return;
- }
+ if(ppmc_get_totf_order3()==0)
+ {
+ byte=-1;
+ return;
+ }
- // Decode current cump
+ // Decode current cump
- symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
+ symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
- // Now check if it's an escape code
- if(symb_cump>=o3_context->max_cump) //the defined code space for the escape code
- {
+ // Now check if it's an escape code
+ if(symb_cump>=o3_context->max_cump) //the defined code space for the escape code
+ {
- // Update coding values
+ // Update coding values
- ppmc_get_escape_prob_order3();
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order3();
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Mark as escape code
+ // Mark as escape code
- byte=-1;
+ byte=-1;
- return; //an escape code
- }
- else
- {
- // Now we have to check what symbol it is
+ return; //an escape code
+ }
+ else
+ {
+ // Now we have to check what symbol it is
- current_cump=0; //cump of the current symbol
+ current_cump=0; //cump of the current symbol
- node=o3_context->prob; //get pointer to linked lists
+ node=o3_context->prob; //get pointer to linked lists
- while(1)
- {
- current_cump+=node->freq; //update cump
- if(symb_cump<current_cump)
- break; //symbol found, break search loop
+ while(1)
+ {
+ current_cump+=node->freq; //update cump
+ if(symb_cump<current_cump)
+ break; //symbol found, break search loop
- node=node->next; //next element
- //we have no need to check for the last symbol, we'll never read further
- //the end of the linked lists, before we'll found the last byte.
- }
+ node=node->next; //next element
+ //we have no need to check for the last symbol, we'll never read further
+ //the end of the linked lists, before we'll found the last byte.
+ }
- //read byte value and probability
+ //read byte value and probability
- symb_prob=node->freq; //get the probability for updating the state
- byte=node->byte; //get byte
- o3_ll_node=node; //used for updating
+ symb_prob=node->freq; //get the probability for updating the state
+ byte=node->byte; //get byte
+ o3_ll_node=node; //used for updating
- // Get the cump of byte
+ // Get the cump of byte
- symb_cump=current_cump-symb_prob;
+ symb_cump=current_cump-symb_prob;
- // Update coding state
+ // Update coding state
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Update coded_in_order used for update exclusion
+ // Update coded_in_order used for update exclusion
- coded_in_order=3;
+ coded_in_order=3;
- return;
- }
+ return;
+ }
}
// linked list.
void ppmc_update_dec_order3(void)
{
- struct _byte_and_freq *node;
+ struct _byte_and_freq *node;
- // First thing first, check if the hash entry is initialized
+ // First thing first, check if the hash entry is initialized
- if(order3_hasht[o3_cntxt]==0) //no pointer to linked list defined yet
- {
+ if(order3_hasht[o3_cntxt]==0) //no pointer to linked list defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- order3_hasht[o3_cntxt]=_context_pool;
+ order3_hasht[o3_cntxt]=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o3_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o3_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // The byte was coded under order three, otherwise it was coded under a
- // lower order (never higher ones, remember that we are using update
- // exclusion) in this case we have to create a new node in the list.
+ // The byte was coded under order three, otherwise it was coded under a
+ // lower order (never higher ones, remember that we are using update
+ // exclusion) in this case we have to create a new node in the list.
- if(coded_in_order==3) //coded under order-3
- {
+ if(coded_in_order==3) //coded under order-3
+ {
- // Update its count and variables of this context and check for renormalization
+ // Update its count and variables of this context and check for renormalization
- o3_ll_node->freq++; //increment its frequency (rather probability)
+ o3_ll_node->freq++; //increment its frequency (rather probability)
- o3_context->max_cump++; //total cump
+ o3_context->max_cump++; //total cump
- if(o3_ll_node->freq==255) //do we have to renormalize?
- ppmc_renormalize_order3(); //renormalize
+ if(o3_ll_node->freq==255) //do we have to renormalize?
+ ppmc_renormalize_order3(); //renormalize
- }
- else
- {
+ }
+ else
+ {
- // Now we have two cases, under a given context (which we actually found)
- // we coded an escape coded, in that case just create a new node in the
- // linked list of bytes and probabilities. Otherwise we didn't find the
- // same node so we have to create it in the linked list for context.
- // And we can be sure that it at least has one element and that
- // "o3_context" points to the last element, so we can put the new element.
+ // Now we have two cases, under a given context (which we actually found)
+ // we coded an escape coded, in that case just create a new node in the
+ // linked list of bytes and probabilities. Otherwise we didn't find the
+ // same node so we have to create it in the linked list for context.
+ // And we can be sure that it at least has one element and that
+ // "o3_context" points to the last element, so we can put the new element.
- if(o3_context->order4321==full_o3_cntxt) //chech if that's the last
- { //element or the a context found
+ if(o3_context->order4321==full_o3_cntxt) //chech if that's the last
+ { //element or the a context found
- // Read till the end of the linked list
+ // Read till the end of the linked list
- node=o3_context->prob; //get pointer to linked list
+ node=o3_context->prob; //get pointer to linked list
- while(1)
- {
- if(node->next==0) //check for the end of the linked list
- break;
- node=node->next; //next node
- }
+ while(1)
+ {
+ if(node->next==0) //check for the end of the linked list
+ break;
+ node=node->next; //next node
+ }
- // Now add element
+ // Now add element
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- o3_context->max_cump++; //total cump
- o3_context->defined_bytes++; //total cump
+ o3_context->max_cump++; //total cump
+ o3_context->defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
- }
- else
- {
+ }
+ }
+ else
+ {
- // We have to create a new context node
+ // We have to create a new context node
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- o3_context->next=_context_pool;
+ o3_context->next=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o3_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o3_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- }
+ }
- }
+ }
}
// This function returns the probability for the escape codes in the variables
void ppmc_get_escape_prob_order3(void)
{
- // To understand that remember that the escape allocated for the escape code
- // is above the current maximum cump and that it has a probability determined
- // by the scheme C.
+ // To understand that remember that the escape allocated for the escape code
+ // is above the current maximum cump and that it has a probability determined
+ // by the scheme C.
- symb_prob=o3_context->defined_bytes;
- symb_cump=o3_context->max_cump;
+ symb_prob=o3_context->defined_bytes;
+ symb_cump=o3_context->max_cump;
}
// have to code under this context.
char ppmc_get_totf_order4(void)
{
- struct context *cntxt_node;
+ struct context *cntxt_node;
- // First make the hash key for order-4
+ // First make the hash key for order-4
- o4_cntxt=ppmc_order4_hash_key(o1_byte,o2_byte,o3_byte,o4_byte);
- full_o4_cntxt=(o1_byte)+(o2_byte<<8)+(o3_byte<<16)+(o4_byte<<24); //order-4
+ o4_cntxt=ppmc_order4_hash_key(o1_byte,o2_byte,o3_byte,o4_byte);
+ full_o4_cntxt=(o1_byte)+(o2_byte<<8)+(o3_byte<<16)+(o4_byte<<24); //order-4
- // Now check the hash entry in the table
+ // Now check the hash entry in the table
- if(order4_hasht[o4_cntxt]==0) //if 0, not initialized
- {
+ if(order4_hasht[o4_cntxt]==0) //if 0, not initialized
+ {
- o4_context=0; //no hash entry
+ o4_context=0; //no hash entry
- return 0; //hash entry not initialized
- }
+ return 0; //hash entry not initialized
+ }
- // Now read trough the linked list of context searching current one
+ // Now read trough the linked list of context searching current one
- cntxt_node=order4_hasht[o4_cntxt];
+ cntxt_node=order4_hasht[o4_cntxt];
- while(1)
- {
+ while(1)
+ {
- if(cntxt_node->order4321==full_o4_cntxt) //compare context
- goto ppmc_gtfo4_cntxt_found;
+ if(cntxt_node->order4321==full_o4_cntxt) //compare context
+ goto ppmc_gtfo4_cntxt_found;
- if(cntxt_node->next==0) //end of context's linked list
- break;
+ if(cntxt_node->next==0) //end of context's linked list
+ break;
- cntxt_node=cntxt_node->next; //next element
+ cntxt_node=cntxt_node->next; //next element
- }
+ }
- // Once there the context was not found
- o4_context=cntxt_node; //pointer to last element in the linked list
+ // Once there the context was not found
+ o4_context=cntxt_node; //pointer to last element in the linked list
- return 0; //it was not present
+ return 0; //it was not present
- // The context is found, so return pointer and cump
+ // The context is found, so return pointer and cump
- ppmc_gtfo4_cntxt_found:
+ppmc_gtfo4_cntxt_found:
- o4_context=cntxt_node;
+ o4_context=cntxt_node;
- // Total cump is current total cump plus the escape for the escape code
+ // Total cump is current total cump plus the escape for the escape code
- total_cump=o4_context->defined_bytes+o4_context->max_cump;
+ total_cump=o4_context->defined_bytes+o4_context->max_cump;
- return 1; //context found
+ return 1; //context found
}
// In case the byte is coded under this context, coded_in_order=4.
char ppmc_code_byte_order4(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Get current context (if present) and total cump.
+ // Get current context (if present) and total cump.
- if(ppmc_get_totf_order4()==0)
- return 0;
+ if(ppmc_get_totf_order4()==0)
+ return 0;
- // See if the byte is present and compute its cump at the same time
+ // See if the byte is present and compute its cump at the same time
- node=o4_context->prob; //pointer to first element in the linked list
+ node=o4_context->prob; //pointer to first element in the linked list
- symb_cump=0; //the first symbol always has a 0 cump
+ symb_cump=0; //the first symbol always has a 0 cump
- // Now search the byte in the linked list
+ // Now search the byte in the linked list
- do{
- if(node->byte==byte)
- goto ppmc_o4_byte_found; //bad thing, I know, anyone has a better idea?
- symb_cump+=node->freq; //add the probability of this byte to the cump
- if(node->next==0)
- break;
- node=node->next; //next element in the linked list
- }while(1);
+ do{
+ if(node->byte==byte)
+ goto ppmc_o4_byte_found; //bad thing, I know, anyone has a better idea?
+ symb_cump+=node->freq; //add the probability of this byte to the cump
+ if(node->next==0)
+ break;
+ node=node->next; //next element in the linked list
+ }while(1);
- // If we reach that point, the byte was not found in the linked list
- // so we don't need the cump, we have to output an escape code, whose
- // probabilities are know using the context structure in the table.
+ // If we reach that point, the byte was not found in the linked list
+ // so we don't need the cump, we have to output an escape code, whose
+ // probabilities are know using the context structure in the table.
- // Byte was not present in the linked list, current node is the last one,
- // and that's the node needed for creating a new node, save it.
+ // Byte was not present in the linked list, current node is the last one,
+ // and that's the node needed for creating a new node, save it.
- o4_ll_node=node;
+ o4_ll_node=node;
- // Now get the probability and cump of the escape code
+ // Now get the probability and cump of the escape code
- symb_cump=o4_context->max_cump;
- symb_prob=o4_context->defined_bytes;
+ symb_cump=o4_context->max_cump;
+ symb_prob=o4_context->defined_bytes;
- // Code the escape code
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ // Code the escape code
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 0;
+ return 0;
- // That code is executed when the byte is found in the linked list
+ // That code is executed when the byte is found in the linked list
- ppmc_o4_byte_found:
+ppmc_o4_byte_found:
- // Everything has been tested, now we can feel free to code the byte,
- // the symb_cump is already computed, now get its probability and code
- // the byte, also save pointer to this element in the linked lists for
- // updating.
+ // Everything has been tested, now we can feel free to code the byte,
+ // the symb_cump is already computed, now get its probability and code
+ // the byte, also save pointer to this element in the linked lists for
+ // updating.
- coded_in_order=4; //successfully coded under order-4
+ coded_in_order=4; //successfully coded under order-4
- o4_ll_node=node; //save it for updating
+ o4_ll_node=node; //save it for updating
- symb_prob=node->freq; //get the probability of the byte
+ symb_prob=node->freq; //get the probability of the byte
- // Code it.
+ // Code it.
- range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
+ range_coder_encode(&rc_coder,total_cump,symb_cump,symb_prob);
- return 1; //byte coded under order-4
+ return 1; //byte coded under order-4
}
void ppmc_update_order4(void)
{
- // First thing first, check if the hash entry is initialized
+ // First thing first, check if the hash entry is initialized
- if(order4_hasht[o4_cntxt]==0) //no pointer to linked list defined yet
- {
+ if(order4_hasht[o4_cntxt]==0) //no pointer to linked list defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- order4_hasht[o4_cntxt]=_context_pool;
+ order4_hasht[o4_cntxt]=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o4_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o4_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // The byte was coded under order three, otherwise it was coded under a
- // lower order (never higher ones, remember that we are using update
- // exclusion) in this case we have to create a new node in the list.
+ // The byte was coded under order three, otherwise it was coded under a
+ // lower order (never higher ones, remember that we are using update
+ // exclusion) in this case we have to create a new node in the list.
- if(coded_in_order==4) //coded under order-4
- {
+ if(coded_in_order==4) //coded under order-4
+ {
- // Update its count and variables of this context and check for renormalization
+ // Update its count and variables of this context and check for renormalization
- o4_ll_node->freq++; //increment its frequency (rather probability)
+ o4_ll_node->freq++; //increment its frequency (rather probability)
- o4_context->max_cump++; //total cump
+ o4_context->max_cump++; //total cump
- if(o4_ll_node->freq==255) //do we have to renormalize?
- ppmc_renormalize_order4(); //renormalize
+ if(o4_ll_node->freq==255) //do we have to renormalize?
+ ppmc_renormalize_order4(); //renormalize
- }
- else
- {
+ }
+ else
+ {
- // Now we have two cases, under a given context (which we actually found)
- // we coded an escape coded, in that case just create a new node in the
- // linked list of bytes and probabilities. Otherwise we didn't find the
- // same node so we have to create it in the linked list for context.
- // And we can be sure that it at least has one element and that
- // "o4_context" points to the last element, so we can put the new element.
+ // Now we have two cases, under a given context (which we actually found)
+ // we coded an escape coded, in that case just create a new node in the
+ // linked list of bytes and probabilities. Otherwise we didn't find the
+ // same node so we have to create it in the linked list for context.
+ // And we can be sure that it at least has one element and that
+ // "o4_context" points to the last element, so we can put the new element.
- if(o4_context->order4321==full_o4_cntxt) //chech if that's the last
- { //element or the a context found
+ if(o4_context->order4321==full_o4_cntxt) //chech if that's the last
+ { //element or the a context found
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- o4_ll_node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ o4_ll_node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- o4_context->max_cump++; //total cump
- o4_context->defined_bytes++; //total cump
+ o4_context->max_cump++; //total cump
+ o4_context->defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
- }
- else
- {
+ }
+ }
+ else
+ {
- // We have to create a new context node
+ // We have to create a new context node
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- o4_context->next=_context_pool;
+ o4_context->next=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o4_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o4_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- }
+ }
- }
+ }
}
// variables.
void ppmc_renormalize_order4(void)
{
- unsigned long counter;
- struct _byte_and_freq *node;
+ unsigned long counter;
+ struct _byte_and_freq *node;
- // Initialize variables. Defined bytes remain the same.
- o4_context->max_cump=0; //clear them
+ // Initialize variables. Defined bytes remain the same.
+ o4_context->max_cump=0; //clear them
- node=o4_context->prob; //get pointer to lined lists
+ node=o4_context->prob; //get pointer to lined lists
- // Divide all the probabilities by 2 and update context variables
- while(1)
- {
- node->freq>>=1; //divide by a factor of 2
+ // Divide all the probabilities by 2 and update context variables
+ while(1)
+ {
+ node->freq>>=1; //divide by a factor of 2
- if(node->freq==0) //don't allow a probability to be 0
- node->freq=1;
+ if(node->freq==0) //don't allow a probability to be 0
+ node->freq=1;
- o4_context->max_cump+=node->freq; //sum to the total cump
+ o4_context->max_cump+=node->freq; //sum to the total cump
- if(node->next==0) //last element
- break;
- node=node->next;
- }
+ if(node->next==0) //last element
+ break;
+ node=node->next;
+ }
}
// "o4_ll_node" the pointer to its node. (so updating is faster)
void ppmc_decode_order4(void)
{
- unsigned long current_cump, counter;
- struct _byte_and_freq *node;
+ unsigned long current_cump, counter;
+ struct _byte_and_freq *node;
- // Get current context (if present) and total cump.
+ // Get current context (if present) and total cump.
- if(ppmc_get_totf_order4()==0)
- {
- byte=-1;
- return;
- }
+ if(ppmc_get_totf_order4()==0)
+ {
+ byte=-1;
+ return;
+ }
- // Decode current cump
+ // Decode current cump
- symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
+ symb_cump=range_decoder_decode(&rc_decoder,total_cump); //decode it
- // Now check if it's an escape code
- if(symb_cump>=o4_context->max_cump) //the defined code space for the escape code
- {
+ // Now check if it's an escape code
+ if(symb_cump>=o4_context->max_cump) //the defined code space for the escape code
+ {
- // Update coding values
+ // Update coding values
- ppmc_get_escape_prob_order4();
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ ppmc_get_escape_prob_order4();
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Mark as escape code
+ // Mark as escape code
- byte=-1;
+ byte=-1;
- return; //an escape code
- }
- else
- {
- // Now we have to check what symbol it is
+ return; //an escape code
+ }
+ else
+ {
+ // Now we have to check what symbol it is
- current_cump=0; //cump of the current symbol
+ current_cump=0; //cump of the current symbol
- node=o4_context->prob; //get pointer to linked lists
+ node=o4_context->prob; //get pointer to linked lists
- while(1)
- {
- current_cump+=node->freq; //update cump
- if(symb_cump<current_cump)
- break; //symbol found, break search loop
+ while(1)
+ {
+ current_cump+=node->freq; //update cump
+ if(symb_cump<current_cump)
+ break; //symbol found, break search loop
- node=node->next; //next element
- //we have no need to check for the last symbol, we'll never read further
- //the end of the linked lists, before we'll found the last byte.
- }
+ node=node->next; //next element
+ //we have no need to check for the last symbol, we'll never read further
+ //the end of the linked lists, before we'll found the last byte.
+ }
- //read byte value and probability
+ //read byte value and probability
- symb_prob=node->freq; //get the probability for updating the state
- byte=node->byte; //get byte
- o4_ll_node=node; //used for updating
+ symb_prob=node->freq; //get the probability for updating the state
+ byte=node->byte; //get byte
+ o4_ll_node=node; //used for updating
- // Get the cump of byte
+ // Get the cump of byte
- symb_cump=current_cump-symb_prob;
+ symb_cump=current_cump-symb_prob;
- // Update coding state
+ // Update coding state
- range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
+ range_decoder_update(&rc_decoder,total_cump,symb_cump,symb_prob);
- // Update coded_in_order used for update exclusion
+ // Update coded_in_order used for update exclusion
- coded_in_order=4;
+ coded_in_order=4;
- return;
- }
+ return;
+ }
}
// linked list.
void ppmc_update_dec_order4(void)
{
- struct _byte_and_freq *node;
+ struct _byte_and_freq *node;
- // First thing first, check if the hash entry is initialized
+ // First thing first, check if the hash entry is initialized
- if(order4_hasht[o4_cntxt]==0) //no pointer to linked list defined yet
- {
+ if(order4_hasht[o4_cntxt]==0) //no pointer to linked list defined yet
+ {
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- order4_hasht[o4_cntxt]=_context_pool;
+ order4_hasht[o4_cntxt]=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o4_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o4_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- return; //nothing else to do
- }
+ return; //nothing else to do
+ }
- // The byte was coded under order four, otherwise it was coded under a
- // lower order (never higher ones, remember that we are using update
- // exclusion) in this case we have to create a new node in the list.
+ // The byte was coded under order four, otherwise it was coded under a
+ // lower order (never higher ones, remember that we are using update
+ // exclusion) in this case we have to create a new node in the list.
- if(coded_in_order==4) //coded under order-4
- {
+ if(coded_in_order==4) //coded under order-4
+ {
- // Update its count and variables of this context and check for renormalization
+ // Update its count and variables of this context and check for renormalization
- o4_ll_node->freq++; //increment its frequency (rather probability)
+ o4_ll_node->freq++; //increment its frequency (rather probability)
- o4_context->max_cump++; //total cump
+ o4_context->max_cump++; //total cump
- if(o4_ll_node->freq==255) //do we have to renormalize?
- ppmc_renormalize_order4(); //renormalize
+ if(o4_ll_node->freq==255) //do we have to renormalize?
+ ppmc_renormalize_order4(); //renormalize
- }
- else
- {
+ }
+ else
+ {
- // Now we have two cases, under a given context (which we actually found)
- // we coded an escape coded, in that case just create a new node in the
- // linked list of bytes and probabilities. Otherwise we didn't find the
- // same node so we have to create it in the linked list for context.
- // And we can be sure that it at least has one element and that
- // "o4_context" points to the last element, so we can put the new element.
+ // Now we have two cases, under a given context (which we actually found)
+ // we coded an escape coded, in that case just create a new node in the
+ // linked list of bytes and probabilities. Otherwise we didn't find the
+ // same node so we have to create it in the linked list for context.
+ // And we can be sure that it at least has one element and that
+ // "o4_context" points to the last element, so we can put the new element.
- if(o4_context->order4321==full_o4_cntxt) //chech if that's the last
- { //element or the a context found
+ if(o4_context->order4321==full_o4_cntxt) //chech if that's the last
+ { //element or the a context found
- // Read till the end of the linked list
+ // Read till the end of the linked list
- node=o4_context->prob; //get pointer to linked list
+ node=o4_context->prob; //get pointer to linked list
- while(1)
- {
- if(node->next==0) //check for the end of the linked list
- break;
- node=node->next; //next node
- }
+ while(1)
+ {
+ if(node->next==0) //check for the end of the linked list
+ break;
+ node=node->next; //next node
+ }
- // Now add element
+ // Now add element
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate mem
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate mem
- node->next=_bytes_pool; //put it in the next free entry
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ node->next=_bytes_pool; //put it in the next free entry
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- o4_context->max_cump++; //total cump
- o4_context->defined_bytes++; //total cump
+ o4_context->max_cump++; //total cump
+ o4_context->defined_bytes++; //total cump
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
- }
- else
- {
+ }
+ }
+ else
+ {
- // We have to create a new context node
+ // We have to create a new context node
- if(ppmc_out_of_memory==1)
- return; //exit this function, we can't allocate memory
+ if(ppmc_out_of_memory==1)
+ return; //exit this function, we can't allocate memory
- // First create the context
+ // First create the context
- o4_context->next=_context_pool;
+ o4_context->next=_context_pool;
- _context_pool->next=0; //this is the last element
- _context_pool->order4321=full_o4_cntxt; //put context
- _context_pool->prob=_bytes_pool; //pointer to linked list
- _context_pool->max_cump=1;
- _context_pool->defined_bytes=1;
+ _context_pool->next=0; //this is the last element
+ _context_pool->order4321=full_o4_cntxt; //put context
+ _context_pool->prob=_bytes_pool; //pointer to linked list
+ _context_pool->max_cump=1;
+ _context_pool->defined_bytes=1;
- // Do update of linked list variables and memory use of contexts
+ // Do update of linked list variables and memory use of contexts
- ++_context_pool; //next time use next entry (this is a pointer)
+ ++_context_pool; //next time use next entry (this is a pointer)
- if(_context_pool==_context_pool_max) //maximum reached
- {
+ if(_context_pool==_context_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_context_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_context_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_context_pool=(struct context *)malloc
- (sizeof(struct context)*_context_pool_elements_inc))==NULL)
- {
- printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_context_pool=(struct context *)malloc
+ (sizeof(struct context)*_context_pool_elements_inc))==NULL)
+ {
+ printf("Can't allocate memory for context's memory pool.\nIndex: %d",_context_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _context_pool_array[_context_pool_index]=_context_pool;
+ _context_pool_array[_context_pool_index]=_context_pool;
- _context_pool_max=_context_pool+_context_pool_elements_inc;
+ _context_pool_max=_context_pool+_context_pool_elements_inc;
- _context_pool_index++;
+ _context_pool_index++;
- }
+ }
- // Now care about the first (and last) linked list element
+ // Now care about the first (and last) linked list element
- _bytes_pool->byte=byte; //initialize byte to current one
- _bytes_pool->freq=1; //it appeared once
- _bytes_pool->next=0; //now this is last element in ll
+ _bytes_pool->byte=byte; //initialize byte to current one
+ _bytes_pool->freq=1; //it appeared once
+ _bytes_pool->next=0; //now this is last element in ll
- // Do update of linked list variables and memory use
+ // Do update of linked list variables and memory use
- ++_bytes_pool; //next time use next entry (this is a pointer)
+ ++_bytes_pool; //next time use next entry (this is a pointer)
- if(_bytes_pool==_bytes_pool_max) //maximum reached
- {
+ if(_bytes_pool==_bytes_pool_max) //maximum reached
+ {
- // First check to see that we still have entries in the array
+ // First check to see that we still have entries in the array
- if(_bytes_pool_index==_mempool_max_index)
- {
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if(_bytes_pool_index==_mempool_max_index)
+ {
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- // Allocate memory for new buffer
+ // Allocate memory for new buffer
- if((_bytes_pool=(struct _byte_and_freq *)malloc
- (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
- {
- printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
- ppmc_out_of_memory=1; //flush
- return;
- }
+ if((_bytes_pool=(struct _byte_and_freq *)malloc
+ (sizeof(struct _byte_and_freq)*_bytes_pool_elements_inc))==NULL)
+ {
+ printf("\nCan't allocate memory for bytes memory pool.\nIndex: %d",_bytes_pool_index);
+ ppmc_out_of_memory=1; //flush
+ return;
+ }
- _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
+ _bytes_pool_array[_bytes_pool_index]=_bytes_pool;
- _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
+ _bytes_pool_max=_bytes_pool+_bytes_pool_elements_inc;
- _bytes_pool_index++;
+ _bytes_pool_index++;
- }
+ }
- }
+ }
- }
+ }
}
// This function returns the probability for the escape codes in the variables
void ppmc_get_escape_prob_order4(void)
{
- // To understand that remember that the escape allocated for the escape code
- // is above the current maximum cump and that it has a probability determined
- // by the scheme C.
+ // To understand that remember that the escape allocated for the escape code
+ // is above the current maximum cump and that it has a probability determined
+ // by the scheme C.
- symb_prob=o4_context->defined_bytes;
- symb_cump=o4_context->max_cump;
+ symb_prob=o4_context->defined_bytes;
+ symb_cump=o4_context->max_cump;
}