[trunk] realloc is misused and may leak memory (Issue#168)

This commit is contained in:
Luc Hermitte 2012-08-22 18:45:31 +00:00
parent 7bfdb31c77
commit 4e81ea2a8a
13 changed files with 11937 additions and 11675 deletions

View File

@ -475,10 +475,17 @@ int main(int argc, char *argv[]) {
// Ending loop // Ending loop
fclose(j2kfile); fclose(j2kfile);
snum++; snum++;
movie->tk[0].sample = (mj2_sample_t*) mj2_sample_t * new_sample = (mj2_sample_t*)
realloc(movie->tk[0].sample, (snum+1) * sizeof(mj2_sample_t)); realloc(movie->tk[0].sample, (snum+1) * sizeof(mj2_sample_t));
movie->tk[0].chunk = (mj2_chunk_t*) mj2_chunk_t * new_chunk = (mj2_chunk_t*)
realloc(movie->tk[0].chunk, (snum+1) * sizeof(mj2_chunk_t)); realloc(movie->tk[0].chunk, (snum+1) * sizeof(mj2_chunk_t));
if (new_sample && new_chunk) {
movie->tk[0].sample = new_sample;
movie->tk[0].chunk = new_chunk;
} else {
fprintf(stderr, "Failed to allocate enough memory to read %s\n", j2kfilename);
return 1;
}
free(frame_codestream); free(frame_codestream);
} }

View File

