root/software/libpackjpg/lib_src/packjpg.h @ 358f0d96
| 525a7e92 | David Sorber | #ifndef PACKJPG_H
|
|
#define PACKJPG_H
|
|||
#include "bitops.h"
|
|||
#include "aricoder.h"
|
|||
#include "pjpgtbl.h"
|
|||
#include "dct8x8.h"
|
|||
#define MEM_ERRMSG "out of memory error"
|
|||
#define FRD_ERRMSG "could not read file / file not found: %s"
|
|||
#define FWR_ERRMSG "could not write file / file write-protected: %s"
|
|||
#define MSG_SIZE 128
|
|||
#define BARLEN 36
|
|||
/* -----------------------------------------------
|
|||
struct declarations
|
|||
----------------------------------------------- */
|
|||
struct componentInfo
|
|||
{
|
|||
unsigned short* qtable; // quantization table
|
|||
int huffdc; // no of huffman table (DC)
|
|||
int huffac; // no of huffman table (AC)
|
|||
int sfv; // sample factor vertical
|
|||
int sfh; // sample factor horizontal
|
|||
int mbs; // blocks in mcu
|
|||
int bcv; // block count vertical (interleaved)
|
|||
int bch; // block count horizontal (interleaved)
|
|||
int bc; // block count (all) (interleaved)
|
|||
int ncv; // block count vertical (non interleaved)
|
|||
int nch; // block count horizontal (non interleaved)
|
|||
int nc; // block count (all) (non interleaved)
|
|||
int sid; // statistical identity
|
|||
int jid; // jpeg internal id
|
|||
};
|
|||
struct huffCodes
|
|||
{
|
|||
unsigned short cval[256];
|
|||
unsigned short clen[256];
|
|||
unsigned short max_eobrun;
|
|||
};
|
|||
struct huffTree
|
|||
{
|
|||
unsigned short l[256];
|
|||
unsigned short r[256];
|
|||
};
|
|||
class packJPG
|
|||
{
|
|||
public:
|
|||
packJPG();
|
|||
~packJPG();
|
|||
static const char* pjglib_version_info(void);
|
|||
static const char* pjglib_short_name(void);
|
|||
/* -----------------------------------------------
|
|||
checks if a file exists
|
|||
----------------------------------------------- */
|
|||
inline bool file_exists(const char* filename)
|
|||
{
|
|||
// needed for both, executable and library
|
|||
FILE* fp = fopen(filename, "rb");
|
|||
if (fp == NULL)
|
|||
{
|
|||
return false;
|
|||
}
|
|||
else
|
|||
{
|
|||
fclose(fp);
|
|||
return true;
|
|||
}
|
|||
}
|
|||
/**************************************************************************
|
|||
* Library functions
|
|||
*************************************************************************/
|
|||
bool pjglib_convert_stream2stream(char* msg);
|
|||
bool pjglib_convert_file2file(char* in, char* out, char* msg);
|
|||
bool pjglib_convert_stream2mem(
|
|||
unsigned char** out_file,
|
|||
unsigned int* out_size,
|
|||
char* msg);
|
|||
void pjglib_init_streams(
|
|||
void* in_src,
|
|||
int in_type,
|
|||
int in_size,
|
|||
void* out_dest,
|
|||
int out_type);
|
|||
/**************************************************************************
|
|||
* Main interface functions
|
|||
*************************************************************************/
|
|||
void process_file(void);
|
|||
void execute(bool (*function)());
|
|||
/**************************************************************************
|
|||
* Main functions
|
|||
*************************************************************************/
|
|||
bool reset_buffers(void);
|
|||
bool read_jpeg(void);
|
|||
bool merge_jpeg(void);
|
|||
bool decode_jpeg(void);
|
|||
bool recode_jpeg(void);
|
|||
bool adapt_icos(void);
|
|||
bool predict_dc(void);
|
|||
bool unpredict_dc(void);
|
|||
bool check_value_range(void);
|
|||
bool calc_zdst_lists(void);
|
|||
bool pack_pjg(void);
|
|||
bool unpack_pjg(void);
|
|||
/* -----------------------------------------------
|
|||
global variables: info about program
|
|||
----------------------------------------------- */
|
|||
static const unsigned char appversion;
|
|||
static const char* subversion;
|
|||
static const char* apptitle;
|
|||
static const char* appname;
|
|||
static const char* versiondate;
|
|||
static const char* author;
|
|||
static const char pjg_magic[2];
|
|||
private:
|
|||
/**************************************************************************
|
|||
* JPEG specific functions
|
|||
*************************************************************************/
|
|||
bool jpg_setup_imginfo(void);
|
|||
bool jpg_parse_jfif(
|
|||
unsigned char type,
|
|||
unsigned int len,
|
|||
unsigned char* segment);
|
|||
bool jpg_rebuild_header(void);
|
|||
int jpg_decode_block_seq(
|
|||
BitReader* huffr,
|
|||
huffTree* dctree,
|
|||
huffTree* actree,
|
|||
short* block);
|
|||
int jpg_encode_block_seq(
|
|||
BitWriter* huffw,
|
|||
huffCodes* dctbl,
|
|||
huffCodes* actbl,
|
|||
short* block);
|
|||
int jpg_decode_dc_prg_fs(
|
|||
BitReader* huffr,
|
|||
huffTree* dctree,
|
|||
short* block);
|
|||
int jpg_encode_dc_prg_fs(
|
|||
BitWriter* huffw,
|
|||
huffCodes* dctbl,
|
|||
short* block);
|
|||
int jpg_decode_ac_prg_fs(
|
|||
BitReader* huffr,
|
|||
huffTree* actree,
|
|||
short* block,
|
|||
int* eobrun,
|
|||
int from,
|
|||
int to);
|
|||
int jpg_encode_ac_prg_fs(
|
|||
BitWriter* huffw,
|
|||
huffCodes* actbl,
|
|||
short* block,
|
|||
int* eobrun,
|
|||
int from,
|
|||
int to);
|
|||
int jpg_decode_dc_prg_sa(BitReader* huffr, short* block);
|
|||
int jpg_encode_dc_prg_sa(BitWriter* huffw, short* block);
|
|||
int jpg_decode_ac_prg_sa(
|
|||
BitReader* huffr,
|
|||
huffTree* actree,
|
|||
short* block,
|
|||
int* eobrun,
|
|||
int from,
|
|||
int to);
|
|||
int jpg_encode_ac_prg_sa(
|
|||
BitWriter* huffw,
|
|||
std::vector<std::uint8_t>& storw,
|
|||
huffCodes* actbl,
|
|||
short* block,
|
|||
int* eobrun,
|
|||
int from,
|
|||
int to);
|
|||
int jpg_decode_eobrun_sa(
|
|||
BitReader* huffr,
|
|||
short* block,
|
|||
int* eobrun,
|
|||
int from,
|
|||
int to);
|
|||
int jpg_encode_eobrun(
|
|||
BitWriter* huffw,
|
|||
huffCodes* actbl,
|
|||
int* eobrun);
|
|||
int jpg_encode_crbits(
|
|||
BitWriter* huffw,
|
|||
std::vector<std::uint8_t>& storw);
|
|||
int jpg_next_huffcode(BitReader* huffw, huffTree* ctree);
|
|||
int jpg_next_mcupos(
|
|||
int* mcu,
|
|||
int* cmp,
|
|||
int* csc,
|
|||
int* sub,
|
|||
int* dpos,
|
|||
int* rstw);
|
|||
int jpg_next_mcuposn(int* cmp, int* dpos, int* rstw);
|
|||
int jpg_skip_eobrun(int* cmp, int* dpos, int* rstw, int* eobrun);
|
|||
void jpg_build_huffcodes(
|
|||
unsigned char* clen,
|
|||
unsigned char* cval,
|
|||
huffCodes* hc,
|
|||
huffTree* ht);
|
|||
/**************************************************************************
|
|||
* 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
|
|||
*************************************************************************/
|
|||
/* -----------------------------------------------
|
|||
global variables: library only variables
|
|||
----------------------------------------------- */
|
|||
int lib_in_type;
|
|||
int lib_out_type;
|
|||
/* -----------------------------------------------
|
|||
global variables: data storage
|
|||
----------------------------------------------- */
|
|||
unsigned short qtables[4][64]; // quantization tables
|
|||
huffCodes hcodes[2][4]; // huffman codes
|
|||
huffTree htrees[2][4]; // huffman decoding trees
|
|||
unsigned char htset[2][4]; // 1 if huffman table is set
|
|||
unsigned char* grbgdata; // garbage data
|
|||
unsigned char* hdrdata ; // header data
|
|||
unsigned char* huffdata; // huffman coded data
|
|||
int hufs; // size of huffman data
|
|||
int hdrs; // size of header
|
|||
int grbs; // size of garbage
|
|||
unsigned int* rstp; // restart markers positions in huffdata
|
|||
unsigned int* scnp; // scan start positions in huffdata
|
|||
int rstc; // count of restart markers
|
|||
int scnc; // count of scans
|
|||
int rsti; // restart interval
|
|||
char padbit; // padbit (for huffman coding)
|
|||
unsigned char* rst_err; // number of wrong-set RST markers per scan
|
|||
unsigned char* zdstdata[4]; // zero distribution (# of non-zeroes) lists (for higher 7x7 block)
|
|||
unsigned char* eobxhigh[4]; // eob in x direction (for higher 7x7 block)
|
|||
unsigned char* eobyhigh[4]; // eob in y direction (for higher 7x7 block)
|
|||
unsigned char* zdstxlow[4]; // # of non zeroes for first row
|
|||
unsigned char* zdstylow[4]; // # of non zeroes for first collumn
|
|||
signed short* colldata[4][64]; // collection sorted DCT coefficients
|
|||
unsigned char* freqscan[4]; // optimized order for frequency scans (only pointers to scans)
|
|||
unsigned char zsrtscan[4][64]; // zero optimized frequency scan
|
|||
int adpt_idct_8x8[4][8 * 8 * 8 * 8]; // precalculated/adapted values for idct (8x8)
|
|||
int adpt_idct_1x8[4][1 * 1 * 8 * 8]; // precalculated/adapted values for idct (1x8)
|
|||
int adpt_idct_8x1[4][8 * 8 * 1 * 1]; // precalculated/adapted values for idct (8x1)
|
|||
/* -----------------------------------------------
|
|||
global variables: info about image
|
|||
----------------------------------------------- */
|
|||
componentInfo cmpnfo[4]; // seperate info for each color component
|
|||
int cmpc; // component count
|
|||
int imgwidth; // width of image
|
|||
int imgheight; // height of image
|
|||
int sfhm; // max horizontal sample factor
|
|||
int sfvm; // max verical sample factor
|
|||
int mcuv; // mcus per line
|
|||
int mcuh; // mcus per collumn
|
|||
int mcuc; // count of mcus
|
|||
/* -----------------------------------------------
|
|||
global variables: info about current scan
|
|||
----------------------------------------------- */
|
|||
int cs_cmpc; // component count in current scan
|
|||
int cs_cmp[4]; // component numbers in current scan
|
|||
int cs_from; // begin - band of current scan ( inclusive )
|
|||
int cs_to; // end - band of current scan ( inclusive )
|
|||
int cs_sah; // successive approximation bit pos high
|
|||
int cs_sal; // successive approximation bit pos low
|
|||
/* -----------------------------------------------
|
|||
global variables: info about files
|
|||
----------------------------------------------- */
|
|||
char* jpgfilename; // name of JPEG file
|
|||
char* pjgfilename; // name of PJG file
|
|||
int jpgfilesize; // size of JPEG file
|
|||
int pjgfilesize; // size of PJG file
|
|||
int jpegtype; // type of JPEG coding: 0->unknown, 1->sequential, 2->progressive
|
|||
int filetype; // type of current file
|
|||
std::unique_ptr<Reader> str_in; // input stream
|
|||
std::unique_ptr<Writer> str_out; // output stream
|
|||
/* -----------------------------------------------
|
|||
global variables: messages
|
|||
----------------------------------------------- */
|
|||
char errormessage[MSG_SIZE];
|
|||
bool (*errorfunction)();
|
|||
// meaning of errorlevel:
|
|||
// -1 -> wrong input
|
|||
// 0 -> no error
|
|||
// 1 -> warning
|
|||
// 2 -> fatal error
|
|||
int errorlevel;
|
|||
/* -----------------------------------------------
|
|||
global variables: settings
|
|||
----------------------------------------------- */
|
|||
int err_tol; // error threshold ( proceed on warnings yes (2) / no (1) )
|
|||
bool disc_meta; // discard meta-info yes / no
|
|||
bool auto_set; // automatic find best settings yes/no
|
|||
int action; // what to do with JPEG/PJG files
|
|||
unsigned char nois_trs[4]; // bit pattern noise threshold
|
|||
unsigned char segm_cnt[4]; // number of segments
|
|||
};
|
|||
#endif
|