/******************************************************************************* * モジュール名称 :Application Common Compression: Aith-1st order * * モジュールラベル :Common App * * タスク区分 :Common Functions * * 機能 :MWをラップする共通関数定義を行う * * 使用上の注意 :特になし * * 作成日・作成者 :2015/5/6 Y.K. * *******************************************************************************/ #include "dpu_api.h" #include "dpu_api_proto.h" #include "app_core.h" // ************************** START of ARITH **************************** // ************************** START of ARITH **************************** // ************************** START of ARITH **************************** #define d_comp_MAXIMUM_SCALE 16383 typedef struct bit_file { unsigned char mask; int rack; int pacifier_counter; } BIT_FILE; typedef struct { unsigned short low_count; unsigned short high_count; unsigned short scale; // unsigned short low; // Start of the current code range unsigned short high; // End of the current code range int underflow_bits; // Number of underflow bits pending // unsigned short code; // The present input code value } SYMBOL; // **** CMP/EXP **** void initialize_model ( short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ); void update_model ( int symbol, int context, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ); // **** ARRAY **** // short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] // ================================================================================= // ==== START of COMPRESSION part ================================================== // ================================================================================= // **** CMP **** // void convert_int_to_symbol ( int, int, SYMBOL *, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ); void encode_symbol ( BIT_FILE *, SYMBOL *, unsigned char *, int * ); //void flush_arithmetic_encoder ( BIT_FILE *, SYMBOL *, unsigned char *, int * ); void OutputBit ( BIT_FILE *, int, unsigned char *, int * ); void OutputBits( BIT_FILE *, unsigned int, int, unsigned char *, int * ); int app_CompArith( unsigned char uc_data[], unsigned char uc_data2[], int i_size, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { int i; int c; int context; int i_size2 = 0; SYMBOL s; BIT_FILE s_cmp; // --- INIT --- s_cmp.rack = 0; s_cmp.mask = 0x80; s_cmp.pacifier_counter = 0; context = 0; initialize_model( s_comp_totals ); s.low = 0; s.high = 0xffff; s.underflow_bits = 0; for (i=0; i= i_size ) return( -1 ); update_model( c, context, s_comp_totals ); context = c; } // // flush_arithmetic_encoder( &s_cmp, &s, uc_data2, &i_size2 ); OutputBit( &s_cmp, s.low & 0x4000, uc_data2, &i_size2 ); s.underflow_bits ++; while ( s.underflow_bits -- > 0 ) OutputBit( &s_cmp, ‾(s.low) & 0x4000, uc_data2, &i_size2 ); OutputBits( &s_cmp, 0L, 16, uc_data2, &i_size2 ); // if ( s_cmp.mask != 0x80 ) uc_data2[ i_size2 ++ ] = s_cmp.rack; return( i_size2 ); } void initialize_model( short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { int context; int i; for ( context = 0 ; context < d_comp_END_OF_STREAM ; context++ ) { for ( i = 0 ; i <= ( d_comp_END_OF_STREAM + 1 ) ; i++ ) { s_comp_totals[ context ][ i ] = i; } } } void update_model( int symbol, int context, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { int i; for ( i = symbol + 1 ; i <= ( d_comp_END_OF_STREAM + 1 ) ; i++ ) { s_comp_totals [ context ][ i ]++; } if ( s_comp_totals[ context ][ d_comp_END_OF_STREAM + 1 ] < d_comp_MAXIMUM_SCALE ) { return; } for ( i = 1 ; i <= ( d_comp_END_OF_STREAM + 1 ) ; i++ ) { s_comp_totals[ context ][ i ] /= 2; if ( s_comp_totals[ context ][ i ] <= s_comp_totals[ context ][ i-1 ] ) { s_comp_totals[ context ][ i ] = s_comp_totals[ context ][ i-1 ] + 1; } } } /* void convert_int_to_symbol( int c, int context, SYMBOL *s, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { s->scale = s_comp_totals[ context ][ d_comp_END_OF_STREAM + 1 ]; s->low_count = s_comp_totals[ context ][ c ]; s->high_count = s_comp_totals[ context ][ c + 1 ]; } */ void encode_symbol( BIT_FILE *stream, SYMBOL *s, unsigned char uc_data2[], int * ip_size2 ) { int range; range = (int) ( s->high - s->low ) + 1; s->high = s->low + (unsigned short)(( range * s->high_count ) / s->scale - 1 ); s->low = s->low + (unsigned short)(( range * s->low_count ) / s->scale ); for ( ; ; ) { if ( ( s->high & 0x8000 ) == ( s->low & 0x8000 ) ) { OutputBit( stream, s->high & 0x8000, uc_data2, ip_size2 ); while ( s->underflow_bits > 0 ) { OutputBit( stream, ‾(s->high) & 0x8000, uc_data2, ip_size2 ); s->underflow_bits --; } } else if ( ( s->low & 0x4000 ) && !( s->high & 0x4000 )) { s->underflow_bits += 1; s->low &= 0x3fff; s->high |= 0x4000; } else { return ; } s->low <<= 1; s->high <<= 1; s->high |= 1; } } /* void flush_arithmetic_encoder( BIT_FILE *stream, SYMBOL *s, unsigned char uc_data2[], int * ip_size2 ) { OutputBit( stream, s->low & 0x4000, uc_data2, ip_size2 ); s->underflow_bits ++; while ( s->underflow_bits -- > 0 ) OutputBit( stream, ‾(s->low) & 0x4000, uc_data2, ip_size2 ); OutputBits( stream, 0L, 16, uc_data2, ip_size2 ); } */ void OutputBit( BIT_FILE *bit_file, int bit, unsigned char uc_data2[], int * ip_size2 ) { if ( bit ) bit_file->rack |= bit_file->mask; bit_file->mask >>= 1; if ( bit_file->mask == 0 ) { uc_data2[ (*ip_size2)++ ] = bit_file->rack; bit_file->pacifier_counter++; bit_file->rack = 0; bit_file->mask = 0x80; } } void OutputBits( BIT_FILE *bit_file, unsigned int code, int count, unsigned char uc_data2[], int * ip_size2 ) { unsigned int mask; mask = 1L << ( count - 1 ); while ( mask != 0) { if ( mask & code ) bit_file->rack |= bit_file->mask; bit_file->mask >>= 1; if ( bit_file->mask == 0 ) { uc_data2[ (*ip_size2)++ ] = bit_file->rack; bit_file->pacifier_counter++; bit_file->rack = 0; bit_file->mask = 0x80; } mask >>= 1; } } // ================================================================================= // ==== END of COMPRESSION part ==================================================== // ================================================================================= /* // ================================================================================= // ==== START of EXPANSION part ==================================================== // ================================================================================= void initialize_arithmetic_decoder( BIT_FILE *, SYMBOL *, unsigned char *, int * ); void remove_symbol_from_stream ( BIT_FILE *, SYMBOL *, unsigned char *, int * ); short get_current_count ( SYMBOL * ); void get_symbol_scale ( int, SYMBOL *, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ); int convert_symbol_to_int ( int, int, SYMBOL *, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ); int InputBit ( BIT_FILE *, unsigned char *, int * ); static unsigned short code; // The present input code value int app_ExpdArith( unsigned char uc_data[], unsigned char uc_data2[], int i_size, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { SYMBOL s; int count; int c; int context; int i_size0 = 0; int i_size2 = 0; // BIT_FILE s_cmp; s_cmp.rack = 0; s_cmp.mask = 0x80; s_cmp.pacifier_counter = 0; context = 0; initialize_model( s_comp_totals ); initialize_arithmetic_decoder( &s_cmp, &s, uc_data, &i_size0 ); for ( ; ; ) { get_symbol_scale( context, &s, s_comp_totals ); count = get_current_count( &s ); c = convert_symbol_to_int( count, context, &s, s_comp_totals ); remove_symbol_from_stream( &s_cmp, &s, uc_data, &i_size0 ); if ( c == d_comp_END_OF_STREAM ) break; uc_data2[ i_size2++ ] = (unsigned char)c; update_model( c, context, s_comp_totals ); context = c; } return( i_size2 ); } void initialize_arithmetic_decoder( BIT_FILE *stream, SYMBOL *s, unsigned char uc_data[], int * ip_size ) { int i; code = 0; for ( i = 0 ; i < 16 ; i++ ) { code <<= 1; code += InputBit( stream, uc_data, ip_size ); } s->low = 0; s->high = 0xffff; } void remove_symbol_from_stream( BIT_FILE *stream, SYMBOL *s, unsigned char uc_data[], int * ip_size ) { int range; range = (int)( s->high - s->low ) + 1; s->high = s->low + (unsigned short)(( range * s->high_count ) / s->scale - 1 ); s->low = s->low + (unsigned short)(( range * s->low_count ) / s->scale ); for ( ; ; ) { if ( ( s->high & 0x8000 ) == ( s->low & 0x8000 ) ) { } else if ((s->low & 0x4000) == 0x4000 && (s->high & 0x4000) == 0 ) { code ^= 0x4000; s->low &= 0x3fff; s->high |= 0x4000; } else return; s->low <<= 1; s->high <<= 1; s->high |= 1; code <<= 1; code += InputBit( stream, uc_data, ip_size ); } } short get_current_count( SYMBOL *s ) { int range; short count; range = (int) ( s->high - s->low ) + 1; count = (short) ((((int) ( code - s->low ) + 1 ) * s->scale-1 ) / range ); return( count ); } void get_symbol_scale( int context, SYMBOL *s, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { s->scale = s_comp_totals[ context][ d_comp_END_OF_STREAM + 1 ]; } int convert_symbol_to_int( int count, int context, SYMBOL *s, short s_comp_totals[ d_comp_END_OF_STREAM ][ d_comp_END_OF_STREAM + 2 ] ) { int c; for ( c = 0; count >= s_comp_totals[ context ][ c + 1 ] ; c++ ) ; s->high_count = s_comp_totals[ context ][ c + 1 ]; s->low_count = s_comp_totals[ context ][ c ]; return( c ); } int InputBit( BIT_FILE *bit_file, unsigned char uc_data[], int * ip_size ) { int value; if ( bit_file->mask == 0x80 ) { bit_file->rack = uc_data[ (* ip_size)++ ]; bit_file->pacifier_counter++; } value = bit_file->rack & bit_file->mask; bit_file->mask >>= 1; if ( bit_file->mask == 0 ) bit_file->mask = 0x80; return( value ? 1 : 0 ); } // *************************************************************************************** // *************************************************************************************** // *************************************************************************************** // *************************************************************************************** */