@ -34,30 +34,30 @@
/** /**
* Creates a validation list. * Creates a validation list.
* *
* @return the newly created validation list. * @return the newly created validation list.
*/ */
opj_procedure_list_t * opj_procedure_list_create() opj_procedure_list_t * opj_procedure_list_create()
{ {
/* memory allocation */ /* memory allocation */
opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t)); opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t));
if if
(! l_validation) (! l_validation)
{ {
return 00; return 00;
} }
/* initialization */ /* initialization */
memset(l_validation,0,sizeof(opj_procedure_list_t)); memset(l_validation,0,sizeof(opj_procedure_list_t));
l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE; l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE;
l_validation->m_procedures = (opj_procedure*)opj_malloc( l_validation->m_procedures = (opj_procedure*)opj_malloc(
OPJ_VALIDATION_SIZE * sizeof(opj_procedure)); OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
if if
(! l_validation->m_procedures) (! l_validation->m_procedures)
{ {
opj_free(l_validation); opj_free(l_validation);
return 00; return 00;
} }
memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure)); memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure));
return l_validation; return l_validation;
} }
@ -69,64 +69,66 @@ opj_procedure_list_t * opj_procedure_list_create()
*/ */
void opj_procedure_list_destroy(opj_procedure_list_t * p_list) void opj_procedure_list_destroy(opj_procedure_list_t * p_list)
{ {
if if
(! p_list) (! p_list)
{ {
return; return;
} }
/* initialization */ /* initialization */
if if
(p_list->m_procedures) (p_list->m_procedures)
{ {
opj_free(p_list->m_procedures); opj_free(p_list->m_procedures);
} }
opj_free(p_list); opj_free(p_list);
} }
/** /**
* Adds a new validation procedure. * Adds a new validation procedure.
* *
* @param p_validation_list the list of procedure to modify. * @param p_validation_list the list of procedure to modify.
* @param p_procedure the procedure to add. * @param p_procedure the procedure to add.
*/ */
opj_bool opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure) opj_bool opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure)
{ {
if if
(p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures) (p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures)
{ {
opj_procedure * new_procedures; opj_procedure * new_procedures;
p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE; p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE;
new_procedures = (opj_procedure*)opj_realloc( new_procedures = (opj_procedure*)opj_realloc(
p_validation_list->m_procedures,p_validation_list->m_nb_max_procedures * sizeof(opj_procedure)); p_validation_list->m_procedures,p_validation_list->m_nb_max_procedures * sizeof(opj_procedure));
if if
(! new_procedures) (! new_procedures)
{ {
opj_free(p_validation_list->m_procedures); opj_free(p_validation_list->m_procedures);
p_validation_list->m_nb_max_procedures = 0; p_validation_list->m_nb_max_procedures = 0;
p_validation_list->m_nb_procedures = 0; p_validation_list->m_nb_procedures = 0;
return OPJ_FALSE; /* opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to add a new validation procedure\n"); */
} fprintf(stderr, "Not enough memory to add a new validation procedure\n");
return OPJ_FALSE;
}
else else
{ {
p_validation_list->m_procedures = new_procedures; p_validation_list->m_procedures = new_procedures;
} }
} }
p_validation_list->m_procedures[p_validation_list->m_nb_procedures] = p_procedure; p_validation_list->m_procedures[p_validation_list->m_nb_procedures] = p_procedure;
++p_validation_list->m_nb_procedures; ++p_validation_list->m_nb_procedures;
return OPJ_TRUE; return OPJ_TRUE;
} }
/** /**
* Gets the number of validation procedures. * Gets the number of validation procedures.
* *
* @param p_validation_list the list of procedure to modify. * @param p_validation_list the list of procedure to modify.
* *
* @return the number of validation procedures. * @return the number of validation procedures.
*/ */
OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list) OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list)
{ {
return p_validation_list->m_nb_procedures; return p_validation_list->m_nb_procedures;
} }
/** /**
@ -134,22 +136,22 @@ OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_valida
* iterator class to iterate through all the procedures inside the validation list. * iterator class to iterate through all the procedures inside the validation list.
* the caller does not take ownership of the pointer. * the caller does not take ownership of the pointer.
* *
* @param p_validation_list the list of procedure to get the first procedure from. * @param p_validation_list the list of procedure to get the first procedure from.
* *
* @return a pointer to the first procedure. * @return a pointer to the first procedure.
*/ */
opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list) opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list)
{ {
return p_validation_list->m_procedures; return p_validation_list->m_procedures;
} }
/** /**
* Clears the list of validation procedures. * Clears the list of validation procedures.
* *
* @param p_validation_list the list of procedure to clear. * @param p_validation_list the list of procedure to clear.
* *
*/ */
void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list) void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list)
{ {
p_validation_list->m_nb_procedures = 0; p_validation_list->m_nb_procedures = 0;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1765,7 +1765,7 @@ static opj_bool opj_jp2_read_header_procedure( opj_jp2_v2_t *jp2,
if (box.type == JP2_JP2C) { if (box.type == JP2_JP2C) {
if (jp2->jp2_state & JP2_STATE_HEADER) { if (jp2->jp2_state & JP2_STATE_HEADER) {
jp2->jp2_state |= JP2_STATE_CODESTREAM; jp2->jp2_state |= JP2_STATE_CODESTREAM;
opj_free(l_current_data); opj_free(l_current_data);
return OPJ_TRUE; return OPJ_TRUE;
} }
else { else {
@ -1785,17 +1785,22 @@ static opj_bool opj_jp2_read_header_procedure( opj_jp2_v2_t *jp2,
if (l_current_handler != 00) { if (l_current_handler != 00) {
if (l_current_data_size > l_last_data_size) { if (l_current_data_size > l_last_data_size) {
l_current_data = (unsigned char*)opj_realloc(l_current_data,l_current_data_size); unsigned char* new_current_data = (unsigned char*)opj_realloc(l_current_data,l_current_data_size);
if (!l_current_data){ if (!l_current_data){
opj_free(l_current_data); opj_free(l_current_data);
opj_event_msg_v2(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
return OPJ_FALSE; return OPJ_FALSE;
} }
l_current_data = new_current_data;
l_last_data_size = l_current_data_size; l_last_data_size = l_current_data_size;
} }
l_nb_bytes_read = opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager); l_nb_bytes_read = opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager);
if (l_nb_bytes_read != l_current_data_size) { if (l_nb_bytes_read != l_current_data_size) {
opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n"); opj_event_msg_v2(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n");
// TODO: LH: why nothing is freed here (as
// all other returns imply a free, even
// in the nominal case)?
return OPJ_FALSE; return OPJ_FALSE;
} }

File diff suppressed because it is too large Load Diff

View File

@ -363,7 +363,7 @@ opj_mqc_t* mqc_create(void) {
void mqc_destroy(opj_mqc_t *mqc) { void mqc_destroy(opj_mqc_t *mqc) {
if(mqc) { if(mqc) {
#ifdef MQC_PERF_OPT #ifdef MQC_PERF_OPT
if (mqc->buffer) { if (mqc->buffer) { // TODO: LH: this test is pointless as free() is a no-op on 0
opj_free(mqc->buffer); opj_free(mqc->buffer);
} }
#endif #endif
@ -508,7 +508,7 @@ void mqc_segmark_enc(opj_mqc_t *mqc) {
} }
} }
void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { opj_bool mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
mqc_setcurctx(mqc, 0); mqc_setcurctx(mqc, 0);
mqc->start = bp; mqc->start = bp;
mqc->end = bp + len; mqc->end = bp + len;
@ -521,7 +521,13 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
unsigned int c; unsigned int c;
unsigned int *ip; unsigned int *ip;
unsigned char *end = mqc->end - 1; unsigned char *end = mqc->end - 1;
mqc->buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int)); void* new_buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(unsigned int));
if (! new_buffer) {
opj_free(mqc->buffer);
mqc->buffer = NULL;
return OPJ_FALSE;
}
mqc->buffer = new_buffer;
ip = (unsigned int *) mqc->buffer; ip = (unsigned int *) mqc->buffer;
while (bp < end) { while (bp < end) {
@ -557,6 +563,7 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
mqc->c <<= 7; mqc->c <<= 7;
mqc->ct -= 7; mqc->ct -= 7;
mqc->a = 0x8000; mqc->a = 0x8000;
return OPJ_TRUE;
} }
int mqc_decode(opj_mqc_t *const mqc) { int mqc_decode(opj_mqc_t *const mqc) {

View File

@ -185,7 +185,7 @@ Initialize the decoder
@param bp Pointer to the start of the buffer from which the bytes will be read @param bp Pointer to the start of the buffer from which the bytes will be read
@param len Length of the input buffer @param len Length of the input buffer
*/ */
void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len); opj_bool mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len);
/** /**
Decode a symbol Decode a symbol
@param mqc MQC handle @param mqc MQC handle

View File

@ -330,8 +330,9 @@ Decode 1 code-block
@param orient @param orient
@param roishift Region of interest shifting value @param roishift Region of interest shifting value
@param cblksty Code-block style @param cblksty Code-block style
@deprecated ?
*/ */
static void t1_decode_cblk( static opj_bool t1_decode_cblk(
opj_t1_t *t1, opj_t1_t *t1,
opj_tcd_cblk_dec_t* cblk, opj_tcd_cblk_dec_t* cblk,
int orient, int orient,
@ -346,7 +347,7 @@ Decode 1 code-block
@param roishift Region of interest shifting value @param roishift Region of interest shifting value
@param cblksty Code-block style @param cblksty Code-block style
*/ */
static void t1_decode_cblk_v2( static opj_bool t1_decode_cblk_v2(
opj_t1_t *t1, opj_t1_t *t1,
opj_tcd_cblk_dec_v2_t* cblk, opj_tcd_cblk_dec_v2_t* cblk,
OPJ_UINT32 orient, OPJ_UINT32 orient,
@ -1393,7 +1394,7 @@ static void t1_encode_cblk(
} }
} }
static void t1_decode_cblk( static opj_bool t1_decode_cblk(
opj_t1_t *t1, opj_t1_t *t1,
opj_tcd_cblk_dec_t* cblk, opj_tcd_cblk_dec_t* cblk,
int orient, int orient,
@ -1435,7 +1436,9 @@ static void t1_decode_cblk(
if (type == T1_TYPE_RAW) { if (type == T1_TYPE_RAW) {
raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len); raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len);
} else { } else {
mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len); if (OPJ_FALSE == mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len)) {
return OPJ_FALSE;
}
} }
for (passno = 0; passno < seg->numpasses; ++passno) { for (passno = 0; passno < seg->numpasses; ++passno) {
@ -1479,6 +1482,7 @@ static void t1_decode_cblk(
} }
} }
} }
return OPJ_TRUE;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
@ -1644,7 +1648,7 @@ void opj_t1_destroy(opj_t1_t *p_t1)
opj_free(p_t1); opj_free(p_t1);
} }
void opj_t1_decode_cblks( opj_t1_t* t1, opj_bool opj_t1_decode_cblks( opj_t1_t* t1,
opj_tcd_tilecomp_v2_t* tilec, opj_tcd_tilecomp_v2_t* tilec,
opj_tccp_t* tccp opj_tccp_t* tccp
) )
@ -1669,12 +1673,14 @@ void opj_t1_decode_cblks( opj_t1_t* t1,
OPJ_INT32 x, y; OPJ_INT32 x, y;
OPJ_UINT32 i, j; OPJ_UINT32 i, j;
t1_decode_cblk_v2( if (OPJ_FALSE == t1_decode_cblk_v2(
t1, t1,
cblk, cblk,
band->bandno, band->bandno,
tccp->roishift, tccp->roishift,
tccp->cblksty); tccp->cblksty)) {
return OPJ_FALSE;
}
x = cblk->x0 - band->x0; x = cblk->x0 - band->x0;
y = cblk->y0 - band->y0; y = cblk->y0 - band->y0;
@ -1727,10 +1733,11 @@ void opj_t1_decode_cblks( opj_t1_t* t1,
} /* precno */ } /* precno */
} /* bandno */ } /* bandno */
} /* resno */ } /* resno */
return OPJ_TRUE;
} }
static void t1_decode_cblk_v2( static opj_bool t1_decode_cblk_v2(
opj_t1_t *t1, opj_t1_t *t1,
opj_tcd_cblk_dec_v2_t* cblk, opj_tcd_cblk_dec_v2_t* cblk,
OPJ_UINT32 orient, OPJ_UINT32 orient,
@ -1773,7 +1780,9 @@ static void t1_decode_cblk_v2(
if (type == T1_TYPE_RAW) { if (type == T1_TYPE_RAW) {
raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len); raw_init_dec(raw, (*seg->data) + seg->dataindex, seg->len);
} else { } else {
mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len); if (OPJ_FALSE == mqc_init_dec(mqc, (*seg->data) + seg->dataindex, seg->len)) {
return OPJ_FALSE;
}
} }
for (passno = 0; passno < seg->real_num_passes; ++passno) { for (passno = 0; passno < seg->real_num_passes; ++passno) {
@ -1801,6 +1810,7 @@ static void t1_decode_cblk_v2(
} }
} }
} }
return OPJ_TRUE;
} }
opj_bool opj_t1_encode_cblks( opj_t1_t *t1, opj_bool opj_t1_encode_cblks( opj_t1_t *t1,

View File

@ -131,7 +131,7 @@ Decode the code-blocks of a tile
@param tilec The tile to decode @param tilec The tile to decode
@param tccp Tile coding parameters @param tccp Tile coding parameters
*/ */
void opj_t1_decode_cblks( opj_t1_t* t1, opj_bool opj_t1_decode_cblks( opj_t1_t* t1,
opj_tcd_tilecomp_v2_t* tilec, opj_tcd_tilecomp_v2_t* tilec,
opj_tccp_t* tccp); opj_tccp_t* tccp);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -38,394 +38,396 @@
*/ */
opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) { opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) {
int nplh[32]; int nplh[32];
int nplv[32]; int nplv[32];
opj_tgt_node_t *node = NULL; opj_tgt_node_t *node = NULL;
opj_tgt_node_t *parentnode = NULL; opj_tgt_node_t *parentnode = NULL;
opj_tgt_node_t *parentnode0 = NULL; opj_tgt_node_t *parentnode0 = NULL;
opj_tgt_tree_t *tree = NULL; opj_tgt_tree_t *tree = NULL;
int i, j, k; int i, j, k;
int numlvls; int numlvls;
int n; int n;
tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
if(!tree) return NULL; if(!tree) return NULL;
tree->numleafsh = numleafsh; tree->numleafsh = numleafsh;
tree->numleafsv = numleafsv; tree->numleafsv = numleafsv;
numlvls = 0; numlvls = 0;
nplh[0] = numleafsh; nplh[0] = numleafsh;
nplv[0] = numleafsv; nplv[0] = numleafsv;
tree->numnodes = 0; tree->numnodes = 0;
do { do {
n = nplh[numlvls] * nplv[numlvls]; n = nplh[numlvls] * nplv[numlvls];
nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
tree->numnodes += n; tree->numnodes += n;
++numlvls; ++numlvls;
} while (n > 1); } while (n > 1);
/* ADD */ /* ADD */
if (tree->numnodes == 0) { if (tree->numnodes == 0) {
opj_free(tree); opj_free(tree);
return NULL; return NULL;
} }
tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
if(!tree->nodes) { if(!tree->nodes) {
opj_free(tree); opj_free(tree);
return NULL; return NULL;
} }
node = tree->nodes; node = tree->nodes;
parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv]; parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv];
parentnode0 = parentnode; parentnode0 = parentnode;
for (i = 0; i < numlvls - 1; ++i) { for (i = 0; i < numlvls - 1; ++i) {
for (j = 0; j < nplv[i]; ++j) { for (j = 0; j < nplv[i]; ++j) {
k = nplh[i]; k = nplh[i];
while (--k >= 0) { while (--k >= 0) {
node->parent = parentnode; node->parent = parentnode;
++node; ++node;
if (--k >= 0) { if (--k >= 0) {
node->parent = parentnode; node->parent = parentnode;
++node; ++node;
} }
++parentnode; ++parentnode;
} }
if ((j & 1) || j == nplv[i] - 1) { if ((j & 1) || j == nplv[i] - 1) {
parentnode0 = parentnode; parentnode0 = parentnode;
} else { } else {
parentnode = parentnode0; parentnode = parentnode0;
parentnode0 += nplh[i]; parentnode0 += nplh[i];
} }
} }
} }
node->parent = 0; node->parent = 0;
tgt_reset(tree); tgt_reset(tree);
return tree; return tree;
} }
opj_tgt_tree_t *tgt_create_v2(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { opj_tgt_tree_t *tgt_create_v2(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) {
OPJ_INT32 nplh[32]; OPJ_INT32 nplh[32];
OPJ_INT32 nplv[32]; OPJ_INT32 nplv[32];
opj_tgt_node_t *node = 00; opj_tgt_node_t *node = 00;
opj_tgt_node_t *l_parent_node = 00; opj_tgt_node_t *l_parent_node = 00;
opj_tgt_node_t *l_parent_node0 = 00; opj_tgt_node_t *l_parent_node0 = 00;
opj_tgt_tree_t *tree = 00; opj_tgt_tree_t *tree = 00;
OPJ_UINT32 i; OPJ_UINT32 i;
OPJ_INT32 j,k; OPJ_INT32 j,k;
OPJ_UINT32 numlvls; OPJ_UINT32 numlvls;
OPJ_UINT32 n; OPJ_UINT32 n;
tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t));
if(!tree) { if(!tree) {
fprintf(stderr, "ERROR in tgt_create_v2 while allocating tree\n"); fprintf(stderr, "ERROR in tgt_create_v2 while allocating tree\n");
return 00; return 00;
} }
memset(tree,0,sizeof(opj_tgt_tree_t)); memset(tree,0,sizeof(opj_tgt_tree_t));
tree->numleafsh = numleafsh; tree->numleafsh = numleafsh;
tree->numleafsv = numleafsv; tree->numleafsv = numleafsv;
numlvls = 0; numlvls = 0;
nplh[0] = numleafsh; nplh[0] = numleafsh;
nplv[0] = numleafsv; nplv[0] = numleafsv;
tree->numnodes = 0; tree->numnodes = 0;
do { do {
n = nplh[numlvls] * nplv[numlvls]; n = nplh[numlvls] * nplv[numlvls];
nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2;
nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2;
tree->numnodes += n; tree->numnodes += n;
++numlvls; ++numlvls;
} while (n > 1); } while (n > 1);
/* ADD */ /* ADD */
if (tree->numnodes == 0) { if (tree->numnodes == 0) {
opj_free(tree); opj_free(tree);
fprintf(stderr, "WARNING in tgt_create_v2 tree->numnodes == 0, no tree created.\n"); fprintf(stderr, "WARNING in tgt_create_v2 tree->numnodes == 0, no tree created.\n");
return 00; return 00;
} }
tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t));
if(!tree->nodes) { if(!tree->nodes) {
fprintf(stderr, "ERROR in tgt_create_v2 while allocating node of the tree\n"); fprintf(stderr, "ERROR in tgt_create_v2 while allocating node of the tree\n");
opj_free(tree); opj_free(tree);
return 00; return 00;
} }
memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t)); memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t));
tree->nodes_size = tree->numnodes * sizeof(opj_tgt_node_t); tree->nodes_size = tree->numnodes * sizeof(opj_tgt_node_t);
node = tree->nodes; node = tree->nodes;
l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv]; l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv];
l_parent_node0 = l_parent_node; l_parent_node0 = l_parent_node;
for (i = 0; i < numlvls - 1; ++i) { for (i = 0; i < numlvls - 1; ++i) {
for (j = 0; j < nplv[i]; ++j) { for (j = 0; j < nplv[i]; ++j) {
k = nplh[i]; k = nplh[i];
while (--k >= 0) { while (--k >= 0) {
node->parent = l_parent_node; node->parent = l_parent_node;
++node; ++node;
if (--k >= 0) { if (--k >= 0) {
node->parent = l_parent_node; node->parent = l_parent_node;
++node; ++node;
} }
++l_parent_node; ++l_parent_node;
} }
if ((j & 1) || j == nplv[i] - 1) { if ((j & 1) || j == nplv[i] - 1) {
l_parent_node0 = l_parent_node; l_parent_node0 = l_parent_node;
} else { } else {
l_parent_node = l_parent_node0; l_parent_node = l_parent_node0;
l_parent_node0 += nplh[i]; l_parent_node0 += nplh[i];
} }
} }
} }
node->parent = 0; node->parent = 0;
tgt_reset(tree); tgt_reset(tree);
return tree; return tree;
} }
/** /**
* Reinitialises a tag-tree from an exixting one. (V2 framevork) * Reinitialises a tag-tree from an exixting one. (V2 framevork)
* *
* @param p_tree the tree to reinitialize. * @param p_tree the tree to reinitialize.
* @param p_num_leafs_h the width of the array of leafs of the tree * @param p_num_leafs_h the width of the array of leafs of the tree
* @param p_num_leafs_v the height of the array of leafs of the tree * @param p_num_leafs_v the height of the array of leafs of the tree
* @return a new tag-tree if successful, NULL otherwise * @return a new tag-tree if successful, NULL otherwise
*/ */
opj_tgt_tree_t *tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v) opj_tgt_tree_t *tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
{ {
OPJ_INT32 l_nplh[32]; OPJ_INT32 l_nplh[32];
OPJ_INT32 l_nplv[32]; OPJ_INT32 l_nplv[32];
opj_tgt_node_t *l_node = 00; opj_tgt_node_t *l_node = 00;
opj_tgt_node_t *l_parent_node = 00; opj_tgt_node_t *l_parent_node = 00;
opj_tgt_node_t *l_parent_node0 = 00; opj_tgt_node_t *l_parent_node0 = 00;
OPJ_UINT32 i; OPJ_UINT32 i;
OPJ_INT32 j,k; OPJ_INT32 j,k;
OPJ_UINT32 l_num_levels; OPJ_UINT32 l_num_levels;
OPJ_UINT32 n; OPJ_UINT32 n;
OPJ_UINT32 l_node_size; OPJ_UINT32 l_node_size;
if if
(! p_tree) (! p_tree)
{ {
return 00; return 00;
} }
if if
((p_tree->numleafsh != p_num_leafs_h) || (p_tree->numleafsv != p_num_leafs_v)) ((p_tree->numleafsh != p_num_leafs_h) || (p_tree->numleafsv != p_num_leafs_v))
{ {
p_tree->numleafsh = p_num_leafs_h; p_tree->numleafsh = p_num_leafs_h;
p_tree->numleafsv = p_num_leafs_v; p_tree->numleafsv = p_num_leafs_v;
l_num_levels = 0; l_num_levels = 0;
l_nplh[0] = p_num_leafs_h; l_nplh[0] = p_num_leafs_h;
l_nplv[0] = p_num_leafs_v; l_nplv[0] = p_num_leafs_v;
p_tree->numnodes = 0; p_tree->numnodes = 0;
do do
{ {
n = l_nplh[l_num_levels] * l_nplv[l_num_levels]; n = l_nplh[l_num_levels] * l_nplv[l_num_levels];
l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2; l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2; l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
p_tree->numnodes += n; p_tree->numnodes += n;
++l_num_levels; ++l_num_levels;
} }
while (n > 1); while (n > 1);
/* ADD */ /* ADD */
if if
(p_tree->numnodes == 0) (p_tree->numnodes == 0)
{ {
tgt_destroy(p_tree); tgt_destroy(p_tree);
return 00; return 00;
} }
l_node_size = p_tree->numnodes * sizeof(opj_tgt_node_t); l_node_size = p_tree->numnodes * sizeof(opj_tgt_node_t);
if if
(l_node_size > p_tree->nodes_size) (l_node_size > p_tree->nodes_size)
{ {
p_tree->nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size); opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
if if
(! p_tree->nodes) (! p_tree->nodes)
{ {
tgt_destroy(p_tree); fprintf(stderr, "Not enough memory to reinitialize the tag tree\n");
return 00; tgt_destroy(p_tree);
} return 00;
memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0 , l_node_size - p_tree->nodes_size); }
p_tree->nodes_size = l_node_size; p_tree->nodes = new_nodes;
} memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0 , l_node_size - p_tree->nodes_size);
l_node = p_tree->nodes; p_tree->nodes_size = l_node_size;
l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv]; }
l_parent_node0 = l_parent_node; l_node = p_tree->nodes;
l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
l_parent_node0 = l_parent_node;
for for
(i = 0; i < l_num_levels - 1; ++i) (i = 0; i < l_num_levels - 1; ++i)
{ {
for for
(j = 0; j < l_nplv[i]; ++j) (j = 0; j < l_nplv[i]; ++j)
{ {
k = l_nplh[i]; k = l_nplh[i];
while while
(--k >= 0) (--k >= 0)
{ {
l_node->parent = l_parent_node; l_node->parent = l_parent_node;
++l_node; ++l_node;
if (--k >= 0) if (--k >= 0)
{ {
l_node->parent = l_parent_node; l_node->parent = l_parent_node;
++l_node; ++l_node;
} }
++l_parent_node; ++l_parent_node;
} }
if ((j & 1) || j == l_nplv[i] - 1) if ((j & 1) || j == l_nplv[i] - 1)
{ {
l_parent_node0 = l_parent_node; l_parent_node0 = l_parent_node;
} }
else else
{ {
l_parent_node = l_parent_node0; l_parent_node = l_parent_node0;
l_parent_node0 += l_nplh[i]; l_parent_node0 += l_nplh[i];
} }
} }
} }
l_node->parent = 0; l_node->parent = 0;
} }
tgt_reset(p_tree); tgt_reset(p_tree);
return p_tree; return p_tree;
} }
/*void tgt_destroy(opj_tgt_tree_t *tree) { /*void tgt_destroy(opj_tgt_tree_t *tree) {
opj_free(tree->nodes); opj_free(tree->nodes);
opj_free(tree); opj_free(tree);
}*/ }*/
void tgt_destroy(opj_tgt_tree_t *p_tree) void tgt_destroy(opj_tgt_tree_t *p_tree)
{ {
if (! p_tree) { if (! p_tree) {
return; return;
} }
if (p_tree->nodes) { if (p_tree->nodes) {
opj_free(p_tree->nodes); opj_free(p_tree->nodes);
p_tree->nodes = 00; p_tree->nodes = 00;
} }
opj_free(p_tree); opj_free(p_tree);
} }
/*void tgt_reset(opj_tgt_tree_t *tree) { /*void tgt_reset(opj_tgt_tree_t *tree) {
int i; int i;
if (NULL == tree) if (NULL == tree)
return; return;
for (i = 0; i < tree->numnodes; i++) { for (i = 0; i < tree->numnodes; i++) {
tree->nodes[i].value = 999; tree->nodes[i].value = 999;
tree->nodes[i].low = 0; tree->nodes[i].low = 0;
tree->nodes[i].known = 0; tree->nodes[i].known = 0;
} }
}*/ }*/
void tgt_reset(opj_tgt_tree_t *p_tree) { void tgt_reset(opj_tgt_tree_t *p_tree) {
OPJ_UINT32 i; OPJ_UINT32 i;
opj_tgt_node_t * l_current_node = 00;; opj_tgt_node_t * l_current_node = 00;;
if (! p_tree) { if (! p_tree) {
return; return;
} }
l_current_node = p_tree->nodes; l_current_node = p_tree->nodes;
for (i = 0; i < p_tree->numnodes; ++i) for (i = 0; i < p_tree->numnodes; ++i)
{ {
l_current_node->value = 999; l_current_node->value = 999;
l_current_node->low = 0; l_current_node->low = 0;
l_current_node->known = 0; l_current_node->known = 0;
++l_current_node; ++l_current_node;
} }
} }
void tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value) { void tgt_setvalue(opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 value) {
opj_tgt_node_t *node; opj_tgt_node_t *node;
node = &tree->nodes[leafno]; node = &tree->nodes[leafno];
while (node && node->value > value) { while (node && node->value > value) {
node->value = value; node->value = value;
node = node->parent; node = node->parent;
} }
} }
void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) { void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
opj_tgt_node_t *stk[31]; opj_tgt_node_t *stk[31];
opj_tgt_node_t **stkptr; opj_tgt_node_t **stkptr;
opj_tgt_node_t *node; opj_tgt_node_t *node;
OPJ_INT32 low; OPJ_INT32 low;
stkptr = stk; stkptr = stk;
node = &tree->nodes[leafno]; node = &tree->nodes[leafno];
while (node->parent) { while (node->parent) {
*stkptr++ = node; *stkptr++ = node;
node = node->parent; node = node->parent;
} }
low = 0; low = 0;
for (;;) { for (;;) {
if (low > node->low) { if (low > node->low) {
node->low = low; node->low = low;
} else { } else {
low = node->low; low = node->low;
} }
while (low < threshold) { while (low < threshold) {
if (low >= node->value) { if (low >= node->value) {
if (!node->known) { if (!node->known) {
bio_write(bio, 1, 1); bio_write(bio, 1, 1);
node->known = 1; node->known = 1;
} }
break; break;
} }
bio_write(bio, 0, 1); bio_write(bio, 0, 1);
++low; ++low;
} }
node->low = low; node->low = low;
if (stkptr == stk) if (stkptr == stk)
break; break;
node = *--stkptr; node = *--stkptr;
} }
} }
OPJ_UINT32 tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) { OPJ_UINT32 tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, OPJ_UINT32 leafno, OPJ_INT32 threshold) {
opj_tgt_node_t *stk[31]; opj_tgt_node_t *stk[31];
opj_tgt_node_t **stkptr; opj_tgt_node_t **stkptr;
opj_tgt_node_t *node; opj_tgt_node_t *node;
OPJ_INT32 low; OPJ_INT32 low;
stkptr = stk; stkptr = stk;
node = &tree->nodes[leafno]; node = &tree->nodes[leafno];
while (node->parent) { while (node->parent) {
*stkptr++ = node; *stkptr++ = node;
node = node->parent; node = node->parent;
} }
low = 0; low = 0;
for (;;) { for (;;) {
if (low > node->low) { if (low > node->low) {
node->low = low; node->low = low;
} else { } else {
low = node->low; low = node->low;
} }
while (low < threshold && low < node->value) { while (low < threshold && low < node->value) {
if (bio_read(bio, 1)) { if (bio_read(bio, 1)) {
node->value = low; node->value = low;
} else { } else {
++low; ++low;
} }
} }
node->low = low; node->low = low;
if (stkptr == stk) { if (stkptr == stk) {
break; break;
} }
node = *--stkptr; node = *--stkptr;
} }
return (node->value < threshold) ? 1 : 0; return (node->value < threshold) ? 1 : 0;
} }

