Update the README.cmake file : an instruction was missing to run the tests correctly.
[openjpeg.git] / mj2 / meta_out.c
index 12c97f35b2c92db50ec05242fa7c062d71bc820d..c77ec20a6485cefcf2683f4de4e8e084e933b2c8 100644 (file)
@@ -11,40 +11,29 @@ A non-exclusive copy of this code has been contributed to the Open JPEG project.
 Except for copyright, inclusion of the code within Open JPEG for distribution and use
 can be bound by the Open JPEG open-source license and disclaimer, expressed elsewhere.
 */
-#include <stdio.h>
-#include <malloc.h>
-#include <setjmp.h>
 
-#include "mj2.h"
-#include <openjpeg.h>
+#include <windows.h> /* for time functions */
 
-//MEMORY LEAK
-#ifdef _DEBUG
-#define _CRTDBG_MAP_ALLOC
-#include <stdlib.h>  // Must be included first
-#include <crtdbg.h>
-#endif
-//MEM
+#include "opj_includes.h"
+#include "mj2.h"
 
-#include <windows.h> /* for time functions */
 #include <time.h>
 #include "meta_out.h"
-#include <string.h>
 
-jmp_buf j2k_error;
-extern j2k_tcp_t j2k_default_tcp;
 static BOOL notes = TRUE;
 static BOOL sampletables = FALSE;
 static BOOL raw = TRUE;
 static BOOL derived = TRUE;
 
+opj_tcp_t *j2k_default_tcp;
+
 /* Forwards */
-int xml_write_overall_header(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int sampleframe);
-int xml_write_moov(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int sampleframe);
+int xml_write_overall_header(FILE *file, FILE *xmlout, opj_mj2_t * movie, unsigned int sampleframe, opj_event_mgr_t *event_mgr);
+int xml_write_moov(FILE *file, FILE *xmlout, opj_mj2_t * movie, unsigned int sampleframe, opj_event_mgr_t *event_mgr);
 
 void uint_to_chars(unsigned int value, char* buf);
 
-void xml_write_trak(FILE *file, FILE *xmlout, mj2_tk_t *track, unsigned int tnum, unsigned int sampleframe);
+void xml_write_trak(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum, unsigned int sampleframe, opj_event_mgr_t *event_mgr);
 void xml_write_tkhd(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum);
 void xml_write_udta(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum);
 void xml_write_mdia(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum);
@@ -56,43 +45,41 @@ void xml_time_out(FILE* xmlout, time_t t);
 
 void int16_to_3packedchars(short int value, char* buf);
 
-void xml_write_moov_udta(FILE* xmlout, mj2_movie_t * movie);
-void xml_write_free_and_skip(FILE* xmlout, mj2_movie_t * movie);
-void xml_write_uuid(FILE* xmlout, mj2_movie_t * movie);
-
-int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int snum);
-
-void xml_out_frame_siz(FILE* xmlout, j2k_image_t *img, j2k_cp_t *cp);
-void xml_out_frame_cod(FILE* xmlout, j2k_tcp_t *tcp);
-void xml_out_frame_coc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps); /* j2k_image_t *img); */
-BOOL same_component_style(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2);
-void xml_out_frame_qcd(FILE* xmlout, j2k_tcp_t *tcp);
-void xml_out_frame_qcc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps); /* j2k_image_t *img); */
-BOOL same_component_quantization(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2);
-void xml_out_frame_rgn(FILE* xmlout, j2k_tcp_t *tcp, int numcomps);/* j2k_image_t *img);*/
-void xml_out_frame_poc(FILE* xmlout, j2k_tcp_t *tcp);
-void xml_out_frame_ppm(FILE* xmlout, j2k_cp_t *cp);
-void xml_out_frame_ppt(FILE* xmlout, j2k_tcp_t *tcp);
+void xml_write_moov_udta(FILE* xmlout, opj_mj2_t * movie);
+void xml_write_free_and_skip(FILE* xmlout, opj_mj2_t * movie);
+void xml_write_uuid(FILE* xmlout, opj_mj2_t * movie);
+
+int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int snum, opj_event_mgr_t *event_mgr);
+
+void xml_out_frame_siz(FILE* xmlout, opj_image_t *img, opj_cp_t *cp);
+void xml_out_frame_cod(FILE* xmlout, opj_tcp_t *tcp);
+void xml_out_frame_coc(FILE* xmlout, opj_tcp_t *tcp, int numcomps); /* opj_image_t *img); */
+BOOL same_component_style(opj_tccp_t *tccp1, opj_tccp_t *tccp2);
+void xml_out_frame_qcd(FILE* xmlout, opj_tcp_t *tcp);
+void xml_out_frame_qcc(FILE* xmlout, opj_tcp_t *tcp, int numcomps); /* opj_image_t *img); */
+BOOL same_component_quantization(opj_tccp_t *tccp1, opj_tccp_t *tccp2);
+void xml_out_frame_rgn(FILE* xmlout, opj_tcp_t *tcp, int numcomps);/* opj_image_t *img);*/
+void xml_out_frame_poc(FILE* xmlout, opj_tcp_t *tcp);
+void xml_out_frame_ppm(FILE* xmlout, opj_cp_t *cp);
+void xml_out_frame_ppt(FILE* xmlout, opj_tcp_t *tcp);
 void xml_out_frame_tlm(FILE* xmlout); /* j2k_default_tcp is passed globally */ /* NO-OP.  TLM NOT SAVED IN DATA STRUCTURE */
 void xml_out_frame_plm(FILE* xmlout); /* j2k_default_tcp is passed globally */ /* NO-OP.  PLM NOT SAVED IN DATA STRUCTURE.  opt in main; can be used in conjunction with PLT */
