diff --git a/ChangeLog b/ChangeLog index 409af193..111ae5af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ What's New for OpenJPEG ! : changed + : added +March 20, 2007 ++ [Parvatha] Added feature for generation of tile parts. Modifications in image_to_j2k.c, openjpeg.c, j2k.c, pi.c ++ [Parvatha] Added function j2k_write_tlm(),to generate TLM marker for a Digital cinema compliant codestream. Modifications in j2k.c. + March 14, 2007 * [FOD] Fixed linux makefile, with help from David Fries and Guido diff --git a/codec/convert.c b/codec/convert.c index 3ff6eb88..999b41ca 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index 014ae1d9..3d423e77 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -414,41 +415,66 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_cparamet } -void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ - int i; - float temp_rate; - +void cinema_parameters(opj_cparameters_t *parameters){ parameters->tile_size_on = false; parameters->cp_tdx=1; parameters->cp_tdy=1; + + /*Tile part*/ + parameters->tp_flag = 'C'; + parameters->tp_on = 1; /*Tile and Image shall be at (0,0)*/ - parameters->cp_tx0=0; parameters->cp_ty0=0; + parameters->cp_tx0 = 0; + parameters->cp_ty0 = 0; + parameters->image_offset_x0 = 0; + parameters->image_offset_y0 = 0; /*Codeblock size= 32*32*/ parameters->cblockw_init = 32; parameters->cblockh_init = 32; + parameters->csty |= 0x01; /*The progression order shall be CPRL*/ - strncpy(parameters->cp_prog,"CPRL",4); - parameters->prog_order = give_progression(parameters->cp_prog); - /*Tile parts not implemented*/ + parameters->prog_order = CPRL; /* No ROI */ parameters->roi_compno = -1; parameters->subsampling_dx = 1; parameters->subsampling_dy = 1; +} + +void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ + int i; + float temp_rate; + switch (parameters->cp_cinema){ + case CINEMA2K_24: + case CINEMA2K_48: + parameters->cp_rsiz = CINEMA2K; + if(parameters->numresolution > 6){ + parameters->numresolution = 6; + } + if (!((image->comps[0].w == 2048) & (image->comps[0].h == 1080))){ + fprintf(stdout,"Image coordinates is not 2K, %d x %d\n",image->comps[0].w,image->comps[0].h); + } + break; + + case CINEMA4K_24: + parameters->cp_rsiz = CINEMA4K; + if(parameters->numresolution < 1){ + parameters->numresolution = 1; + }else if(parameters->numresolution > 7){ + parameters->numresolution = 7; + } + if (!((image->comps[0].w == 4096) & (image->comps[0].h == 2160))){ + fprintf(stdout,"Image coordinates is not 4K, %d x %d\n",image->comps[0].w,image->comps[0].h); + } + break; + } switch (parameters->cp_cinema){ case CINEMA2K_24: case CINEMA4K_24: - if (image->comps[0].w == 2048 || image->comps[0].h == 1080){ - parameters->numresolution = 6; - parameters->cp_rsiz = CINEMA2K; - }else{ - fprintf(stdout,"One of the image coordinates are not 2K\n"); - } - for(i=0;itcp_numlayers;i++){ temp_rate = 0 ; if (parameters->tcp_rates[i]== 0){ @@ -466,13 +492,7 @@ void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image){ break; case CINEMA2K_48: - if (image->comps[0].w == 4096 || image->comps[0].h == 2160){ - parameters->numresolution = 7; - parameters->cp_rsiz= CINEMA4K; - }else{ - fprintf(stdout,"One of the image coordinates are not 4K\n"); - } - for(i=0;itcp_numlayers;i++){ + for(i=0;itcp_numlayers;i++){ if (parameters->tcp_rates[i]== 0){ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); @@ -889,6 +909,15 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,i } break; + /* ------------------------------------------------------ */ + + case 'v': /* Tile part generation*/ + { + parameters->tp_flag = optarg[0]; + parameters->tp_on = 1; + } + break; + /* ------------------------------------------------------ */ case 'z': /* Image Directory path */ @@ -1262,6 +1291,11 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,i } /* check for possible errors */ + if (parameters->cp_cinema){ + if(parameters->tcp_numlayers > 0){ + fprintf(stdout,"Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n"); + } + } if(img_fol->set_imgdir == 1){ if(!(parameters->infile[0] == 0)){ fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n"); @@ -1369,6 +1403,11 @@ int main(int argc, char **argv) { if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol) == 1) { return 0; } + + if (parameters.cp_cinema){ + cinema_parameters(¶meters); + } + /* Create comment for codestream */ if(parameters.cp_comment == NULL) { @@ -1480,6 +1519,10 @@ int main(int argc, char **argv) { break; } + if(parameters.cp_cinema){ + cinema_setup_encoder(¶meters,image); + } + /* encode the destination image */ /* ---------------------------- */ @@ -1494,10 +1537,6 @@ int main(int argc, char **argv) { /* catch events using our callbacks and give a local context */ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - if(parameters.cp_cinema){ - cinema_setup_encoder(¶meters,image); - } - /* setup the encoder parameters using the current image and user parameters */ opj_setup_encoder(cinfo, ¶meters, image); diff --git a/codec/j2k_to_image.c b/codec/j2k_to_image.c index 223f44ee..ccc22471 100644 --- a/codec/j2k_to_image.c +++ b/codec/j2k_to_image.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index fb9aeaff..3768a110 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -175,6 +176,11 @@ Read the PPT marker (packet packet headers, tile-part header) */ static void j2k_read_ppt(opj_j2k_t *j2k); /** +Write the TLM marker (Mainheader) +@param j2k J2K handle +*/ +static void j2k_write_tlm(opj_j2k_t *j2k); +/** Write the SOT marker (start of tile-part) @param j2k J2K handle */ @@ -228,6 +234,28 @@ static void j2k_read_unk(opj_j2k_t *j2k); /*@}*/ /* ----------------------------------------------------------------------- */ +typedef struct j2k_prog_order{ + OPJ_PROG_ORDER enum_prog; + char str_prog[4]; +}j2k_prog_order_t; + +j2k_prog_order_t j2k_prog_order_list[] = { + {CPRL, "CPRL"}, + {LRCP, "LRCP"}, + {PCRL, "PCRL"}, + {RLCP, "RLCP"}, + {RPCL, "RPCL"} +}; + +char *convert_progression_order(OPJ_PROG_ORDER prg_order){ + j2k_prog_order_t *po; + for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){ + if(po->enum_prog == prg_order){ + break; + } + } + return po->str_prog; +} void j2k_dump_image(FILE *fd, opj_image_t * img) { int compno; @@ -303,6 +331,58 @@ void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { } /* ----------------------------------------------------------------------- */ +int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){ + char *prog; + int i; + int tpnum=1,tpend=0; + opj_tcp_t *tcp = &cp->tcps[tileno]; + prog = convert_progression_order(tcp->prg); + + if(cp->tp_on == 1){ + for(i=0;i<4;i++){ + if(tpend!=1){ + if( cp->tp_flag == prog[i] ){ + tpend=1;cp->tp_pos=i; + } + switch(prog[i]){ + case 'C': + tpnum= tpnum * tcp->pocs[pino].compE; + break; + case 'R': + tpnum= tpnum * tcp->pocs[pino].resE; + break; + case 'P': + tpnum= tpnum * tcp->pocs[pino].prcE; + break; + case 'L': + tpnum= tpnum * tcp->pocs[pino].layE; + break; + } + } + } + }else{ + tpnum=1; + } + return tpnum; +} + +/** mem allocation for TLM marker*/ +int j2k_generate_tlm(opj_cp_t *cp,int img_numcomp,opj_image_t *image ){ + int pino,tileno,maxres=0,totnum_tp=0; + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + for(pino = 0; pino <= tcp->numpocs; pino++) { + int tp_num=0; + opj_pi_iterator_t *pi = (opj_pi_iterator_t *) opj_malloc(sizeof(opj_pi_iterator_t)); + pi = pi_initialise_encode(image, cp, tileno,pino); + if(!pi) { return -1;} + tp_num = j2k_get_num_tp(cp,pino,tileno); + totnum_tp = totnum_tp + tp_num; + pi_destroy(pi, cp, tileno); + } + } + return totnum_tp; +} static void j2k_write_soc(opj_j2k_t *j2k) { opj_cio_t *cio = j2k->cio; @@ -1067,6 +1147,18 @@ static void j2k_read_ppt(opj_j2k_t *j2k) { tcp->ppt_store = j; } +static void j2k_write_tlm(opj_j2k_t *j2k){ + int lenp; + opj_cio_t *cio = j2k->cio; + j2k->tlm_start = cio_tell(cio); + cio_write(cio, J2K_MS_TLM, 2);/* TLM */ + lenp = 4 + (5*j2k->totnum_tp); + cio_write(cio,lenp,2); /* Ltlm */ + cio_write(cio, 0,1); /* Ztlm=0*/ + cio_write(cio,80,1); /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */ + cio_skip(cio,5*j2k->totnum_tp); +} + static void j2k_write_sot(opj_j2k_t *j2k) { int lenp, len; @@ -1078,8 +1170,8 @@ static void j2k_write_sot(opj_j2k_t *j2k) { cio_skip(cio, 2); /* Lsot (further) */ cio_write(cio, j2k->curtileno, 2); /* Isot */ cio_skip(cio, 4); /* Psot (further in j2k_write_sod) */ - cio_write(cio, 0, 1); /* TPsot */ - cio_write(cio, 1, 1); /* TNsot */ + cio_write(cio, j2k->cur_tp_num , 1); /* TPsot */ + cio_write(cio, j2k->cur_totnum_tp, 1); /* TNsot */ len = cio_tell(cio) - lenp; cio_seek(cio, lenp); cio_write(cio, len, 2); /* Lsot */ @@ -1197,6 +1289,9 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ opj_cp_t *cp = j2k->cp; opj_cio_t *cio = j2k->cio; + + tcd->cur_tp_num = j2k->cur_tp_num; + tcd->cur_totnum_tp = j2k->cur_totnum_tp; cio_write(cio, J2K_MS_SOD, 2); if (j2k->curtileno == 0) { @@ -1225,6 +1320,13 @@ static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { cio_seek(cio, j2k->sot_start + 6); cio_write(cio, totlen, 4); cio_seek(cio, j2k->sot_start + totlen); + /* Writing Ttlm and Ptlm in TLM marker */ + if(cp->cinema){ + cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num)); + cio_write(cio, j2k->curtileno, 1); + cio_write(cio, totlen, 4); + } + cio_seek(cio, j2k->sot_start + totlen); } static void j2k_read_sod(opj_j2k_t *j2k) { @@ -1827,6 +1929,11 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ cp->tdy = image->y1 - cp->ty0; } + if(parameters->tp_on){ + cp->tp_flag = parameters->tp_flag; + cp->tp_on = 1; + } + cp->img_size = 0; for(i=0;inumcomps ;i++){ cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec); @@ -2289,6 +2396,14 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index) /* <cinema){ + for (compno = 1; compno < image->numcomps; compno++) { + j2k_write_coc(j2k, compno); + j2k_write_qcc(j2k, compno); + } + } + for (compno = 0; compno < image->numcomps; compno++) { opj_tcp_t *tcp = &cp->tcps[0]; if (tcp->tccps[compno].roishift) @@ -2303,12 +2418,23 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index) } /* << INDEX */ + /* TLM Marker*/ + if(cp->cinema){ + j2k->totnum_tp = j2k_generate_tlm(cp,image->numcomps,image); + j2k_write_tlm(j2k); + } + /**** Main Header ENDS here ***/ + /* create the tile encoder */ tcd = tcd_create(j2k->cinfo); /* encode each tile */ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + int pino; + int tilepartno=0; + + opj_tcp_t *tcp = &cp->tcps[tileno]; opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); j2k->curtileno = tileno; @@ -2327,18 +2453,36 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index) } /* << INDEX */ - j2k_write_sot(j2k); - - for (compno = 1; compno < image->numcomps; compno++) { - j2k_write_coc(j2k, compno); - j2k_write_qcc(j2k, compno); - } - if (cp->tcps[tileno].numpocs) { - j2k_write_poc(j2k); - } + for(pino = 0; pino <= tcp->numpocs; pino++) { + int tot_num_tp; + opj_pi_iterator_t *pi = NULL; + tcd->cur_pino=pino; + tcd->pi = pi_initialise_encode(image, cp, tileno,pino); + pi=tcd->pi; + + /*Get number of tile parts*/ + tot_num_tp = j2k_get_num_tp(cp,pino,tileno); + tcd->tp_pos = cp->tp_pos; - j2k_write_sod(j2k, tcd); - + for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){ + j2k->cur_tp_num = tilepartno; + j2k->cur_totnum_tp = tot_num_tp; + j2k_write_sot(j2k); + + if(j2k->cur_tp_num == 0 && cp->cinema == 0){ + for (compno = 1; compno < image->numcomps; compno++) { + j2k_write_coc(j2k, compno); + j2k_write_qcc(j2k, compno); + } + if (cp->tcps[tileno].numpocs) { + j2k_write_poc(j2k); + } + } + + j2k_write_sod(j2k, tcd); + } + pi_destroy(pi, cp, tileno); + } /* INDEX >> */ if(image_info && image_info->index_on) { image_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h index 5f8e0824..639fbcef 100644 --- a/libopenjpeg/j2k.h +++ b/libopenjpeg/j2k.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -193,6 +194,12 @@ typedef struct opj_cp { int img_size; /** Rsiz*/ OPJ_RSIZ_CAPABILITIES rsiz; + /** Enabling Tile part generation*/ + char tp_on; + /** Flag determining tile part generation*/ + char tp_flag; + /** Position of tile part flag in progression order*/ + int tp_pos; /** allocation by rate/distortion */ int disto_alloc; /** allocation by fixed layer */ @@ -384,6 +391,18 @@ typedef struct opj_j2k { int state; /** number of the tile curently concern by coding/decoding */ int curtileno; + /** Tilepart number currently coding*/ + int cur_tp_num; + /** Total number of tileparts of the current tile*/ + int cur_totnum_tp; + /** + locate the start position of the TLM marker + after encoding the tilepart, a jump (in j2k_write_sod) is done to the TLM marker to store the value of its length. + */ + int tlm_start; + /** Total num of tile parts in whole image = num tiles* num tileparts in each tile*/ + /** used in TLMmarker*/ + int totnum_tp; /** locate the position of the end of the tile in the codestream, used to detect a truncated codestream (in j2k_read_sod) @@ -474,6 +493,14 @@ Coding parameters are returned in j2k->cp. */ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image); /** +Converts an enum type progression order to string type +*/ +char *convert_progression_order(OPJ_PROG_ORDER prg_order); +/** +Generates the number of tile parts for the current tile +*/ +int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno); +/** Encode an image into a JPEG-2000 codestream @param j2k J2K compressor handle @param cio Output buffer stream diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c index 3db8a5f7..b9e90d23 100644 --- a/libopenjpeg/openjpeg.c +++ b/libopenjpeg/openjpeg.c @@ -231,7 +231,7 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete parameters->roi_compno = -1; /* no ROI */ parameters->subsampling_dx = 1; parameters->subsampling_dy = 1; - + parameters->tp_on = 0; parameters->decod_format = -1; parameters->cod_format = -1; /* UniPG>> */ diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index d5543b92..12349532 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -211,6 +212,12 @@ typedef struct opj_poc { OPJ_PROG_ORDER prg; int tile; char progorder[4]; + int txS,txE,tyS,tyE,dx,dy; + int tx0,tx1,ty0,ty1; + int layno0, precno0, precno1; + int layS, resS, compS, prcS; + int layE, resE, compE, prcE; + int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t; } opj_poc_t; /** @@ -219,10 +226,12 @@ Compression parameters typedef struct opj_cparameters { /** Digital Cinema compliance 0-not compliant, 1-compliant*/ OPJ_CINEMA_MODE cp_cinema; - /** Progression order*/ - char cp_prog[4]; /** Profile name*/ OPJ_RSIZ_CAPABILITIES cp_rsiz; + /** Tile part generation*/ + char tp_on; + /** Flag for Tile part generation*/ + char tp_flag; /** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ bool tile_size_on; /** XTOsiz */ diff --git a/libopenjpeg/opj_includes.h b/libopenjpeg/opj_includes.h index 4d48f2c8..72152a5e 100644 --- a/libopenjpeg/opj_includes.h +++ b/libopenjpeg/opj_includes.h @@ -84,10 +84,10 @@ Most compilers implement their own version of this keyword ... #include "raw.h" #include "bio.h" #include "tgt.h" +#include "pi.h" #include "tcd.h" #include "t1.h" #include "dwt.h" -#include "pi.h" #include "t2.h" #include "mct.h" #include "int.h" diff --git a/libopenjpeg/pi.c b/libopenjpeg/pi.c index 61352001..9cd92d89 100644 --- a/libopenjpeg/pi.c +++ b/libopenjpeg/pi.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -100,7 +101,10 @@ static bool pi_next_lrcp(opj_pi_iterator_t * pi) { continue; } res = &comp->resolutions[pi->resno]; - for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) { + if (!pi->tp_on){ + pi->poc.precno1 = res->pw * res->ph; + } + for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; @@ -136,7 +140,10 @@ static bool pi_next_rlcp(opj_pi_iterator_t * pi) { continue; } res = &comp->resolutions[pi->resno]; - for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) { + if(!pi->tp_on){ + pi->poc.precno1 = res->pw * res->ph; + } + for (pi->precno = pi->poc.precno0; pi->precno < pi->poc.precno1; pi->precno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { pi->include[index] = 1; @@ -175,10 +182,15 @@ static bool pi_next_rpcl(opj_pi_iterator_t * pi) { } } } - +if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { int levelno; int trx0, try0; @@ -254,9 +266,14 @@ static bool pi_next_pcrl(opj_pi_iterator_t * pi) { } } } - - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { comp = &pi->comps[pi->compno]; for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { @@ -330,8 +347,14 @@ static bool pi_next_cprl(opj_pi_iterator_t * pi) { pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); } - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + if (!pi->tp_on){ + pi->poc.ty0 = pi->ty0; + pi->poc.tx0 = pi->tx0; + pi->poc.ty1 = pi->ty1; + pi->poc.tx1 = pi->tx1; + } + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { int levelno; int trx0, try0; @@ -384,7 +407,7 @@ LABEL_SKIP:; ========================================================== */ -opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) { +opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno) { int p, q; int compno, resno, pino; opj_pi_iterator_t *pi = NULL; @@ -513,11 +536,163 @@ opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) { pi[pino].poc.compno1 = tcp->pocs[pino].compno1; pi[pino].poc.prg = tcp->pocs[pino].prg; } + pi[pino].poc.layno0 = 0; + pi[pino].poc.precno0 = 0; + pi[pino].poc.precno1 = maxprec; + } return pi; } + +opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, int pino){ + int p, q; + int compno, resno; + int maxres = 0; + int maxprec = 0; + opj_pi_iterator_t *pi = NULL; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tccp = NULL; + size_t array_size; + + tcp = &cp->tcps[tileno]; + + array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); + pi = (opj_pi_iterator_t *) opj_malloc(array_size); + pi->tp_on = cp->tp_on; + if(!pi) { return NULL;} + + p = tileno % cp->tw; + q = tileno / cp->tw; + + pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0); + pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0); + pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1); + pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1); + pi[pino].numcomps = image->numcomps; + + array_size = image->numcomps * sizeof(opj_pi_comp_t); + pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); + if(!pi[pino].comps) { + pi_destroy(pi, cp, tileno); + return NULL; + } + memset(pi[pino].comps, 0, array_size); + + for (compno = 0; compno < pi->numcomps; compno++) { + int tcx0, tcy0, tcx1, tcy1; + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + tccp = &tcp->tccps[compno]; + comp->dx = image->comps[compno].dx; + comp->dy = image->comps[compno].dy; + comp->numresolutions = tccp->numresolutions; + + array_size = comp->numresolutions * sizeof(opj_pi_resolution_t); + comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); + if(!comp->resolutions) { + pi_destroy(pi, cp, tileno); + return NULL; + } + + tcx0 = int_ceildiv(pi->tx0, comp->dx); + tcy0 = int_ceildiv(pi->ty0, comp->dy); + tcx1 = int_ceildiv(pi->tx1, comp->dx); + tcy1 = int_ceildiv(pi->ty1, comp->dy); + if (comp->numresolutions > maxres) { + maxres = comp->numresolutions; + } + + for (resno = 0; resno < comp->numresolutions; resno++) { + int levelno; + int rx0, ry0, rx1, ry1; + int px0, py0, px1, py1; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + if (tccp->csty & J2K_CCP_CSTY_PRT) { + res->pdx = tccp->prcw[resno]; + res->pdy = tccp->prch[resno]; + } else { + res->pdx = 15; + res->pdy = 15; + } + levelno = comp->numresolutions - 1 - resno; + rx0 = int_ceildivpow2(tcx0, levelno); + ry0 = int_ceildivpow2(tcy0, levelno); + rx1 = int_ceildivpow2(tcx1, levelno); + ry1 = int_ceildivpow2(tcy1, levelno); + px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; + py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; + px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; + py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; + res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx); + res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy); + + if (res->pw*res->ph > maxprec) { + maxprec = res->pw * res->ph; + } + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = maxprec * pi[pino].step_p; + pi[pino].step_r = image->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + for (compno = 0; compno < pi->numcomps; compno++) { + opj_pi_comp_t *comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolutions; resno++) { + int dx, dy; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + pi[pino].dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi[pino].dy = !pi->dy ? dy : int_min(pi->dy, dy); + } + } + + if (pino == 0) { + array_size = image->numcomps * maxres * tcp->numlayers * 100 * sizeof(short int); + pi[pino].include = (short int *) opj_malloc(array_size); + if(!pi[pino].include) { + pi_destroy(pi, cp, tileno); + return NULL; + } + } + else { + pi[pino].include = pi[pino - 1].include; + } + + /* Generation of boundaries for each prog flag*/ + if (tcp->POC == 1){ + tcp->pocs[pino].compS= tcp->pocs[pino].compno0; + tcp->pocs[pino].compE= tcp->pocs[pino].compno1; + tcp->pocs[pino].resS = tcp->pocs[pino].resno0; + tcp->pocs[pino].resE = tcp->pocs[pino].resno1; + tcp->pocs[pino].layE = tcp->pocs[pino].layno1; + tcp->pocs[pino].prg = tcp->pocs[pino].prg; + }else { + tcp->pocs[pino].compS= 0; + tcp->pocs[pino].compE= image->numcomps; + tcp->pocs[pino].resS = 0; + tcp->pocs[pino].resE = maxres; + tcp->pocs[pino].layE = tcp->numlayers; + tcp->pocs[pino].prg = tcp->prg; + } + tcp->pocs[pino].layS = 0; + tcp->pocs[pino].prcS = 0; + tcp->pocs[pino].prcE = maxprec;; + tcp->pocs[pino].txS = pi[pino].tx0; + tcp->pocs[pino].txE = pi[pino].tx1; + tcp->pocs[pino].tyS = pi[pino].ty0; + tcp->pocs[pino].tyE = pi[pino].ty1; + tcp->pocs[pino].dx = pi[pino].dx; + tcp->pocs[pino].dy = pi[pino].dy; + return pi; + } + + + void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { int compno, pino; opj_tcp_t *tcp = &cp->tcps[tileno]; @@ -559,3 +734,312 @@ bool pi_next(opj_pi_iterator_t * pi) { return false; } +int pi_check_next_level(int pos,opj_cp_t *cp,int tileno, int pino, char *prog){ + int i,l; + opj_tcp_t *tcps =&cp->tcps[tileno]; + opj_poc_t *tcp = &tcps->pocs[pino]; + if(pos>=0){ + for(i=pos;pos>=0;i--){ + switch(prog[i]){ + case 'R': + if(tcp->res_t==tcp->resE){ + l=pi_check_next_level(pos-1,cp,tileno,pino,prog); + if(l==1){ + return 1; + }else{ + return 0; + } + }else{ + return 1; + } + break; + case 'C': + if(tcp->comp_t==tcp->compE){ + l=pi_check_next_level(pos-1,cp,tileno,pino,prog); + if(l==1){ + return 1; + }else{ + return 0; + } + }else{ + return 1; + } + break; + case 'L': + if(tcp->lay_t==tcp->layE){ + l=pi_check_next_level(pos-1,cp,tileno,pino,prog); + if(l==1){ + return 1; + }else{ + return 0; + } + }else{ + return 1; + } + break; + case 'P': + switch(tcp->prg){ + case LRCP||RLCP: + if(tcp->prc_t == tcp->prcE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + return 1; + }else{ + return 0; + } + }else{ + return 1; + } + break; + default: + if(tcp->tx0_t == tcp->txE){ + //TY + if(tcp->ty0_t == tcp->tyE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + return 1; + }else{ + return 0; + } + }else{ + return 1; + }//TY + }else{ + return 1; + } + break; + }//end case P + }//end switch + }//end for + }//end if + return 0; +} + + +void pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos,char final_encoding) { + char *prog; + int i,l; + int incr_top=1,resetX=0; + opj_tcp_t *tcps =&cp->tcps[tileno]; + opj_poc_t *tcp= &tcps->pocs[pino]; + prog = convert_progression_order(tcp->prg); + + pi[pino].first = 1; + pi[pino].poc.prg = tcp->prg; + + if(!(cp->tp_on & final_encoding)){ + pi[pino].poc.resno0 = tcp->resS; + pi[pino].poc.resno1 = tcp->resE; + pi[pino].poc.compno0 = tcp->compS; + pi[pino].poc.compno1 = tcp->compE; + pi[pino].poc.layno0 = tcp->layS; + pi[pino].poc.layno1 = tcp->layE; + pi[pino].poc.precno0 = tcp->prcS; + pi[pino].poc.precno1 = tcp->prcE; + pi[pino].poc.tx0 = tcp->txS; + pi[pino].poc.ty0 = tcp->tyS; + pi[pino].poc.tx1 = tcp->txE; + pi[pino].poc.ty1 = tcp->tyE; + }else { + for(i=tppos+1;i<4;i++){ + switch(prog[i]){ + case 'R': + pi[pino].poc.resno0 = tcp->resS; + pi[pino].poc.resno1 = tcp->resE; + break; + case 'C': + pi[pino].poc.compno0 = tcp->compS; + pi[pino].poc.compno1 = tcp->compE; + break; + case 'L': + pi[pino].poc.layno0 = tcp->layS; + pi[pino].poc.layno1 = tcp->layE; + break; + case 'P': + switch(tcp->prg){ + case LRCP: + case RLCP: + pi[pino].poc.precno0 = tcp->prcS; + pi[pino].poc.precno1 = tcp->prcE; + break; + default: + pi[pino].poc.tx0 = tcp->txS; + pi[pino].poc.ty0 = tcp->tyS; + pi[pino].poc.tx1 = tcp->txE; + pi[pino].poc.ty1 = tcp->tyE; + break; + } + break; + } + } + + if(tpnum==0){ + for(i=tppos;i>=0;i--){ + switch(prog[i]){ + case 'C': + tcp->comp_t = tcp->compS; + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + break; + case 'R': + tcp->res_t = tcp->resS; + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + break; + case 'L': + tcp->lay_t = tcp->layS; + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + break; + case 'P': + switch(tcp->prg){ + case LRCP: + case RLCP: + tcp->prc_t = tcp->prcS; + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + break; + default: + tcp->tx0_t = tcp->txS; + tcp->ty0_t = tcp->tyS; + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx); + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->tx0_t = pi[pino].poc.tx1; + tcp->ty0_t = pi[pino].poc.ty1; + break; + } + break; + } + } + incr_top=1; + }else{ + for(i=tppos;i>=0;i--){ + if(incr_top==1){ + switch(prog[i]){ + case 'R': + if(tcp->res_t==tcp->resE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + tcp->res_t = tcp->resS; + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + incr_top=1; + }else{ + incr_top=0; + } + }else{ + pi[pino].poc.resno0 = tcp->res_t; + pi[pino].poc.resno1 = tcp->res_t+1; + tcp->res_t+=1; + incr_top=0; + } + break; + case 'C': + if(tcp->comp_t ==tcp->compE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + tcp->comp_t = tcp->compS; + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + incr_top=1; + }else{ + incr_top=0; + } + }else{ + pi[pino].poc.compno0 = tcp->comp_t; + pi[pino].poc.compno1 = tcp->comp_t+1; + tcp->comp_t+=1; + incr_top=0; + } + break; + case 'L': + if(tcp->lay_t == tcp->layE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + tcp->lay_t = tcp->layS; + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + incr_top=1; + }else{ + incr_top=0; + } + }else{ + pi[pino].poc.layno0 = tcp->lay_t; + pi[pino].poc.layno1 = tcp->lay_t+1; + tcp->lay_t+=1; + incr_top=0; + } + break; + case 'P': + switch(tcp->prg){ + case LRCP: + case RLCP: + if(tcp->prc_t == tcp->prcE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + tcp->prc_t = tcp->prcS; + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + incr_top=1; + }else{ + incr_top=0; + } + }else{ + pi[pino].poc.precno0 = tcp->prc_t; + pi[pino].poc.precno1 = tcp->prc_t+1; + tcp->prc_t+=1; + incr_top=0; + } + break; + default: + if(tcp->tx0_t >= tcp->txE){ + if(tcp->ty0_t >= tcp->tyE){ + l=pi_check_next_level(i-1,cp,tileno,pino,prog); + if(l==1){ + tcp->ty0_t = tcp->tyS; + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->ty0_t = pi[pino].poc.ty1; + incr_top=1;resetX=1; + }else{ + incr_top=0;resetX=0; + } + }else{ + pi[pino].poc.ty0 = tcp->ty0_t; + pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); + tcp->ty0_t = pi[pino].poc.ty1; + incr_top=0;resetX=1; + } + if(resetX==1){ + tcp->tx0_t = tcp->txS; + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); + tcp->tx0_t = pi[pino].poc.tx1; + } + }else{ + pi[pino].poc.tx0 = tcp->tx0_t; + pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); + tcp->tx0_t = pi[pino].poc.tx1; + incr_top=0; + } + break; + } + break; + } + } + } + } + } +} + + diff --git a/libopenjpeg/pi.h b/libopenjpeg/pi.h index 6ed2b94b..9d6ece4b 100644 --- a/libopenjpeg/pi.h +++ b/libopenjpeg/pi.h @@ -65,6 +65,8 @@ typedef struct opj_pi_comp { Packet iterator */ typedef struct opj_pi_iterator { + /** Enabling Tile part generation*/ + char tp_on; /** precise if the packet has been already used (usefull for progression order change) */ short int *include; /** layer step used to localize the packet in the include vector */ @@ -99,14 +101,33 @@ typedef struct opj_pi_iterator { /*@{*/ /* ----------------------------------------------------------------------- */ /** -Create a packet iterator +Create a packet iterator for Encoder @param image Raw image for which the packets will be listed @param cp Coding parameters @param tileno Number that identifies the tile for which to list the packets @return Returns a packet iterator that points to the first packet of the tile @see pi_destroy */ -opj_pi_iterator_t *pi_create(opj_image_t * image, opj_cp_t * cp, int tileno); +opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, int pino); +/** +Modify the packet iterator for enabling tile part generation +@param pi Handle to the packet iterator generated in pi_initialise_encode +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@param tpnum Tile part number of the current tile +@param tppos The position of the tile part flag in the progression order +@param final_encoding If 0 Create a new packet iterator which is destroyed at end of call,If 1 use the packet iterator previously generated. +*/ +void pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos,char final_encoding); +/** +Create a packet iterator for Decoder +@param image Raw image for which the packets will be listed +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@return Returns a packet iterator that points to the first packet of the tile +@see pi_destroy +*/ +opj_pi_iterator_t *pi_create_decode(opj_image_t * image, opj_cp_t * cp, int tileno); /** Destroy a packet iterator diff --git a/libopenjpeg/t2.c b/libopenjpeg/t2.c index b0862aad..3e6f0e7b 100644 --- a/libopenjpeg/t2.c +++ b/libopenjpeg/t2.c @@ -562,59 +562,59 @@ static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_t /* ----------------------------------------------------------------------- */ -int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info) { +int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info,opj_pi_iterator_t *tcd_pi,int tpnum, int tppos,int pino, char final_encoding){ unsigned char *c = dest; int e = 0; opj_pi_iterator_t *pi = NULL; - int pino; opj_image_t *image = t2->image; opj_cp_t *cp = t2->cp; - - /* create a packet iterator */ - pi = pi_create(image, cp, tileno); + + if(final_encoding == 0){ + pi = pi_initialise_encode(image, cp, tileno,pino); + }else{ + pi = tcd_pi; + } if(!pi) { /* TODO: throw an error */ return -999; } + pi_create_encode(pi, cp,tileno,pino,tpnum,tppos,final_encoding); + if(image_info) { image_info->num = 0; } - - for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { - while (pi_next(&pi[pino])) { - if (pi[pino].layno < maxlayers) { - e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, image_info, tileno); - if (e == -999) { - break; - } else { - c += e; - } - - /* INDEX >> */ - if(image_info && image_info->index_on) { - if(image_info->index_write) { - opj_tile_info_t *info_TL = &image_info->tile[tileno]; - opj_packet_info_t *info_PK = &info_TL->packet[image_info->num]; - if (!image_info->num) { - info_PK->start_pos = info_TL->end_header + 1; - } else { - info_PK->start_pos = info_TL->packet[image_info->num - 1].end_pos + 1; - } - info_PK->end_pos = info_PK->start_pos + e - 1; - } - image_info->num++; - } - /* << INDEX */ + while (pi_next(&pi[pino])) { + if (pi[pino].layno < maxlayers) { + e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, image_info, tileno); + if (e == -999) { + break; + } else { + c += e; } + /* INDEX >> */ + if(image_info && image_info->index_on) { + if(image_info->index_write) { + opj_tile_info_t *info_TL = &image_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[image_info->num]; + if (!image_info->num) { + info_PK->start_pos = info_TL->end_header + 1; + } else { + info_PK->start_pos = info_TL->packet[image_info->num - 1].end_pos + 1; + } + info_PK->end_pos = info_PK->start_pos + e - 1; + } + + image_info->num++; + } + /* << INDEX */ } } - - /* don't forget to release pi */ - pi_destroy(pi, cp, tileno); - + if(final_encoding == 0){ + pi_destroy(pi, cp, tileno); + } if (e == -999) { return e; } @@ -632,7 +632,7 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj opj_cp_t *cp = t2->cp; /* create a packet iterator */ - pi = pi_create(image, cp, tileno); + pi = pi_create_decode(image, cp, tileno); if(!pi) { /* TODO: throw an error */ return -999; diff --git a/libopenjpeg/t2.h b/libopenjpeg/t2.h index 62b1a102..dfe0dda1 100644 --- a/libopenjpeg/t2.h +++ b/libopenjpeg/t2.h @@ -66,8 +66,7 @@ Encode the packets of a tile to a destination buffer @param len the length of the destination buffer @param image_info structure to create an index file */ -int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info); - +int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_image_info_t *image_info,opj_pi_iterator_t *tcd_pi,int tpnum, int tppos,int pino,char final_encoding); /** Decode the packets of a tile from a source buffer @param t2 T2 handle diff --git a/libopenjpeg/tcd.c b/libopenjpeg/tcd.c index 89658ce7..cfd31d52 100644 --- a/libopenjpeg/tcd.c +++ b/libopenjpeg/tcd.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006-2007, Parvatha Elangovan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1041,7 +1042,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in if (cp->fixed_quality) { /* fixed_quality */ if(cp->cinema){ - l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info); + l = t2_encode_packets(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info,tcd->pi,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,0); if (l == -999) { lo = thresh; continue; @@ -1064,7 +1065,7 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in lo = thresh; } } else { - l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info); + l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info,tcd->pi,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,0); /* TODO: what to do with l ??? seek / tell ??? */ /* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */ if (l == -999) { @@ -1122,6 +1123,8 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op tcd_tcp = tcd->tcp; cp = tcd->cp; + encoding_time = opj_clock(); /* time needed to encode a tile */ + if(tcd->cur_tp_num == 0){ /* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */ if(image_info && image_info->index_on) { opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ @@ -1141,8 +1144,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op /* << INDEX */ /*---------------TILE-------------------*/ - encoding_time = opj_clock(); /* time needed to encode a tile */ - + for (compno = 0; compno < tile->numcomps; compno++) { int x, y; @@ -1218,7 +1220,7 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op /* Fixed layer allocation */ tcd_rateallocate_fixed(tcd); } - + } /*--------------TIER2------------------*/ /* INDEX */ @@ -1227,18 +1229,24 @@ int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, op } t2 = t2_create(tcd->cinfo, image, cp); - l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, image_info); + l = t2_encode_packets(t2,tileno, tile, tcd_tcp->numlayers, dest, len, image_info,tcd->pi,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,1); t2_destroy(t2); /*---------------CLEAN-------------------*/ encoding_time = opj_clock() - encoding_time; - opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time); - - /* cleaning memory */ - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - opj_free(tilec->data); + if(tcd->cur_totnum_tp > 1){ + opj_event_msg(tcd->cinfo, EVT_INFO, "- Tile part num %d encoded in %f s\n", tcd->cur_tp_num,encoding_time); + }else{ + opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time); + } + + if(tcd->cur_tp_num == tcd->cur_totnum_tp - 1){ + /* cleaning memory */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_free(tilec->data); + } } return l; diff --git a/libopenjpeg/tcd.h b/libopenjpeg/tcd.h index ce909fda..9a3503f4 100644 --- a/libopenjpeg/tcd.h +++ b/libopenjpeg/tcd.h @@ -158,6 +158,14 @@ typedef struct opj_tcd_image { Tile coder/decoder */ typedef struct opj_tcd { + /** Position of the tilepart flag in Progression order*/ + int tp_pos; + /** Current tile part number*/ + int cur_tp_num; + /** Total number of tileparts of the current tile*/ + int cur_totnum_tp; + /** Current Packet iterator number */ + int cur_pino; /** codec context */ opj_common_ptr cinfo; @@ -173,6 +181,8 @@ typedef struct opj_tcd { opj_tcp_t *tcp; /** current encoded/decoded tile */ int tcd_tileno; + /** Packet iterator*/ + opj_pi_iterator_t *pi; } opj_tcd_t; /** @name Exported functions */