View File

@ -42,346 +42,349 @@
#include "opj_config.h" #include "opj_config.h"
#include <stdlib.h> #include <stdlib.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#define strcasecmp _stricmp #define strcasecmp _stricmp
#define strncasecmp _strnicmp #define strncasecmp _strnicmp
#else #else
#include <strings.h> #include <strings.h>
#endif /* _WIN32 */ #endif /* _WIN32 */
#include "openjpeg.h" #include "openjpeg.h"
#include "format_defs.h" #include "format_defs.h"
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Declarations */ /* Declarations */
int get_file_format(const char *filename); int get_file_format(const char *filename);
static int infile_format(const char *fname); static int infile_format(const char *fname);
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
int get_file_format(const char *filename) { int get_file_format(const char *filename) {
unsigned int i; unsigned int i;
static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" }; static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" };
static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT }; static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT };
char * ext = strrchr(filename, '.'); char * ext = strrchr(filename, '.');
if (ext == NULL) if (ext == NULL)
return -1; return -1;
ext++; ext++;
if(ext) { if(ext) {
for(i = 0; i < sizeof(format)/sizeof(*format); i++) { for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
if(strcasecmp(ext, extension[i]) == 0) { if(strcasecmp(ext, extension[i]) == 0) {
return format[i]; return format[i];
} }
} }
} }
return -1; return -1;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a" #define JP2_RFC3745_MAGIC "\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a"
#define JP2_MAGIC "\x0d\x0a\x87\x0a" #define JP2_MAGIC "\x0d\x0a\x87\x0a"
/* position 45: "\xff\x52" */ /* position 45: "\xff\x52" */
#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51" #define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51"
static int infile_format(const char *fname) static int infile_format(const char *fname)
{ {
FILE *reader; FILE *reader;
const char *s, *magic_s; const char *s, *magic_s;
int ext_format, magic_format; int ext_format, magic_format;
unsigned char buf[12]; unsigned char buf[12];
unsigned int l_nb_read; unsigned int l_nb_read;
reader = fopen(fname, "rb"); reader = fopen(fname, "rb");
if (reader == NULL) if (reader == NULL)
return -1; return -1;
memset(buf, 0, 12); memset(buf, 0, 12);
l_nb_read = fread(buf, 1, 12, reader); l_nb_read = fread(buf, 1, 12, reader);
fclose(reader); fclose(reader);
if (l_nb_read != 12) if (l_nb_read != 12)
return -1; return -1;
ext_format = get_file_format(fname); ext_format = get_file_format(fname);
if (ext_format == JPT_CFMT) if (ext_format == JPT_CFMT)
return JPT_CFMT; return JPT_CFMT;
if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) { if (memcmp(buf, JP2_RFC3745_MAGIC, 12) == 0 || memcmp(buf, JP2_MAGIC, 4) == 0) {
magic_format = JP2_CFMT; magic_format = JP2_CFMT;
magic_s = ".jp2"; magic_s = ".jp2";
} }
else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) { else if (memcmp(buf, J2K_CODESTREAM_MAGIC, 4) == 0) {
magic_format = J2K_CFMT; magic_format = J2K_CFMT;
magic_s = ".j2k or .jpc or .j2c"; magic_s = ".j2k or .jpc or .j2c";
} }
else else
return -1; return -1;
if (magic_format == ext_format) if (magic_format == ext_format)
return ext_format; return ext_format;
s = fname + strlen(fname) - 4; s = fname + strlen(fname) - 4;
fputs("\n===========================================\n", stderr); fputs("\n===========================================\n", stderr);
fprintf(stderr, "The extension of this file is incorrect.\n" fprintf(stderr, "The extension of this file is incorrect.\n"
"FOUND %s. SHOULD BE %s\n", s, magic_s); "FOUND %s. SHOULD BE %s\n", s, magic_s);
fputs("===========================================\n", stderr); fputs("===========================================\n", stderr);
return magic_format; return magic_format;
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/** /**
sample error callback expecting a FILE* client object sample error callback expecting a FILE* client object
*/ */
void error_callback_file(const char *msg, void *client_data) { void error_callback_file(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data; FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg); fprintf(stream, "[ERROR] %s", msg);
} }
/** /**
sample warning callback expecting a FILE* client object sample warning callback expecting a FILE* client object
*/ */
void warning_callback_file(const char *msg, void *client_data) { void warning_callback_file(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data; FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg); fprintf(stream, "[WARNING] %s", msg);
} }
/** /**
sample error debug callback expecting no client object sample error debug callback expecting no client object
*/ */
void error_callback(const char *msg, void *client_data) { void error_callback(const char *msg, void *client_data) {
(void)client_data; (void)client_data;
fprintf(stdout, "[ERROR] %s", msg); fprintf(stdout, "[ERROR] %s", msg);
} }
/** /**
sample warning debug callback expecting no client object sample warning debug callback expecting no client object
*/ */
void warning_callback(const char *msg, void *client_data) { void warning_callback(const char *msg, void *client_data) {
(void)client_data; (void)client_data;
fprintf(stdout, "[WARNING] %s", msg); fprintf(stdout, "[WARNING] %s", msg);
} }
/** /**
sample debug callback expecting no client object sample debug callback expecting no client object
*/ */
void info_callback(const char *msg, void *client_data) { void info_callback(const char *msg, void *client_data) {
(void)client_data; (void)client_data;
fprintf(stdout, "[INFO] %s", msg); fprintf(stdout, "[INFO] %s", msg);
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
opj_dparameters_t l_param; opj_dparameters_t l_param;
opj_codec_t * l_codec; opj_codec_t * l_codec;
opj_image_t * l_image; opj_image_t * l_image;
FILE * l_file; FILE * l_file;
opj_stream_t * l_stream; opj_stream_t * l_stream;
OPJ_UINT32 l_data_size; OPJ_UINT32 l_data_size;
OPJ_UINT32 l_max_data_size = 1000; OPJ_UINT32 l_max_data_size = 1000;
OPJ_UINT32 l_tile_index; OPJ_UINT32 l_tile_index;
OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000); OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000);
opj_bool l_go_on = OPJ_TRUE; opj_bool l_go_on = OPJ_TRUE;
OPJ_INT32 l_tile_x0=0, l_tile_y0=0 ; OPJ_INT32 l_tile_x0=0, l_tile_y0=0 ;
OPJ_UINT32 l_tile_width=0, l_tile_height=0, l_nb_tiles_x=0, l_nb_tiles_y=0, l_nb_comps=0 ; OPJ_UINT32 l_tile_width=0, l_tile_height=0, l_nb_tiles_x=0, l_nb_tiles_y=0, l_nb_comps=0 ;
OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1; OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1;
int da_x0=0; int da_x0=0;
int da_y0=0; int da_y0=0;
int da_x1=1000; int da_x1=1000;
int da_y1=1000; int da_y1=1000;
char input_file[64]; char input_file[64];
/* should be test_tile_decoder 0 0 1000 1000 tte1.j2k */
if( argc == 6 )
{
da_x0=atoi(argv[1]);
da_y0=atoi(argv[2]);
da_x1=atoi(argv[3]);
da_y1=atoi(argv[4]);
strcpy(input_file,argv[5]);
} /* should be test_tile_decoder 0 0 1000 1000 tte1.j2k */
else if( argc == 6 )
{ {
da_x0=0; da_x0=atoi(argv[1]);
da_y0=0; da_y0=atoi(argv[2]);
da_x1=1000; da_x1=atoi(argv[3]);
da_y1=1000; da_y1=atoi(argv[4]);
strcpy(input_file,"test.j2k"); strcpy(input_file,argv[5]);
}
if (! l_data) { }
return EXIT_FAILURE; else
} {
da_x0=0;
da_y0=0;
da_x1=1000;
da_y1=1000;
strcpy(input_file,"test.j2k");
}
l_file = fopen(input_file,"rb"); if (! l_data) {
if (! l_file) return EXIT_FAILURE;
{ }
fprintf(stdout, "ERROR while opening input file\n");
free(l_data);
return EXIT_FAILURE;
}
l_stream = opj_stream_create_default_file_stream(l_file,OPJ_TRUE); l_file = fopen(input_file,"rb");
if (!l_stream){ if (! l_file)
fclose(l_file); {
free(l_data); fprintf(stdout, "ERROR while opening input file\n");
fprintf(stderr, "ERROR -> failed to create the stream from the file\n"); free(l_data);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Set the default decoding parameters */ l_stream = opj_stream_create_default_file_stream(l_file,OPJ_TRUE);
opj_set_default_decoder_parameters(&l_param); if (!l_stream){
fclose(l_file);
free(l_data);
fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
return EXIT_FAILURE;
}
/* */ /* Set the default decoding parameters */
l_param.decod_format = infile_format(input_file); opj_set_default_decoder_parameters(&l_param);
/** you may here add custom decoding parameters */ /* */
/* do not use layer decoding limitations */ l_param.decod_format = infile_format(input_file);
l_param.cp_layer = 0;
/* do not use resolutions reductions */ /** you may here add custom decoding parameters */
l_param.cp_reduce = 0; /* do not use layer decoding limitations */
l_param.cp_layer = 0;
/* to decode only a part of the image data */ /* do not use resolutions reductions */
//opj_restrict_decoding(&l_param,0,0,1000,1000); l_param.cp_reduce = 0;
switch(l_param.decod_format) { /* to decode only a part of the image data */
case J2K_CFMT: /* JPEG-2000 codestream */ //opj_restrict_decoding(&l_param,0,0,1000,1000);
{
/* Get a decoder handle */
l_codec = opj_create_decompress(CODEC_J2K);
break;
}
case JP2_CFMT: /* JPEG 2000 compressed image data */
{
/* Get a decoder handle */
l_codec = opj_create_decompress(CODEC_JP2);
break;
}
default:
{
fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
return EXIT_FAILURE;
}
}
/* catch events using our callbacks and give a local context */
opj_set_info_handler(l_codec, info_callback,00); switch(l_param.decod_format) {
opj_set_warning_handler(l_codec, warning_callback,00); case J2K_CFMT: /* JPEG-2000 codestream */
opj_set_error_handler(l_codec, error_callback,00); {
/* Get a decoder handle */
/* Setup the decoder decoding parameters using user parameters */ l_codec = opj_create_decompress(CODEC_J2K);
if (! opj_setup_decoder(l_codec, &l_param)) break;
{ }
fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n"); case JP2_CFMT: /* JPEG 2000 compressed image data */
{
/* Get a decoder handle */
l_codec = opj_create_decompress(CODEC_JP2);
break;
}
default:
{
fprintf(stderr, "ERROR -> Not a valid JPEG2000 file!\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
return EXIT_FAILURE;
}
}
/* catch events using our callbacks and give a local context */
opj_set_info_handler(l_codec, info_callback,00);
opj_set_warning_handler(l_codec, warning_callback,00);
opj_set_error_handler(l_codec, error_callback,00);
/* Setup the decoder decoding parameters using user parameters */
if (! opj_setup_decoder(l_codec, &l_param))
{
fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
return EXIT_FAILURE;
}
/* Read the main header of the codestream and if necessary the JP2 boxes*/
if (! opj_read_header(l_stream, l_codec, &l_image))
{
fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
return EXIT_FAILURE;
}
if (!opj_set_decode_area(l_codec, l_image, da_x0, da_y0,da_x1, da_y1)){
fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
while (l_go_on)
{
if (! opj_read_tile_header( l_codec,
l_stream,
&l_tile_index,
&l_data_size,
&l_current_tile_x0,
&l_current_tile_y0,
&l_current_tile_x1,
&l_current_tile_y1,
&l_nb_comps,
&l_go_on))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
if (l_go_on)
{
if (l_data_size > l_max_data_size)
{
OPJ_BYTE *l_new_data = (OPJ_BYTE *) realloc(l_data, l_data_size);
if (! l_new_data)
{
fclose(l_file);
free(l_new_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
l_data = l_new_data;
l_max_data_size = l_data_size;
}
if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
/** now should inspect image to know the reduction factor and then how to behave with data */
}
}
if (! opj_end_decompress(l_codec,l_stream))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
/* Free memory */
fclose(l_file); fclose(l_file);
free(l_data); free(l_data);
opj_stream_destroy(l_stream); opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec); opj_destroy_codec(l_codec);
return EXIT_FAILURE; opj_image_destroy(l_image);
}
/* Read the main header of the codestream and if necessary the JP2 boxes*/
if (! opj_read_header(l_stream, l_codec, &l_image))
{
fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
return EXIT_FAILURE;
}
if (!opj_set_decode_area(l_codec, l_image, da_x0, da_y0,da_x1, da_y1)){ // Print profiling
fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n"); //PROFPRINT();
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
while (l_go_on)
{
if (! opj_read_tile_header( l_codec,
l_stream,
&l_tile_index,
&l_data_size,
&l_current_tile_x0,
&l_current_tile_y0,
&l_current_tile_x1,
&l_current_tile_y1,
&l_nb_comps,
&l_go_on))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
if (l_go_on)
{
if (l_data_size > l_max_data_size)
{
l_data = (OPJ_BYTE *) realloc(l_data,l_data_size);
if (! l_data)
{
fclose(l_file);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
l_max_data_size = l_data_size;
}
if (! opj_decode_tile_data(l_codec,l_tile_index,l_data,l_data_size,l_stream))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
/** now should inspect image to know the reduction factor and then how to behave with data */
}
}
if (! opj_end_decompress(l_codec,l_stream))
{
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
return EXIT_FAILURE;
}
/* Free memory */
fclose(l_file);
free(l_data);
opj_stream_destroy(l_stream);
opj_destroy_codec(l_codec);
opj_image_destroy(l_image);
// Print profiling
//PROFPRINT();
return EXIT_SUCCESS;
} }