]> granicus.if.org Git - openjpeg/commitdiff
Added option for Digital cinema profile compliant codestream. This can be chosen...
authorParvatha Elangovan <p.elangovan@intopix.com>
Wed, 7 Mar 2007 16:04:33 +0000 (16:04 +0000)
committerParvatha Elangovan <p.elangovan@intopix.com>
Wed, 7 Mar 2007 16:04:33 +0000 (16:04 +0000)
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

ChangeLog
codec/image_to_j2k.c
libopenjpeg/cio.c
libopenjpeg/j2k.c
libopenjpeg/j2k.h
libopenjpeg/openjpeg.c
libopenjpeg/openjpeg.h
libopenjpeg/tcd.c

index 5ec873e26dd3b54de95f7e27f3994cf1fa0b9835..3c55378f72a58387b24f57e44b9627a53c5848e1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 28208c5cd93ba8e1423ba810836393af99276248..014ae1d9e85e6147dcc28eb90cd589735f16ac9f 100644 (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 'z':                       /* Image Directory path */
+                       {
+                               img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
+                               strcpy(img_fol->imgdirpath,optarg);
+                               img_fol->set_imgdir=1;
+                       }
+                       break;
 
-                       case 'y':                       /* Image Directory path */
-                               {
-                                       img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
-                                       strcpy(img_fol->imgdirpath,optarg);
-                                       img_fol->set_imgdir=1;
+                               /* ------------------------------------------------------ */
+                       
+                       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;
                                }
-                               break;
-
-
+                               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);
 
index eadf71b2119851adb4815f1c0ffb7518287b2c29..6082e9be9f038736fc9755be97e769dcf9240781 100644 (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);
index db291ff23db08a1e0e8f8c87b2aec22fdc0e0017..fb9aeaff6403a9042ee7769344cd4646fbbde10e 100644 (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;
+
+                       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{
+                               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 {
-                                                       tccp->prch[j] = int_floorlog2(size_prch);
+                                                       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;
                                        }
-                                       p++;
-                                       /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */
-                               }
-                       } else {
-                               for (j = 0; j < tccp->numresolutions; j++) {
-                                       tccp->prcw[j] = 15;
-                                       tccp->prch[j] = 15;
                                }
                        }
 
index 9738bf850d9938c98fa322f87da799c79aabc9c7..5f8e08248809018a385ef97caacf12d4ebc5441e 100644 (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 */
index b522939e0d866a51755b5c200dce1096f05b3147..3db8a5f755f017d51f5fa20de007d0e429350f1f 100644 (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;
index ceb5df2cd43fed142eb03e6cd9069c100da5b49a..d5543b926d2d9a9ee30db923ecfe74c718cf680a 100644 (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 */
index 73c3ef5e99c5e82e2f32cb30798c966ff97b44ce..89658ce70b99650a4143d0428c94913a2ec852c0 100644 (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 ??? */