diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index 922182bd..2a24f456 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -318,7 +318,8 @@ int main(int argc, char **argv) int ir = 0; int res_spec = 0; /* For various precinct sizes specification */ char sep; - char *outbuf; + char *j2k_codestream; + char *jp2_codestream; FILE *f; @@ -848,10 +849,11 @@ int main(int argc, char **argv) return 1; } } else { - outbuf = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); /* Allocate memory for all tiles */ - cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 2); + j2k_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); + /* Allocate memory for all tiles */ + cio_init(j2k_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); len = - j2k_encode(&img, &cp, outbuf, + j2k_encode(&img, &cp, j2k_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2, index); if (len == 0) { fprintf(stderr, "failed to encode image\n"); @@ -862,8 +864,8 @@ int main(int argc, char **argv) fprintf(stderr, "failed to open %s for writing\n", outfile); return 1; } - fwrite(outbuf, 1, len, f); - free(outbuf); + fwrite(j2k_codestream, 1, len, f); + free(j2k_codestream); fclose(f); } } else { /* JP2 format output */ @@ -873,30 +875,40 @@ int main(int argc, char **argv) jp2_struct->image = &img; /* Initialising the standard JP2 box content */ - /* If you wish to modify those boxes, you have to modify the jp2_struct content */ + /* If you wish to modify those boxes, you have to modify + the jp2_struct content */ if (jp2_init_stdjp2(jp2_struct, &img)) { fprintf(stderr, "Error with jp2 initialization"); return 1; }; if (cp.intermed_file == 1) { - /*For the moment, JP2 format does not use intermediary files for each tile */ + /*For the moment, JP2 format does not use intermediary + files for each tile */ cp.intermed_file = 0; } - outbuf = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); - cio_init(outbuf, cp.tdx * cp.tdy * cp.tw * cp.th * 2); - len = jp2_encode(jp2_struct, &cp, outbuf, index); + j2k_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); + jp2_codestream = (char *) malloc(cp.tdx * cp.tdy * cp.tw * cp.th * 2); + + cio_init(j2k_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); + len = j2k_encode(&img, &cp, j2k_codestream, + cp.tdx * cp.tdy * cp.tw * cp.th * 2, index); if (len == 0) { fprintf(stderr, "failed to encode image\n"); return 1; } + jp2_struct->j2k_codestream_len = len; + + cio_init(jp2_codestream, cp.tdx * cp.tdy * cp.tw * cp.th * 2); + len = jp2_wrap_j2k(jp2_struct, j2k_codestream, jp2_codestream); f = fopen(outfile, "wb"); if (!f) { fprintf(stderr, "failed to open %s for writing\n", outfile); return 1; } - fwrite(outbuf, 1, len, f); - free(outbuf); + fwrite(jp2_codestream, 1, len, f); + free(jp2_codestream); + free(j2k_codestream); fclose(f); } diff --git a/codec/j2k_to_image.c b/codec/j2k_to_image.c index f1534d53..ea4e52d0 100644 --- a/codec/j2k_to_image.c +++ b/codec/j2k_to_image.c @@ -25,12 +25,20 @@ * POSSIBILITY OF SUCH DAMAGE. */ + + //MEMORY LEAK + #ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include // Must be included first + #include + #endif + //MEM @@ -147,6 +155,7 @@ int main(int argc, char **argv) src_name--; S1 = *src_name; + /* J2K format */ if ((S1 == 'j' && S2 == '2' && S3 == 'k') || (S1 == 'J' && S2 == '2' && S3 == 'K') || (S1 == 'j' && S2 == '2' @@ -165,7 +174,12 @@ int main(int argc, char **argv) jp2_struct->image = &img; - if (jp2_decode(src, len, jp2_struct, &cp)) { + if (jp2_read_struct(src, jp2_struct, len)) { + fprintf(stderr, "j2k_to_image: failed to decode jp2 structure!\n"); + return 1; + } + + if (!j2k_decode(src + jp2_struct->j2k_codestream_offset, jp2_struct->j2k_codestream_len, &img, &cp)) { fprintf(stderr, "j2k_to_image: failed to decode image!\n"); return 1; } @@ -561,12 +575,20 @@ int main(int argc, char **argv) break; } + + j2k_dec_release(); + + //MEMORY LEAK + #ifdef _DEBUG + _CrtDumpMemoryLeaks(); + #endif + //MEM return 0; diff --git a/libopenjpeg/jp2.c b/libopenjpeg/jp2.c index 31794dee..ab69212d 100644 --- a/libopenjpeg/jp2.c +++ b/libopenjpeg/jp2.c @@ -65,6 +65,11 @@ int jp2_read_boxhdr(jp2_box_t * box) return 1; }; box->length = cio_read(4); + if (box->length == 0) + box->length = cio_numbytesleft() + 12; + } + else if (box->length == 0) { + box->length = cio_numbytesleft() + 8; } return 0; } @@ -418,34 +423,33 @@ int jp2_read_ftyp(jp2_struct_t * jp2_struct) jp2_struct->cl[i] = cio_read(4); /* CLi */ if (cio_tell() - box.init_pos != box.length) { - fprintf(stderr, "Error with FTYP Box\n"); + fprintf(stderr, "Error with FTYP Box\n"); return 1; } return 0; } -int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, - char *index) +int jp2_write_jp2c(jp2_struct_t * jp2_struct, char *j2k_codestream) { - int len; jp2_box_t box; box.init_pos = cio_tell(); cio_skip(4); cio_write(JP2_JP2C, 4); // JP2C - len = j2k_encode(img, cp, jp2_buffer, cp->tdx * cp->tdy * cp->th * cp->tw * 2, index); + jp2_struct->j2k_codestream_offset = cio_tell(); + memcpy(cio_getbp(),j2k_codestream, jp2_struct->j2k_codestream_len); - box.length = cio_tell() - box.init_pos; + box.length = 8 + jp2_struct->j2k_codestream_len; cio_seek(box.init_pos); cio_write(box.length, 4); /* L */ cio_seek(box.init_pos + box.length); + return box.length; } -int jp2_read_jp2c(unsigned char *src, int len, jp2_struct_t * jp2_struct, - j2k_cp_t * cp) +int jp2_read_jp2c(unsigned char *src, jp2_struct_t * jp2_struct) { jp2_box_t box; @@ -455,12 +459,8 @@ int jp2_read_jp2c(unsigned char *src, int len, jp2_struct_t * jp2_struct, return 1; } - src += cio_tell(); - - if (j2k_decode(src, len, jp2_struct->image, cp) == 0) { - fprintf(stderr, "JP2F box: failed to decode J2K bitstream image!\n"); - return 1; - } + jp2_struct->j2k_codestream_offset = cio_tell(); + jp2_struct->j2k_codestream_len = box.length - 8; return 0; } @@ -508,8 +508,8 @@ int jp2_read_jp() } -int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, - j2k_cp_t * cp) + +int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct, int len) { cio_init(src, len); @@ -519,20 +519,17 @@ int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, return 1; if (jp2_read_jp2h(jp2_struct)) return 1; - if (jp2_read_jp2c(src, len, jp2_struct, cp)) + if (jp2_read_jp2c(src, jp2_struct)) return 1; return 0; } -int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, - char *index) +int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, char *output) { - int len; - jp2_write_jp(); jp2_write_ftyp(jp2_struct); jp2_write_jp2h(jp2_struct); - len = jp2_write_jp2c(jp2_struct->image, cp, output, index); + jp2_write_jp2c(jp2_struct, j2k_codestream); return cio_tell(); } diff --git a/libopenjpeg/jp2.h b/libopenjpeg/jp2.h index 21ee133d..f8c7b3af 100644 --- a/libopenjpeg/jp2.h +++ b/libopenjpeg/jp2.h @@ -53,6 +53,8 @@ typedef struct { unsigned int *cl; jp2_comps_t *comps; j2k_image_t *image; + unsigned int j2k_codestream_offset; + unsigned int j2k_codestream_len; } jp2_struct_t; typedef struct { @@ -69,17 +71,13 @@ typedef struct { */ int jp2_init_stdjp2(jp2_struct_t * jp2_struct, j2k_image_t * img); -/* int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, - * char *index); +/* int jp2_write_jp2c(char *j2k_codestream, int j2k_len); * * Write the jp2c codestream box - * img: the j2k_image that will be compressed - * jp2_buffer: the buffer that will recieve the compressed data - * index: the name of the index file + * jp2_struct: the jp2 structure you are working with + * j2k_codestream: the j2k codestream to include in jp2 file */ -int jp2_write_jp2c(j2k_image_t * img, j2k_cp_t * cp, char *jp2_buffer, - char *index); - +int jp2_write_jp2c(jp2_struct_t * jp2_struct, char *j2k_codestream); /* int jp2_write_jp2h(jp2_struct_t * jp2_struct); * @@ -95,28 +93,25 @@ void jp2_write_jp2h(jp2_struct_t * jp2_struct); */ int jp2_read_jp2h(jp2_struct_t * jp2_struct); -/* int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, - * char *index); +/* int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, + int j2k_len, char *output) * - * Encode a JP2 file - * jp2_buffer: the buffer containing the pointer to the image to encode - * cp: coding parameters of the image - * outbuf: pointer to memory where compressed data will be written - * index: the name of the index file + * Wrap a J2K codestream in a JP2 file + * jp2_struct: the jp2 structure used to create jp2 boxes + * j2k_codestream: the j2k codestream to include in jp2 file + * output: pointer to jp2 codestream that will be created */ -int jp2_encode(jp2_struct_t * jp2_struct, j2k_cp_t * cp, char *output, - char *index); +int jp2_wrap_j2k(jp2_struct_t * jp2_struct, char *j2k_codestream, + char *output); -/* int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, - * j2k_cp_t * cp); + +/* int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct); * - * Decode a JP2 file + * Decode the structure of a JP2 file * src: pointer to memory where compressed data is stored - * len: length of src buffer * jp2_struct: the jp2 structure that will be created - * cp: coding parameters of the image + * len: length of jp2 codestream */ -int jp2_decode(unsigned char *src, int len, jp2_struct_t * jp2_struct, - j2k_cp_t * cp); +int jp2_read_struct(unsigned char *src, jp2_struct_t * jp2_struct, int len); #endif