]> granicus.if.org Git - openjpeg/commitdiff
[1.5] backport revisions 996, 997, 1000, 1008-1012 from trunk (JPIP modifications)
authorAntonin Descampe <antonin@gmail.com>
Tue, 1 Nov 2011 23:28:07 +0000 (23:28 +0000)
committerAntonin Descampe <antonin@gmail.com>
Tue, 1 Nov 2011 23:28:07 +0000 (23:28 +0000)
28 files changed:
CHANGES
applications/JavaOpenJPEG/JavaOpenJPEG.c
applications/codec/image_to_j2k.c
applications/jpip/CHANGES
applications/jpip/README
applications/jpip/libopenjpip/j2kheader_manager.c
applications/jpip/libopenjpip/jp2k_encoder.c
applications/jpip/libopenjpip/msgqueue_manager.c
applications/jpip/libopenjpip/msgqueue_manager.h
applications/jpip/opj_client/opj_dec_server/CMakeLists.txt
applications/jpip/opj_client/opj_dec_server/Makefile.am
applications/jpip/opj_client/opj_dec_server/Makefile.nix
applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.c [new file with mode: 0644]
applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.h [new file with mode: 0644]
applications/jpip/opj_client/opj_dec_server/imgsock_manager.c
applications/jpip/opj_client/opj_dec_server/imgsock_manager.h
applications/jpip/opj_client/opj_dec_server/opj_dec_server.c
applications/jpip/opj_client/opj_viewer/dist/opj_viewer-20111018.jar [new file with mode: 0644]
applications/jpip/opj_client/opj_viewer/dist/opj_viewer.jar
applications/jpip/opj_server/CMakeLists.txt
applications/jpip/opj_server/Makefile.am
applications/jpip/opj_server/Makefile.nix
applications/jpip/opj_server/jpip_parser.c [new file with mode: 0644]
applications/jpip/opj_server/jpip_parser.h [new file with mode: 0644]
applications/jpip/opj_server/opj_server.c
applications/jpip/opj_server/query_parser.c
applications/jpip/opj_server/query_parser.h
applications/jpip/tools/jpip_to_j2k.c

diff --git a/CHANGES b/CHANGES
index 5565b914c0756492bbf310e6d98b4d9d127b1090..1c7d77461cb8c3fc2f2d8099722db42253470d58 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,7 @@ What's New for OpenJPEG
 
 October 21, 2011
 * [mickael] remove one obvious memory leak from test functions
+! [kaori]   change -v option was renamed to -u, which is equivalent to -TP long option
 
 October 20, 2011
 * [mickael] remove obvious memory leak from applications
index 0926b77cba4dcb87d476f78aaa05d2f7ebd3ce3f..eea41c251881438de331f897ee2d978fc4ad7f27 100644 (file)
@@ -204,6 +204,8 @@ void encode_help_display() {
        fprintf(stdout,"                 Indicate multiple modes by adding their values. \n");\r
        fprintf(stdout,"                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");\r
        fprintf(stdout,"\n");\r
+       fprintf(stdout,"-TP          : devide packets of every tile into tile-parts (-TP R) [R, L, C]\n");\r
+       fprintf(stdout,"\n");\r
        fprintf(stdout,"-x           : create an index file *.Idx (-x index_name.Idx) \n");\r
        fprintf(stdout,"\n");\r
        fprintf(stdout,"-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");\r
@@ -499,7 +501,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
                {"cinema2K",REQ_ARG, NULL ,'w'},\r
                {"cinema4K",NO_ARG, NULL ,'y'},\r
                {"ImgDir",REQ_ARG, NULL ,'z'},\r
-               {"TP",REQ_ARG, NULL ,'v'},\r
+               {"TP",REQ_ARG, NULL ,'u'},\r
                {"SOP",NO_ARG, NULL ,'S'},\r
                {"EPH",NO_ARG, NULL ,'E'},\r
                {"OutFor",REQ_ARG, NULL ,'O'},\r
@@ -510,7 +512,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
 \r
        /* parse the command line */\r
 /* UniPG>> */\r
-       const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:"\r
+       const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:J"\r
 #ifdef USE_JPWL\r
                "W:"\r
 #endif /* USE_JPWL */\r
@@ -871,7 +873,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
 \r
                        /* ------------------------------------------------------ */\r
                        \r
-                       case 'v':                       /* Tile part generation*/\r
+                       case 'u':                       /* Tile part generation*/\r
                        {\r
                                parameters->tp_flag = opj_optarg[0];\r
                                parameters->tp_on = 1;\r
index 93d0c6ff6029b64b0879160cc9aa47f21e90de59..968afcc6567606f5b2378643c32b93ea877c196a 100644 (file)
@@ -193,6 +193,8 @@ void encode_help_display(void) {
        fprintf(stdout,"                 Indicate multiple modes by adding their values. \n");
        fprintf(stdout,"                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
        fprintf(stdout,"\n");
+       fprintf(stdout,"-TP          : devide packets of every tile into tile-parts (-TP R) [R, L, C]\n");
+       fprintf(stdout,"\n");
        fprintf(stdout,"-x           : create an index file *.Idx (-x index_name.Idx) \n");
        fprintf(stdout,"\n");
        fprintf(stdout,"-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");
@@ -581,7 +583,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
                {"cinema2K",REQ_ARG, NULL ,'w'},
                {"cinema4K",NO_ARG, NULL ,'y'},
                {"ImgDir",REQ_ARG, NULL ,'z'},
-               {"TP",REQ_ARG, NULL ,'v'},
+               {"TP",REQ_ARG, NULL ,'u'},
                {"SOP",NO_ARG, NULL ,'S'},
                {"EPH",NO_ARG, NULL ,'E'},
                {"OutFor",REQ_ARG, NULL ,'O'},
@@ -591,7 +593,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
        };
 
        /* parse the command line */
-       const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:v:"
+       const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:J"
 #ifdef USE_JPWL
                "W:"
 #endif /* USE_JPWL */
@@ -1005,7 +1007,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
 
                        /* ------------------------------------------------------ */
 
-                       case 'v':                       /* Tile part generation*/
+                       case 'u':                       /* Tile part generation*/
                        {
                                parameters->tp_flag = opj_optarg[0];
                                parameters->tp_on = 1;
index 34fa3cfca7ca0adca55c4a9a80e37a98a8d063fb..c5ae11ad41a4a94a672d4d5be850c4f954052f44 100644 (file)
@@ -5,6 +5,15 @@ What's New for OpenJPIP
 ! : changed
 + : added
 
+October 14, 2011
+! [kaori] rearranged opj_server, opj_dec_server directory
+
+October 14, 2011
++ [kaori] enable all progression orders
+
+October 12, 2011
++ [kaori] enable layers requests; restricting the number of codesream quality layers
+
 October 11, 2011
 + [antonin] enable JPT-stream request from client viewer option (credit to kaori)
 
index 0bd22fdaf164845869f8c4309986a0ed30ec622f..9842b9360fb51c56292154f9c112b193892848d7 100644 (file)
@@ -126,11 +126,11 @@ Client:
 ----------
 
 An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale.
-   % ./image_to_j2k -i copenhague1.tif -o copenhague1.jp2 -p RPCL -c [64,64] -t 640,480 -jpip -v R
+   % ./image_to_j2k -i copenhague1.tif -o copenhague1.jp2 -p RPCL -c [64,64] -t 640,480 -jpip -TP R
 
  options
   -jpip : embed index table box into the output JP2 file (obligation for JPIP)
-  -v R  : partition a tile into tile parts of different resolution levels (obligation for JPT-stream)
+  -TP R : partition a tile into tile parts of different resolution levels (obligation for JPT-stream)
 
 <Option>
  3. Embed metadata into JP2 file
index ad94d587329bfac1694d71bf3a7991796f5a8731..afbb2525a6be882f4b91d4fb67d8fd5bcf2c3506 100644 (file)
@@ -162,8 +162,7 @@ bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SI
   if( !(newLcod = modify_CODmkrstream( COD, numOfdecomp, j2kstream)))
     return false;
 
-  // memmove( j2kstream+2+newLcod, j2kstream+2+COD.Lcod, (*j2klen)-(SIZ.Lsiz+newLcod+6));// new->oldLcod
-   memmove( j2kstream+2+newLcod, j2kstream+2+COD.Lcod, (*j2klen)-(SIZ.Lsiz+COD.Lcod+6));
+  memmove( j2kstream+2+newLcod, j2kstream+2+COD.Lcod, (*j2klen)-(SIZ.Lsiz+COD.Lcod+6));
   *j2klen -= ( COD.Lcod - newLcod);
   
   return true;
@@ -222,6 +221,7 @@ Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *COD
     newLcod = COD.Lcod;
     CODstream += 2;
   }
+  
   CODstream += 5; // skip Scod & SGcod
   
   // SPcod
index e1488cde306082cdd1c99abc2d17343738e29579..5025bf8eff039227a49451dd13297ddc367a8033 100644 (file)
@@ -221,10 +221,11 @@ Byte_t * recons_codestream_from_JPTstream( msgqueue_param_t *msgqueue, Byte_t *j
   return j2kstream;
 }
 
-Byte_t * recons_RPCLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
-                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
-                              int *max_reslev, Byte8_t *j2klen);
+Byte_t * add_SOTmkr( Byte_t *j2kstream, Byte8_t *j2klen);
 
+Byte_t * recons_bitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                          Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                          int *max_reslev, Byte8_t *j2klen);
 
 Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
 {
@@ -244,11 +245,6 @@ Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *j
   if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, &COD))
     return j2kstream;
 
-  if( COD.prog_order != RPCL){
-    fprintf( FCGI_stderr, "Error, Only RPCL order supported\n");
-    return j2kstream;
-  }
-
   if( fw == 0 || fh == 0)
     mindeclev = 0;
   else
@@ -265,6 +261,7 @@ Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *j
     SOToffset = *j2klen;
     while(( ptr = search_message( TILE_HEADER_MSG, tileID, csn, ptr))!=NULL){
       if( ptr->bin_offset == binOffset){
+       j2kstream = add_SOTmkr( j2kstream, j2klen);
        j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
        foundTH = true;
        binOffset += ptr->length;
@@ -273,17 +270,17 @@ Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *j
     }
 
     if( foundTH){
-      j2kstream = recons_RPCLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, &max_reslev, j2klen);
+      j2kstream = recons_bitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, &max_reslev, j2klen);     
       modify_tileheader( j2kstream, SOToffset, (max_reslev<COD.numOfdecomp ? max_reslev : -1), SIZ.Csiz, j2klen);
     }
     else
       j2kstream = add_emptytilestream( tileID, j2kstream, j2klen);
   }
-  
+
   if( max_reslev < COD.numOfdecomp)
     if( !modify_mainheader( j2kstream, max_reslev, SIZ, COD, j2klen))
       return j2kstream;
-  
+
   j2kstream = add_EOC( j2kstream, j2klen);
   return j2kstream;
 }
@@ -306,55 +303,300 @@ Byte_t * add_mainhead_msgstream( msgqueue_param_t *msgqueue, Byte_t *origstream,
   return j2kstream;
 }
 
