Added option for Digital cinema profile compliant codestream. This can be chosen by "-cinema2K" or "-cinema4K" for a 2K and 4K compliance respectively. The feature for tileparts has not been implemented in this version. Modification in image_to_j2k.c

Added the Digital Cinema profiles (CINEMA2K and CINEMA4K) to the list of profiles recognized in the codestream SIZ marker segment. Modification in openjpeg.h,j2k.c
Added feature for constant quality within bitrate defined in Digital cinema standards. Modification in tcd.c
Modified the method of generation of buffer length. Modification in cio.c
This commit is contained in:
Parvatha Elangovan 2007-03-07 16:04:33 +00:00
parent 9e5d0b1a40
commit 78003a016a
8 changed files with 249 additions and 56 deletions

View File

@ -5,6 +5,13 @@ What's New for OpenJPEG
! : changed
+ : added
March 7, 2007
+ [Parvatha] Added option for Digital cinema profile compliant codestream. This can be chosen by "-cinema2K" or "-cinema4K" for a 2K and 4K compliance respectively. The feature for tileparts has not been implemented in this version. Modification in image_to_j2k.c
+ [Parvatha] Added the Digital Cinema profiles (CINEMA2K and CINEMA4K) to the list of profiles recognized in the codestream SIZ marker segment. Modification in openjpeg.h,j2k.c
+ [Parvatha] Added feature for constant quality within bitrate defined in Digital cinema standards. Modification in tcd.c
! [Parvatha] Modified the method of generation of buffer length. Modification in cio.c
March 1, 2007
* [FOD] Modified codec projects (*.dsp) and makefile to include the tiff library (modified codec/image_to_j2k.dsp codec/j2k_to_image.dsp and codec/makefile)
+ [GB] Zoom capability and decoder settings dialog in OPJViewer; modified JPWL library .dsp project in order to create a library with embedded JPWL functions

View File