-void xml_out_frame_plt(FILE* xmlout, j2k_tcp_t *tcp); /* NO-OP.  PLM NOT SAVED IN DATA STRUCTURE.  opt in main; can be used in conjunction with PLT */
+void xml_out_frame_plt(FILE* xmlout, opj_tcp_t *tcp); /* NO-OP.  PLM NOT SAVED IN DATA STRUCTURE.  opt in main; can be used in conjunction with PLT */
 void xml_out_frame_crg(FILE* xmlout); /* j2k_default_tcp is passed globally */ /* opt in main; */
-void xml_out_frame_com(FILE* xmlout, j2k_tcp_t *tcp); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main; */
+void xml_out_frame_com(FILE* xmlout, opj_tcp_t *tcp); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main; */
 void xml_out_dump_hex(FILE* xmlout, char *data, int data_len, char* s);
 void xml_out_dump_hex_and_ascii(FILE* xmlout, char *data, int data_len, char* s);
-void xml_out_frame_jp2h(FILE* xmlout, jp2_struct_t *jp2_struct);
+void xml_out_frame_jp2h(FILE* xmlout, opj_jp2_t *jp2_struct);
 #ifdef NOTYET
 /* Shown with cp, extended, as data structure... but it could be a new different one */
-void xml_out_frame_jp2i(FILE* xmlout, j2k_cp_t *cp);/* IntellectualProperty 'jp2i' (no restrictions on location) */
-void xml_out_frame_xml(FILE* xmlout, j2k_cp_t *cp); /* XML 'xml\040' (0x786d6c20).  Can appear multiply */
-void xml_out_frame_uuid(FILE* xmlout, j2k_cp_t *cp); /* UUID 'uuid' (top level only) */
-void xml_out_frame_uinf(FILE* xmlout, j2k_cp_t *cp); /* UUIDInfo 'uinf', includes UUIDList 'ulst' and URL 'url\40' */
-void xml_out_frame_unknown_type(FILE* xmlout, j2k_cp_t *cp);
+void xml_out_frame_jp2i(FILE* xmlout, opj_cp_t *cp);/* IntellectualProperty 'jp2i' (no restrictions on location) */
+void xml_out_frame_xml(FILE* xmlout, opj_cp_t *cp); /* XML 'xml\040' (0x786d6c20).  Can appear multiply */
+void xml_out_frame_uuid(FILE* xmlout, opj_cp_t *cp); /* UUID 'uuid' (top level only) */
+void xml_out_frame_uinf(FILE* xmlout, opj_cp_t *cp); /* UUIDInfo 'uinf', includes UUIDList 'ulst' and URL 'url\40' */
+void xml_out_frame_unknown_type(FILE* xmlout, opj_cp_t *cp);
 #endif
 
 
-/* ------------------------------------------------------------------------------------------- */
-
 void xml_write_init(BOOL n, BOOL t, BOOL r, BOOL d)
 {
   /* Init file globals */
@@ -102,7 +89,7 @@ void xml_write_init(BOOL n, BOOL t, BOOL r, BOOL d)
   derived = d;
 }
 