-Byte_t * add_padding( Byte8_t padding, Byte_t *j2kstream, Byte8_t *j2klen);
+Byte_t * add_SOTmkr( Byte_t *j2kstream, Byte8_t *j2klen)
+{
+  Byte_t *buf;
+  const Byte2_t SOT = 0x90ff;
+
+  buf = (Byte_t *)malloc(( *j2klen)+2);
+
+  memcpy( buf, j2kstream, *j2klen);
+  memcpy( buf+(*j2klen), &SOT, 2);
+  
+  *j2klen += 2;
+
+  if(j2kstream) free(j2kstream);
+
+  return buf;
+}
+
+Byte_t * recons_LRCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_RLCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_RPCLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_PCRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_CPRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_bitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                          Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                          int *max_reslev, Byte8_t *j2klen)
+{
+  switch( COD.prog_order){
+  case LRCP:
+    return recons_LRCPbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+  case RLCP:
+    return recons_RLCPbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+  case RPCL:
+    return recons_RPCLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+  case PCRL:
+    return recons_PCRLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+  case CPRL:
+    return recons_CPRLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+  default:
+    fprintf( FCGI_stderr, "Error, progression order not supported\n");
+  }
+  return j2kstream;
+}
+
+int comp_numOfprcts( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r);
+Byte8_t comp_seqID( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r, int p);
+
+Byte_t * recons_packet( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                       Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev, 
+                       int comp_idx, int res_idx, int prct_idx, int lay_idx, Byte8_t *j2klen);
+
+Byte_t * recons_LRCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen)
+{
+  int r, p, c, l, numOfprcts;
+
+  for( l=0; l<COD.numOflayers; l++)
+    for( r=0; r<=(COD.numOfdecomp-mindeclev); r++){
+      if( COD.Scod & 0x01)
+       numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+      else
+       numOfprcts = 1;
+      
+      for( c=0; c<SIZ.Csiz; c++)
+       for( p=0; p<numOfprcts; p++)
+         j2kstream = recons_packet( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, p, l, j2klen);
+    }
+  
+  return j2kstream;
+}
+
+Byte_t * recons_RLCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen)
+{
+  int r, p, c, l, numOfprcts;
+  
+  for( r=0; r<=(COD.numOfdecomp-mindeclev); r++){
+    if( COD.Scod & 0x01)
+      numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+    else
+      numOfprcts = 1;
+
+    for( l=0; l<COD.numOflayers; l++)
+      for( c=0; c<SIZ.Csiz; c++)
+       for( p=0; p<numOfprcts; p++)
+         j2kstream = recons_packet( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, p, l, j2klen);
+  }
+      
+  return j2kstream;
+}
+
+Byte_t * recons_precinct( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                         Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev, 
+                         int comp_idx, int res_idx, Byte8_t seqID, Byte8_t *j2klen);
 
 Byte_t * recons_RPCLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
                               Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
                               int *max_reslev, Byte8_t *j2klen)
 {
   int r, p, c, numOfprcts;
-  bool foundPrec;
-  Byte8_t binOffset, precID, seqID;
-  Byte4_t XTsiz, YTsiz;
-  message_param_t *ptr;
+  Byte8_t seqID;
   
   for( r=0, seqID=0; r<=(COD.numOfdecomp-mindeclev); r++){
     
-    if( COD.Scod & 0x01){
-      XTsiz = get_tile_XSiz( SIZ, tileID, COD.numOfdecomp-r);
-      YTsiz = get_tile_YSiz( SIZ, tileID, COD.numOfdecomp-r);
-      numOfprcts = ceil((double)XTsiz/(double)COD.XPsiz[r])*ceil((double)YTsiz/(double)COD.YPsiz[r]);
-    }
+    if( COD.Scod & 0x01)
+      numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
     else
       numOfprcts = 1;
     
-    for( p=0; p<numOfprcts; p++, seqID++){      
-      for( c=0; c<SIZ.Csiz; c++){
-
-       precID = comp_precinct_id( tileID, c, seqID, SIZ.Csiz, SIZ.XTnum*SIZ.YTnum);
-
-       ptr = msgqueue->first;
-       binOffset = 0;
-       foundPrec = false;
-       while(( ptr = search_message( PRECINCT_MSG, precID, csn, ptr))!=NULL){
-         if( ptr->bin_offset == binOffset){
-           j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
-           
-           foundPrec = true;
-           binOffset += ptr->length;
-           if( *max_reslev < r)
-             *max_reslev = r;
-         }
-         ptr = ptr->next;
-       }
-       if(!foundPrec && COD.Scod & 0x01)
-         j2kstream = add_padding( 1, j2kstream, j2klen);
+    for( p=0; p<numOfprcts; p++, seqID++)
+      for( c=0; c<SIZ.Csiz; c++)
+       j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+  }
+      
+  return j2kstream;
+}
+
+Byte_t * recons_PCRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen)
+{
+  int r, p, c, min_numOfprcts, numOfprcts, min_numOfres;
+  Byte8_t seqID;
+  
+  min_numOfres = COD.numOfdecomp-mindeclev + 1;
+
+  if( COD.Scod & 0x01){
+    min_numOfprcts = 0;
+    for( r=0; r<min_numOfres; r++){
+      numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+      
+      if( numOfprcts < min_numOfprcts || min_numOfprcts == 0)
+       min_numOfprcts = numOfprcts;
+    }
+  }
+  else
+    min_numOfprcts = 1;
+  
+  for( p=0; p<min_numOfprcts; p++)
+    for( c=0; c<SIZ.Csiz; c++)
+      for( r=0; r<min_numOfres; r++){
+       seqID = comp_seqID( tileID, SIZ, COD, r, p);
+       j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+      }
+    
+  return j2kstream;
+}
+
+
+Byte_t * recons_CPRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                              Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev, 
+                              int *max_reslev, Byte8_t *j2klen)
+{
+  int r, p, c, min_numOfprcts, numOfprcts, min_numOfres;
+  Byte8_t seqID;
+  
+  min_numOfres = COD.numOfdecomp-mindeclev + 1;
+
+  if( COD.Scod & 0x01){
+    min_numOfprcts = 0;
+    for( r=0; r<min_numOfres; r++){
+      numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+      
+      if( numOfprcts < min_numOfprcts || min_numOfprcts == 0)
+       min_numOfprcts = numOfprcts;
+    }
+  }
+  else
+    min_numOfprcts = 1;
+  
+  for( c=0; c<SIZ.Csiz; c++)
+    for( p=0; p<min_numOfprcts; p++)
+      for( r=0; r<min_numOfres; r++){
+       seqID = comp_seqID( tileID, SIZ, COD, r, p);
+       j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+      }
+  
+  return j2kstream;
+}
+
+int comp_numOfprcts( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r)
+{  
+  Byte4_t XTsiz, YTsiz;
+  
+  XTsiz = get_tile_XSiz( SIZ, tileID, COD.numOfdecomp-r);
+  YTsiz = get_tile_YSiz( SIZ, tileID, COD.numOfdecomp-r);
+  
+  return ceil((double)XTsiz/(double)COD.XPsiz[r])*ceil((double)YTsiz/(double)COD.YPsiz[r]);    
+}
+
+Byte_t * add_padding( Byte8_t padding, Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_packet( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                       Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev, 
+                       int comp_idx, int res_idx, int prct_idx, int lay_idx, Byte8_t *j2klen)
+{
+  Byte8_t seqID, precID, binOffset;
+  message_param_t *ptr;
+  bool foundPrec;
+  int l;
+
+  seqID = comp_seqID( tileID, SIZ, COD, res_idx, prct_idx);
+  precID = comp_precinct_id( tileID, comp_idx, seqID, SIZ.Csiz, SIZ.XTnum*SIZ.YTnum);
+                 
+  ptr = msgqueue->first;
+  binOffset = 0;
+  foundPrec = false;
+  l = 0;
+         
+  while(( ptr = search_message( PRECINCT_MSG, precID, csn, ptr))!=NULL){
+    if( ptr->bin_offset == binOffset){
+      if( lay_idx == l){
+       j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+       foundPrec = true;
+       if( *max_reslev < res_idx)
+         *max_reslev = res_idx;
+               
+       break;
       }
+      binOffset += ptr->length;
+      l++;
     }
+    ptr = ptr->next;
   }
+  if( !foundPrec && COD.Scod & 0x01)
+    j2kstream = add_padding( 1, j2kstream, j2klen);
+  
   return j2kstream;
 }
 
+
+Byte_t * recons_precinct( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn, 
+                         Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev, 
+                         int comp_idx, int res_idx, Byte8_t seqID, Byte8_t *j2klen)
+{
+  Byte8_t precID, binOffset;
+  message_param_t *ptr;
+  bool foundPrec;
+
+  precID = comp_precinct_id( tileID, comp_idx, seqID, SIZ.Csiz, SIZ.XTnum*SIZ.YTnum);
+  
+  ptr = msgqueue->first;
+  binOffset = 0;
+  foundPrec = false;
+
+  while(( ptr = search_message( PRECINCT_MSG, precID, csn, ptr))!=NULL){
+    if( ptr->bin_offset == binOffset){
+      j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+      
+      foundPrec = true;
+      binOffset += ptr->length;
+      if( *max_reslev < res_idx)
+       *max_reslev = res_idx;
+
+      if( ptr->last_byte)
+       break;
+    }
+    ptr = ptr->next;
+  }
+  if(!foundPrec && COD.Scod & 0x01)
+    j2kstream = add_padding( COD.numOflayers, j2kstream, j2klen);
+
+  return j2kstream;
+}
+
+Byte8_t comp_seqID( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r, int p)
+{
+  Byte8_t seqID = 0;
+  int rr;
+  
+  for( rr=0; rr<r; rr++)
+    seqID += comp_numOfprcts( tileID, SIZ, COD, rr);
+  
+  seqID += p;
+  
+  return seqID;
+}
+
 Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, bool isJPPstream)
 {
   Byte8_t last_tileID = 0;
index 8cc89f487dce413bae48a8106ac114839f9424f5..295c2360cc843c1a5dbacf10e0a99b9b15afc184 100644 (file)
@@ -101,7 +101,8 @@ void print_msgqueue( msgqueue_param_t *msgqueue)
     fprintf( logstream, "\t csn: %lld\n", ptr->csn );
     fprintf( logstream, "\t bin_offset: %#llx\n", ptr->bin_offset );
     fprintf( logstream, "\t length: %#llx\n", ptr->length );
-    fprintf( logstream, "\t aux: %lld\n", ptr->aux );
+    if( ptr->class_id%2)
+      fprintf( logstream, "\t aux: %lld\n", ptr->aux );
     fprintf( logstream, "\t last_byte: %d\n", ptr->last_byte );
     if( ptr->phld)
       print_placeholder( ptr->phld);
@@ -162,9 +163,9 @@ void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue)
     msg->class_id = TILE_HEADER_MSG;
     msg->csn = target->csn;
     msg->bin_offset = 0;
-    msg->length = codeidx->tileheader[tile_id]->tlen;
+    msg->length = codeidx->tileheader[tile_id]->tlen-2; // SOT marker segment is removed
     msg->aux = 0; // non exist
-    msg->res_offset = codeidx->offset + get_elemOff( codeidx->tilepart, 0, tile_id);
+    msg->res_offset = codeidx->offset + get_elemOff( codeidx->tilepart, 0, tile_id) + 2; // skip SOT marker seg
     msg->phld = NULL;
     msg->next = NULL;
     
@@ -210,7 +211,7 @@ void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
     if( !tp_model[i]){
       msg = (message_param_t *)malloc( sizeof(message_param_t));
       
-      msg->last_byte = i==numOftparts-1? true : false;
+      msg->last_byte = (i==numOftparts-1);
       msg->in_class_id = tile_id;
       msg->class_id = class_id;
       msg->csn = target->csn;
@@ -229,35 +230,48 @@ void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
   }
 }
 
-void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue)
+void enqueue_precinct( int seq_id, int tile_id, int comp_id, int layers, msgqueue_param_t *msgqueue)
 {
   cachemodel_param_t *cachemodel;
   index_param_t *codeidx;
   faixbox_param_t *precpacket;
   message_param_t *msg;
-  Byte8_t nmax;
-
+  Byte8_t nmax, binOffset, binLength;
+  int layer_id, numOflayers;
+  
   cachemodel = msgqueue->cachemodel;
   codeidx = cachemodel->target->codeidx;
   precpacket = codeidx->precpacket[ comp_id];
+  numOflayers = codeidx->COD.numOflayers;
 
   nmax = get_nmax(precpacket);
+  if( layers < 0)
+    layers = numOflayers;
+    
+  binOffset = 0;
+  for( layer_id = 0; layer_id < layers; layer_id++){
+
+    binLength = get_elemLen( precpacket, seq_id*numOflayers+layer_id, tile_id);
+    
+    if( !cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id*numOflayers+layer_id]){
   
-  if( !cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id]){
-    msg = (message_param_t *)malloc( sizeof(message_param_t));
-    msg->last_byte = true;
-    msg->in_class_id = comp_precinct_id( tile_id, comp_id, seq_id, codeidx->SIZ.Csiz, codeidx->SIZ.XTnum * codeidx->SIZ.YTnum);
-    msg->class_id = PRECINCT_MSG;
-    msg->csn = cachemodel->target->csn;
-    msg->bin_offset = 0;
-    msg->length = get_elemLen( precpacket, seq_id, tile_id);
-    msg->aux = 0;
-    msg->res_offset = codeidx->offset+get_elemOff( precpacket, seq_id, tile_id);
-    msg->phld = NULL;
-    msg->next = NULL;
+      msg = (message_param_t *)malloc( sizeof(message_param_t));
+      msg->last_byte = (layer_id == (numOflayers-1));
+      msg->in_class_id = comp_precinct_id( tile_id, comp_id, seq_id, codeidx->SIZ.Csiz, codeidx->SIZ.XTnum * codeidx->SIZ.YTnum);
+      msg->class_id = PRECINCT_MSG;
+      msg->csn = cachemodel->target->csn;
+      msg->bin_offset = binOffset;
+      msg->length = binLength;
+      msg->aux = 0;
+      msg->res_offset = codeidx->offset+get_elemOff( precpacket, seq_id*numOflayers+layer_id, tile_id);
+      msg->phld = NULL;
+      msg->next = NULL;
 
-    enqueue_message( msg, msgqueue);
-    cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id] = true;
+      enqueue_message( msg, msgqueue);
+      
+      cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id*numOflayers+layer_id] = true;
+    }
+    binOffset += binLength;
   }
 }
 
index d75a551856e7d621803d5ac79f234af2cd2fe8b7..7236d89c607c39ab7eb0d9842bbafc98f18afb9e 100644 (file)
@@ -129,9 +129,10 @@ void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue);
  * @param[in]     seq_id   precinct sequence number within its tile
  * @param[in]     tile_id  tile index
  * @param[in]     comp_id  component number
+ * @param[in]     layers   num of layers
  * @param[in,out] msgqueue message queue
  */
-void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue);
+void enqueue_precinct( int seq_id, int tile_id, int comp_id, int layers, msgqueue_param_t *msgqueue);
 
 
 /**
index 56c4c7af031dcd25d548420a4a3fdc5775298515..10e9aa5c57b3a95e579cf66485f80b926118959b 100644 (file)
@@ -5,6 +5,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/opj_dec_server.c
 ${CMAKE_CURRENT_SOURCE_DIR}/jp2k_decoder.c
 ${CMAKE_CURRENT_SOURCE_DIR}/imgsock_manager.c
 ${CMAKE_CURRENT_SOURCE_DIR}/jpipstream_manager.c
+${CMAKE_CURRENT_SOURCE_DIR}/dec_clientmsg_handler.c
 )
 
 INCLUDE_DIRECTORIES(
index 96c10ebe4990a5cd798eb08aea08bda55cbe8b76..b9e32c92b67c39b038978c499cb25c407220d3c8 100644 (file)
@@ -20,10 +20,12 @@ cache_manager.h \
 imgsock_manager.c \
 imgsock_manager.h \
 jp2k_decoder.c \
+dec_clientmsg_handler.c \
+dec_clientmsg_handler.h \
 jp2k_decoder.h \
 jpipstream_manager.c \
 jpipstream_manager.h \
-opj_dec_server.c
+opj_dec_server.c 
 
 
 install-data-hook:
index dd8e06cf1ee20a7c30ea48ef73770501c102bc3f..b29671f2ebd9ea46f65db9557012bcf048070291 100644 (file)
@@ -10,7 +10,8 @@ ALL = opj_dec_server
 
 all: $(ALL)
 
-opj_dec_server: opj_dec_server.o jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o $(LIBFNAME)
-       $(CC) $(CFLAGS) $< jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o $(LDFLAGS) $(LIBFNAME) -o $@
+opj_dec_server: opj_dec_server.o jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o dec_clientmsg_handler.o $(LIBFNAME)
+       $(CC) $(CFLAGS) $< jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o dec_clientmsg_handler.o $(LDFLAGS) $(LIBFNAME) -o $@
+
 clean:
        rm -f $(ALL) *.o *~
diff --git a/applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.c b/applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.c
new file mode 100644 (file)
index 0000000..e7b64ee
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "dec_clientmsg_handler.h"
+#include "ihdrbox_manager.h"
+#include "jpipstream_manager.h"
+#include "jp2k_encoder.h"
+
+
+//! maximum length of channel identifier
+#define MAX_LENOFCID 30
+
+/**
+ * handle JPT- JPP- stream message
+ *
+ * @param[in]     connected_socket socket descriptor
+ * @param[in]     cachelist        cache list pointer
+ * @param[in,out] jpipstream       address of JPT- JPP- stream pointer
+ * @param[in,out] streamlen        address of stream length
+ * @param[in,out] msgqueue         message queue pointer
+ */
+void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist, Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue);
+
+/**
+ * handle PNM request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] jpipstream       jpipstream pointer
+ * @param[in] msgqueue         message queue pointer
+ * @param[in] cachelist        cache list pointer
+ */
+void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist);
+
+/**
+ * handle XML request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] jpipstream       address of caching jpipstream pointer
+ * @param[in] cachelist        cache list pointer
+ */
+void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist);
+
+/**
+ * handle TargetID request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist        cache list pointer
+ */
+void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
+
+/**
+ * handle ChannelID request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist        cache list pointer
+ */
+void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
+
+/**
+ * handle distroy ChannelID message
+ *
+ * @param[in]     connected_socket socket descriptor
+ * @param[in,out] cachelist        cache list pointer
+ */
+void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
+
+/**
+ * handle saving JP2 file request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist        cache list pointer
+ * @param[in] msgqueue         message queue pointer
+ * @param[in] jpipstream       address of caching jpipstream pointer
+ */
+void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream);
+
+bool handle_clientmsg( SOCKET connected_socket, cachelist_param_t *cachelist, Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue)
+{
+  bool quit = false;
+  msgtype_t msgtype = identify_clientmsg( connected_socket);
+  
+  switch( msgtype){
+  case JPIPSTREAM:
+    handle_JPIPstreamMSG( connected_socket, cachelist, jpipstream, streamlen, msgqueue);
+    break;
+      
+  case PNMREQ:
+    handle_PNMreqMSG( connected_socket, *jpipstream, msgqueue, cachelist);
+    break;
+    
+  case XMLREQ:
+    handle_XMLreqMSG( connected_socket, *jpipstream, cachelist);
+    break;
+
+  case TIDREQ:
+    handle_TIDreqMSG( connected_socket, cachelist);
+    break;
+                                               
+  case CIDREQ:
+    handle_CIDreqMSG( connected_socket, cachelist);
+    break;
+
+  case CIDDST:
+    handle_dstCIDreqMSG( connected_socket, cachelist);
+    break;
+
+  case JP2SAVE:
+    handle_JP2saveMSG( connected_socket, cachelist, msgqueue, *jpipstream);
+    break;
+
+  case QUIT:
+    quit = true;
+    save_codestream( *jpipstream, *streamlen, "jpt");
+    break;
+  case MSGERROR:
+    break;
+  }
+        
+  printf("\t end of the connection\n\n");
+  if( close_socket(connected_socket) != 0){
+    perror("close");
+    return false;
+  }
+  if( quit)
+    return false;
+
+  return true;
+}
+
+
+void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist,
+                          Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue)
+{
+  Byte_t *newjpipstream;
+  int newstreamlen = 0;
+  cache_param_t *cache;
+  char target[MAX_LENOFTARGET], tid[MAX_LENOFTID], cid[MAX_LENOFCID];
+  metadatalist_param_t *metadatalist;
+  
+  newjpipstream = receive_JPIPstream( connected_socket, target, tid, cid, &newstreamlen);
+
+  parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
+
+  *jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
+  free( newjpipstream);
+
+  metadatalist = gene_metadatalist();
+  parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist);
+
+  // cid registration
+  if( target[0] != 0){
+    if((cache = search_cache( target, cachelist))){
+      if( tid[0] != 0)
+       update_cachetid( tid, cache);
+      if( cid[0] != 0)
+       add_cachecid( cid, cache);
+    }
+    else{
+      cache = gene_cache( target, msgqueue->last->csn, tid, cid);
+      insert_cache_into_list( cache, cachelist);
+    }
+  }
+  else
+    cache = search_cacheBycsn( msgqueue->last->csn, cachelist);
+
+  if( cache->metadatalist)
+    delete_metadatalist( &cache->metadatalist);
+  cache->metadatalist = metadatalist;
+
+  response_signal( connected_socket, true);
+}
+
+void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist)
+{
+  Byte_t *pnmstream;
+  ihdrbox_param_t *ihdrbox;
+  char cid[MAX_LENOFCID], tmp[10];
+  cache_param_t *cache;
+  int fw, fh;
+
+  receive_line( connected_socket, cid);
+  if(!(cache = search_cacheBycid( cid, cachelist)))
+    if(!(cache = search_cacheBytid( cid, cachelist)))
+      return;
+
+  receive_line( connected_socket, tmp);
+  fw = atoi( tmp);
+  
+  receive_line( connected_socket, tmp);
+  fh = atoi( tmp);
+
+  pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox);
+  ihdrbox = cache->ihdrbox;
+
+  send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1);
+
+  free( pnmstream);
+}
+
+void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist)
+{
+  char cid[MAX_LENOFCID];
+  cache_param_t *cache;
+
+  receive_line( connected_socket, cid);
+  if(!(cache = search_cacheBycid( cid, cachelist)))
+    return;
+  
+  boxcontents_param_t *boxcontents = cache->metadatalist->last->boxcontents;
+  Byte_t *xmlstream = (Byte_t *)malloc( boxcontents->length);
+  memcpy( xmlstream, jpipstream+boxcontents->offset, boxcontents->length);
+  send_XMLstream( connected_socket, xmlstream, boxcontents->length);
+  free( xmlstream);
+}
+
+void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+  char target[MAX_LENOFTARGET], *tid = NULL;
+  cache_param_t *cache;
+  int tidlen = 0;
+
+  receive_line( connected_socket, target);
+  cache = search_cache( target, cachelist);
+  
+  if( cache){
+    tid = cache->tid;
+    tidlen = strlen(tid);
+  }
+  send_TIDstream( connected_socket, tid, tidlen);
+}
+
+void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+  char target[MAX_LENOFTARGET], *cid = NULL;
+  cache_param_t *cache;
+  int cidlen = 0;
+
+  receive_line( connected_socket, target);
+  cache = search_cache( target, cachelist);
+  
+  if( cache){
+    if( cache->numOfcid > 0){
+      cid = cache->cid[ cache->numOfcid-1];
+      cidlen = strlen(cid);
+    }
+  }
+  send_CIDstream( connected_socket, cid, cidlen);
+}
+
+void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+  char cid[MAX_LENOFCID];
+
+  receive_line( connected_socket, cid);
+  remove_cachecid( cid, cachelist);
+  response_signal( connected_socket, true);
+}
+
+void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream)
+{
+  char cid[MAX_LENOFCID];
+  cache_param_t *cache;
+  Byte_t *jp2stream;
+  Byte8_t jp2len;
+
+  receive_line( connected_socket, cid);
+  if(!(cache = search_cacheBycid( cid, cachelist)))
+    return;
+  
+  jp2stream = recons_jp2( msgqueue, jpipstream, cache->csn, &jp2len);
+
+  if( jp2stream){
+    save_codestream( jp2stream, jp2len, "jp2");
+    free( jp2stream);
+  }
+}
diff --git a/applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.h b/applications/jpip/opj_client/opj_dec_server/dec_clientmsg_handler.h
new file mode 100644 (file)
index 0000000..0170c16
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara 
+ * Copyright (c) 2011,      Lucian Corlaciu, GSoC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        DEC_CLIENTMSG_HANDLER_H_
+# define       DEC_CLIENTMSG_HANDLER_H_
+
+#include "bool.h"
+#include "imgsock_manager.h"
+#include "cache_manager.h"
+#include "byte_manager.h"
+#include "msgqueue_manager.h"
+
+/**
+ * handle client message
+ *
+ * @param[in]     connected_socket socket descriptor
+ * @param[in]     cachelist        cache list pointer
+ * @param[in,out] jpipstream       address of JPT- JPP- stream pointer
+ * @param[in,out] streamlen        address of stream length
+ * @param[in,out] msgqueue         message queue pointer
+ */
+bool handle_clientmsg( SOCKET connected_socket, cachelist_param_t *cachelist, Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue);
+
+
+#endif             /* !DEC_CLIENTMSG_HANDLER_H_ */
index 4e6652aceb1f1ef027277c22b7dbf2d1bc046c4d..ccc2b04c8976b68032125c63b4ac16ad2d73ab32 100644 (file)
@@ -56,7 +56,7 @@ SOCKET open_listeningsocket()
   struct sockaddr_in sin;
   int sock_optval = 1;
   int port = 5000;
-
+  
   listening_socket = socket(AF_INET, SOCK_STREAM, 0);
   if ( listening_socket == -1 ){
     perror("socket");
@@ -76,13 +76,13 @@ SOCKET open_listeningsocket()
 
   if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){
     perror("bind");
-    closesocket(listening_socket);
+    close_socket(listening_socket);
     exit(1);
   }
 
   if( listen(listening_socket, SOMAXCONN) == -1){
     perror("listen");
-    closesocket(listening_socket);
+    close_socket(listening_socket);
     exit(1);
   }
   printf("port %d is listened\n", port);
@@ -90,6 +90,14 @@ SOCKET open_listeningsocket()
   return listening_socket;
 }
 
+SOCKET accept_socket( SOCKET listening_socket)
+{
+  struct sockaddr_in peer_sin;
+  unsigned int addrlen = sizeof(peer_sin);
+
+  return accept( listening_socket, (struct sockaddr *)&peer_sin, &addrlen);
+}
+
 msgtype_t identify_clientmsg( SOCKET connected_socket)
 {
   int receive_size;
@@ -285,3 +293,12 @@ void response_signal( SOCKET connected_socket, bool succeed)
   if( send( connected_socket, &code, 1, 0) != 1)
     fprintf( stderr, "Response signalling error\n");
 }
+
+int close_socket( SOCKET sock)
+{
+#ifdef _WIN32
+  return closesocket( sock);
+#else
+  return close( sock);
+#endif
+}
index 713c099ecb0fd7e26063324ec7e8b4ddfdfc2d8f..bb8e1bcf682fec9e004595b3bc965048587f96da 100644 (file)
@@ -38,7 +38,6 @@
 #include <winsock2.h>
 #else
 typedef int SOCKET;
-#define closesocket close
 #endif //_WIN32
 
 /**
@@ -48,6 +47,15 @@ typedef int SOCKET;
  */
 SOCKET open_listeningsocket();
 
+/**
+ * accept a new connection to the listenning socket
+ *
+ * @param listening_socket listenning socket
+ * @return                 connected socket (-1 if error occurs)
+ */
+SOCKET accept_socket( SOCKET listening_socket);
+
+
 #define NUM_OF_MSGTYPES 8
 typedef enum eMSGTYPE{ JPIPSTREAM, PNMREQ, XMLREQ, TIDREQ, CIDREQ, CIDDST, JP2SAVE, QUIT, MSGERROR} msgtype_t;
 
@@ -125,8 +133,16 @@ void response_signal( SOCKET connected_socket, bool succeed);
  * @param [out] buf              string to be stored
  * @return                       red size
  */
-
 int receive_line(SOCKET connected_socket, char *buf);
+
+/**
+ * close socket
+ *
+ * @param [in] sock closing socket
+ * @return     0 if succeed, -1 if failed
+ */
+int close_socket( SOCKET sock);
+
 #endif /* !IMGSOCK_MANAGER_H_ */
 
 /*! \file
index 5786397e4358c53af9698e3d79e6b6e3462979b6..6e8957a285000245d7bcc0ffabe4a9f5da351190 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#include "dec_clientmsg_handler.h"
+#include "imgsock_manager.h"
 #include "byte_manager.h"
 #include "msgqueue_manager.h"
-#include "ihdrbox_manager.h"
-#include "imgsock_manager.h"
-#include "jpipstream_manager.h"
 #include "cache_manager.h"
-#include "jp2k_encoder.h"
+
 
 #ifdef _WIN32
 WSADATA initialisation_win32;
-#else
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#endif //_WIN32
-
-//! maximum length of target name
-#define MAX_LENOFTARGET 128
-
-//! maximum length of channel identifier
-#define MAX_LENOFCID 30
-
-/**
- * handle JPT- JPP- stream message
- *
- * @param[in]     connected_socket socket descriptor
- * @param[in]     cachelist        cache list pointer
- * @param[in,out] jpipstream       address of JPT- JPP- stream pointer
- * @param[in,out] streamlen        address of stream length
- * @param[in,out] msgqueue         message queue pointer
- */
-void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist, Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue);
-
-/**
- * handle PNM request message
- *
- * @param[in] connected_socket socket descriptor
- * @param[in] jpipstream       jpipstream pointer
- * @param[in] msgqueue         message queue pointer
- * @param[in] cachelist        cache list pointer
- */
-void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist);
-
-/**
- * handle XML request message
- *
- * @param[in] connected_socket socket descriptor
- * @param[in] jpipstream       address of caching jpipstream pointer
- * @param[in] cachelist        cache list pointer
- */
-void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist);
-
-/**
- * handle TargetID request message
- *
- * @param[in] connected_socket socket descriptor
- * @param[in] cachelist        cache list pointer
- */
-void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
-
-/**
- * handle ChannelID request message
- *
- * @param[in] connected_socket socket descriptor
- * @param[in] cachelist        cache list pointer
- */
-void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
-
-/**
- * handle distroy ChannelID message
- *
- * @param[in]     connected_socket socket descriptor
- * @param[in,out] cachelist        cache list pointer
- */
-void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
-
-/**
- * handle saving JP2 file request message
- *
- * @param[in] connected_socket socket descriptor
- * @param[in] cachelist        cache list pointer
- * @param[in] msgqueue         message queue pointer
- * @param[in] jpipstream       address of caching jpipstream pointer
- */
-void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream);
+#endif
 
 int main(int argc, char *argv[]){
-
+  
   SOCKET connected_socket;
-  struct sockaddr_in peer_sin;
   Byte_t *jpipstream = NULL;
   int jpipstreamlen = 0;
   msgqueue_param_t *msgqueue = gene_msgqueue( true, NULL);
-  bool quit = false;
 
 #ifdef _WIN32
   int erreur = WSAStartup(MAKEWORD(2,2),&initialisation_win32);
@@ -151,60 +72,15 @@ int main(int argc, char *argv[]){
     printf( "Initialisation Winsock\n");
 #endif //_WIN32
   
-  int listening_socket = open_listeningsocket();
+  SOCKET listening_socket = open_listeningsocket();
   
-  unsigned int addrlen = sizeof(peer_sin);
-
   cachelist_param_t *cachelist = gene_cachelist();
   
-  while(( connected_socket = accept(listening_socket, (struct sockaddr *)&peer_sin, &addrlen))!=-1 ){
-    msgtype_t msgtype = identify_clientmsg( connected_socket);
-    
-    switch( msgtype){
-    case JPIPSTREAM:
-      handle_JPIPstreamMSG( connected_socket, cachelist, &jpipstream, &jpipstreamlen, msgqueue);
-      break;
-      
-    case PNMREQ:
-      handle_PNMreqMSG( connected_socket, jpipstream, msgqueue, cachelist);
-      break;
-    
-    case XMLREQ:
-      handle_XMLreqMSG( connected_socket, jpipstream, cachelist);
-      break;
-
-    case TIDREQ:
-      handle_TIDreqMSG( connected_socket, cachelist);
-      break;
-                                               
-    case CIDREQ:
-      handle_CIDreqMSG( connected_socket, cachelist);
-      break;
-
-    case CIDDST:
-      handle_dstCIDreqMSG( connected_socket, cachelist);
-      break;
-
-    case JP2SAVE:
-      handle_JP2saveMSG( connected_socket, cachelist, msgqueue, jpipstream);
-      break;
-
-    case QUIT:
-      quit = true;
-      break;
-    case MSGERROR:
-      break;
-    }
-        
-    printf("\t end of the connection\n\n");
-    if( closesocket(connected_socket) != 0){
-      perror("close");
-      return -1;
-    }
-    if( quit)
+  while(( connected_socket = accept_socket( listening_socket)) != -1 )
+    if(!(handle_clientmsg( connected_socket, cachelist, &jpipstream, &jpipstreamlen, msgqueue)))
       break;
-  }
-  if( closesocket(listening_socket) != 0){
+  
+  if( close_socket(listening_socket) != 0){
     perror("close");
     return -1;
   }
@@ -214,7 +90,6 @@ int main(int argc, char *argv[]){
   if( msgqueue)
     delete_msgqueue( &msgqueue);
   
-  //save_codestream( jpipstream, jpipstreamlen, "jpt");
   free( jpipstream);
 
 #ifdef _WIN32
@@ -227,150 +102,3 @@ int main(int argc, char *argv[]){
 
   return 0;
 }
-
-void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist,
-                          Byte_t **jpipstream, int *streamlen, msgqueue_param_t *msgqueue)
-{
-  Byte_t *newjpipstream;
-  int newstreamlen = 0;
-  cache_param_t *cache;
-  char target[MAX_LENOFTARGET], tid[MAX_LENOFTID], cid[MAX_LENOFCID];
-  metadatalist_param_t *metadatalist;
-  
-  newjpipstream = receive_JPIPstream( connected_socket, target, tid, cid, &newstreamlen);
-
-  parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
-
-  *jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
-  free( newjpipstream);
-
-  metadatalist = gene_metadatalist();
-  parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist);
-
-  // cid registration
-  if( target[0] != 0){
-    if((cache = search_cache( target, cachelist))){
-      if( tid[0] != 0)
-       update_cachetid( tid, cache);
-      if( cid[0] != 0)
-       add_cachecid( cid, cache);
-    }
-    else{
-      cache = gene_cache( target, msgqueue->last->csn, tid, cid);
-      insert_cache_into_list( cache, cachelist);
-    }
-  }
-  else
-    cache = search_cacheBycsn( msgqueue->last->csn, cachelist);
-
-  if( cache->metadatalist)
-    delete_metadatalist( &cache->metadatalist);
-  cache->metadatalist = metadatalist;
-
-  response_signal( connected_socket, true);
-}
-
-void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist)
-{
-  Byte_t *pnmstream;
-  ihdrbox_param_t *ihdrbox;
-  char cid[MAX_LENOFCID], tmp[10];
-  cache_param_t *cache;
-  int fw, fh;
-
-  receive_line( connected_socket, cid);
-  if(!(cache = search_cacheBycid( cid, cachelist)))
-    if(!(cache = search_cacheBytid( cid, cachelist)))
-      return;
-
-  receive_line( connected_socket, tmp);
-  fw = atoi( tmp);
-  
-  receive_line( connected_socket, tmp);
-  fh = atoi( tmp);
-
-  pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox);
-  ihdrbox = cache->ihdrbox;
-
-  send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1);
-
-  free( pnmstream);
-}
-
-void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist)
-{
-  char cid[MAX_LENOFCID];
-  cache_param_t *cache;
-
-  receive_line( connected_socket, cid);
-  if(!(cache = search_cacheBycid( cid, cachelist)))
-    return;
-  
-  boxcontents_param_t *boxcontents = cache->metadatalist->last->boxcontents;
-  Byte_t *xmlstream = (Byte_t *)malloc( boxcontents->length);
-  memcpy( xmlstream, jpipstream+boxcontents->offset, boxcontents->length);
-  send_XMLstream( connected_socket, xmlstream, boxcontents->length);
-  free( xmlstream);
-}
-
-void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
-{
-  char target[MAX_LENOFTARGET], *tid = NULL;
-  cache_param_t *cache;
-  int tidlen = 0;
-
-  receive_line( connected_socket, target);
-  cache = search_cache( target, cachelist);
-  
-  if( cache){
-    tid = cache->tid;
-    tidlen = strlen(tid);
-  }
-  send_TIDstream( connected_socket, tid, tidlen);
-}
-
-void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
-{
-  char target[MAX_LENOFTARGET], *cid = NULL;
-  cache_param_t *cache;
-  int cidlen = 0;
-
-  receive_line( connected_socket, target);
-  cache = search_cache( target, cachelist);
-  
-  if( cache){
-    if( cache->numOfcid > 0){
-      cid = cache->cid[ cache->numOfcid-1];
-      cidlen = strlen(cid);
-    }
-  }
-  send_CIDstream( connected_socket, cid, cidlen);
-}
-
-void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
-{
-  char cid[MAX_LENOFCID];
-
-  receive_line( connected_socket, cid);
-  remove_cachecid( cid, cachelist);
-  response_signal( connected_socket, true);
-}
-
-void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream)
-{
-  char cid[MAX_LENOFCID];
-  cache_param_t *cache;
-  Byte_t *jp2stream;
-  Byte8_t jp2len;
-
-  receive_line( connected_socket, cid);
-  if(!(cache = search_cacheBycid( cid, cachelist)))
-    return;
-  
-  jp2stream = recons_jp2( msgqueue, jpipstream, cache->csn, &jp2len);
-
-  if( jp2stream){
-    save_codestream( jp2stream, jp2len, "jp2");
-    free( jp2stream);
-  }
-}
diff --git a/applications/jpip/opj_client/opj_viewer/dist/opj_viewer-20111018.jar b/applications/jpip/opj_client/opj_viewer/dist/opj_viewer-20111018.jar
new file mode 100644 (file)
index 0000000..a17ca3b
Binary files /dev/null and b/applications/jpip/opj_client/opj_viewer/dist/opj_viewer-20111018.jar differ
index 2c3fead77e5aa94e2740c0961831c802da07c8cb..b135bb0f327da642c0383ba25038e8f723c8b64f 120000 (symlink)
@@ -1 +1 @@
-opj_viewer-20111007.jar
\ No newline at end of file
+opj_viewer-20111018.jar
\ No newline at end of file
index 29007e1b7c73a9135941bb6b5adc081c71e50dcf..e0ed5469f7454af4aa085611f651f5b0b725f2b8 100644 (file)
@@ -10,6 +10,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/opj_server.c
 ${CMAKE_CURRENT_SOURCE_DIR}/query_parser.c
 ${CMAKE_CURRENT_SOURCE_DIR}/channel_manager.c
 ${CMAKE_CURRENT_SOURCE_DIR}/session_manager.c
+${CMAKE_CURRENT_SOURCE_DIR}/jpip_parser.c
 )
 
 # Build executable
index 9fa75b7942c5ed5ed1b7a2f72068273bbf41fc51..cb03c9ced22c5ba75f48baa6c2d7b4180aafd4a9 100644 (file)
@@ -18,9 +18,11 @@ channel_manager.c \
 opj_server.c \
 query_parser.c \
 session_manager.c \
+jpip_parser.c \
 channel_manager.h \
 query_parser.h \
-session_manager.h
+session_manager.h \
+jpip_parser.h
 
 install-data-hook:
        @echo -e " (B)\t$(bindir)/opj_server$(EXEEXT)" >> $(top_builddir)/report.txt
index 3df9a6ee2afa60c3a4d280a43e31bebc7b67c829..ac2389b49f16e5f2916b03376fe6bdf985b4ae49 100644 (file)
@@ -8,8 +8,8 @@ ALL = opj_server
 
 all: $(ALL)
 
-opj_server: opj_server.o query_parser.o channel_manager.o session_manager.o $(LIBFNAME)
-         $(CC) $(CFLAGS) $< query_parser.o channel_manager.o session_manager.o $(LDFLAGS) -o $@
+opj_server: opj_server.o query_parser.o channel_manager.o session_manager.o jpip_parser.o $(LIBFNAME)
+         $(CC) $(CFLAGS) $< query_parser.o channel_manager.o session_manager.o jpip_parser.o $(LDFLAGS) -o $@
 
 clean:
        rm -f $(ALL) *.o *~
diff --git a/applications/jpip/opj_server/jpip_parser.c b/applications/jpip/opj_server/jpip_parser.c
new file mode 100644 (file)
index 0000000..9b49a36
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara 
+ * Copyright (c) 2011,      Lucian Corlaciu, GSoC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "jpip_parser.h"
+#include "channel_manager.h"
+#include "imgreg_manager.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif //SERVER
+
+/**
+ * REQUEST: target identification by target or tid request
+ *
+ * @param[in]     query_param   structured query
+ * @param[in]     targetlist    target list pointer
+ * @param[out]    target        address of target pointer
+ * @return                      if succeeded (true) or failed (false)
+ */
+bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target);
+
+/**
+ * REQUEST: channel association
+ *          this must be processed before any process
+ *
+ * @param[in]     query_param   structured query
+ * @param[in]     sessionlist   session list pointer
+ * @param[out]    cursession    address of the associated session pointer
+ * @param[out]    curchannel    address of the associated channel pointer
+ * @return                      if succeeded (true) or failed (false)
+ */
+bool associate_channel( query_param_t    query_param, 
+                       sessionlist_param_t *sessionlist,
+                       session_param_t **cursession, 
+                       channel_param_t **curchannel);
+/**
+ * REQUEST: new channel (cnew) assignment
+ *
+ * @param[in]     query_param   structured query
+ * @param[in]     sessionlist   session list pointer
+ * @param[in]     target        requested target pointer
+ * @param[in,out] cursession    address of the associated/opened session pointer
+ * @param[in,out] curchannel    address of the associated/opened channel pointer
+ * @return                      if succeeded (true) or failed (false)
+ */
+bool open_channel( query_param_t query_param, 
+                  sessionlist_param_t *sessionlist,
+                  target_param_t *target,
+                  session_param_t **cursession, 
+                  channel_param_t **curchannel);
+
+/**
+ * REQUEST: channel close (cclose)
+ *
+ * @param[in]     query_param   structured query
+ * @param[in]     sessionlist   session list pointer
+ * @param[in,out] cursession    address of the session pointer of deleting channel
+ * @param[in,out] curchannel    address of the deleting channel pointer
+ * @return                      if succeeded (true) or failed (false)
+ */
+bool close_channel( query_param_t query_param, 
+                   sessionlist_param_t *sessionlist,
+                   session_param_t **cursession, 
+                   channel_param_t **curchannel);
+
+/**
+ * REQUEST: view-window (fsiz)
+ *
+ * @param[in]     query_param structured query
+ * @param[in]     target      requested target pointer
+ * @param[in,out] cursession  associated session pointer
+ * @param[in,out] curchannel  associated channel pointer
+ * @param[out]    msgqueue    address of the message queue pointer
+ * @return                    if succeeded (true) or failed (false)
+ */
+bool gene_JPIPstream( query_param_t query_param,
+                    target_param_t *target,
+                    session_param_t *cursession, 
+                    channel_param_t *curchannel,
+                    msgqueue_param_t **msgqueue);
+
+bool parse_JPIPrequest( query_param_t query_param,
+                       sessionlist_param_t *sessionlist,
+                       targetlist_param_t *targetlist,
+                       msgqueue_param_t **msgqueue)
+{ 
+  target_param_t *target = NULL;
+  session_param_t *cursession = NULL;
+  channel_param_t *curchannel = NULL;
+
+  if( query_param.target[0] != '\0' || query_param.tid[0] != '\0'){
+    if( !identify_target( query_param, targetlist, &target))
+      return false;
+  }
+
+  if( query_param.cid[0] != '\0'){
+    if( !associate_channel( query_param, sessionlist, &cursession, &curchannel))
+      return false;
+  }
+
+  if( query_param.cnew){
+    if( !open_channel( query_param, sessionlist, target, &cursession, &curchannel))
+      return false;
+  }
+  if( query_param.cclose[0][0] != '\0')
+    if( !close_channel( query_param, sessionlist, &cursession, &curchannel))
+      return false;
+  
+  if( (query_param.fx > 0 && query_param.fy > 0) || query_param.box_type[0][0] != 0)
+    if( !gene_JPIPstream( query_param, target, cursession, curchannel, msgqueue))
+      return false;
+  
+  return true;
+}
+
+bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target)
+{
+  if( query_param.tid[0] !='\0' && strcmp( query_param.tid, "0") != 0 ){
+    if( query_param.cid[0] != '\0'){
+      fprintf( FCGI_stdout, "Reason: Target can not be specified both through tid and cid\r\n");
+      fprintf( FCGI_stdout, "Status: 400\r\n");
+      return false;
+    }
+    if( ( *target = search_targetBytid( query_param.tid, targetlist)))
+      return true;
+  }
+
+  if( query_param.target[0] !='\0')
+    if( !( *target = search_target( query_param.target, targetlist)))
+      if(!( *target = gene_target( targetlist, query_param.target)))
+       return false;
+
+  if( *target){
+    fprintf( FCGI_stdout, "JPIP-tid: %s\r\n", (*target)->tid);
+    return true;
+  }
+  else{
+    fprintf( FCGI_stdout, "Reason: target not found\r\n");
+    fprintf( FCGI_stdout, "Status: 400\r\n");
+    return false;
+  }
+}
+
+bool associate_channel( query_param_t    query_param, 
+                       sessionlist_param_t *sessionlist,
+                       session_param_t **cursession, 
+                       channel_param_t **curchannel)
+{
+  if( search_session_and_channel( query_param.cid, sessionlist, cursession, curchannel)){
+    
+    if( !query_param.cnew)
+      set_channel_variable_param( query_param, *curchannel);
+  }
+  else{
+    fprintf( FCGI_stderr, "Error: process canceled\n");
+    return false;
+  }
+  return true;
+}
+
+bool open_channel( query_param_t query_param, 
+                  sessionlist_param_t *sessionlist,
+                  target_param_t *target,
+                  session_param_t **cursession, 
+                  channel_param_t **curchannel)
+{
+  cachemodel_param_t *cachemodel = NULL;
+
+  if( target){
+    if( !(*cursession))
+      *cursession = gene_session( sessionlist);
+    if( !( cachemodel = search_cachemodel( target, (*cursession)->cachemodellist)))
+      if( !(cachemodel = gene_cachemodel( (*cursession)->cachemodellist, target, query_param.return_type==JPPstream)))
+       return false;
+  }
+  else
+    if( *curchannel)
+      cachemodel = (*curchannel)->cachemodel;
+
+  *curchannel = gene_channel( query_param, cachemodel, (*cursession)->channellist);
+  if( *curchannel == NULL)
+    return false;
+
+  return true;
+}
+
+bool close_channel( query_param_t query_param, 
+                   sessionlist_param_t *sessionlist,
+                   session_param_t **cursession, 
+                   channel_param_t **curchannel)
+{
+  if( query_param.cclose[0][0] =='*'){
+#ifndef SERVER
+    fprintf( logstream, "local log: close all\n");
+#endif
+    // all channels associatd with the session will be closed
+    if( !delete_session( cursession, sessionlist))
+      return false;
+  }
+  else{
+    // check if all entry belonging to the same session
+    int i=0;
+    while( query_param.cclose[i][0] !='\0'){
+      
+      // In case of the first entry of close cid
+      if( *cursession == NULL){
+       if( !search_session_and_channel( query_param.cclose[i], sessionlist, cursession, curchannel))
+         return false;
+      }
+      else // second or more entry of close cid
+       if( !(*curchannel=search_channel( query_param.cclose[i], (*cursession)->channellist))){
+         fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", query_param.cclose[i]); 
+         return false;
+       }
+      i++;
+    }
+    // delete channels
+    i=0;
+    while( query_param.cclose[i][0] !='\0'){
+      
+      *curchannel = search_channel( query_param.cclose[i], (*cursession)->channellist);
+      delete_channel( curchannel, (*cursession)->channellist);
+      i++;
+    }
+    
+    if( (*cursession)->channellist->first == NULL || (*cursession)->channellist->last == NULL)
+      // In case of empty session
+      delete_session( cursession, sessionlist);
+  }
+  return true;
+}
+
+
+/**
+ * enqueue tiles or precincts into the message queue
+ *
+ * @param[in] query_param structured query
+ * @param[in] msgqueue    message queue pointer  
+ */
+void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue);
+
+/**
+ * enqueue metadata bins into the message queue
+ *
+ * @param[in]     query_param  structured query
+ * @param[in]     metadatalist pointer to metadata bin list
+ * @param[in,out] msgqueue     message queue pointer  
+ */
+void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
+
+
+bool gene_JPIPstream( query_param_t query_param,
+                     target_param_t *target,
+                     session_param_t *cursession, 
+                     channel_param_t *curchannel,
+                     msgqueue_param_t **msgqueue)
+{
+  index_param_t *codeidx;
+  cachemodel_param_t *cachemodel;
+  
+  if( !cursession || !curchannel){ // stateless
+    if( !target)
+      return false;
+    if( !(cachemodel = gene_cachemodel( NULL, target, query_param.return_type==JPPstream)))
+      return false;
+    *msgqueue = gene_msgqueue( true, cachemodel);
+  }
+  else{ // session
+    cachemodel  = curchannel->cachemodel;
+    target = cachemodel->target;
+    *msgqueue = gene_msgqueue( false, cachemodel);
+  }
+  
+  codeidx = target->codeidx;
+
+  if( cachemodel->jppstream)
+    fprintf( FCGI_stdout, "Content-type: image/jpp-stream\r\n");
+  else
+    fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
+  
+  if( query_param.layers != -1){
+    if( query_param.layers  > codeidx->COD.numOflayers){
+      fprintf( FCGI_stdout, "JPIP-layers: %d\r\n", codeidx->COD.numOflayers);
+      query_param.layers = codeidx->COD.numOflayers;
+    }
+  }
+
+  //meta
+  if( query_param.box_type[0][0] != 0  && query_param.len != 0)
+    enqueue_metabins( query_param, codeidx->metadatalist, *msgqueue); 
+
+  // image codestream
+  if( query_param.fx > 0 && query_param.fy > 0){
+    if( !cachemodel->mhead_model && query_param.len != 0)
+      enqueue_mainheader( *msgqueue);
+    enqueue_imagedata( query_param, *msgqueue);
+  }
+  return true;
+}
+
+
+/**
+ * enqueue precinct data-bins into the queue
+ *
+ * @param[in] xmin      min x coordinate in the tile at the decomposition level
+ * @param[in] xmax      max x coordinate in the tile at the decomposition level
+ * @param[in] ymin      min y coordinate in the tile at the decomposition level
+ * @param[in] ymax      max y coordinate in the tile at the decomposition level
+ * @param[in] tile_id   tile index
+ * @param[in] level     decomposition level
+ * @param[in] lastcomp  last component number
+ * @param[in] comps     pointer to the array that stores the requested components
+ * @param[in] layers    number of quality layers
+ * @param[in] msgqueue  message queue
+ * @return
+ */
+void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue);
+
+/**
+ * enqueue all precincts inside a tile into the queue
+ *
+ * @param[in] tile_id   tile index
+ * @param[in] level     decomposition level
+ * @param[in] lastcomp  last component number
+ * @param[in] comps     pointer to the array that stores the requested components
+ * @param[in] layers    number of quality layers
+ * @param[in] msgqueue  message queue
+ * @return
+ */
+void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue);
+
+void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue)
+{
+  index_param_t *codeidx;
+  imgreg_param_t imgreg;
+  range_param_t tile_Xrange, tile_Yrange;
+  int u, v, tile_id;
+  int xmin, xmax, ymin, ymax;
+  int numOfreslev;
+
+  codeidx = msgqueue->cachemodel->target->codeidx;
+
+  if( !(msgqueue->cachemodel->jppstream)  &&  get_nmax( codeidx->tilepart) == 1) // normally not the case
+    numOfreslev = 1;
+  else
+    numOfreslev = codeidx->COD.numOfdecomp+1;
+
+  imgreg  = map_viewin2imgreg( query_param.fx, query_param.fy, 
+                              query_param.rx, query_param.ry, query_param.rw, query_param.rh,
+                              codeidx->SIZ.XOsiz, codeidx->SIZ.YOsiz, codeidx->SIZ.Xsiz, codeidx->SIZ.Ysiz, 
+                              numOfreslev );
+
+  if( query_param.len == 0)
+    return;
+
+  for( u=0, tile_id=0; u<codeidx->SIZ.YTnum; u++){
+    tile_Yrange = get_tile_Yrange( codeidx->SIZ, tile_id, imgreg.level);
+    
+    for( v=0; v<codeidx->SIZ.XTnum; v++, tile_id++){
+      tile_Xrange = get_tile_Xrange( codeidx->SIZ, tile_id, imgreg.level);
+       
+      if( tile_Xrange.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
+       if( tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox || 
+           tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox + imgreg.sx ||
+           tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy || 
+           tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy + imgreg.sy) {
+         //printf("Tile completely excluded from view-window %d\n", tile_id);
+         // Tile completely excluded from view-window
+       }
+       else if( tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox && 
+                tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx && 
+                tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy && 
+                tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy) {
+         // Tile completely contained within view-window
+         // high priority
+         //printf("Tile completely contained within view-window %d\n", tile_id);
+         if( msgqueue->cachemodel->jppstream){
+           enqueue_tileheader( tile_id, msgqueue);
+           enqueue_allprecincts( tile_id, imgreg.level, query_param.lastcomp, query_param.comps, query_param.layers, msgqueue);
+         }
+         else
+           enqueue_tile( tile_id, imgreg.level, msgqueue);
+       }
+       else{
+         // Tile partially overlaps view-window
+         // low priority
+         //printf("Tile partially overlaps view-window %d\n", tile_id);
+         if( msgqueue->cachemodel->jppstream){
+           enqueue_tileheader( tile_id, msgqueue);
+
+           xmin = tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox ? 0 : imgreg.xosiz + imgreg.ox - tile_Xrange.minvalue;
+           xmax = tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx ? tile_Xrange.maxvalue - tile_Xrange.minvalue -1 : imgreg.xosiz + imgreg.ox + imgreg.sx - tile_Xrange.minvalue -1;
+           ymin = tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy ? 0 : imgreg.yosiz + imgreg.oy - tile_Yrange.minvalue;
+           ymax = tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy ? tile_Yrange.maxvalue - tile_Yrange.minvalue -1 : imgreg.yosiz + imgreg.oy + imgreg.sy - tile_Yrange.minvalue -1;
+           enqueue_precincts( xmin, xmax, ymin, ymax, tile_id, imgreg.level, query_param.lastcomp, query_param.comps, query_param.layers, msgqueue);
+         }
+         else
+           enqueue_tile( tile_id, imgreg.level, msgqueue);
+       }
+      }
+    }
+  }
+}
+
+
+void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue)
+{
+  index_param_t *codeidx;
+  int c, u, v, res_lev, dec_lev;
+  int seq_id;
+  Byte4_t XTsiz, YTsiz;
+  Byte4_t XPsiz, YPsiz;
+  Byte4_t xminP, xmaxP, yminP, ymaxP;
+
+  codeidx  = msgqueue->cachemodel->target->codeidx;
+
+  for( c=0; c<codeidx->SIZ.Csiz; c++)
+    if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
+      seq_id = 0;
+      for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
+       
+       XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
+       YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
+       
+       XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
+       YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
+         
+       for( u=0; u<ceil((double)YTsiz/(double)YPsiz); u++){
+         yminP = u*YPsiz;
+         ymaxP = (u+1)*YPsiz-1;
+         if( YTsiz <= ymaxP)
+           ymaxP = YTsiz-1;
+         
+         for( v=0; v<ceil((double)XTsiz/(double)XPsiz); v++, seq_id++){
+           xminP = v*XPsiz;
+           xmaxP = (v+1)*XPsiz-1;
+           if( XTsiz <= xmaxP)
+             xmaxP = XTsiz-1;
+           
+           if( xmaxP < xmin || xminP > xmax || ymaxP < ymin || yminP > ymax){
+             // Precinct completely excluded from view-window
+           }
+           else if( xminP >= xmin && xmaxP <= xmax && yminP >= ymin && ymaxP <= ymax){
+             // Precinct completely contained within view-window
+             // high priority
+             enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+           }
+           else{
+             // Precinct partially overlaps view-window
+             // low priority
+             enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+           }
+         }
+       }
+      }
+    }
+}
+
+void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue)
+{
+  index_param_t *codeidx;
+  int c, i, res_lev, dec_lev;
+  int seq_id;
+  Byte4_t XTsiz, YTsiz;
+  Byte4_t XPsiz, YPsiz;
+
+  codeidx  = msgqueue->cachemodel->target->codeidx;
+
+  for( c=0; c<codeidx->SIZ.Csiz; c++)
+    if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
+      seq_id = 0;
+      for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
+       
+       XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
+       YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
+       
+       XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
+       YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
+       
+       for( i=0; i<ceil((double)YTsiz/(double)YPsiz)*ceil((double)XTsiz/(double)XPsiz); i++, seq_id++)
+         enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+      }
+    }
+}
+
+void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
+{
+  int i;
+  for( i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
+    if( query_param.box_type[i][0] == '*'){
+      // not implemented
+    }
+    else{
+      int idx = search_metadataidx( query_param.box_type[i], metadatalist);
+
+      if( idx != -1)
+       enqueue_metadata( idx, msgqueue);
+    }
+  }
+}
diff --git a/applications/jpip/opj_server/jpip_parser.h b/applications/jpip/opj_server/jpip_parser.h
new file mode 100644 (file)
index 0000000..bcb5edb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara 
+ * Copyright (c) 2011,      Lucian Corlaciu, GSoC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef        JPIP_PARSER_H_
+# define       JPIP_PARSER_H_
+
+#include "bool.h"
+#include "query_parser.h"
+#include "session_manager.h"
+#include "target_manager.h"
+#include "msgqueue_manager.h"
+
+/**
+ * parse JPIP request
+ *
+ * @param[in]     query_param   structured query
+ * @param[in]     sessionlist   session list pointer
+ * @param[in]     targetlist    target list pointer
+ * @param[in,out] msgqueue      address of the message queue pointer
+ * @return                      if succeeded (true) or failed (false)
+ */
+bool parse_JPIPrequest( query_param_t query_param,
+                       sessionlist_param_t *sessionlist,
+                       targetlist_param_t *targetlist,
+                       msgqueue_param_t **msgqueue);
+
+
+#endif             /* !JPIP_PARSER_H_ */
index a9778cd4a992d4930b41303720bfb393be0041d3..b39ad56eb8e234186daf04b65ed07d366230d37e 100644 (file)
 #include <math.h>
 
 #include "query_parser.h"
-#include "channel_manager.h"
+#include "jpip_parser.h"
 #include "session_manager.h"
 #include "target_manager.h"
-#include "imgreg_manager.h"
 #include "msgqueue_manager.h"
 
 #ifndef QUIT_SIGNAL
 #define logstream stderr
 #endif //SERVER
 
-/**
- * parse JPIP request
- *
- * @param[in]     query_param   structured query
- * @param[in]     sessionlist   session list pointer
- * @param[in]     targetlist    target list pointer
- * @param[in,out] msgqueue      address of the message queue pointer
- * @return                      if succeeded (true) or failed (false)
- */
-bool parse_JPIPrequest( query_param_t query_param,
-                       sessionlist_param_t *sessionlist,
-                       targetlist_param_t *targetlist,
-                       msgqueue_param_t **msgqueue);
-
 int main(void)
 { 
   sessionlist_param_t *sessionlist;
@@ -144,481 +129,3 @@ int main(void)
 
   return 0;
 }
-
-/**
- * REQUEST: target identification by target or tid request
- *
- * @param[in]     query_param   structured query
- * @param[in]     targetlist    target list pointer
- * @param[out]    target        address of target pointer
- * @return                      if succeeded (true) or failed (false)
- */
-bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target);
-
-/**
- * REQUEST: channel association
- *          this must be processed before any process
- *
- * @param[in]     query_param   structured query
- * @param[in]     sessionlist   session list pointer
- * @param[out]    cursession    address of the associated session pointer
- * @param[out]    curchannel    address of the associated channel pointer
- * @return                      if succeeded (true) or failed (false)
- */
-bool associate_channel( query_param_t    query_param, 
-                       sessionlist_param_t *sessionlist,
-                       session_param_t **cursession, 
-                       channel_param_t **curchannel);
-/**
- * REQUEST: new channel (cnew) assignment
- *
- * @param[in]     query_param   structured query
- * @param[in]     sessionlist   session list pointer
- * @param[in]     target        requested target pointer
- * @param[in,out] cursession    address of the associated/opened session pointer
- * @param[in,out] curchannel    address of the associated/opened channel pointer
- * @return                      if succeeded (true) or failed (false)
- */
-bool open_channel( query_param_t query_param, 
-                  sessionlist_param_t *sessionlist,
-                  target_param_t *target,
-                  session_param_t **cursession, 
-                  channel_param_t **curchannel);
-
-/**
- * REQUEST: channel close (cclose)
- *
- * @param[in]     query_param   structured query
- * @param[in]     sessionlist   session list pointer
- * @param[in,out] cursession    address of the session pointer of deleting channel
- * @param[in,out] curchannel    address of the deleting channel pointer
- * @return                      if succeeded (true) or failed (false)
- */
-bool close_channel( query_param_t query_param, 
-                   sessionlist_param_t *sessionlist,
-                   session_param_t **cursession, 
-                   channel_param_t **curchannel);
-
-/**
- * REQUEST: view-window (fsiz)
- *
- * @param[in]     query_param structured query
- * @param[in]     target      requested target pointer
- * @param[in,out] cursession  associated session pointer
- * @param[in,out] curchannel  associated channel pointer
- * @param[out]    msgqueue    address of the message queue pointer
- * @return                    if succeeded (true) or failed (false)
- */
-bool gene_JPIPstream( query_param_t query_param,
-                    target_param_t *target,
-                    session_param_t *cursession, 
-                    channel_param_t *curchannel,
-                    msgqueue_param_t **msgqueue);
-
-bool parse_JPIPrequest( query_param_t query_param,
-                       sessionlist_param_t *sessionlist,
-                       targetlist_param_t *targetlist,
-                       msgqueue_param_t **msgqueue)
-{ 
-  target_param_t *target = NULL;
-  session_param_t *cursession = NULL;
-  channel_param_t *curchannel = NULL;
-
-  if( query_param.target[0] != '\0' || query_param.tid[0] != '\0'){
-    if( !identify_target( query_param, targetlist, &target))
-      return false;
-  }
-
-  if( query_param.cid[0] != '\0'){
-    if( !associate_channel( query_param, sessionlist, &cursession, &curchannel))
-      return false;
-  }
-
-  if( query_param.cnew){
-    if( !open_channel( query_param, sessionlist, target, &cursession, &curchannel))
-      return false;
-  }
-  if( query_param.cclose[0][0] != '\0')
-    if( !close_channel( query_param, sessionlist, &cursession, &curchannel))
-      return false;
-  
-  if( (query_param.fx > 0 && query_param.fy > 0) || query_param.box_type[0][0] != 0)
-    if( !gene_JPIPstream( query_param, target, cursession, curchannel, msgqueue))
-      return false;
-  
-  return true;
-}
-
-bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target)
-{
-  if( query_param.tid[0] !='\0' && strcmp( query_param.tid, "0") != 0 ){
-    if( query_param.cid[0] != '\0'){
-      fprintf( FCGI_stdout, "Reason: Target can not be specified both through tid and cid\r\n");
-      fprintf( FCGI_stdout, "Status: 400\r\n");
-      return false;
-    }
-    if( ( *target = search_targetBytid( query_param.tid, targetlist)))
-      return true;
-  }
-
-  if( query_param.target[0] !='\0')
-    if( !( *target = search_target( query_param.target, targetlist)))
-      if(!( *target = gene_target( targetlist, query_param.target)))
-       return false;
-
-  if( *target){
-    fprintf( FCGI_stdout, "JPIP-tid: %s\r\n", (*target)->tid);
-    return true;
-  }
-  else{
-    fprintf( FCGI_stdout, "Reason: target not found\r\n");
-    fprintf( FCGI_stdout, "Status: 400\r\n");
-    return false;
-  }
-}
-
-bool associate_channel( query_param_t    query_param, 
-                       sessionlist_param_t *sessionlist,
-                       session_param_t **cursession, 
-                       channel_param_t **curchannel)
-{
-  if( search_session_and_channel( query_param.cid, sessionlist, cursession, curchannel)){
-    
-    if( !query_param.cnew)
-      set_channel_variable_param( query_param, *curchannel);
-  }
-  else{
-    fprintf( FCGI_stderr, "Error: process canceled\n");
-    return false;
-  }
-  return true;
-}
-
-bool open_channel( query_param_t query_param, 
-                  sessionlist_param_t *sessionlist,
-                  target_param_t *target,
-                  session_param_t **cursession, 
-                  channel_param_t **curchannel)
-{
-  cachemodel_param_t *cachemodel = NULL;
-
-  if( target){
-    if( !(*cursession))
-      *cursession = gene_session( sessionlist);
-    if( !( cachemodel = search_cachemodel( target, (*cursession)->cachemodellist)))
-      if( !(cachemodel = gene_cachemodel( (*cursession)->cachemodellist, target, query_param.return_type==JPPstream)))
-       return false;
-  }
-  else
-    if( *curchannel)
-      cachemodel = (*curchannel)->cachemodel;
-
-  *curchannel = gene_channel( query_param, cachemodel, (*cursession)->channellist);
-  if( *curchannel == NULL)
-    return false;
-
-  return true;
-}
-
-bool close_channel( query_param_t query_param, 
-                   sessionlist_param_t *sessionlist,
-                   session_param_t **cursession, 
-                   channel_param_t **curchannel)
-{
-  if( query_param.cclose[0][0] =='*'){
-#ifndef SERVER
-    fprintf( logstream, "local log: close all\n");
-#endif
-    // all channels associatd with the session will be closed
-    if( !delete_session( cursession, sessionlist))
-      return false;
-  }
-  else{
-    // check if all entry belonging to the same session
-    int i=0;
-    while( query_param.cclose[i][0] !='\0'){
-      
-      // In case of the first entry of close cid
-      if( *cursession == NULL){
-       if( !search_session_and_channel( query_param.cclose[i], sessionlist, cursession, curchannel))
-         return false;
-      }
-      else // second or more entry of close cid
-       if( !(*curchannel=search_channel( query_param.cclose[i], (*cursession)->channellist))){
-         fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", query_param.cclose[i]); 
-         return false;
-       }
-      i++;
-    }
-    // delete channels
-    i=0;
-    while( query_param.cclose[i][0] !='\0'){
-      
-      *curchannel = search_channel( query_param.cclose[i], (*cursession)->channellist);
-      delete_channel( curchannel, (*cursession)->channellist);
-      i++;
-    }
-    
-    if( (*cursession)->channellist->first == NULL || (*cursession)->channellist->last == NULL)
-      // In case of empty session
-      delete_session( cursession, sessionlist);
-  }
-  return true;
-}
-
-
-/**
- * enqueue tiles or precincts into the message queue
- *
- * @param[in] query_param structured query
- * @param[in] msgqueue    message queue pointer  
- */
-void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue);
-
-/**
- * enqueue metadata bins into the message queue
- *
- * @param[in]     query_param  structured query
- * @param[in]     metadatalist pointer to metadata bin list
- * @param[in,out] msgqueue     message queue pointer  
- */
-void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
-
-
-bool gene_JPIPstream( query_param_t query_param,
-                     target_param_t *target,
-                     session_param_t *cursession, 
-                     channel_param_t *curchannel,
-                     msgqueue_param_t **msgqueue)
-{
-  index_param_t *codeidx;
-  cachemodel_param_t *cachemodel;
-  
-  if( !cursession || !curchannel){ // stateless
-    if( !target)
-      return false;
-    if( !(cachemodel = gene_cachemodel( NULL, target, query_param.return_type==JPPstream)))
-      return false;
-    *msgqueue = gene_msgqueue( true, cachemodel);
-  }
-  else{ // session
-    cachemodel  = curchannel->cachemodel;
-    target = cachemodel->target;
-    *msgqueue = gene_msgqueue( false, cachemodel);
-  }
-  
-  if( cachemodel->jppstream)
-    fprintf( FCGI_stdout, "Content-type: image/jpp-stream\r\n");
-  else
-    fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
-
-  codeidx = target->codeidx;
-
-  //meta
-  if( query_param.box_type[0][0] != 0)
-    enqueue_metabins( query_param, codeidx->metadatalist, *msgqueue); 
-
-  // image codestream
-  if( query_param.fx > 0 && query_param.fy > 0){
-    if( !cachemodel->mhead_model)
-      enqueue_mainheader( *msgqueue);
-    enqueue_imagedata( query_param, *msgqueue);
-  }
-  return true;
-}
-
-
-/**
- * enqueue precinct data-bins into the queue
- *
- * @param[in] xmin      min x coordinate in the tile at the decomposition level
- * @param[in] xmax      max x coordinate in the tile at the decomposition level
- * @param[in] ymin      min y coordinate in the tile at the decomposition level
- * @param[in] ymax      max y coordinate in the tile at the decomposition level
- * @param[in] tile_id   tile index
- * @param[in] level     decomposition level
- * @param[in] lastcomp  last component number
- * @param[in] comps     pointer to the array that stores the requested components
- * @param[in] msgqueue  message queue
- * @return
- */
-void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue);
-
-/**
- * enqueue all precincts inside a tile into the queue
- *
- * @param[in] tile_id   tile index
- * @param[in] level     decomposition level
- * @param[in] lastcomp  last component number
- * @param[in] comps     pointer to the array that stores the requested components
- * @param[in] msgqueue  message queue
- * @return
- */
-void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue);
-
-void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue)
-{
-  index_param_t *codeidx;
-  imgreg_param_t imgreg;
-  range_param_t tile_Xrange, tile_Yrange;
-  int u, v, tile_id;
-  int xmin, xmax, ymin, ymax;
-  int numOfreslev;
-
-  codeidx = msgqueue->cachemodel->target->codeidx;
-
-  if( !(msgqueue->cachemodel->jppstream)  &&  get_nmax( codeidx->tilepart) == 1) // normally not the case
-    numOfreslev = 1;
-  else
-    numOfreslev = codeidx->COD.numOfdecomp+1;
-
-  imgreg  = map_viewin2imgreg( query_param.fx, query_param.fy, 
-                              query_param.rx, query_param.ry, query_param.rw, query_param.rh,
-                              codeidx->SIZ.XOsiz, codeidx->SIZ.YOsiz, codeidx->SIZ.Xsiz, codeidx->SIZ.Ysiz, 
-                              numOfreslev );
-
-  for( u=0, tile_id=0; u<codeidx->SIZ.YTnum; u++){
-    tile_Yrange = get_tile_Yrange( codeidx->SIZ, tile_id, imgreg.level);
-    
-    for( v=0; v<codeidx->SIZ.XTnum; v++, tile_id++){
-      tile_Xrange = get_tile_Xrange( codeidx->SIZ, tile_id, imgreg.level);
-       
-      if( tile_Xrange.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
-       if( tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox || 
-           tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox + imgreg.sx ||
-           tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy || 
-           tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy + imgreg.sy) {
-         //printf("Tile completely excluded from view-window %d\n", tile_id);
-         // Tile completely excluded from view-window
-       }
-       else if( tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox && 
-                tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx && 
-                tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy && 
-                tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy) {
-         // Tile completely contained within view-window
-         // high priority
-         //printf("Tile completely contained within view-window %d\n", tile_id);
-         if( msgqueue->cachemodel->jppstream){
-           enqueue_tileheader( tile_id, msgqueue);
-           enqueue_allprecincts( tile_id, imgreg.level, query_param.lastcomp, query_param.comps, msgqueue);
-         }
-         else
-           enqueue_tile( tile_id, imgreg.level, msgqueue);
-       }
-       else{
-         // Tile partially overlaps view-window
-         // low priority
-         //printf("Tile partially overlaps view-window %d\n", tile_id);
-         if( msgqueue->cachemodel->jppstream){
-           enqueue_tileheader( tile_id, msgqueue);
-
-           xmin = tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox ? 0 : imgreg.xosiz + imgreg.ox - tile_Xrange.minvalue;
-           xmax = tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx ? tile_Xrange.maxvalue - tile_Xrange.minvalue -1 : imgreg.xosiz + imgreg.ox + imgreg.sx - tile_Xrange.minvalue -1;
-           ymin = tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy ? 0 : imgreg.yosiz + imgreg.oy - tile_Yrange.minvalue;
-           ymax = tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy ? tile_Yrange.maxvalue - tile_Yrange.minvalue -1 : imgreg.yosiz + imgreg.oy + imgreg.sy - tile_Yrange.minvalue -1;
-           enqueue_precincts( xmin, xmax, ymin, ymax, tile_id, imgreg.level, query_param.lastcomp, query_param.comps, msgqueue);
-         }
-         else
-           enqueue_tile( tile_id, imgreg.level, msgqueue);
-       }
-      }
-    }
-  }
-}
-
-
-void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue)
-{
-  index_param_t *codeidx;
-  int c, u, v, res_lev, dec_lev;
-  int seq_id;
-  Byte4_t XTsiz, YTsiz;
-  Byte4_t XPsiz, YPsiz;
-  Byte4_t xminP, xmaxP, yminP, ymaxP;
-
-  codeidx  = msgqueue->cachemodel->target->codeidx;
-
-  for( c=0; c<codeidx->SIZ.Csiz; c++)
-    if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
-      seq_id = 0;
-      for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
-       
-       XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
-       YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
-       
-       XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
-       YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
-         
-       for( u=0; u<ceil((double)YTsiz/(double)YPsiz); u++){
-         yminP = u*YPsiz;
-         ymaxP = (u+1)*YPsiz-1;
-         if( YTsiz <= ymaxP)
-           ymaxP = YTsiz-1;
-         
-         for( v=0; v<ceil((double)XTsiz/(double)XPsiz); v++, seq_id++){
-           xminP = v*XPsiz;
-           xmaxP = (v+1)*XPsiz-1;
-           if( XTsiz <= xmaxP)
-             xmaxP = XTsiz-1;
-           
-           if( xmaxP < xmin || xminP > xmax || ymaxP < ymin || yminP > ymax){
-             // Precinct completely excluded from view-window
-           }
-           else if( xminP >= xmin && xmaxP <= xmax && yminP >= ymin && ymaxP <= ymax){
-             // Precinct completely contained within view-window
-             // high priority
-             enqueue_precinct( seq_id, tile_id, c, msgqueue);
-           }
-           else{
-             // Precinct partially overlaps view-window
-             // low priority
-             enqueue_precinct( seq_id, tile_id, c, msgqueue);
-           }
-         }
-       }
-      }
-    }
-}
-
-void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue)
-{
-  index_param_t *codeidx;
-  int c, i, res_lev, dec_lev;
-  int seq_id;
-  Byte4_t XTsiz, YTsiz;
-  Byte4_t XPsiz, YPsiz;
-
-  codeidx  = msgqueue->cachemodel->target->codeidx;
-
-  for( c=0; c<codeidx->SIZ.Csiz; c++)
-    if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
-      seq_id = 0;
-      for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
-       
-       XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
-       YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
-       
-       XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
-       YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
-       
-       for( i=0; i<ceil((double)YTsiz/(double)YPsiz)*ceil((double)XTsiz/(double)XPsiz); i++, seq_id++)
-         enqueue_precinct( seq_id, tile_id, c, msgqueue);
-      }
-    }
-}
-
-void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
-{
-  int i;
-  for( i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
-    if( query_param.box_type[i][0] == '*'){
-      // not implemented
-    }
-    else{
-      int idx = search_metadataidx( query_param.box_type[i], metadatalist);
-
-      if( idx != -1)
-       enqueue_metadata( idx, msgqueue);
-    }
-  }
-}
index 1195dcc5d4402e2f4d0bdc787bd1513a6615db9e..a29c8f12978d98457e2421481672314895a5e7e1 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include "query_parser.h"
 
 #ifdef SERVER
