Revision bbce362f
Added by David Sorber about 8 years ago
| software/packJPG_library/lib_src/packjpg.cpp | ||
|---|---|---|
|
#define CLAMPED(l,h,v) (( v < l ) ? l : ( v > h ) ? h : v)
|
||
|
|
||
|
|
||
|
|
||
|
// special realloc with guaranteed free() of previous memory
|
||
|
static inline void* frealloc(void* ptr, size_t size)
|
||
|
{
|
||
| ... | ... | |
|
return n_ptr;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
function declarations: pjg-specific
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
bool pjg_encode_zstscan(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_zdst_high(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_zdst_low(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_dc(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_ac_high(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_ac_low(ArithmeticEncoder* enc, int cmp);
|
||
|
bool pjg_encode_generic(ArithmeticEncoder* enc, unsigned char* data, int len);
|
||
|
bool pjg_encode_bit(ArithmeticEncoder* enc, unsigned char bit);
|
||
|
|
||
|
bool pjg_decode_zstscan(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_zdst_high(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_zdst_low(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_dc(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_ac_high(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_ac_low(ArithmeticDecoder* dec, int cmp);
|
||
|
bool pjg_decode_generic(ArithmeticDecoder* dec, unsigned char** data, int* len);
|
||
|
bool pjg_decode_bit(ArithmeticDecoder* dec, unsigned char* bit);
|
||
|
|
||
|
void pjg_get_zerosort_scan(unsigned char* sv, int cmp);
|
||
|
bool pjg_optimize_header(void);
|
||
|
bool pjg_unoptimize_header(void);
|
||
|
|
||
|
void pjg_aavrg_prepare(unsigned short** abs_coeffs, int* weights, unsigned short* abs_store, int cmp);
|
||
|
int pjg_aavrg_context(unsigned short** abs_coeffs, int* weights, int pos, int p_y, int p_x, int r_x);
|
||
|
int pjg_lakh_context(signed short** coeffs_x, signed short** coeffs_a, int* pred_cf, int pos);
|
||
|
void get_context_nnb(int pos, int w, int* a, int* b);
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
function declarations: DCT
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
int idct_2d_fst_1x8(int cmp, int dpos, int ix, int iy);
|
||
|
int idct_2d_fst_8x1(int cmp, int dpos, int ix, int iy);
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
function declarations: prediction
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
#if defined( USE_PLOCOI )
|
||
|
int dc_coll_predictor(int cmp, int dpos);
|
||
|
#else
|
||
|
int dc_1ddct_predictor(int cmp, int dpos);
|
||
|
#endif
|
||
|
inline int plocoi(int a, int b, int c);
|
||
|
inline int median_int(int* values, int size);
|
||
|
inline float median_float(float* values, int size);
|
||
|
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
function declarations: developers functions
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
// these are developers functions, they are not needed
|
||
|
// in any way to compress jpg or decompress pjg
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#if defined(DEV_INFOS)
|
||
|
int dev_size_hdr = 0;
|
||
|
int dev_size_cmp[4] = { 0 };
|
||
|
int dev_size_zsr[4] = { 0 };
|
||
|
int dev_size_dc[4] = { 0 };
|
||
|
int dev_size_ach[4] = { 0 };
|
||
|
int dev_size_acl[4] = { 0 };
|
||
|
int dev_size_zdh[4] = { 0 };
|
||
|
int dev_size_zdl[4] = { 0 };
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Initialize static members
|
||
|
const unsigned char packJPG::appversion = 25;
|
||
|
const char* packJPG::subversion = "k";
|
||
| ... | ... | |
|
return (const char*) v_name;
|
||
|
}
|
||
|
|
||
|
/* ----------------------- Begin of library only functions -------------------------- */
|
||
|
/* ------------------- Begin of library only functions --------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
DLL export converter function
|
||
| ... | ... | |
|
lib_out_type = out_type;
|
||
|
}
|
||
|
|
||
|
/* ----------------------- End of libary only functions -------------------------- */
|
||
|
/* -------------------- End of libary only functions ----------------------- */
|
||
|
|
||
|
/* ----------------------- Begin of main interface functions -------------------------- */
|
||
|
/* ----------------- Begin of main interface functions --------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
processes one file
|
||
| ... | ... | |
|
/* ------------------- End of JPEG specific functions ---------------------- */
|
||
|
|
||
|
|
||
|
/* ------------------- End of PJG specific functions ----------------------- */
|
||
|
/* ------------------- Begin PJG specific functions ------------------------ */
|
||
|
|
||
|
#if 0
|
||
|
/* -----------------------------------------------
|
||
|
encodes frequency scanorder to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_zstscan(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_zstscan(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
model_s* model;
|
||
|
|
||
| ... | ... | |
|
int cpos; // coded position
|
||
|
int c, i;
|
||
|
|
||
|
|
||
|
// calculate zero sort scan
|
||
|
pjg_get_zerosort_scan(zsrtscan[cmp], cmp);
|
||
|
|
||
| ... | ... | |
|
cpos = 1;
|
||
|
// encode position
|
||
|
for (tpos = 0; freqlist[tpos] != zsrtscan[cmp][i]; tpos++)
|
||
|
{
|
||
|
if (freqlist[tpos] != 0)
|
||
|
{
|
||
|
cpos++;
|
||
|
}
|
||
|
}
|
||
|
// remove from list
|
||
|
freqlist[tpos] = 0;
|
||
|
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// delete model
|
||
|
delete (model);
|
||
|
delete model;
|
||
|
|
||
|
// set zero sort scan as freqscan
|
||
|
freqscan[cmp] = zsrtscan[cmp];
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes # of non zeroes to pjg (high)
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_zdst_high(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_zdst_high(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
model_s* model;
|
||
|
|
||
| ... | ... | |
|
int bc;
|
||
|
int w;
|
||
|
|
||
|
|
||
|
// init model, constants
|
||
|
model = INIT_MODEL_S(49 + 1, 25 + 1, 1);
|
||
|
zdstls = zdstdata[cmp];
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// clean up
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes # of non zeroes to pjg (low)
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_zdst_low(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_zdst_low(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
model_s* model;
|
||
|
|
||
| ... | ... | |
|
int dpos;
|
||
|
int bc;
|
||
|
|
||
|
|
||
|
// init model, constants
|
||
|
model = INIT_MODEL_S(8, 8, 2);
|
||
|
zdstls_x = zdstxlow[cmp];
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// clean up
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes DC coefficients to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_dc(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_dc(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
unsigned char* segm_tab;
|
||
|
|
||
| ... | ... | |
|
int r_x; //, r_y;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// decide segmentation setting
|
||
|
segm_tab = segm_tables[segm_cnt[cmp] - 1];
|
||
|
|
||
| ... | ... | |
|
|
||
|
// free memory / clear models
|
||
|
free(absv_store);
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes high (7x7) AC coefficients to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_ac_high(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_ac_high(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
unsigned char* segm_tab;
|
||
|
|
||
| ... | ... | |
|
int r_x; //, r_y;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// decide segmentation setting
|
||
|
segm_tab = segm_tables[segm_cnt[cmp] - 1];
|
||
|
|
||
| ... | ... | |
|
free(absv_store);
|
||
|
free(sgn_store);
|
||
|
free(zdstls);
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes first row/col AC coefficients to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_ac_low(ArithmeticEncoder* enc, int cmp)
|
||
|
bool packJPG::pjg_encode_ac_low(ArithmeticEncoder* enc, int cmp)
|
||
|
{
|
||
|
model_s* mod_len;
|
||
|
model_b* mod_sgn;
|
||
| ... | ... | |
|
int p_x, p_y;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// init models for bitlenghts and -patterns
|
||
|
mod_len = INIT_MODEL_S(11, (segm_cnt[cmp] > 11) ? segm_cnt[cmp] : 11, 2);
|
||
|
mod_res = INIT_MODEL_B(1 << 4, 2);
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// free memory / clear models
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_top);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_top;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes a stream of generic (8bit) data to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_generic(ArithmeticEncoder* enc, unsigned char* data, int len)
|
||
|
bool packJPG::pjg_encode_generic(
|
||
|
ArithmeticEncoder* enc,
|
||
|
unsigned char* data,
|
||
|
int len)
|
||
|
{
|
||
|
model_s* model;
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// arithmetic encode data
|
||
|
model = INIT_MODEL_S(256 + 1, 256, 1);
|
||
|
for (i = 0; i < len; i++)
|
||
| ... | ... | |
|
}
|
||
|
// encode end-of-data symbol (256)
|
||
|
encode_ari(enc, model, 256);
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes one bit to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_encode_bit(ArithmeticEncoder* enc, unsigned char bit)
|
||
|
bool packJPG::pjg_encode_bit(ArithmeticEncoder* enc, unsigned char bit)
|
||
|
{
|
||
|
model_b* model;
|
||
|
|
||
|
|
||
|
// encode one bit
|
||
|
model = INIT_MODEL_B(1, -1);
|
||
|
encode_ari(enc, model, bit);
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
encodes frequency scanorder to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_zstscan(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_zstscan(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
model_s* model;;
|
||
|
|
||
| ... | ... | |
|
int cpos; // coded position
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// set first position in zero sort scan
|
||
|
zsrtscan[cmp][0] = 0;
|
||
|
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// delete model
|
||
|
delete (model);
|
||
|
delete model;
|
||
|
|
||
|
// set zero sort scan as freqscan
|
||
|
freqscan[cmp] = zsrtscan[cmp];
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes # of non zeroes from pjg (high)
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_zdst_high(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_zdst_high(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
model_s* model;
|
||
|
|
||
| ... | ... | |
|
int bc;
|
||
|
int w;
|
||
|
|
||
|
|
||
|
// init model, constants
|
||
|
model = INIT_MODEL_S(49 + 1, 25 + 1, 1);
|
||
|
zdstls = zdstdata[cmp];
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// clean up
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes # of non zeroes from pjg (low)
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_zdst_low(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_zdst_low(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
model_s* model;
|
||
|
|
||
| ... | ... | |
|
int dpos;
|
||
|
int bc;
|
||
|
|
||
|
|
||
|
// init model, constants
|
||
|
model = INIT_MODEL_S(8, 8, 2);
|
||
|
zdstls_x = zdstxlow[cmp];
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// clean up
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes DC coefficients from pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_dc(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_dc(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
unsigned char* segm_tab;
|
||
|
|
||
| ... | ... | |
|
int r_x; //, r_y;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// decide segmentation setting
|
||
|
segm_tab = segm_tables[segm_cnt[cmp] - 1];
|
||
|
|
||
| ... | ... | |
|
|
||
|
// free memory / clear models
|
||
|
free(absv_store);
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes high (7x7) AC coefficients to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_ac_high(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_ac_high(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
unsigned char* segm_tab;
|
||
|
|
||
| ... | ... | |
|
int r_x;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// decide segmentation setting
|
||
|
segm_tab = segm_tables[segm_cnt[cmp] - 1];
|
||
|
|
||
| ... | ... | |
|
free(absv_store);
|
||
|
free(sgn_store);
|
||
|
free(zdstls);
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes high (7x7) AC coefficients to pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_ac_low(ArithmeticDecoder* dec, int cmp)
|
||
|
bool packJPG::pjg_decode_ac_low(ArithmeticDecoder* dec, int cmp)
|
||
|
{
|
||
|
model_s* mod_len;
|
||
|
model_b* mod_sgn;
|
||
| ... | ... | |
|
int p_x, p_y;
|
||
|
int w, bc;
|
||
|
|
||
|
|
||
|
// init models for bitlenghts and -patterns
|
||
|
mod_len = INIT_MODEL_S(11, (segm_cnt[cmp] > 11) ? segm_cnt[cmp] : 11, 2);
|
||
|
mod_res = INIT_MODEL_B(1 << 4, 2);
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// free memory / clear models
|
||
|
delete (mod_len);
|
||
|
delete (mod_res);
|
||
|
delete (mod_top);
|
||
|
delete (mod_sgn);
|
||
|
|
||
|
delete mod_len;
|
||
|
delete mod_res;
|
||
|
delete mod_top;
|
||
|
delete mod_sgn;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
deodes a stream of generic (8bit) data from pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_generic(ArithmeticDecoder* dec, unsigned char** data, int* len)
|
||
|
bool packJPG::pjg_decode_generic(
|
||
|
ArithmeticDecoder* dec,
|
||
|
unsigned char** data,
|
||
|
int* len)
|
||
|
{
|
||
|
MemoryWriter* bwrt;
|
||
|
model_s* model;
|
||
|
int c;
|
||
|
|
||
|
|
||
|
// start byte writer
|
||
|
bwrt = new MemoryWriter();
|
||
|
|
||
| ... | ... | |
|
bwrt->write_byte((unsigned char) c);
|
||
|
model->shift_context(c);
|
||
|
}
|
||
|
delete (model);
|
||
|
delete model;
|
||
|
|
||
|
// check for out of memory
|
||
|
if (bwrt->error())
|
||
| ... | ... | |
|
}
|
||
|
delete bwrt;
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
decodes one bit from pjg
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_decode_bit(ArithmeticDecoder* dec, unsigned char* bit)
|
||
|
bool packJPG::pjg_decode_bit(ArithmeticDecoder* dec, unsigned char* bit)
|
||
|
{
|
||
|
model_b* model;
|
||
|
|
||
|
|
||
|
model = INIT_MODEL_B(1, -1);
|
||
|
model_b* model = INIT_MODEL_B(1, -1);
|
||
|
(*bit) = decode_ari(dec, model);
|
||
|
delete (model);
|
||
|
|
||
|
delete model;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
get zero sort frequency scan vector
|
||
|
----------------------------------------------- */
|
||
|
void pjg_get_zerosort_scan(unsigned char* sv, int cmp)
|
||
|
void packJPG::pjg_get_zerosort_scan(unsigned char* sv, int cmp)
|
||
|
{
|
||
|
unsigned int zdist[64]; // distributions of zeroes per band
|
||
|
int bc = cmpnfo[cmp].bc;
|
||
| ... | ... | |
|
int swap;
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// preset sv & zdist
|
||
|
for (i = 0; i < 64; i++)
|
||
|
{
|
||
| ... | ... | |
|
|
||
|
// count zeroes for each frequency
|
||
|
for (bpos = 0; bpos < 64; bpos++)
|
||
|
{
|
||
|
for (dpos = 0; dpos < bc; dpos++)
|
||
|
if (colldata[cmp][bpos][dpos] == 0)
|
||
|
{
|
||
|
zdist[bpos]++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// bubble sort according to count of zeroes (descending order)
|
||
|
while (!done)
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
optimizes JFIF header for compression
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_optimize_header(void)
|
||
|
bool packJPG::pjg_optimize_header(void)
|
||
|
{
|
||
|
unsigned char type = 0x00; // type of current marker segment
|
||
|
unsigned int len = 0; // length of current marker segment
|
||
| ... | ... | |
|
unsigned int spos; // sub position
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// search for DHT (0xFFC4) & DQT (0xFFDB) marker segments
|
||
|
// header parser loop
|
||
|
while ((int) hpos < hdrs)
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
undoes the header optimizations
|
||
|
----------------------------------------------- */
|
||
|
bool pjg_unoptimize_header(void)
|
||
|
bool packJPG::pjg_unoptimize_header(void)
|
||
|
{
|
||
|
unsigned char type = 0x00; // type of current marker segment
|
||
|
unsigned int len = 0; // length of current marker segment
|
||
| ... | ... | |
|
unsigned int spos; // sub position
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// search for DHT (0xFFC4) & DQT (0xFFDB) marker segments
|
||
|
// header parser loop
|
||
|
while ((int) hpos < hdrs)
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
preparations for special average context
|
||
|
----------------------------------------------- */
|
||
|
void pjg_aavrg_prepare(unsigned short** abs_coeffs, int* weights, unsigned short* abs_store, int cmp)
|
||
|
void packJPG::pjg_aavrg_prepare(
|
||
|
unsigned short** abs_coeffs,
|
||
|
int* weights,
|
||
|
unsigned short* abs_store,
|
||
|
int cmp)
|
||
|
{
|
||
|
int w = cmpnfo[cmp].bch;
|
||
|
|
||
| ... | ... | |
|
weights[5] = abs_ctx_weights_lum[0][2][1]; // left
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
special average context used in coeff encoding
|
||
|
----------------------------------------------- */
|
||
|
int pjg_aavrg_context(unsigned short** abs_coeffs, int* weights, int pos, int p_y, int p_x, int r_x)
|
||
|
int packJPG::pjg_aavrg_context(
|
||
|
unsigned short** abs_coeffs,
|
||
|
int* weights,
|
||
|
int pos,
|
||
|
int p_y,
|
||
|
int p_x,
|
||
|
int r_x)
|
||
|
{
|
||
|
int ctx_avr = 0; // AVERAGE context
|
||
|
int w_ctx = 0; // accumulated weight of context
|
||
|
int w_curr; // current weight of context
|
||
|
|
||
|
|
||
|
// different cases due to edge treatment
|
||
|
if (p_y >= 2)
|
||
|
{
|
||
| ... | ... | |
|
return (w_ctx != 0) ? (ctx_avr + (w_ctx / 2)) / w_ctx : 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
lakhani ac context used in coeff encoding
|
||
|
----------------------------------------------- */
|
||
|
int pjg_lakh_context(signed short** coeffs_x, signed short** coeffs_a, int* pred_cf, int pos)
|
||
|
int packJPG::pjg_lakh_context(
|
||
|
signed short** coeffs_x,
|
||
|
signed short** coeffs_a,
|
||
|
int* pred_cf,
|
||
|
int pos)
|
||
|
{
|
||
|
int pred = 0;
|
||
|
|
||
| ... | ... | |
|
return pred;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Calculates coordinates for nearest neighbor context
|
||
|
----------------------------------------------- */
|
||
|
void get_context_nnb(int pos, int w, int* a, int* b)
|
||
|
void packJPG::get_context_nnb(int pos, int w, int* a, int* b)
|
||
|
{
|
||
|
// this function calculates and returns coordinates for
|
||
|
// a simple 2D context
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
/* ----------------------- End of PJG specific functions -------------------------- */
|
||
|
|
||
|
/* ----------------------- Begin ofDCT specific functions -------------------------- */
|
||
|
/* -------------------- End of PJG specific functions ---------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
inverse DCT transform using precalc tables (fast)
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* ------------------- Begin of DCT specific functions --------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
inverse DCT transform using precalc tables (fast)
|
||
|
----------------------------------------------- */
|
||
|
int idct_2d_fst_8x1(int cmp, int dpos, int ix, int iy)
|
||
|
int packJPG::idct_2d_fst_8x1(int cmp, int dpos, int ix, int iy)
|
||
|
{
|
||
|
int idct = 0;
|
||
|
int ixy;
|
||
|
|
||
|
|
||
|
// calculate start index
|
||
|
ixy = ix << 3;
|
||
|
|
||
| ... | ... | |
|
idct += colldata[cmp][27][dpos] * adpt_idct_8x1[cmp][ixy + 6];
|
||
|
idct += colldata[cmp][28][dpos] * adpt_idct_8x1[cmp][ixy + 7];
|
||
|
|
||
|
|
||
|
return idct;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
inverse DCT transform using precalc tables (fast)
|
||
|
----------------------------------------------- */
|
||
|
int idct_2d_fst_1x8(int cmp, int dpos, int ix, int iy)
|
||
|
int packJPG::idct_2d_fst_1x8(int cmp, int dpos, int ix, int iy)
|
||
|
{
|
||
|
int idct = 0;
|
||
|
int ixy;
|
||
|
|
||
|
|
||
|
// calculate start index
|
||
|
ixy = iy << 3;
|
||
|
|
||
| ... | ... | |
|
idct += colldata[cmp][21][dpos] * adpt_idct_1x8[cmp][ixy + 6];
|
||
|
idct += colldata[cmp][35][dpos] * adpt_idct_1x8[cmp][ixy + 7];
|
||
|
|
||
|
|
||
|
return idct;
|
||
|
}
|
||
|
|
||
|
/* ----------------------- End of DCT specific functions -------------------------- */
|
||
|
/* ------------------- End of DCT specific functions ----------------------- */
|
||
|
|
||
|
/* ----------------------- Begin of prediction functions -------------------------- */
|
||
|
|
||
|
/* -------------------- Begin of prediction functions ---------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
returns predictor for collection data
|
||
|
----------------------------------------------- */
|
||
|
#if defined(USE_PLOCOI)
|
||
|
int dc_coll_predictor(int cmp, int dpos)
|
||
|
//~ #if defined(USE_PLOCOI)
|
||
|
int packJPG::dc_coll_predictor(int cmp, int dpos)
|
||
|
{
|
||
|
signed short* coefs = colldata[cmp][0];
|
||
|
int w = cmpnfo[cmp].bch;
|
||
| ... | ... | |
|
|
||
|
return plocoi(a, b, c);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
//~ #endif
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
1D DCT predictor for DC coefficients
|
||
|
----------------------------------------------- */
|
||
|
#if !defined(USE_PLOCOI)
|
||
|
int dc_1ddct_predictor(int cmp, int dpos)
|
||
|
//~ #if !defined(USE_PLOCOI)
|
||
|
int packJPG::dc_1ddct_predictor(int cmp, int dpos)
|
||
|
{
|
||
|
int w = cmpnfo[cmp].bch;
|
||
|
int px = (dpos % w);
|
||
| ... | ... | |
|
int xb = 0;
|
||
|
int swap;
|
||
|
|
||
|
|
||
|
// store current block DC coefficient
|
||
|
swap = colldata[cmp][0][dpos];
|
||
|
colldata[cmp][0][dpos] = 0;
|
||
| ... | ... | |
|
|
||
|
return pred;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
loco-i predictor
|
||
|
----------------------------------------------- */
|
||
|
inline int plocoi(int a, int b, int c)
|
||
|
{
|
||
|
// a -> left; b -> above; c -> above-left
|
||
|
int min, max;
|
||
|
|
||
|
min = (a < b) ? a : b;
|
||
|
max = (a > b) ? a : b;
|
||
|
|
||
|
if (c >= max)
|
||
|
{
|
||
|
return min;
|
||
|
}
|
||
|
if (c <= min)
|
||
|
{
|
||
|
return max;
|
||
|
}
|
||
|
|
||
|
return a + b - c;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
calculates median out of an integer array
|
||
|
----------------------------------------------- */
|
||
|
inline int median_int(int* values, int size)
|
||
|
{
|
||
|
int middle = (size >> 1);
|
||
|
bool done;
|
||
|
int swap;
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// sort data first
|
||
|
done = false;
|
||
|
while (!done)
|
||
|
{
|
||
|
done = true;
|
||
|
for (i = 1; i < size; i++)
|
||
|
if (values[i] < values[i - 1])
|
||
|
{
|
||
|
swap = values[i];
|
||
|
values[i] = values[i - 1];
|
||
|
values[i - 1] = swap;
|
||
|
done = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// return median
|
||
|
return ((size % 2) == 0) ?
|
||
|
(values[middle] + values[middle - 1]) / 2 : values[middle];
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
calculates median out of an float array
|
||
|
----------------------------------------------- */
|
||
|
inline float median_float(float* values, int size)
|
||
|
{
|
||
|
int middle = (size >> 1);
|
||
|
bool done;
|
||
|
float swap;
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// sort data first
|
||
|
done = false;
|
||
|
while (!done)
|
||
|
{
|
||
|
done = true;
|
||
|
for (i = 1; i < size; i++)
|
||
|
if (values[i] < values[i - 1])
|
||
|
{
|
||
|
swap = values[i];
|
||
|
values[i] = values[i - 1];
|
||
|
values[i - 1] = swap;
|
||
|
done = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// return median
|
||
|
if ((size % 2) == 0)
|
||
|
{
|
||
|
return (values[middle] + values[middle - 1]) / 2.0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return (values[middle]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* ----------------------- End of prediction functions -------------------------- */
|
||
|
|
||
|
/* ----------------------- Begin of miscellaneous helper functions -------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
displays progress bar on screen
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
creates filename, callocs memory for it
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
creates filename, callocs memory for it
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
changes extension of filename
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
adds underscore after filename
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* ----------------------- End of miscellaneous helper functions -------------------------- */
|
||
|
|
||
|
/* ----------------------- Begin of developers functions -------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes header file
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes huffman coded file
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes collections of DCT coefficients
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes zero distribution data to file;
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes to file
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes error info file
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes info to textfile
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Writes distribution for use in valdist.h
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
Do inverse DCT and write pgms
|
||
|
----------------------------------------------- */
|
||
|
|
||
|
/* ----------------------- End of developers functions -------------------------- */
|
||
|
|
||
|
/* ----------------------- End of file -------------------------- */
|
||
|
|
||
|
#endif
|
||
|
//~ #endif
|
||
| software/packJPG_library/lib_src/packjpg.h | ||
|---|---|---|
|
/**************************************************************************
|
||
|
* PJG specific functions
|
||
|
*************************************************************************/
|
||
|
|
||
|
|
||
|
|
||
|
bool pjg_encode_zstscan(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_zdst_high(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_zdst_low(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_dc(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_ac_high(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_ac_low(ArithmeticEncoder* enc, int cmp);
|
||
|
|
||
|
bool pjg_encode_generic(
|
||
|
ArithmeticEncoder* enc,
|
||
|
unsigned char* data,
|
||
|
int len);
|
||
|
|
||
|
bool pjg_encode_bit(ArithmeticEncoder* enc, unsigned char bit);
|
||
|
|
||
|
bool pjg_decode_zstscan(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_zdst_high(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_zdst_low(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_dc(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_ac_high(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_ac_low(ArithmeticDecoder* dec, int cmp);
|
||
|
|
||
|
bool pjg_decode_generic(
|
||
|
ArithmeticDecoder* dec,
|
||
|
unsigned char** data,
|
||
|
int* len);
|
||
|
|
||
|
bool pjg_decode_bit(ArithmeticDecoder* dec, unsigned char* bit);
|
||
|
|
||
|
void pjg_get_zerosort_scan(unsigned char* sv, int cmp);
|
||
|
|
||
|
bool pjg_optimize_header(void);
|
||
|
|
||
|
bool pjg_unoptimize_header(void);
|
||
|
|
||
|
void pjg_aavrg_prepare(
|
||
|
unsigned short** abs_coeffs,
|
||
|
int* weights,
|
||
|
unsigned short* abs_store,
|
||
|
int cmp);
|
||
|
|
||
|
int pjg_aavrg_context(
|
||
|
unsigned short** abs_coeffs,
|
||
|
int* weights,
|
||
|
int pos,
|
||
|
int p_y,
|
||
|
int p_x,
|
||
|
int r_x);
|
||
|
|
||
|
int pjg_lakh_context(
|
||
|
signed short** coeffs_x,
|
||
|
signed short** coeffs_a,
|
||
|
int* pred_cf,
|
||
|
int pos);
|
||
|
|
||
|
void get_context_nnb(int pos, int w, int* a, int* b);
|
||
|
|
||
|
/**************************************************************************
|
||
|
* DCT functions
|
||
|
*************************************************************************/
|
||
|
|
||
|
int idct_2d_fst_8x1(int cmp, int dpos, int ix, int iy);
|
||
|
|
||
|
int idct_2d_fst_1x8(int cmp, int dpos, int ix, int iy);
|
||
|
|
||
|
/**************************************************************************
|
||
|
* Prediction functions
|
||
|
*************************************************************************/
|
||
|
|
||
|
int dc_coll_predictor(int cmp, int dpos);
|
||
|
|
||
|
int dc_1ddct_predictor(int cmp, int dpos);
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
loco-i predictor
|
||
|
----------------------------------------------- */
|
||
|
inline int plocoi(int a, int b, int c)
|
||
|
{
|
||
|
// a -> left; b -> above; c -> above-left
|
||
|
|
||
|
int min = (a < b) ? a : b;
|
||
|
int max = (a > b) ? a : b;
|
||
|
|
||
|
if (c >= max)
|
||
|
{
|
||
|
return min;
|
||
|
}
|
||
|
if (c <= min)
|
||
|
{
|
||
|
return max;
|
||
|
}
|
||
|
|
||
|
return a + b - c;
|
||
|
}
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
calculates median out of an integer array
|
||
|
----------------------------------------------- */
|
||
|
inline int median_int(int* values, int size)
|
||
|
{
|
||
|
int middle = (size >> 1);
|
||
|
bool done;
|
||
|
int swap;
|
||
|
int i;
|
||
|
|
||
|
// sort data first
|
||
|
done = false;
|
||
|
while (!done)
|
||
|
{
|
||
|
done = true;
|
||
|
for (i = 1; i < size; i++)
|
||
|
{
|
||
|
if (values[i] < values[i - 1])
|
||
|
{
|
||
|
swap = values[i];
|
||
|
values[i] = values[i - 1];
|
||
|
values[i - 1] = swap;
|
||
|
done = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// return median
|
||
|
return ((size % 2) == 0) ?
|
||
|
(values[middle] + values[middle - 1]) / 2 : values[middle];
|
||
|
}
|
||
|
|
||
|
/* -----------------------------------------------
|
||
|
calculates median out of an float array
|
||
|
----------------------------------------------- */
|
||
|
inline float median_float(float* values, int size)
|
||
|
{
|
||
|
int middle = (size >> 1);
|
||
|
bool done;
|
||
|
float swap;
|
||
|
int i;
|
||
|
|
||
|
|
||
|
// sort data first
|
||
|
done = false;
|
||
|
while (!done)
|
||
|
{
|
||
|
done = true;
|
||
|
for (i = 1; i < size; i++)
|
||
|
{
|
||
|
if (values[i] < values[i - 1])
|
||
|
{
|
||
|
swap = values[i];
|
||
|
values[i] = values[i - 1];
|
||
|
values[i - 1] = swap;
|
||
|
done = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// return median
|
||
|
if ((size % 2) == 0)
|
||
|
{
|
||
|
return (values[middle] + values[middle - 1]) / 2.0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return (values[middle]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**************************************************************************
|
||
|
* Member variables
|
||
WIP for libpackjpg reorganization: finished moving functions into the
wrapper class