-int xml_write_struct(FILE* file, FILE *xmlout, mj2_movie_t * movie, unsigned int sampleframe, char* stringDTD) {
+int xml_write_struct(FILE* file, FILE *xmlout, opj_mj2_t * movie, unsigned int sampleframe, char* stringDTD, opj_event_mgr_t *event_mgr) {
 
   if(stringDTD != NULL)
   {
@@ -116,14 +103,14 @@ int xml_write_struct(FILE* file, FILE *xmlout, mj2_movie_t * movie, unsigned int
     fprintf(xmlout,"<?xml version=\"1.0\" standalone=\"yes\"?>\n");    
 
   fprintf(xmlout, "<MJ2_File>\n");
-  xml_write_overall_header(file, xmlout, movie, sampleframe);
+  xml_write_overall_header(file, xmlout, movie, sampleframe, event_mgr);
   fprintf(xmlout, "</MJ2_File>");
   return 0;
 }
 
 /* ------------- */
 
-int xml_write_overall_header(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int sampleframe)
+int xml_write_overall_header(FILE *file, FILE *xmlout, opj_mj2_t * movie, unsigned int sampleframe, opj_event_mgr_t *event_mgr)
 {
   int i;
   char buf[5];
@@ -143,7 +130,7 @@ int xml_write_overall_header(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsi
   }
   fprintf(xmlout,   "    </CompatibilityList>\n");
   fprintf(xmlout,   "  </FileType>\n");
-  xml_write_moov(file, xmlout, movie, sampleframe);
+  xml_write_moov(file, xmlout, movie, sampleframe, event_mgr);
   // To come?              <mdat>  // This is the container for media data that can also be accessed through track structures,
                                    // so is redundant, and simply not of interest as metadata
   //                       <moof>  // Allows incremental build up of movie.  Probably not in Simple Profile
@@ -154,7 +141,7 @@ int xml_write_overall_header(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsi
 
 /* ------------- */
 
-int xml_write_moov(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int sampleframe)
+int xml_write_moov(FILE *file, FILE *xmlout, opj_mj2_t * movie, unsigned int sampleframe, opj_event_mgr_t *event_mgr)
 {
   unsigned int tnum;
   mj2_tk_t *track;
@@ -188,10 +175,6 @@ int xml_write_moov(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int s
   if(notes)
     fprintf(xmlout, "      <!-- Timescale defines time units in one second -->\n");
   fprintf(xmlout,   "      <Rate>\n");        /* Rate to play presentation  (default = 0x00010000)          */
-#define CURRENTSTRUCT
-#ifdef CURRENTSTRUCT
-  movie->rate = movie->rate << 16;
-#endif
   if(notes) {
     fprintf(xmlout, "      <!-- Rate to play presentation is stored as fixed-point binary 16.16 value. Decimal value is approximation. -->\n");
     fprintf(xmlout, "      <!-- Rate is expressed relative to normal (default) value of 0x00010000 (1.0) -->\n");
@@ -200,11 +183,6 @@ int xml_write_moov(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int s
     fprintf(xmlout, "        <AsHex>0x%08x</AsHex>\n", movie->rate);
   if(derived)
     fprintf(xmlout, "        <AsDecimal>%12.6f</AsDecimal>\n", (double)movie->rate/(double)0x00010000);
-#ifdef CURRENTSTRUCT
-  if(notes)
-    fprintf(xmlout, "        <!-- Current m2j_to_metadata implementation always shows bits to right of decimal as zeroed. -->\n");
-  movie->rate = movie->rate >> 16;
-#endif
   fprintf(xmlout,   "      </Rate>\n");
   fprintf(xmlout,   "      <Duration>\n");
   if(raw)
@@ -272,7 +250,7 @@ int xml_write_moov(FILE *file, FILE *xmlout, mj2_movie_t * movie, unsigned int s
 
   track = &(movie->tk[tnum]);
   // For now, output info on first video track
-  xml_write_trak(file, xmlout, track, tnum, sampleframe);
+  xml_write_trak(file, xmlout, track, tnum, sampleframe, event_mgr);
 
   // to come:                <MovieExtends mvek> // possibly not in Simple Profile
   xml_write_moov_udta(xmlout, movie); /* NO OP so far */ /* <UserDataBox udta> contains <CopyrightBox cprt> */
@@ -341,7 +319,7 @@ void xml_time_out(FILE* xmlout, time_t t)
 
 /* ------------- */
 
-void xml_write_moov_udta(FILE* xmlout, mj2_movie_t * movie) {
+void xml_write_moov_udta(FILE* xmlout, opj_mj2_t * movie) {
   /* Compare with xml_write_udta */
 #ifdef NOTYET
   /* NO-OP so far.  Optional UserData 'udta' (zero or one in moov or each trak)
@@ -368,7 +346,7 @@ void xml_write_moov_udta(FILE* xmlout, mj2_movie_t * movie) {
 #endif
 }
 
-void xml_write_free_and_skip(FILE* xmlout, mj2_movie_t * movie) {
+void xml_write_free_and_skip(FILE* xmlout, opj_mj2_t * movie) {
 #ifdef NOTYET
   /* NO-OP so far.  There can be zero or more instances of free and/or skip
      at the top level of the file.  This may be a place where the user squirrel's metadata.
@@ -396,7 +374,7 @@ void xml_write_free_and_skip(FILE* xmlout, mj2_movie_t * movie) {
 #endif
 }
 
-void xml_write_uuid(FILE* xmlout, mj2_movie_t * movie) {
+void xml_write_uuid(FILE* xmlout, opj_mj2_t * movie) {
 /* Univeral Unique IDs of 16 bytes.  */
 #ifdef NOTYET
   /* NO-OP so far.  There can be zero or more instances of private uuid boxes in a file.
@@ -420,7 +398,7 @@ void xml_write_uuid(FILE* xmlout, mj2_movie_t * movie) {
 
 /* ------------- */
 
-void xml_write_trak(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum, unsigned int sampleframe)
+void xml_write_trak(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum, unsigned int sampleframe, opj_event_mgr_t *event_mgr)
 {
   fprintf(xmlout,    "    <Track BoxType=\"trak\" Instance=\"%d\">\n", tnum);
   xml_write_tkhd(file, xmlout, track, tnum);
@@ -442,7 +420,7 @@ void xml_write_trak(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum
       // Someday maybe do a smart range scan... for (snum=0; snum < track->num_samples; snum++){
       //  fprintf(stdout,"Frame %d: ",snum+1);
       sample = &track->sample[snum];
-         if(xml_out_frame(file, xmlout, sample, snum))
+         if(xml_out_frame(file, xmlout, sample, snum, event_mgr))
            return; /* Not great error handling here */
     }
   }
@@ -932,14 +910,29 @@ void xml_write_stbl(FILE* file, FILE* xmlout, mj2_tk_t *track, unsigned int tnum
 
 /* ------------- */
 
-int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int snum)
+int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int snum, opj_event_mgr_t *event_mgr)
 {
-  j2k_image_t img;
-  j2k_cp_t cp;
+       opj_dparameters_t parameters;   /* decompression parameters */
+  opj_image_t *img;
+  opj_cp_t *cp;
   int i;
   int numcomps;
   unsigned char* frame_codestream;
-/*  char xmloutname[50]; */
+       opj_dinfo_t* dinfo = NULL;      /* handle to a decompressor */
+       opj_cio_t *cio = NULL;  
+       opj_j2k_t *j2k;
+
+       /* JPEG 2000 compressed image data */
+
+       /* get a decoder handle */
+       dinfo = opj_create_decompress(CODEC_J2K);
+
+       /* catch events using our callbacks and give a local context */
+       opj_set_event_mgr((opj_common_ptr)dinfo, event_mgr, stderr);
+
+       /* setup the decoder decoding parameters using the current image and user parameters */
+       parameters.cp_limit_decoding = DECODE_ALL_BUT_PACKETS;
+       opj_setup_decoder(dinfo, &parameters);  
 
   frame_codestream = (unsigned char*) malloc (sample->sample_size-8); /* Skipping JP2C marker */
   if(frame_codestream == NULL)
@@ -947,65 +940,71 @@ int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int s
 
   fseek(file,sample->offset+8,SEEK_SET);
   fread(frame_codestream,sample->sample_size-8,1, file);  /* Assuming that jp and ftyp markers size do */
+
+       /* open a byte stream */
+       cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream, sample->sample_size-8);
+
   /* Decode J2K to image: */
-  if (!j2k_decode(frame_codestream, sample->sample_size-8, &img, &cp)) {
-    free(frame_codestream);
-#ifndef NO_PACKETS_DECODING
-    for (i=0; i<img.numcomps; i++)
-      free(img.comps[i].data);
-#endif
-    j2k_dec_release();
-    return 1;
-  }
+       img = opj_decode(dinfo, cio);
+  if (!img) {
+               fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
+               opj_destroy_decompress(dinfo);
+               opj_cio_close(cio);
+               return 1;
+       }
+
+       j2k = (opj_j2k_t*)dinfo->j2k_handle;
+       j2k_default_tcp = j2k->default_tcp;
+       cp = j2k->cp;
 
-  numcomps = img.numcomps;
-/*  Alignments:        "      <       To help maintain xml pretty-printing */  
+  numcomps = img->numcomps;
+  /*  Alignments:        "      <       To help maintain xml pretty-printing */  
   fprintf(xmlout,      "      <JP2_Frame Num=\"%d\">\n", snum+1);
   fprintf(xmlout,      "        <MainHeader>\n");
   /* There can be multiple codestreams; a particular image is entirely within a single codestream */
   /* TO DO:  A frame can be represented by two I-guess-contigious codestreams if its interleaved. */
   fprintf(xmlout,      "          <StartOfCodestream Marker=\"SOC\" />\n");
   /* "cp" stands for "coding parameter"; "tcp" is tile coding parameters, "tccp" is tile-component coding parameters */
-  xml_out_frame_siz(xmlout, &img, &cp); /* reqd in main */
-  xml_out_frame_cod(xmlout, &j2k_default_tcp); /* reqd in main */
-  xml_out_frame_coc(xmlout, &j2k_default_tcp, numcomps); /* opt in main, at most 1 per component */
-  xml_out_frame_qcd(xmlout, &j2k_default_tcp); /* reqd in main */
-  xml_out_frame_qcc(xmlout, &j2k_default_tcp, numcomps);       /* opt in main, at most 1 per component */
-  xml_out_frame_rgn(xmlout, &j2k_default_tcp, numcomps); /* opt, at most 1 per component */
-  xml_out_frame_poc(xmlout, &j2k_default_tcp); /*  opt (but reqd in main or tile for any progression order changes) */
+  xml_out_frame_siz(xmlout, img, cp); /* reqd in main */
+  xml_out_frame_cod(xmlout, j2k_default_tcp); /* reqd in main */
+  xml_out_frame_coc(xmlout, j2k_default_tcp, numcomps); /* opt in main, at most 1 per component */
+  xml_out_frame_qcd(xmlout, j2k_default_tcp); /* reqd in main */
+  xml_out_frame_qcc(xmlout, j2k_default_tcp, numcomps);        /* opt in main, at most 1 per component */
+  xml_out_frame_rgn(xmlout, j2k_default_tcp, numcomps); /* opt, at most 1 per component */
+  xml_out_frame_poc(xmlout, j2k_default_tcp); /*  opt (but reqd in main or tile for any progression order changes) */
   /* Next four get j2k_default_tcp passed globally: */
 #ifdef SUPPRESS_FOR_NOW
-  xml_out_frame_ppm(xmlout, &cp); /* opt (but either PPM or PPT [distributed in tile headers] or codestream packet header reqd) */
+  xml_out_frame_ppm(xmlout, cp); /* opt (but either PPM or PPT [distributed in tile headers] or codestream packet header reqd) */
 #endif
   xml_out_frame_tlm(xmlout); /* NO-OP.  TLM NOT SAVED IN DATA STRUCTURE */ /* opt */
   xml_out_frame_plm(xmlout); /* NO-OP.  PLM NOT SAVED IN DATA STRUCTURE */ /* opt in main; can be used in conjunction with PLT */
   xml_out_frame_crg(xmlout); /* NO-OP.  CRG NOT SAVED IN DATA STRUCTURE */ /* opt in main; */
-  xml_out_frame_com(xmlout, &j2k_default_tcp); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main; */
+  xml_out_frame_com(xmlout, j2k_default_tcp); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main; */
 
   fprintf(xmlout,      "        </MainHeader>\n");
 
   /*   TO DO: all the tile headers (sigh)  */
-  fprintf(xmlout,      "        <TilePartHeaders Count=\"%d\">\n", cp.tileno_size);            /* size of the vector tileno */
-  for(i = 0; i < cp.tileno_size; i++) { /* I think cp.tileno_size will be same number as (cp.tw * cp.th) or as global j2k_curtileno */
+  fprintf(xmlout,      "        <TilePartHeaders Count=\"%d\">\n", cp->tileno_size);           /* size of the vector tileno */
+  for(i = 0; i < cp->tileno_size; i++) { /* I think cp->tileno_size will be same number as (cp->tw * cp->th) or as global j2k_curtileno */
     // Standard seems to use zero-based # for tile-part.
-    fprintf(xmlout,    "          <TilePartHeader Num=\"%d\" ID=\"%d\">\n", i, cp.tileno[i]);                  /* ID number of the tiles present in the codestream */
+    fprintf(xmlout,    "          <TilePartHeader Num=\"%d\" ID=\"%d\">\n", i, cp->tileno[i]);                 /* ID number of the tiles present in the codestream */
     fprintf(xmlout,    "            <StartOfTilePart Marker=\"SOT\" />\n");
        /* All markers in tile-part headers (between SOT and SOD) are optional, unless structure requires. */
     if(i == 0) {
-      xml_out_frame_cod(xmlout, &(cp.tcps[i])); /* No more than 1 per tile */
-      xml_out_frame_coc(xmlout, &(cp.tcps[i]), numcomps); /* No more than 1 per component */
-      xml_out_frame_qcd(xmlout, &(cp.tcps[i])); /* No more than 1 per tile */
-      xml_out_frame_qcc(xmlout, &(cp.tcps[i]), numcomps);      /* No more than 1 per component */
-      xml_out_frame_rgn(xmlout, &(cp.tcps[i]), numcomps); /* No more than 1 per component */
+      xml_out_frame_cod(xmlout, &(cp->tcps[i])); /* No more than 1 per tile */
+      xml_out_frame_coc(xmlout, &(cp->tcps[i]), numcomps); /* No more than 1 per component */
+      xml_out_frame_qcd(xmlout, &(cp->tcps[i])); /* No more than 1 per tile */
+      xml_out_frame_qcc(xmlout, &(cp->tcps[i]), numcomps);     /* No more than 1 per component */
+      xml_out_frame_rgn(xmlout, &(cp->tcps[i]), numcomps); /* No more than 1 per component */
     }
-    xml_out_frame_poc(xmlout, &(cp.tcps[i])); /* Reqd only if any progression order changes different from main POC */
+    xml_out_frame_poc(xmlout, &(cp->tcps[i])); /* Reqd only if any progression order changes different from main POC */
 #ifdef SUPPRESS_FOR_NOW
-    xml_out_frame_ppt(xmlout, &(cp.tcps[i])); /* Either PPT [distributed in tile headers] or PPM or codestream packet header reqd. */
+    xml_out_frame_ppt(xmlout, &(cp->tcps[i])); /* Either PPT [distributed in tile headers] or PPM or codestream packet header reqd. */
 #endif
-    xml_out_frame_plt(xmlout, &(cp.tcps[i])); /* NO-OP.  PLT NOT SAVED IN DATA STRUCTURE */ /* Can be used in conjunction with main's PLM */
-    xml_out_frame_com(xmlout, &(cp.tcps[i])); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */
-    /* j2k_tcp_t * cp.tcps; "tile coding parameters" */
-    /* Maybe not: fprintf(xmlout,  "        <>%d</>, cp.matrice[i];                    */ /* Fixed layer    */
+    xml_out_frame_plt(xmlout, &(cp->tcps[i])); /* NO-OP.  PLT NOT SAVED IN DATA STRUCTURE */ /* Can be used in conjunction with main's PLM */
+    xml_out_frame_com(xmlout, &(cp->tcps[i])); /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */
+    /* opj_tcp_t * cp->tcps; "tile coding parameters" */
+    /* Maybe not: fprintf(xmlout,  "        <>%d</>, cp->matrice[i];                   */ /* Fixed layer    */
     fprintf(xmlout,    "            <StartOfData Marker=\"SOD\" />\n");
     if(notes)
       fprintf(xmlout,  "            <!-- Tile-part bitstream, not shown, follows tile-part header and SOD marker. -->\n");
@@ -1028,14 +1027,14 @@ int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int s
   /* Extra commentary: */
   if(notes) {
     fprintf(xmlout,    "      <!-- Given the number and size of components, mj2_to_frame would try to convert this -->\n");
-    if (((img.numcomps == 3) && (img.comps[0].dx == img.comps[1].dx / 2) 
-      && (img.comps[0].dx == img.comps[2].dx / 2 ) && (img.comps[0].dx == 1)) 
-      || (img.numcomps == 1)) {
+    if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2) 
+      && (img->comps[0].dx == img->comps[2].dx / 2 ) && (img->comps[0].dx == 1)) 
+      || (img->numcomps == 1)) {
       fprintf(xmlout,  "      <!-- file to a YUV movie in the normal manner. -->\n");
     }
-    else if ((img.numcomps == 3) && 
-      (img.comps[0].dx == 1) && (img.comps[1].dx == 1)&&
-         (img.comps[2].dx == 1))  {// If YUV 4:4:4 input --> to bmp
+    else if ((img->numcomps == 3) && 
+      (img->comps[0].dx == 1) && (img->comps[1].dx == 1)&&
+         (img->comps[2].dx == 1))  {// If YUV 4:4:4 input --> to bmp
          fprintf(xmlout,  "      <!-- YUV 4:4:4 file to a series of .bmp files. -->\n");
     }
     else {
@@ -1043,11 +1042,8 @@ int xml_out_frame(FILE* file, FILE* xmlout, mj2_sample_t *sample, unsigned int s
     }
   }
 
-#ifndef NO_PACKETS_DECODING
-  for (i=0; i<img.numcomps; i++)
-    free(img.comps[i].data);
-#endif
-  j2k_dec_release();
+       opj_destroy_decompress(dinfo);
+       opj_cio_close(cio);
   free(frame_codestream);
 
   return 0;
@@ -1070,9 +1066,9 @@ void int16_to_3packedchars(short int value, char* buf)
 
 /* ------------- */
 
-void xml_out_frame_siz(FILE* xmlout, j2k_image_t *img, j2k_cp_t *cp)
+void xml_out_frame_siz(FILE* xmlout, opj_image_t *img, opj_cp_t *cp)
 {
-  j2k_comp_t *comp;
+  opj_image_comp_t *comp;
   int i;
 
   fprintf(xmlout,    "          <ImageAndFileSize Marker=\"SIZ\">\n");
@@ -1137,17 +1133,17 @@ void xml_out_frame_siz(FILE* xmlout, j2k_image_t *img, j2k_cp_t *cp)
 
 /* ------------- */
 
-void xml_out_frame_cod(FILE* xmlout, j2k_tcp_t *tcp)
+void xml_out_frame_cod(FILE* xmlout, opj_tcp_t *tcp)
 {
 /* Could be called with tcp = &j2k_default_tcp;
 /* Or, for tile-part header, with &j2k_cp->tcps[j2k_curtileno]
 /*  Alignment for main:"          < < < <   To help maintain xml pretty-printing */  
 /*  Alignment for tile:"            < < <   To help maintain xml pretty-printing */  
-  j2k_tccp_t *tccp;
+  opj_tccp_t *tccp;
   int i;
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
   tccp = &(tcp->tccps[0]);
@@ -1221,14 +1217,14 @@ void xml_out_frame_cod(FILE* xmlout, j2k_tcp_t *tcp)
 
 /* ------------- */
 
-void xml_out_frame_coc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps) /* Optional in main & tile-part headers */
+void xml_out_frame_coc(FILE* xmlout, opj_tcp_t *tcp, int numcomps) /* Optional in main & tile-part headers */
 {
 /* Uses global j2k_default_tcp */
-  j2k_tccp_t *tccp, *firstcomp_tccp;
+  opj_tccp_t *tccp, *firstcomp_tccp;
   int i, compno;
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
 
@@ -1240,7 +1236,7 @@ void xml_out_frame_coc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps) /* Optional i
   /* Let's pretend that [0] is the default and all others are not */
   if(notes) {
     fprintf(xmlout,    "%s<!-- mj2_to_metadata implementation always reports component[0] as using default COD, -->\n", s);
-    if(tcp == &j2k_default_tcp)
+    if(tcp == j2k_default_tcp)
       fprintf(xmlout,  "%s<!-- and any other component, with main-header style values different from [0], as COC. -->\n", s);
     else
       fprintf(xmlout,  "%s<!-- and any other component, with tile-part-header style values different from [0], as COC. -->\n", s);
@@ -1314,7 +1310,7 @@ void xml_out_frame_coc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps) /* Optional i
 
 /* ------------- */
 
-BOOL same_component_style(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2)
+BOOL same_component_style(opj_tccp_t *tccp1, opj_tccp_t *tccp2)
 {
   int i;
 
@@ -1340,14 +1336,14 @@ BOOL same_component_style(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2)
 
 /* ------------- */
 
-void xml_out_frame_qcd(FILE* xmlout, j2k_tcp_t *tcp)
+void xml_out_frame_qcd(FILE* xmlout, opj_tcp_t *tcp)
 {
   /* This code will compile only if declaration of j2k_default_tcp is changed from static (to implicit extern) in j2k.c */
-  j2k_tccp_t *tccp;
+  opj_tccp_t *tccp;
   int bandno, numbands;
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
 
@@ -1471,16 +1467,16 @@ void xml_out_frame_qcd(FILE* xmlout, j2k_tcp_t *tcp)
 
 /* ------------- */
 
-void xml_out_frame_qcc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
+void xml_out_frame_qcc(FILE* xmlout, opj_tcp_t *tcp, int numcomps)
 {
 /* Uses global j2k_default_tcp */
   /* This code will compile only if declaration of j2k_default_tcp is changed from static (to implicit extern) in j2k.c */
-  j2k_tccp_t *tccp, *firstcomp_tccp;
+  opj_tccp_t *tccp, *firstcomp_tccp;
   int bandno, numbands;
   int compno;
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
 
@@ -1492,7 +1488,7 @@ void xml_out_frame_qcc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
   /* Let's pretend that [0] is the default and all others are not */
   if(notes) {
     fprintf(xmlout,      "%s<!-- mj2_to_metadata implementation always reports component[0] as using default QCD, -->\n", s);
-    if(tcp == &j2k_default_tcp)
+    if(tcp == j2k_default_tcp)
       fprintf(xmlout,    "%s<!-- and any other component, with main-header quantization values different from [0], as QCC. -->\n", s);
     else
       fprintf(xmlout,    "%s<!-- and any other component, with tile-part-header quantization values different from [0], as QCC. -->\n", s);
@@ -1505,7 +1501,7 @@ void xml_out_frame_qcc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
 
     /* Compare j2k_read_qcx */
     fprintf(xmlout,      "%s<QuantizationComponent Marker=\"QCC\" Component=\"%d\">\n", s, compno); /* Required in main header, single occurrence */
-    tccp = &j2k_default_tcp.tccps[0];
+    tccp = &j2k_default_tcp->tccps[0];
     /* Not retained or perhaps of interest: Lqcd   It maybe can be calculated.  */
     fprintf(xmlout,      "%s  <Sqcc>\n", s);           /* 1 byte */
     if(notes)
@@ -1617,7 +1613,7 @@ void xml_out_frame_qcc(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
 
 /* ------------- */
 
-BOOL same_component_quantization(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2)
+BOOL same_component_quantization(opj_tccp_t *tccp1, opj_tccp_t *tccp2)
 {
   int bandno, numbands;
 
@@ -1658,13 +1654,13 @@ BOOL same_component_quantization(j2k_tccp_t *tccp1, j2k_tccp_t *tccp2)
 
 /* ------------- */
 
-void xml_out_frame_rgn(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
+void xml_out_frame_rgn(FILE* xmlout, opj_tcp_t *tcp, int numcomps)
 {
   int compno, SPrgn;
   /* MJ2 files can have regions of interest if hybridized with JPX Part II */
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
 
@@ -1690,13 +1686,13 @@ void xml_out_frame_rgn(FILE* xmlout, j2k_tcp_t *tcp, int numcomps)
 
 /* ------------- */
 
-void xml_out_frame_poc(FILE* xmlout, j2k_tcp_t *tcp) { /* Progression Order Change */
+void xml_out_frame_poc(FILE* xmlout, opj_tcp_t *tcp) { /* Progression Order Change */
   /* Compare j2k_read_poc() */
   int i;
-  j2k_poc_t *poc;
+  opj_poc_t *poc;
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
   char* s = spaces;
-  if(tcp == &j2k_default_tcp) {
+  if(tcp == j2k_default_tcp) {
     s++;s++; /* shorten s to 10 spaces if main */
   }
   
@@ -1743,7 +1739,7 @@ void xml_out_frame_poc(FILE* xmlout, j2k_tcp_t *tcp) { /* Progression Order Chan
 /* Suppress PPM and PPT since we're not showing data from the third option, namely within the codestream, and
 that's evidently what frames_to_mj2 uses.  And a hex dump isn't so useful anyway */
 
-void xml_out_frame_ppm(FILE *xmlout, j2k_cp_t *cp) { /* For main header, not tile-part (which uses PPT instead). */
+void xml_out_frame_ppm(FILE *xmlout, opj_cp_t *cp) { /* For main header, not tile-part (which uses PPT instead). */
 /* Either the PPM or PPT is required if the packet headers are not distributed in the bit stream */
 /* Use of PPM and PPT are mutually exclusive. */
 /* Compare j2k_read_ppm() */
@@ -1774,7 +1770,7 @@ void xml_out_frame_ppm(FILE *xmlout, j2k_cp_t *cp) { /* For main header, not til
 
 /* ------------- */
 
-void xml_out_frame_ppt(FILE *xmlout, j2k_tcp_t *tcp) { /* For tile-part header, not main (which uses PPM instead). */
+void xml_out_frame_ppt(FILE *xmlout, opj_tcp_t *tcp) { /* For tile-part header, not main (which uses PPM instead). */
 /* Either the PPM or PPT is required if the packet headers are not distributed in the bit stream */
 /* Use of PPM and PPT are mutually exclusive. */
 /* Compare j2k_read_ppt() */
@@ -1824,7 +1820,7 @@ void xml_out_frame_plm(FILE* xmlout) { /* opt, main header only; can be used in
 
 /* ------------- */
 
-void xml_out_frame_plt(FILE* xmlout, j2k_tcp_t *tcp) { /* opt, tile-part headers only; can be used in conjunction with main header's PLM */
+void xml_out_frame_plt(FILE* xmlout, opj_tcp_t *tcp) { /* opt, tile-part headers only; can be used in conjunction with main header's PLM */
 /* NO-OP.  PLT NOT SAVED IN DATA STRUCTURE */
        /* Compare j2k_read_plt()... which doesn't retain anything! */
 /* Tile-part header indents are 12 spaces */
@@ -1879,7 +1875,7 @@ void xml_out_frame_crg(FILE* xmlout) { /* NO-OP.  CRG NOT SAVED IN DATA STRUCTUR
 /* ------------- */
 
 /* Regrettably from a metadata point of view, j2k_read_com() skips over any comments in main header or tile-part-header */
-void xml_out_frame_com(FILE* xmlout, j2k_tcp_t *tcp) { /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main or tile-part headers; */
+void xml_out_frame_com(FILE* xmlout, opj_tcp_t *tcp) { /* NO-OP.  COM NOT SAVED IN DATA STRUCTURE */ /* opt in main or tile-part headers; */
 /* Compare j2k_read_com()... which doesn't retain anything! */
 #ifdef NOTYET
   char spaces[13] = "            "; /* 12 spaces if tilepart*/
@@ -1948,8 +1944,8 @@ void xml_out_dump_hex_and_ascii(FILE* xmlout, char *data, int data_len, char* s)
 
 /* ------------- */
 
-void xml_out_frame_jp2h(FILE* xmlout, jp2_struct_t *jp2_struct) {  /* JP2 Header */
-/* Compare jp2_read_jp2h(jp2_struct_t * jp2_struct) */
+void xml_out_frame_jp2h(FILE* xmlout, opj_jp2_t *jp2_struct) {  /* JP2 Header */
+/* Compare jp2_read_jp2h(opj_jp2_t * jp2_struct) */
   int i;
 
   fprintf(xmlout,      "              <JP2Header BoxType=\"jp2h\">\n");
@@ -2052,7 +2048,7 @@ void xml_out_frame_jp2h(FILE* xmlout, jp2_struct_t *jp2_struct) {  /* JP2 Header
 
 #ifdef NOTYET
 IMAGE these use cp structure, extended... but we could use a new data structure instead
-void xml_out_frame_jp2i(FILE* xmlout, j2k_cp_t *cp) {
+void xml_out_frame_jp2i(FILE* xmlout, opj_cp_t *cp) {
   /* IntellectualProperty 'jp2i' (no restrictions on location) */
   int i;
   IMAGE cp->jp2i, cp->jp2i_count, cp->jp2i_data (array of chars), cp->cp2i_len (array of ints)
@@ -2070,7 +2066,7 @@ void xml_out_frame_jp2i(FILE* xmlout, j2k_cp_t *cp) {
   }
 }
 
-void xml_out_frame_xml(FILE* xmlout, j2k_cp_t *cp) {
+void xml_out_frame_xml(FILE* xmlout, opj_cp_t *cp) {
   /* XML 'xml\040' (0x786d6c20).  Can appear multiply, before or after jp2c codestreams */
   IMAGE cp->xml, cp->xml_count, cp->xml_data (array of chars)
   MAYBE WE DON'T NEED cp->xml_len (array of ints) IF WE ASSUME xml_data IS NULL-TERMINATED.
@@ -2089,7 +2085,7 @@ void xml_out_frame_xml(FILE* xmlout, j2k_cp_t *cp) {
   }
 }
 
-void xml_out_frame_uuid(FILE* xmlout, j2k_cp_t *cp) {
+void xml_out_frame_uuid(FILE* xmlout, opj_cp_t *cp) {
        /* UUID 'uuid' (top level only) */
        /* Part I 1.7.2 says: may appear multiply in JP2 file, anywhere except before File Type box */
        /* Part III 5.2.1 says: Private extensions shall be achieved through the 'uuid' type. */
@@ -2119,7 +2115,7 @@ void xml_out_frame_uuid(FILE* xmlout, j2k_cp_t *cp) {
   }
 }
 
-void xml_out_frame_uinf(FILE* xmlout, j2k_cp_t *cp) {
+void xml_out_frame_uinf(FILE* xmlout, opj_cp_t *cp) {
        /* UUIDInfo 'uinf', includes UUIDList 'ulst' and URL 'url\40' */
        /* Part I 1.7.3 says: may appear multiply in JP2 file, anywhere at the top level except before File Type box */
        /* So there may be multiple ulst's, and each can have multiple UUIDs listed (with a single URL) */
@@ -2151,7 +2147,7 @@ void xml_out_frame_uinf(FILE* xmlout, j2k_cp_t *cp) {
 }
 
 IMAGE these use cp structure, extended... but we could use a new data structure instead
-void xml_out_frame_unknown_type(FILE* xmlout, j2k_cp_t *cp) {
+void xml_out_frame_unknown_type(FILE* xmlout, opj_cp_t *cp) {
   /* Part III 5.2.1 says "Type fields not defined here are reserved.  Private extensions
      shall be acieved through the 'uuid' type." [This implies an unknown
      type would be an error, but then...] "Boxes not explicitly defined in this standard,