@ -55,6 +55,8 @@
#define TIF_DFMT 14
/* ----------------------------------------------------------------------- */
#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
typedef struct dircnt{
/** Buffer for holding images read from Directory*/
@ -125,8 +127,10 @@ void encode_help_display() {
fprintf(stdout,"------------\n");
fprintf(stdout,"\n");
fprintf(stdout,"Required Parameters (except with -h):\n");
fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");
fprintf(stdout,"\n");
fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");
fprintf(stdout," When using this option -OutFor must be used\n");
fprintf(stdout,"\n");
fprintf(stdout,"-OutFor \n");
fprintf(stdout," REQUIRED only if -ImgDir is used\n");
@ -134,6 +138,7 @@ void encode_help_display() {
fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP format\n");
fprintf(stdout,"\n");
fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm) \n");
fprintf(stdout," When using this option -o must be used\n");
fprintf(stdout,"\n");
fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");
fprintf(stdout,"\n");
@ -141,6 +146,12 @@ void encode_help_display() {
fprintf(stdout,"\n");
fprintf(stdout,"-h : display the help information \n ");
fprintf(stdout,"\n");
fprintf(stdout,"-cinema2k : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
fprintf(stdout,"\n");
fprintf(stdout,"-cinema4k : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
fprintf(stdout," Frames per second not required. Default value is 24fps\n");
fprintf(stdout,"\n");
fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
fprintf(stdout," - The rate specified for each quality level is the desired \n");
fprintf(stdout," compression factor.\n");
@ -403,16 +414,92 @@ 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;
parameters->tile_size_on = false;
parameters->cp_tdx=1;
parameters->cp_tdy=1;
/*Tile and Image shall be at (0,0)*/
parameters->cp_tx0=0; parameters->cp_ty0=0;
/*Codeblock size= 32*32*/
parameters->cblockw_init = 32;
parameters->cblockh_init = 32;
/*The progression order shall be CPRL*/
strncpy(parameters->cp_prog,"CPRL",4);
parameters->prog_order = give_progression(parameters->cp_prog);
/*Tile parts not implemented*/
/* No ROI */
parameters->roi_compno = -1;
parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
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;i<parameters->tcp_numlayers;i++){
temp_rate = 0 ;
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_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
}else{
temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
(parameters->tcp_rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
if (temp_rate > CINEMA_24_CS ){
parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
(CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
}
}
}
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;i<parameters->tcp_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);
}else{
parameters->tcp_rates[i]=((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
(parameters->tcp_rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
if (parameters->tcp_rates[i] > CINEMA_48_CS ){
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);
}
}
}
break;
}
parameters->cp_disto_alloc = 1;
}
/* ------------------------------------------------------------------------------------ */
int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,img_fol_t *img_fol) {
int i, j,totlen;
option_t long_option[]={
{"DCI",NO_ARG, NULL ,'z'},
{"ImgDir",REQ_ARG, NULL ,'y'},
{"fps",REQ_ARG, NULL ,'w'},
{"cinema2k",REQ_ARG, NULL ,'w'},
{"cinema4k",NO_ARG, NULL ,'y'},
{"ImgDir",REQ_ARG, NULL ,'z'},
{"TP",REQ_ARG, NULL ,'v'},
{"SOP",NO_ARG, NULL ,'S'},
{"EPH",NO_ARG, NULL ,'E'},
@ -803,17 +890,45 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,i
break;
/* ------------------------------------------------------ */
case 'y': /* Image Directory path */
{
img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
strcpy(img_fol->imgdirpath,optarg);
img_fol->set_imgdir=1;
}
break;
case 'z': /* Image Directory path */
{
img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
strcpy(img_fol->imgdirpath,optarg);
img_fol->set_imgdir=1;
}
break;
/* ------------------------------------------------------ */
case 'w': /* Digital Cinema 2K profile compliance*/
{
int fps=0;
sscanf(optarg,"%d",&fps);
if(fps == 24){
parameters->cp_cinema = CINEMA2K_24;
}else if(fps == 48 ){
parameters->cp_cinema = CINEMA2K_48;
}else {
fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
return 1;
}
fprintf(stdout,"CINEMA 2K compliant codestream\n");
}
break;
/* ------------------------------------------------------ */
case 'y': /* Digital Cinema 4K profile compliance*/
{
parameters->cp_cinema = CINEMA4K_24;
fprintf(stdout,"CINEMA 4K compliant codestream\n");
}
break;
/* ------------------------------------------------------ */
/* UniPG>> */
#ifdef USE_JPWL
/* ------------------------------------------------------ */
@ -1379,6 +1494,10 @@ 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(&parameters,image);
}
/* setup the encoder parameters using the current image and user parameters */
opj_setup_encoder(cinfo, &parameters, image);

View File

@ -58,7 +58,7 @@ opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer
opj_free(cio);
return NULL;
}
cio->length = cp->tdx * cp->tdy * cp->tw * cp->th * 4;
cio->length = (int) (1.3 * cp->img_size);
cio->buffer = (unsigned char *)opj_malloc(cio->length);
if(!cio->buffer) {
opj_free(cio);

View File

@ -324,7 +324,7 @@ static void j2k_write_siz(opj_j2k_t *j2k) {
cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */
lenp = cio_tell(cio);
cio_skip(cio, 2);
cio_write(cio, 0, 2); /* Rsiz (capabilities) */
cio_write(cio, cp->rsiz, 2); /* Rsiz (capabilities) */
cio_write(cio, image->x1, 4); /* Xsiz */
cio_write(cio, image->y1, 4); /* Ysiz */
cio_write(cio, image->x0, 4); /* X0siz */
@ -1780,7 +1780,8 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
/*
copy user encoding parameters
*/
cp->cinema = parameters->cp_cinema;
cp->rsiz = parameters->cp_rsiz;
cp->disto_alloc = parameters->cp_disto_alloc;
cp->fixed_alloc = parameters->cp_fixed_alloc;
cp->fixed_quality = parameters->cp_fixed_quality;
@ -1826,6 +1827,11 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
cp->tdy = image->y1 - cp->ty0;
}
cp->img_size = 0;
for(i=0;i<image->numcomps ;i++){
cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec);
}
/* UniPG>> */
#ifdef USE_JPWL
/*
@ -1940,42 +1946,60 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_
} else {
tccp->roishift = 0;
}
if (parameters->csty & J2K_CCP_CSTY_PRT) {
int p = 0;
for (j = tccp->numresolutions - 1; j >= 0; j--) {
if (p < parameters->res_spec) {
if (parameters->prcw_init[p] < 1) {
tccp->prcw[j] = 1;
} else {
tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]);
}
if (parameters->prch_init[p] < 1) {
tccp->prch[j] = 1;
} else {
tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
}
} else {
int res_spec = parameters->res_spec;
int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
if (size_prcw < 1) {
tccp->prcw[j] = 1;
} else {
tccp->prcw[j] = int_floorlog2(size_prcw);
}
if (size_prch < 1) {
tccp->prch[j] = 1;
} else {
tccp->prch[j] = int_floorlog2(size_prch);
}
}
p++;
/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
if(parameters->cp_cinema)
{
//Precinct size for lowest frequency subband=128
tccp->prcw[0] = 7;
tccp->prch[0] = 7;
//Precinct size at all other resolutions = 256
for (j = 1; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 8;
tccp->prch[j] = 8;
}
} else {
for (j = 0; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 15;
tccp->prch[j] = 15;
}else{
if (parameters->csty & J2K_CCP_CSTY_PRT) {
int p = 0;
for (j = tccp->numresolutions - 1; j >= 0; j--) {
if (p < parameters->res_spec) {
if (parameters->prcw_init[p] < 1) {
tccp->prcw[j] = 1;
} else {
tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]);
}
if (parameters->prch_init[p] < 1) {
tccp->prch[j] = 1;
}else {
tccp->prch[j] = int_floorlog2(parameters->prch_init[p]);
}
} else {
int res_spec = parameters->res_spec;
int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
if (size_prcw < 1) {
tccp->prcw[j] = 1;
} else {
tccp->prcw[j] = int_floorlog2(size_prcw);
}
if (size_prch < 1) {
tccp->prch[j] = 1;
} else {
tccp->prch[j] = int_floorlog2(size_prch);
}
}
p++;
/*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
} //end for
} else {
for (j = 0; j < tccp->numresolutions; j++) {
tccp->prcw[j] = 15;
tccp->prch[j] = 15;
}
}
}

View File

@ -187,6 +187,12 @@ typedef struct opj_tcp {
Coding parameters
*/
typedef struct opj_cp {
/** Digital cinema profile*/
OPJ_CINEMA_MODE cinema;
/** Size of the image in bits*/
int img_size;
/** Rsiz*/
OPJ_RSIZ_CAPABILITIES rsiz;
/** allocation by rate/distortion */
int disto_alloc;
/** allocation by fixed layer */

View File

@ -222,7 +222,9 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete
if(parameters) {
memset(parameters, 0, sizeof(opj_cparameters_t));
/* default coding parameters */
parameters->cp_cinema = OFF;
parameters->numresolution = 6;
parameters->cp_rsiz = STD_RSIZ;
parameters->cblockw_init = 64;
parameters->cblockh_init = 64;
parameters->prog_order = LRCP;

View File

@ -113,6 +113,19 @@ braindamage below.
==========================================================
*/
typedef enum RSIZ_CAPABILITIES {
STD_RSIZ = 0,
CINEMA2K = 3, /** Profile name for a 2K image*/
CINEMA4K = 4 /** Profile name for a 4K image*/
} OPJ_RSIZ_CAPABILITIES;
typedef enum CINEMA_MODE {
OFF = 0,
CINEMA2K_24 = 1,
CINEMA2K_48 = 2,
CINEMA4K_24 = 3
}OPJ_CINEMA_MODE;
/** Progression order */
typedef enum PROG_ORDER {
PROG_UNKNOWN = -1, /**< place-holder */
@ -204,6 +217,12 @@ typedef struct opj_poc {
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;
/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */
bool tile_size_on;
/** XTOsiz */

View File

@ -1040,13 +1040,29 @@ bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_image_in
tcd_makelayer(tcd, layno, thresh, 0);
if (cp->fixed_quality) { /* fixed_quality */
distoachieved = (layno == 0) ?
tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
if (distoachieved < distotarget) {
hi = thresh;
continue;
if(cp->cinema){
l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info);
if (l == -999) {
lo = thresh;
continue;
}else{
distoachieved = layno == 0 ?
tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
if (distoachieved < distotarget) {
hi=thresh; continue;
}else{
lo=thresh;
}
}
}else{
distoachieved = (layno == 0) ?
tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
if (distoachieved < distotarget) {
hi = thresh;
continue;
}
lo = thresh;
}
lo = thresh;
} else {
l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, image_info);
/* TODO: what to do with l ??? seek / tell ??? */