@@ -116,6 +117,9 @@ void parse_query( char *query_string, query_param_t *query_param)
       else if( strcasecmp( fieldname, "rsiz") == 0)
        sscanf( fieldval, "%d,%d", &query_param->rw, &query_param->rh);
       
+      else if( strcasecmp( fieldname, "layers") == 0)
+       sscanf( fieldval, "%d", &query_param->layers);
+      
       else if( strcasecmp( fieldname, "cid") == 0)
        strcpy( query_param->cid, fieldval);
 
@@ -137,6 +141,9 @@ void parse_query( char *query_string, query_param_t *query_param)
        else if( strncasecmp( fieldval, "jpt-stream", 10) == 0)
          query_param->return_type = JPTstream;
       }
+
+      else if( strcasecmp( fieldname, "len") == 0)
+       sscanf( fieldval, "%d", &query_param->len);
     }
   }
 }
@@ -145,18 +152,19 @@ void init_queryparam( query_param_t *query_param)
 {
   int i;
 
-  query_param->target[0]='\0';
-  query_param->tid[0]='\0';
-  query_param->fx=-1;
-  query_param->fy=-1;
-  query_param->rx=-1;
-  query_param->ry=-1;
-  query_param->rw=-1;
-  query_param->rh=-1;
+  query_param->target[0] = '\0';
+  query_param->tid[0] = '\0';
+  query_param->fx = -1;
+  query_param->fy = -1;
+  query_param->rx = -1;
+  query_param->ry = -1;
+  query_param->rw = -1;
+  query_param->rh = -1;
+  query_param->layers = -1;
   query_param->lastcomp = -1;
   query_param->comps = NULL;  
-  query_param->cid[0]='\0';
-  query_param->cnew=false;
+  query_param->cid[0] = '\0';
+  query_param->cnew = false;
   memset( query_param->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
   memset( query_param->box_type, 0, MAX_NUMOFBOX*4);
   memset( query_param->limit, 0, MAX_NUMOFBOX*sizeof(int));
@@ -171,6 +179,7 @@ void init_queryparam( query_param_t *query_param)
   query_param->max_depth = -1;
   query_param->metadata_only = false;
   query_param->return_type = UNKNOWN;
+  query_param->len = -1;
 }
 
 
@@ -208,6 +217,7 @@ void print_queryparam( query_param_t query_param)
   fprintf( logstream, "\t tid: %s\n", query_param.tid);
   fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy);
   fprintf( logstream, "\t rx,ry: %d, %d \t rw,rh: %d, %d\n", query_param.rx, query_param.ry, query_param.rw, query_param.rh);
+  fprintf( logstream, "\t layers: %d\n", query_param.layers);
   fprintf( logstream, "\t components: ");
   if( query_param.lastcomp == -1)
     fprintf( logstream, "ALL\n");
@@ -234,6 +244,7 @@ void print_queryparam( query_param_t query_param)
   fprintf( logstream, "\t max-depth: %d\n", query_param.max_depth);
   fprintf( logstream, "\t metadata-only: %d\n", query_param.metadata_only);
   fprintf( logstream, "\t image return type: %d, [JPP-stream=0, JPT-stream=1, UNKNOWN=-1]\n", query_param.return_type);
+  fprintf( logstream, "\t len:  %d\n", query_param.len);
 }
 
 void str2cclose( char *src, char cclose[][MAX_LENOFCID])
index 2df9609bdcb517dafdd674742ed3e84e08a99b9a..55be9dd188f2782de8c57c0262903bc2f431c268 100644 (file)
@@ -58,6 +58,7 @@ typedef struct query_param{
   char tid[MAX_LENOFTID];                     //!< target identifier
   int fx, fy;                                 //!< frame size (fx,fy)
   int rx, ry, rw, rh;                         //!< roi region
+  int layers;                                 //!< quality layers
   int lastcomp;                               //!< last component number
   bool *comps;                                //!< components for jpp-stream, null means all components
   char cid[MAX_LENOFCID];                     //!< channel identifier
@@ -74,6 +75,7 @@ typedef struct query_param{
   int max_depth;                              //!< max-depth
   bool metadata_only;                         //!< metadata-only request
   image_return_t return_type;                 //!< image return type
+  int len;                                    //!< maximum response length
 } query_param_t;
 
 
index dfceb69ff1a8e4eb12b71b4fc1e6aa2d8db70ec8..9a469e74d07dcb04cc10e43668fce539bdbbd8c0 100644 (file)
@@ -89,6 +89,7 @@ int main(int argc,char *argv[])
   
   //print_msgqueue( msgqueue);
   
+  // arguments fw, fh need to be set for LRCP, PCRL, CPRL
   j2kstream = recons_j2k( msgqueue, jpipstream, msgqueue->first->csn, 0, 0, &j2klen);
     
   delete_msgqueue( &msgqueue);