Project

General

Profile

« Previous | Next » 

Revision 073c5385

Added by David Sorber about 8 years ago

WIP for libpackjpg reorganization: moved all main interface and main
functions inside the wrapper class

View differences:

software/packJPG_library/lib_src/packjpg.cpp
// #define DEV_BUILD // uncomment to include developer functions
// #define DEV_INFOS // uncomment to include developer information
#define QUANT(cm, bp) (cmpnfo[cm].qtable[ bp ])
#define QUANT(cm, bp) (cmpnfo[cm].qtable[bp])
#define MAX_V(cm, bp) (( QUANT(cm,bp) > 0 ) ? ( ( freqmax[bp] + QUANT(cm,bp) - 1 ) / QUANT(cm,bp) ) : 0)
// #define QUN_V(v,cm,bp) ( ( QUANT(cm,bp) > 0 ) ? ( ( v > 0 ) ? ( v + (QUANT(cm,bp)/2) ) / QUANT(cm,bp) : ( v - (QUANT(cm,bp)/2) ) / QUANT(cm,bp) ) : 0 )
......
static inline void* frealloc(void* ptr, size_t size)
{
void* n_ptr = realloc(ptr, (size) ? size : 1);
if (n_ptr == NULL)
if (n_ptr == nullptr)
{
free(ptr);
}
......
#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 };
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
......
return (const char*) v_name;
}
#if 0
/* ----------------------- Begin of library only functions -------------------------- */
/* -----------------------------------------------
DLL export converter function
----------------------------------------------- */
bool pjglib_convert_stream2stream(char* msg)
bool packJPG::pjglib_convert_stream2stream(char* msg)
{
// process in main function
return pjglib_convert_stream2mem(NULL, NULL, msg);
return pjglib_convert_stream2mem(nullptr, nullptr, msg);
}
/* -----------------------------------------------
DLL export converter function
----------------------------------------------- */
bool pjglib_convert_file2file(char* in, char* out, char* msg)
bool packJPG::pjglib_convert_file2file(char* in, char* out, char* msg)
{
// init streams
pjglib_init_streams((void*) in, 0, 0, (void*) out, 0);
// process in main function
return pjglib_convert_stream2mem(NULL, NULL, msg);
return pjglib_convert_stream2mem(nullptr, nullptr, msg);
}
/* -----------------------------------------------
DLL export converter function
----------------------------------------------- */
bool pjglib_convert_stream2mem(unsigned char** out_file, unsigned int* out_size, char* msg)
bool packJPG::pjglib_convert_stream2mem(
unsigned char** out_file,
unsigned int* out_size,
char* msg)
{
clock_t begin, end;
int total;
float cr;
// use automatic settings
auto_set = true;
......
// fetch pointer and size of output (only for memory output)
if ((errorlevel < err_tol) && (lib_out_type == 1) &&
(out_file != NULL) && (out_size != NULL))
(out_file != nullptr) && (out_size != nullptr))
{
*out_size = str_out->num_bytes_written();
*out_file = str_out->get_c_data();
......
}
}
}
if (msg != NULL)
if (msg != nullptr)
{
strcpy(msg, errormessage);
}
......
cr = (jpgfilesize > 0) ? (100.0 * pjgfilesize / jpgfilesize) : 0;
// write success message else
if (msg != NULL)
if (msg != nullptr)
{
switch (filetype)
{
......
/* -----------------------------------------------
DLL export init input (file/mem)
----------------------------------------------- */
void pjglib_init_streams(void* in_src, int in_type, int in_size, void* out_dest, int out_type)
void packJPG::pjglib_init_streams(
void* in_src,
int in_type,
int in_size,
void* out_dest,
int out_type)
{
/* a short reminder about input/output stream types:
......
vice versa for output streams! */
unsigned char buffer[ 2 ];
unsigned char buffer[2];
// (re)set errorlevel
errorfunction = NULL;
errorfunction = nullptr;
errorlevel = 0;
jpgfilesize = 0;
pjgfilesize = 0;
......
lib_out_type = out_type;
}
/* ----------------------- End of libary only functions -------------------------- */
/* ----------------------- Begin of main interface functions -------------------------- */
/* -----------------------------------------------
reads in commandline arguments
----------------------------------------------- */
/* -----------------------------------------------
UI for processing one file
----------------------------------------------- */
/* -----------------------------------------------
gets statusmessage for function
----------------------------------------------- */
/* -----------------------------------------------
shows help in case of wrong input
----------------------------------------------- */
/* -----------------------------------------------
processes one file
----------------------------------------------- */
void process_file(void)
void packJPG::process_file(void)
{
if (filetype == F_JPG)
{
switch (action)
{
case A_COMPRESS:
execute(read_jpeg);
execute(decode_jpeg);
execute(check_value_range);
execute(adapt_icos);
execute(predict_dc);
execute(calc_zdst_lists);
execute(pack_pjg);
read_jpeg();
decode_jpeg();
check_value_range();
adapt_icos();
predict_dc();
calc_zdst_lists();
pack_pjg();
break;
default:
......
switch (action)
{
case A_COMPRESS:
execute(unpack_pjg);
execute(adapt_icos);
execute(unpredict_dc);
execute(recode_jpeg);
execute(merge_jpeg);
unpack_pjg();
adapt_icos();
unpredict_dc();
recode_jpeg();
merge_jpeg();
break;
default:
break;
}
}
// reset buffers
reset_buffers();
}
/* -----------------------------------------------
main-function execution routine
----------------------------------------------- */
void execute(bool (*function)())
void packJPG::execute(bool (*function)())
{
if (errorlevel < err_tol)
{
......
(*function)();
// store errorfunction if needed
if ((errorlevel > 0) && (errorfunction == NULL))
if ((errorlevel > 0) && (errorfunction == nullptr))
{
errorfunction = function;
}
......
/* ----------------------- Begin of main functions -------------------------- */
/* -----------------------------------------------
check file and determine filetype
----------------------------------------------- */
/* -----------------------------------------------
swap streams / init verification
----------------------------------------------- */
/* -----------------------------------------------
comparison between input & output
----------------------------------------------- */
/* -----------------------------------------------
set each variable to its initial value
----------------------------------------------- */
bool reset_buffers(void)
bool packJPG::reset_buffers(void)
{
int cmp, bpos;
int i;
// -- free buffers --
// free buffers & set pointers NULL
if (hdrdata != NULL)
// free buffers & set pointers nullptr
if (hdrdata != nullptr)
{
free(hdrdata);
}
if (huffdata != NULL)
if (huffdata != nullptr)
{
free(huffdata);
}
if (grbgdata != NULL)
if (grbgdata != nullptr)
{
free(grbgdata);
}
if (rst_err != NULL)
if (rst_err != nullptr)
{
free(rst_err);
}
if (rstp != NULL)
if (rstp != nullptr)
{
free(rstp);
}
if (scnp != NULL)
if (scnp != nullptr)
{
free(scnp);
}
hdrdata = NULL;
huffdata = NULL;
grbgdata = NULL;
rst_err = NULL;
rstp = NULL;
scnp = NULL;
hdrdata = nullptr;
huffdata = nullptr;
grbgdata = nullptr;
rst_err = nullptr;
rstp = nullptr;
scnp = nullptr;
// free image arrays
for (cmp = 0; cmp < 4; cmp++)
{
if (zdstdata[ cmp ] != NULL)
if (zdstdata[cmp] != nullptr)
{
free(zdstdata[cmp]);
}
if (eobxhigh[ cmp ] != NULL)
if (eobxhigh[cmp] != nullptr)
{
free(eobxhigh[cmp]);
}
if (eobyhigh[ cmp ] != NULL)
if (eobyhigh[cmp] != nullptr)
{
free(eobyhigh[cmp]);
}
if (zdstxlow[ cmp ] != NULL)
if (zdstxlow[cmp] != nullptr)
{
free(zdstxlow[cmp]);
}
if (zdstylow[ cmp ] != NULL)
if (zdstylow[cmp] != nullptr)
{
free(zdstylow[cmp]);
}
zdstdata[ cmp ] = NULL;
eobxhigh[ cmp ] = NULL;
eobyhigh[ cmp ] = NULL;
zdstxlow[ cmp ] = NULL;
zdstylow[ cmp ] = NULL;
freqscan[ cmp ] = (unsigned char*) stdscan;
zdstdata[cmp] = nullptr;
eobxhigh[cmp] = nullptr;
eobyhigh[cmp] = nullptr;
zdstxlow[cmp] = nullptr;
zdstylow[cmp] = nullptr;
freqscan[cmp] = (unsigned char*) stdscan;
for (bpos = 0; bpos < 64; bpos++)
{
if (colldata[ cmp ][ bpos ] != NULL)
if (colldata[cmp][bpos] != nullptr)
{
free(colldata[cmp][bpos]);
}
colldata[ cmp ][ bpos ] = NULL;
colldata[cmp][bpos] = nullptr;
}
}
// -- set variables --
// preset componentinfo
for (cmp = 0; cmp < 4; cmp++)
{
cmpnfo[ cmp ].sfv = -1;
cmpnfo[ cmp ].sfh = -1;
cmpnfo[ cmp ].mbs = -1;
cmpnfo[ cmp ].bcv = -1;
cmpnfo[ cmp ].bch = -1;
cmpnfo[ cmp ].bc = -1;
cmpnfo[ cmp ].ncv = -1;
cmpnfo[ cmp ].nch = -1;
cmpnfo[ cmp ].nc = -1;
cmpnfo[ cmp ].sid = -1;
cmpnfo[ cmp ].jid = -1;
cmpnfo[ cmp ].qtable = NULL;
cmpnfo[ cmp ].huffdc = -1;
cmpnfo[ cmp ].huffac = -1;
cmpnfo[cmp].sfv = -1;
cmpnfo[cmp].sfh = -1;
cmpnfo[cmp].mbs = -1;
cmpnfo[cmp].bcv = -1;
cmpnfo[cmp].bch = -1;
cmpnfo[cmp].bc = -1;
cmpnfo[cmp].ncv = -1;
cmpnfo[cmp].nch = -1;
cmpnfo[cmp].nc = -1;
cmpnfo[cmp].sid = -1;
cmpnfo[cmp].jid = -1;
cmpnfo[cmp].qtable = nullptr;
cmpnfo[cmp].huffdc = -1;
cmpnfo[cmp].huffac = -1;
}
// preset imgwidth / imgheight / component count
......
// reset quantization / huffman tables
for (i = 0; i < 4; i++)
{
htset[ 0 ][ i ] = 0;
htset[ 1 ][ i ] = 0;
htset[0][i] = 0;
htset[1][i] = 0;
for (bpos = 0; bpos < 64; bpos++)
{
qtables[ i ][ bpos ] = 0;
qtables[i][bpos] = 0;
}
}
......
// reset padbit
padbit = -1;
return true;
}
/* -----------------------------------------------
Read in header & image data
----------------------------------------------- */
bool read_jpeg(void)
bool packJPG::read_jpeg(void)
{
unsigned char* segment = NULL; // storage for current segment
unsigned char* segment = nullptr; // storage for current segment
unsigned int ssize = 1024; // current size of segment array
unsigned char type = 0x00; // type of current marker segment
unsigned int len = 0; // length of current marker segment
......
MemoryWriter* hdrw;
MemoryWriter* grbgw;
// preset count of scans
scnc = 0;
......
// alloc memory for segment data first
segment = (unsigned char*) calloc(ssize, sizeof(char));
if (segment == NULL)
if (segment == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
// store number of wrongly set rst markers
if (crst > 0)
{
if (rst_err == NULL)
if (rst_err == nullptr)
{
rst_err = (unsigned char*) calloc(scnc + 1, sizeof(char));
if (rst_err == NULL)
if (rst_err == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
}
}
}
if (rst_err != NULL)
if (rst_err != nullptr)
{
// realloc and set only if needed
rst_err = (unsigned char*) frealloc(rst_err, (scnc + 1) * sizeof(char));
if (rst_err == NULL)
if (rst_err == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
errorlevel = 1;
crst = 255;
}
rst_err[ scnc ] = crst;
rst_err[scnc] = crst;
}
// end of current scan
scnc++;
// on with the header parser routines
segment[ 0 ] = 0xFF;
segment[ 1 ] = tmp;
segment[0] = 0xFF;
segment[1] = tmp;
break;
}
}
......
{
break;
}
if (segment[ 0 ] != 0xFF)
if (segment[0] != 0xFF)
{
// ugly fix for incorrect marker segment sizes
sprintf(errormessage, "size mismatch in marker segment FF %2X", type);
......
{
break;
}
if (segment[ 0 ] == 0xFF)
if (segment[0] == 0xFF)
{
errorlevel = 1;
}
......
}
// read segment type
type = segment[ 1 ];
type = segment[1];
// if EOI is encountered make a quick exit
if (type == 0xD9)
......
{
break;
}
len = 2 + B_SHORT(segment[ 2 ], segment[ 3 ]);
len = 2 + B_SHORT(segment[2], segment[3]);
if (len < 4)
{
break;
......
if (ssize < len)
{
segment = (unsigned char*) frealloc(segment, len);
if (segment == NULL)
if (segment == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
// JPEG reader loop end
// free writers
delete (hdrw);
delete (huffw);
delete hdrw;
delete huffw;
// check if everything went OK
if ((hdrs == 0) || (hufs == 0))
......
return true;
}
/* -----------------------------------------------
Merges header & image data to jpeg
----------------------------------------------- */
bool merge_jpeg(void)
bool packJPG::merge_jpeg(void)
{
unsigned char SOI[ 2 ] = { 0xFF, 0xD8 }; // SOI segment
unsigned char EOI[ 2 ] = { 0xFF, 0xD9 }; // EOI segment
unsigned char SOI[2] = {0xFF, 0xD8}; // SOI segment
unsigned char EOI[2] = {0xFF, 0xD9}; // EOI segment
unsigned char mrk = 0xFF; // marker start
unsigned char stv = 0x00; // 0xFF stuff value
unsigned char rst = 0xD0; // restart marker
......
unsigned int scan = 1; // number of current scan
unsigned int tmp; // temporary storage variable
// write SOI
str_out->write(SOI, 2);
......
{
break;
}
type = hdrdata[ hpos + 1 ];
len = 2 + B_SHORT(hdrdata[ hpos + 2 ], hdrdata[ hpos + 3 ]);
type = hdrdata[hpos + 1];
len = 2 + B_SHORT(hdrdata[hpos + 2], hdrdata[hpos + 3]);
hpos += len;
}
......
break;
}
// (re)set corrected rst pos
cpos = 0;
// write & expand huffman coded image data
for (ipos = scnp[ scan - 1 ]; ipos < scnp[ scan ]; ipos++)
for (ipos = scnp[scan - 1]; ipos < scnp[scan]; ipos++)
{
// write current byte
str_out->write_byte(huffdata[ipos]);
// check current byte, stuff if needed
if (huffdata[ ipos ] == 0xFF)
if (huffdata[ipos] == 0xFF)
{
str_out->write_byte(stv);
}
// insert restart markers if needed
if (rstp != NULL)
if (rstp != nullptr)
{
if (ipos == rstp[ rpos ])
if (ipos == rstp[rpos])
{
rst = 0xD0 + (cpos % 8);
str_out->write_byte(mrk);
......
}
}
// insert false rst markers at end if needed
if (rst_err != NULL)
if (rst_err != nullptr)
{
while (rst_err[ scan - 1 ] > 0)
while (rst_err[scan - 1] > 0)
{
rst = 0xD0 + (cpos % 8);
str_out->write_byte(mrk);
str_out->write_byte(rst);
cpos++;
rst_err[ scan - 1 ]--;
rst_err[scan - 1]--;
}
}
......
// get filesize
jpgfilesize = str_out->num_bytes_written();
return true;
}
/* -----------------------------------------------
JPEG decoding routine
----------------------------------------------- */
bool decode_jpeg(void)
bool packJPG::decode_jpeg(void)
{
BitReader* huffr; // bitwise reader for image data
......
unsigned int len = 0; // length of current marker segment
unsigned int hpos = 0; // current position in header
int lastdc[ 4 ]; // last dc for each component
short block[ 64 ]; // store block for coeffs
int lastdc[4]; // last dc for each component
short block[64]; // store block for coeffs
int peobrun; // previous eobrun
int eobrun; // run of eobs
int rstw; // restart wait counter
......
int mcu, sub, csc;
int eob, sta;
// open huffman coded image data for input in BitReader
huffr = new BitReader(huffdata, hufs);
......
{
break;
}
type = hdrdata[ hpos + 1 ];
len = 2 + B_SHORT(hdrdata[ hpos + 2 ], hdrdata[ hpos + 3 ]);
type = hdrdata[hpos + 1];
len = 2 + B_SHORT(hdrdata[hpos + 2], hdrdata[hpos + 3]);
if ((type == 0xC4) || (type == 0xDA) || (type == 0xDD))
{
if (!jpg_parse_jfif(type, len, &(hdrdata[ hpos ])))
if (!jpg_parse_jfif(type, len, &(hdrdata[hpos])))
{
return false;
}
......
// check if huffman tables are available
for (csc = 0; csc < cs_cmpc; csc++)
{
cmp = cs_cmp[ csc ];
if (((cs_sal == 0) && (htset[ 0 ][ cmpnfo[cmp].huffdc ] == 0)) ||
((cs_sah > 0) && (htset[ 1 ][ cmpnfo[cmp].huffac ] == 0)))
cmp = cs_cmp[csc];
if (((cs_sal == 0) && (htset[0][cmpnfo[cmp].huffdc] == 0)) ||
((cs_sah > 0) && (htset[1][cmpnfo[cmp].huffac] == 0)))
{
sprintf(errormessage, "huffman table missing in scan%i", scnc);
delete huffr;
......
}
}
// intial variables set for decoding
cmp = cs_cmp[ 0 ];
cmp = cs_cmp[0];
csc = 0;
mcu = 0;
sub = 0;
......
while (true)
{
// (re)set last DCs for diff coding
lastdc[ 0 ] = 0;
lastdc[ 1 ] = 0;
lastdc[ 2 ] = 0;
lastdc[ 3 ] = 0;
lastdc[0] = 0;
lastdc[1] = 0;
lastdc[2] = 0;
lastdc[3] = 0;
// (re)set status
eob = 0;
......
{
// decode block
eob = jpg_decode_block_seq(huffr,
&(htrees[ 0 ][ cmpnfo[cmp].huffdc ]),
&(htrees[ 1 ][ cmpnfo[cmp].huffdc ]),
&(htrees[0][cmpnfo[cmp].huffdc]),
&(htrees[1][cmpnfo[cmp].huffdc]),
block);
// check for non optimal coding
if ((eob > 1) && (block[ eob - 1 ] == 0))
if ((eob > 1) && (block[eob - 1] == 0))
{
sprintf(errormessage, "reconstruction of inefficient coding not supported");
errorlevel = 1;
}
// fix dc
block[ 0 ] += lastdc[ cmp ];
lastdc[ cmp ] = block[ 0 ];
block[0] += lastdc[cmp];
lastdc[cmp] = block[0];
// copy to colldata
for (bpos = 0; bpos < eob; bpos++)
{
colldata[ cmp ][ bpos ][ dpos ] = block[ bpos ];
colldata[cmp][bpos][dpos] = block[bpos];
}
// check for errors, proceed if no error encountered
......
while (sta == 0)
{
sta = jpg_decode_dc_prg_fs(huffr,
&(htrees[ 0 ][ cmpnfo[cmp].huffdc ]),
&(htrees[0][cmpnfo[cmp].huffdc]),
block);
// fix dc for diff coding
colldata[cmp][0][dpos] = block[0] + lastdc[ cmp ];
lastdc[ cmp ] = colldata[cmp][0][dpos];
colldata[cmp][0][dpos] = block[0] + lastdc[cmp];
lastdc[cmp] = colldata[cmp][0][dpos];
// bitshift for succesive approximation
colldata[cmp][0][dpos] <<= cs_sal;
......
while (sta == 0)
{
// decode next bit
sta = jpg_decode_dc_prg_sa(huffr,
block);
sta = jpg_decode_dc_prg_sa(huffr, block);
// shift in next bit
colldata[cmp][0][dpos] += block[0] << cs_sal;
......
{
// decode block
eob = jpg_decode_block_seq(huffr,
&(htrees[ 0 ][ cmpnfo[cmp].huffdc ]),
&(htrees[ 1 ][ cmpnfo[cmp].huffdc ]),
&(htrees[0][cmpnfo[cmp].huffdc]),
&(htrees[1][cmpnfo[cmp].huffdc]),
block);
// check for non optimal coding
if ((eob > 1) && (block[ eob - 1 ] == 0))
if ((eob > 1) && (block[eob - 1] == 0))
{
sprintf(errormessage, "reconstruction of inefficient coding not supported");
errorlevel = 1;
}
// fix dc
block[ 0 ] += lastdc[ cmp ];
lastdc[ cmp ] = block[ 0 ];
block[0] += lastdc[cmp];
lastdc[cmp] = block[0];
// copy to colldata
for (bpos = 0; bpos < eob; bpos++)
{
colldata[ cmp ][ bpos ][ dpos ] = block[ bpos ];
colldata[cmp][bpos][dpos] = block[bpos];
}
// check for errors, proceed if no error encountered
......
while (sta == 0)
{
sta = jpg_decode_dc_prg_fs(huffr,
&(htrees[ 0 ][ cmpnfo[cmp].huffdc ]),
&(htrees[0][cmpnfo[cmp].huffdc]),
block);
// fix dc for diff coding
colldata[cmp][0][dpos] = block[0] + lastdc[ cmp ];
lastdc[ cmp ] = colldata[cmp][0][dpos];
colldata[cmp][0][dpos] = block[0] + lastdc[cmp];
lastdc[cmp] = colldata[cmp][0][dpos];
// bitshift for succesive approximation
colldata[cmp][0][dpos] <<= cs_sal;
......
while (sta == 0)
{
// decode next bit
sta = jpg_decode_dc_prg_sa(huffr,
block);
sta = jpg_decode_dc_prg_sa(huffr, block);
// shift in next bit
colldata[cmp][0][dpos] += block[0] << cs_sal;
......
{
// decode block
eob = jpg_decode_ac_prg_fs(huffr,
&(htrees[ 1 ][ cmpnfo[cmp].huffac ]),
&(htrees[1][cmpnfo[cmp].huffac]),
block, &eobrun, cs_from, cs_to);
if (eobrun > 0)
{
// check for non optimal coding
if ((eob == cs_from) && (peobrun > 0) &&
(peobrun < hcodes[ 1 ][ cmpnfo[cmp].huffac ].max_eobrun - 1))
(peobrun < hcodes[1][cmpnfo[cmp].huffac].max_eobrun - 1))
{
sprintf(errormessage,
"reconstruction of inefficient coding not supported");
......
// copy to colldata
for (bpos = cs_from; bpos < eob; bpos++)
{
colldata[ cmp ][ bpos ][ dpos ] = block[ bpos ] << cs_sal;
colldata[cmp][bpos][dpos] = block[bpos] << cs_sal;
}
}
else
......
// copy from colldata
for (bpos = cs_from; bpos <= cs_to; bpos++)
{
block[ bpos ] = colldata[ cmp ][ bpos ][ dpos ];
block[bpos] = colldata[cmp][bpos][dpos];
}
if (eobrun == 0)
{
// decode block (long routine)
eob = jpg_decode_ac_prg_sa(huffr,
&(htrees[ 1 ][ cmpnfo[cmp].huffac ]),
&(htrees[1][cmpnfo[cmp].huffac]),
block, &eobrun, cs_from, cs_to);
if (eobrun > 0)
{
// check for non optimal coding
if ((eob == cs_from) && (peobrun > 0) &&
(peobrun < hcodes[ 1 ][ cmpnfo[cmp].huffac ].max_eobrun - 1))
(peobrun < hcodes[1][cmpnfo[cmp].huffac].max_eobrun - 1))
{
sprintf(errormessage,
"reconstruction of inefficient coding not supported");
......
// copy back to colldata
for (bpos = cs_from; bpos <= cs_to; bpos++)
{
colldata[ cmp ][ bpos ][ dpos ] += block[ bpos ] << cs_sal;
colldata[cmp][bpos][dpos] += block[bpos] << cs_sal;
}
// proceed only if no error encountered
......
}
// clean up
delete (huffr);
delete huffr;
return true;
}
/* -----------------------------------------------
JPEG encoding routine
----------------------------------------------- */
bool recode_jpeg(void)
bool packJPG::recode_jpeg(void)
{
BitWriter* huffw; // bitwise writer for image data
......
unsigned int len = 0; // length of current marker segment
unsigned int hpos = 0; // current position in header
int lastdc[ 4 ]; // last dc for each component0
short block[ 64 ]; // store block for coeffs
int lastdc[4]; // last dc for each component0
short block[64]; // store block for coeffs
int eobrun; // run of eobs
int rstw; // restart wait counter
......
int eob, sta;
int tmp;
// open huffman coded image data in BitWriter
huffw = new BitWriter(padbit);
......
{
break;
}
type = hdrdata[ hpos + 1 ];
len = 2 + B_SHORT(hdrdata[ hpos + 2 ], hdrdata[ hpos + 3 ]);
type = hdrdata[hpos + 1];
len = 2 + B_SHORT(hdrdata[hpos + 2], hdrdata[hpos + 3]);
if ((type == 0xC4) || (type == 0xDA) || (type == 0xDD))
{
if (!jpg_parse_jfif(type, len, &(hdrdata[ hpos ])))
if (!jpg_parse_jfif(type, len, &(hdrdata[hpos])))
{
return false;
}
......
break;
}
// (re)alloc scan positons array
if (scnp == NULL)
if (scnp == nullptr)
{
scnp = (unsigned int*) calloc(scnc + 2, sizeof(int));
}
......
{
scnp = (unsigned int*) frealloc(scnp, (scnc + 2) * sizeof(int));
}
if (scnp == NULL)
if (scnp == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
if (rsti > 0)
{
tmp = rstc + ((cs_cmpc > 1) ?
(mcuc / rsti) : (cmpnfo[ cs_cmp[ 0 ] ].bc / rsti));
if (rstp == NULL)
(mcuc / rsti) : (cmpnfo[cs_cmp[0]].bc / rsti));
if (rstp == nullptr)
{
rstp = (unsigned int*) calloc(tmp + 1, sizeof(int));
}
......
{
rstp = (unsigned int*) frealloc(rstp, (tmp + 1) * sizeof(int));
}
if (rstp == NULL)
if (rstp == nullptr)
{
sprintf(errormessage, MEM_ERRMSG);
errorlevel = 2;
......
}
// intial variables set for encoding
cmp = cs_cmp[ 0 ];
cmp = cs_cmp[0];
csc = 0;
mcu = 0;
sub = 0;
dpos = 0;
// store scan position
scnp[ scnc ] = huffw->num_bytes_written();
scnp[scnc] = huffw->num_bytes_written();
// JPEG imagedata encoding routines
while (true)
{
// (re)set last DCs for diff coding
lastdc[ 0 ] = 0;
lastdc[ 1 ] = 0;
lastdc[ 2 ] = 0;
lastdc[ 3 ] = 0;
lastdc[0] = 0;
lastdc[1] = 0;
lastdc[2] = 0;
lastdc[3] = 0;
// (re)set status
sta = 0;
......
// copy from colldata
for (bpos = 0; bpos < 64; bpos++)
{
block[ bpos ] = colldata[ cmp ][ bpos ][ dpos ];
block[bpos] = colldata[cmp][bpos][dpos];
}
// diff coding for dc
block[ 0 ] -= lastdc[ cmp ];
lastdc[ cmp ] = colldata[ cmp ][ 0 ][ dpos ];
block[0] -= lastdc[cmp];
lastdc[cmp] = colldata[cmp][0][dpos];
// encode block
eob = jpg_encode_block_seq(huffw,
&(hcodes[ 0 ][ cmpnfo[cmp].huffdc ]),
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[0][cmpnfo[cmp].huffdc]),
&(hcodes[1][cmpnfo[cmp].huffac]),
block);
// check for errors, proceed if no error encountered
......
while (sta == 0)
{
// diff coding & bitshifting for dc
tmp = colldata[ cmp ][ 0 ][ dpos ] >> cs_sal;
block[ 0 ] = tmp - lastdc[ cmp ];
lastdc[ cmp ] = tmp;
tmp = colldata[cmp][0][dpos] >> cs_sal;
block[0] = tmp - lastdc[cmp];
lastdc[cmp] = tmp;
// encode dc
sta = jpg_encode_dc_prg_fs(huffw,
&(hcodes[ 0 ][ cmpnfo[cmp].huffdc ]),
&(hcodes[0][cmpnfo[cmp].huffdc]),
block);
// next mcupos if no error happened
......
while (sta == 0)
{
// fetch bit from current bitplane
block[ 0 ] = BITN(colldata[ cmp ][ 0 ][ dpos ], cs_sal);
block[0] = BITN(colldata[cmp][0][dpos], cs_sal);
// encode dc correction bit
sta = jpg_encode_dc_prg_sa(huffw, block);
......
// copy from colldata
for (bpos = 0; bpos < 64; bpos++)
{
block[ bpos ] = colldata[ cmp ][ bpos ][ dpos ];
block[bpos] = colldata[cmp][bpos][dpos];
}
// diff coding for dc
block[ 0 ] -= lastdc[ cmp ];
lastdc[ cmp ] = colldata[ cmp ][ 0 ][ dpos ];
block[0] -= lastdc[cmp];
lastdc[cmp] = colldata[cmp][0][dpos];
// encode block
eob = jpg_encode_block_seq(huffw,
&(hcodes[ 0 ][ cmpnfo[cmp].huffdc ]),
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[0][cmpnfo[cmp].huffdc]),
&(hcodes[1][cmpnfo[cmp].huffac]),
block);
// check for errors, proceed if no error encountered
......
while (sta == 0)
{
// diff coding & bitshifting for dc
tmp = colldata[ cmp ][ 0 ][ dpos ] >> cs_sal;
block[ 0 ] = tmp - lastdc[ cmp ];
lastdc[ cmp ] = tmp;
tmp = colldata[cmp][0][dpos] >> cs_sal;
block[0] = tmp - lastdc[cmp];
lastdc[cmp] = tmp;
// encode dc
sta = jpg_encode_dc_prg_fs(huffw,
&(hcodes[ 0 ][ cmpnfo[cmp].huffdc ]),
&(hcodes[0][cmpnfo[cmp].huffdc]),
block);
// check for errors, increment dpos otherwise
......
while (sta == 0)
{
// fetch bit from current bitplane
block[ 0 ] = BITN(colldata[ cmp ][ 0 ][ dpos ], cs_sal);
block[0] = BITN(colldata[cmp][0][dpos], cs_sal);
// encode dc correction bit
sta = jpg_encode_dc_prg_sa(huffw, block);
......
{
// copy from colldata
for (bpos = cs_from; bpos <= cs_to; bpos++)
block[ bpos ] =
FDIV2(colldata[ cmp ][ bpos ][ dpos ], cs_sal);
block[bpos] =
FDIV2(colldata[cmp][bpos][dpos], cs_sal);
// encode block
eob = jpg_encode_ac_prg_fs(huffw,
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[1][cmpnfo[cmp].huffac]),
block, &eobrun, cs_from, cs_to);
// check for errors, proceed if no error encountered
......
// encode remaining eobrun
jpg_encode_eobrun(huffw,
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[1][cmpnfo[cmp].huffac]),
&eobrun);
}
else
......
{
// copy from colldata
for (bpos = cs_from; bpos <= cs_to; bpos++)
block[ bpos ] =
FDIV2(colldata[ cmp ][ bpos ][ dpos ], cs_sal);
block[bpos] =
FDIV2(colldata[cmp][bpos][dpos], cs_sal);
// encode block
eob = jpg_encode_ac_prg_sa(huffw, storw,
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[1][cmpnfo[cmp].huffac]),
block, &eobrun, cs_from, cs_to);
// check for errors, proceed if no error encountered
......
// encode remaining eobrun
jpg_encode_eobrun(huffw,
&(hcodes[ 1 ][ cmpnfo[cmp].huffac ]),
&(hcodes[1][cmpnfo[cmp].huffac]),
&eobrun);
// encode remaining correction bits
......
{
if (rsti > 0) // store rstp & stay in the loop
{
rstp[ rstc++ ] = huffw->num_bytes_written() - 1;
rstp[rstc++] = huffw->num_bytes_written() - 1;
}
}
}
......
delete huffw;
// store last scan & restart positions
scnp[ scnc ] = hufs;
if (rstp != NULL)
scnp[scnc] = hufs;
if (rstp != nullptr)
{
rstp[ rstc ] = hufs;
rstp[rstc] = hufs;
}
return true;
}
/* -----------------------------------------------
adapt ICOS tables for quantizer tables
----------------------------------------------- */
bool adapt_icos(void)
bool packJPG::adapt_icos(void)
{
unsigned short quant[ 64 ]; // local copy of quantization
unsigned short quant[64]; // local copy of quantization
int ipos;
int cmp;
for (cmp = 0; cmp < cmpc; cmp++)
{
// make a local copy of the quantization values, check
for (ipos = 0; ipos < 64; ipos++)
{
quant[ ipos ] = QUANT(cmp, zigzag[ ipos ]);
if (quant[ ipos ] >= 2048) // if this is true, it can be safely assumed (for 8 bit JPEG), that all coefficients are zero
quant[ipos] = QUANT(cmp, zigzag[ipos]);
if (quant[ipos] >= 2048) // if this is true, it can be safely assumed (for 8 bit JPEG), that all coefficients are zero
{
quant[ ipos ] = 0;
quant[ipos] = 0;
}
}
// adapt idct 8x8 table
for (ipos = 0; ipos < 64 * 64; ipos++)
{
adpt_idct_8x8[ cmp ][ ipos ] = icos_idct_8x8[ ipos ] * quant[ ipos % 64 ];
adpt_idct_8x8[cmp][ipos] = icos_idct_8x8[ipos] * quant[ipos % 64];
}
// adapt idct 1x8 table
for (ipos = 0; ipos < 8 * 8; ipos++)
{
adpt_idct_1x8[ cmp ][ ipos ] = icos_idct_1x8[ ipos ] * quant[(ipos % 8) * 8 ];
adpt_idct_1x8[cmp][ipos] = icos_idct_1x8[ipos] * quant[(ipos % 8) * 8];
}
// adapt idct 8x1 table
for (ipos = 0; ipos < 8 * 8; ipos++)
{
adpt_idct_8x1[ cmp ][ ipos ] = icos_idct_1x8[ ipos ] * quant[ ipos % 8 ];
adpt_idct_8x1[cmp][ipos] = icos_idct_1x8[ipos] * quant[ipos % 8];
}
}
return true;
}
/* -----------------------------------------------
filter DC coefficients
----------------------------------------------- */
bool predict_dc(void)
bool packJPG::predict_dc(void)
{
signed short* coef;
int absmaxp;
......
int corr_f;
int cmp, dpos;
// apply prediction, store prediction error instead of DC
for (cmp = 0; cmp < cmpc; cmp++)
{
......
for (dpos = cmpnfo[cmp].bc - 1; dpos > 0; dpos--)
{
coef = &(colldata[cmp][0][dpos]);
#if defined( USE_PLOCOI )
#if defined(USE_PLOCOI)
(*coef) -= dc_coll_predictor(cmp, dpos); // loco-i predictor
#else
(*coef) -= dc_1ddct_predictor(cmp, dpos); // 1d dct
......
return true;
}
/* -----------------------------------------------
unpredict DC coefficients
----------------------------------------------- */
bool unpredict_dc(void)
bool packJPG::unpredict_dc(void)
{
signed short* coef;
int absmaxp;
......
int corr_f;
int cmp, dpos;
// remove prediction, store DC instead of prediction error
for (cmp = 0; cmp < cmpc; cmp++)
{
......
}
}
return true;
}
/* -----------------------------------------------
checks range of values, error if out of bounds
----------------------------------------------- */
bool check_value_range(void)
bool packJPG::check_value_range(void)
{
int absmax;
int cmp, bpos, dpos;
......
}
}
return true;
}
/* -----------------------------------------------
calculate zero distribution lists
----------------------------------------------- */
bool calc_zdst_lists(void)
bool packJPG::calc_zdst_lists(void)
{
int cmp, bpos, dpos;
int b_x, b_y;
// this functions counts, for each DCT block, the number of non-zero coefficients
for (cmp = 0; cmp < cmpc; cmp++)
{
......
// calculate # on non-zeroes per block (separately for lower 7x7 block & first row/collumn)
for (bpos = 1; bpos < 64; bpos++)
{
b_x = unzigzag[ bpos ] % 8;
b_y = unzigzag[ bpos ] / 8;
b_x = unzigzag[bpos] % 8;
b_y = unzigzag[bpos] / 8;
if (b_x == 0)
{
for (dpos = 0; dpos < cmpnfo[cmp].bc; dpos++)
......
}
}
return true;
}
/* -----------------------------------------------
packs all parts to compressed pjg
----------------------------------------------- */
bool pack_pjg(void)
bool packJPG::pack_pjg(void)
{
unsigned char hcode;
int cmp;
......
int dev_size = 0;
#endif
// PJG-Header
str_out->write(reinterpret_cast<const unsigned char*>(pjg_magic), 2);
......
return false;
}
// also encode one bit to signal false/correct use of RST markers
if (!pjg_encode_bit(encoder, (rst_err == NULL) ? 0 : 1))
if (!pjg_encode_bit(encoder, (rst_err == nullptr) ? 0 : 1))
{
return false;
}
// encode # of false set RST markers per scan
if (rst_err != NULL)
if (rst_err != nullptr)
if (!pjg_encode_generic(encoder, rst_err, scnc))
{
return false;
......
{
return false;
}
dev_size_zsr[ cmp ] += str_out->getpos() - dev_size;
dev_size_zsr[cmp] += str_out->getpos() - dev_size;
dev_size = str_out->getpos();
// encode zero-distribution-lists for higher (7x7) ACs
if (!pjg_encode_zdst_high(encoder, cmp))
{
return false;
}
dev_size_zdh[ cmp ] += str_out->getpos() - dev_size;
dev_size_zdh[cmp] += str_out->getpos() - dev_size;
dev_size = str_out->getpos();
// encode coefficients for higher (7x7) ACs
if (!pjg_encode_ac_high(encoder, cmp))
{
return false;
}
dev_size_ach[ cmp ] += str_out->getpos() - dev_size;
dev_size_ach[cmp] += str_out->getpos() - dev_size;
dev_size = str_out->getpos();
// encode zero-distribution-lists for lower ACs
if (!pjg_encode_zdst_low(encoder, cmp))
{
return false;
}
dev_size_zdl[ cmp ] += str_out->getpos() - dev_size;
dev_size_zdl[cmp] += str_out->getpos() - dev_size;
dev_size = str_out->getpos();
// encode coefficients for first row / collumn ACs
if (!pjg_encode_ac_low(encoder, cmp))
{
return false;
}
dev_size_acl[ cmp ] += str_out->getpos() - dev_size;
dev_size_acl[cmp] += str_out->getpos() - dev_size;
dev_size = str_out->getpos();
// encode coefficients for DC
if (!pjg_encode_dc(encoder, cmp))
{
return false;
}
dev_size_dc[ cmp ] += str_out->getpos() - dev_size;
dev_size_cmp[ cmp ] =
dev_size_zsr[ cmp ] + dev_size_zdh[ cmp ] + dev_size_zdl[ cmp ] +
dev_size_ach[ cmp ] + dev_size_acl[ cmp ] + dev_size_dc[ cmp ];
dev_size_dc[cmp] += str_out->getpos() - dev_size;
dev_size_cmp[cmp] =
dev_size_zsr[cmp] + dev_size_zdh[cmp] + dev_size_zdl[cmp] +
dev_size_ach[cmp] + dev_size_acl[cmp] + dev_size_dc[cmp];
#endif
}
......
}
// finalize arithmetic compression
delete (encoder);
delete encoder;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff