diff --git a/applications/jpip/CHANGES b/applications/jpip/CHANGES index 7d52da31..71fe35f7 100644 --- a/applications/jpip/CHANGES +++ b/applications/jpip/CHANGES @@ -5,6 +5,9 @@ What's New for OpenJPIP ! : changed + : added +November 16, 2011 +* [kaori] fixed Region of Interest option, and memory leak of opj_dec_server + November 8, 2011 ! [kaori] updated main page of doxygen diff --git a/applications/jpip/libopenjpip/cache_manager.c b/applications/jpip/libopenjpip/cache_manager.c index adc0ba87..77000439 100644 --- a/applications/jpip/libopenjpip/cache_manager.c +++ b/applications/jpip/libopenjpip/cache_manager.c @@ -180,8 +180,8 @@ void add_cachecid( char *cid, cache_param_t *cache) { if( !cid) return; - - if( realloc( cache->cid, (cache->numOfcid+1)*sizeof(char *)) == NULL){ + + if( (cache->cid = realloc( cache->cid, (cache->numOfcid+1)*sizeof(char *))) == NULL){ fprintf( stderr, "failed to add new cid to cache table in add_cachecid()\n"); return; } diff --git a/applications/jpip/libopenjpip/dec_clientmsg_handler.c b/applications/jpip/libopenjpip/dec_clientmsg_handler.c index 294285af2..5fd3b038 100644 --- a/applications/jpip/libopenjpip/dec_clientmsg_handler.c +++ b/applications/jpip/libopenjpip/dec_clientmsg_handler.c @@ -90,7 +90,7 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par char *CIDorTID, tmp[10]; cache_param_t *cache; int fw, fh; - + CIDorTID = receive_string( connected_socket); if(!(cache = search_cacheBycid( CIDorTID, cachelist))) @@ -107,11 +107,12 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par receive_line( connected_socket, tmp); fh = atoi( tmp); - pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox); - ihdrbox = cache->ihdrbox; + ihdrbox = NULL; + pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &ihdrbox); send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1); + free( ihdrbox); free( pnmstream); } @@ -185,6 +186,36 @@ void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist) free( cid); } +void handle_SIZreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist) +{ + char *tid, *cid; + cache_param_t *cache; + Byte4_t width, height; + + tid = receive_string( connected_socket); + cid = receive_string( connected_socket); + + cache = NULL; + + if( tid[0] != '0') + cache = search_cacheBytid( tid, cachelist); + + if( !cache && cid[0] != '0') + cache = search_cacheBycid( cid, cachelist); + + free( tid); + free( cid); + + width = height = 0; + if( cache){ + if( !cache->ihdrbox) + cache->ihdrbox = get_SIZ_from_jpipstream( jpipstream, msgqueue, cache->csn); + width = cache->ihdrbox->width; + height = cache->ihdrbox->height; + } + send_SIZstream( connected_socket, width, height); +} + void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream) { char *cid; diff --git a/applications/jpip/libopenjpip/dec_clientmsg_handler.h b/applications/jpip/libopenjpip/dec_clientmsg_handler.h index 88a6fbed..58424bfd 100644 --- a/applications/jpip/libopenjpip/dec_clientmsg_handler.h +++ b/applications/jpip/libopenjpip/dec_clientmsg_handler.h @@ -91,6 +91,14 @@ void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist); */ void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist); +/** + * handle SIZ request message + * + * @param[in] connected_socket socket descriptor + * @param[in,out] cachelist cache list pointer + */ +void handle_SIZreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist); + /** * handle saving JP2 file request message * diff --git a/applications/jpip/libopenjpip/imgsock_manager.c b/applications/jpip/libopenjpip/imgsock_manager.c index 79149f5f..0c1cbe6f 100644 --- a/applications/jpip/libopenjpip/imgsock_manager.c +++ b/applications/jpip/libopenjpip/imgsock_manager.c @@ -85,7 +85,7 @@ SOCKET open_listeningsocket() close_socket(listening_socket); exit(1); } - printf("port %d is listened\n", port); + fprintf( stderr, "port %d is listened\n", port); return listening_socket; } @@ -102,7 +102,7 @@ msgtype_t identify_clientmsg( SOCKET connected_socket) { int receive_size; char buf[BUF_LEN]; - char *magicid[] = { "JPIP-stream", "PNM request", "XML request", "TID request", "CID request", "CID destroy", "JP2 save", "QUIT"}; + char *magicid[] = { "JPIP-stream", "PNM request", "XML request", "TID request", "CID request", "CID destroy", "SIZ request", "JP2 save", "QUIT"}; int i; receive_size = receive_line( connected_socket, buf); @@ -114,7 +114,7 @@ msgtype_t identify_clientmsg( SOCKET connected_socket) for( i=0; i> 16) & 0xff; + responce[4] = (width >> 8) & 0xff; + responce[5] = width & 0xff; + responce[6] = (height >> 16) & 0xff; + responce[7] = (height >> 8) & 0xff; + responce[8] = height & 0xff; + + send_stream( connected_socket, responce, 9); +} + void send_stream( SOCKET connected_socket, void *stream, int length) { void *ptr = stream; diff --git a/applications/jpip/libopenjpip/imgsock_manager.h b/applications/jpip/libopenjpip/imgsock_manager.h index 5961a581..7da94b90 100644 --- a/applications/jpip/libopenjpip/imgsock_manager.h +++ b/applications/jpip/libopenjpip/imgsock_manager.h @@ -56,8 +56,8 @@ SOCKET open_listeningsocket(); 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; +#define NUM_OF_MSGTYPES 9 +typedef enum eMSGTYPE{ JPIPSTREAM, PNMREQ, XMLREQ, TIDREQ, CIDREQ, CIDDST, SIZREQ, JP2SAVE, QUIT, MSGERROR} msgtype_t; /** * indeitify client message type @@ -84,8 +84,8 @@ Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid, * * @param [in] connected_socket file descriptor of the connected socket * @param [in] pnmstream PGM/PPM image codestream - * @param [in] width width of the image - * @param [in] height height of the image + * @param [in] width width of the PGM/PPM image (different from the original image) + * @param [in] height height of the PGM/PPM image * @param [in] numofcomp number of components of the image * @param [in] maxval maximum value of the image (only 255 supported) */ @@ -118,6 +118,15 @@ void send_TIDstream( SOCKET connected_socket, char *tid, int tidlen); */ void send_CIDstream( SOCKET connected_socket, char *cid, int cidlen); +/** + * send SIZ data stream to the client + * + * @param [in] connected_socket file descriptor of the connected socket + * @param [in] width original width of the image + * @param [in] height original height of the image + */ +void send_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int height); + /** * send response signal to the client * @@ -192,13 +201,19 @@ int close_socket( SOCKET sock); * client -> server: CID destroy\\n ciddata \n * server -> client: 1 or 0 (of 1Byte response signal) * - *\section sec7 JP2 save + *\section sec7 SIZ request + * Get original size of image + * + * client -> server: SIZ request\\n tidstring\\n cidstring\\n \n + * server -> client: SIZ (3Byte) width (3Byte Big endian) height (3Byte Big endian) + * + *\section sec8 JP2 save * Save in JP2 file format * * client -> server: JP2 save\\n ciddata \n * server -> client: 1 or 0 (of 1Byte response signal) * - *\section sec8 QUIT + *\section sec9 QUIT * Quit the opj_dec_server program * * client -> server: quit or QUIT diff --git a/applications/jpip/libopenjpip/index_manager.c b/applications/jpip/libopenjpip/index_manager.c index 83e2d3b5..6eafa40b 100644 --- a/applications/jpip/libopenjpip/index_manager.c +++ b/applications/jpip/libopenjpip/index_manager.c @@ -188,8 +188,7 @@ void delete_index( index_param_t **index) delete_metadatalist( &((*index)->metadatalist)); - free( (*index)->COD.XPsiz); - free( (*index)->COD.YPsiz); + delete_COD( (*index)->COD); delete_faixbox( &((*index)->tilepart)); @@ -204,6 +203,12 @@ void delete_index( index_param_t **index) free(*index); } +void delete_COD( CODmarker_param_t COD) +{ + if( COD.XPsiz) free( COD.XPsiz); + if( COD.YPsiz) free( COD.YPsiz); +} + bool check_JP2boxidx( boxlist_param_t *toplev_boxlist) { box_param_t *iptr, *fidx, *prxy; diff --git a/applications/jpip/libopenjpip/index_manager.h b/applications/jpip/libopenjpip/index_manager.h index 74e25c72..5aeee0db 100644 --- a/applications/jpip/libopenjpip/index_manager.h +++ b/applications/jpip/libopenjpip/index_manager.h @@ -129,6 +129,14 @@ void print_COD( CODmarker_param_t COD); */ void delete_index( index_param_t **index); +/** + * delete dynamic arrays in COD marker + * + * @param[in] COD COD marker information + */ +void delete_COD( CODmarker_param_t COD); + + //! 1-dimensional range parameters typedef struct range_param{ Byte4_t minvalue; //!< minimal value diff --git a/applications/jpip/libopenjpip/jp2k_decoder.c b/applications/jpip/libopenjpip/jp2k_decoder.c index 933331b2..28f33226 100644 --- a/applications/jpip/libopenjpip/jp2k_decoder.c +++ b/applications/jpip/libopenjpip/jp2k_decoder.c @@ -74,11 +74,11 @@ Byte_t * j2k_to_pnm( Byte_t *j2kstream, Byte8_t j2klen, ihdrbox_param_t **ihdrbo /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, j2kstream, j2klen); - fprintf( stderr, "opj_decode dinfo:%p cio:%p\n", dinfo, cio); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); - fprintf( stderr, "done\n"); + fprintf(stderr, "image is decoded!\n"); + if(!image) { fprintf(stderr, "ERROR -> jp2_to_image: failed to decode image!\n"); opj_destroy_decompress(dinfo); diff --git a/applications/jpip/libopenjpip/jp2k_encoder.c b/applications/jpip/libopenjpip/jp2k_encoder.c index 5025bf8e..013e4316 100644 --- a/applications/jpip/libopenjpip/jp2k_encoder.c +++ b/applications/jpip/libopenjpip/jp2k_encoder.c @@ -278,10 +278,14 @@ Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *j } if( max_reslev < COD.numOfdecomp) - if( !modify_mainheader( j2kstream, max_reslev, SIZ, COD, j2klen)) + if( !modify_mainheader( j2kstream, max_reslev, SIZ, COD, j2klen)){ + delete_COD( COD); return j2kstream; + } j2kstream = add_EOC( j2kstream, j2klen); + delete_COD( COD); + return j2kstream; } @@ -785,3 +789,9 @@ Byte_t * gene_emptytilestream( const Byte8_t tileID, Byte8_t *length) return buf; } + +Byte_t * recons_j2kmainhead( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *j2klen) +{ + *j2klen = 0; + return add_mainhead_msgstream( msgqueue, jpipstream, NULL, csn, j2klen); +} diff --git a/applications/jpip/libopenjpip/jp2k_encoder.h b/applications/jpip/libopenjpip/jp2k_encoder.h index 9a86dd3f..3945e2a0 100644 --- a/applications/jpip/libopenjpip/jp2k_encoder.h +++ b/applications/jpip/libopenjpip/jp2k_encoder.h @@ -60,5 +60,15 @@ Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn */ Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len); +/** + * reconstruct j2k codestream of mainheader from message queue + * + * @param[in] msgqueue message queue pointer + * @param[in] jpipstream original jpt- jpp- stream + * @param[in] csn codestream number + * @param[out] j2klen pointer to the j2k codestream length + * @return generated reconstructed j2k codestream + */ +Byte_t * recons_j2kmainhead( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *j2klen); #endif /* !JP2K_ENCODER_H_ */ diff --git a/applications/jpip/libopenjpip/jpipstream_manager.c b/applications/jpip/libopenjpip/jpipstream_manager.c index 97b61526..bb1418f7 100644 --- a/applications/jpip/libopenjpip/jpipstream_manager.c +++ b/applications/jpip/libopenjpip/jpipstream_manager.c @@ -35,6 +35,8 @@ #include "jpipstream_manager.h" #include "jp2k_encoder.h" #include "jp2k_decoder.h" +#include "ihdrbox_manager.h" +#include "j2kheader_manager.h" Byte_t * update_JPIPstream( Byte_t *newstream, int newstreamlen, Byte_t *cache_stream, int *streamlen) { @@ -81,3 +83,28 @@ Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte return pnmstream; } + +ihdrbox_param_t * get_SIZ_from_jpipstream( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn) +{ + ihdrbox_param_t *ihdrbox; + Byte_t *j2kstream; + Byte8_t j2klen; + SIZmarker_param_t SIZ; + + j2kstream = recons_j2kmainhead( msgqueue, jpipstream, csn, &j2klen); + if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, NULL)){ + free( j2kstream); + return NULL; + } + + ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t)); + + ihdrbox->width = SIZ.Xsiz; + ihdrbox->height = SIZ.Ysiz; + ihdrbox->nc = SIZ.Csiz; + ihdrbox->bpc = SIZ.Ssiz[0]; + + free( j2kstream); + + return ihdrbox; +} diff --git a/applications/jpip/libopenjpip/jpipstream_manager.h b/applications/jpip/libopenjpip/jpipstream_manager.h index d9e7702a..795ae4a0 100644 --- a/applications/jpip/libopenjpip/jpipstream_manager.h +++ b/applications/jpip/libopenjpip/jpipstream_manager.h @@ -37,3 +37,5 @@ Byte_t * update_JPIPstream( Byte_t *newstream, int newstreamlen, Byte_t *cache_s void save_codestream( Byte_t *codestream, Byte8_t streamlen, char *fmt); Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn, int fw, int fh, ihdrbox_param_t **ihdrbox); + +ihdrbox_param_t * get_SIZ_from_jpipstream( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn); diff --git a/applications/jpip/libopenjpip/openjpip.c b/applications/jpip/libopenjpip/openjpip.c index a4f3000a..ee8bcfde 100644 --- a/applications/jpip/libopenjpip/openjpip.c +++ b/applications/jpip/libopenjpip/openjpip.c @@ -205,6 +205,10 @@ bool handle_clientreq( client_t client, dec_server_record_t *rec) case CIDDST: handle_dstCIDreqMSG( client, rec->cachelist); break; + + case SIZREQ: + handle_SIZreqMSG( client, rec->jpipstream, rec->msgqueue, rec->cachelist); + break; case JP2SAVE: handle_JP2saveMSG( client, rec->cachelist, rec->msgqueue, rec->jpipstream); @@ -218,7 +222,7 @@ bool handle_clientreq( client_t client, dec_server_record_t *rec) break; } - printf("\t end of the connection\n\n"); + fprintf( stderr, "\t end of the connection\n\n"); if( close_socket(client) != 0){ perror("close"); return false; diff --git a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111018.jar b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111018.jar deleted file mode 100644 index a17ca3b6..00000000 Binary files a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111018.jar and /dev/null differ diff --git a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111026.jar b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar similarity index 61% rename from applications/jpip/util/opj_viewer/dist/opj_viewer-20111026.jar rename to applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar index a1b6789a..cfdf6601 100644 Binary files a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111026.jar and b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar differ diff --git a/applications/jpip/util/opj_viewer/dist/opj_viewer.jar b/applications/jpip/util/opj_viewer/dist/opj_viewer.jar index 4fceec6d..07d0dbd5 120000 --- a/applications/jpip/util/opj_viewer/dist/opj_viewer.jar +++ b/applications/jpip/util/opj_viewer/dist/opj_viewer.jar @@ -1 +1 @@ -opj_viewer-20111026.jar \ No newline at end of file +opj_viewer-20111116.jar \ No newline at end of file diff --git a/applications/jpip/util/opj_viewer/src/ImageManager.java b/applications/jpip/util/opj_viewer/src/ImageManager.java index 5634123f..bd4cadd1 100644 --- a/applications/jpip/util/opj_viewer/src/ImageManager.java +++ b/applications/jpip/util/opj_viewer/src/ImageManager.java @@ -33,15 +33,32 @@ import java.awt.Image; public class ImageManager extends JPIPHttpClient { private PnmImage pnmimage; + private int origwidth; + private int origheight; public ImageManager( String uri) { super( uri); pnmimage = null; + origwidth = 0; + origheight = 0; } - public int getOrigWidth(){ return pnmimage.get_width();} - public int getOrigHeight(){ return pnmimage.get_height();} + public int getOrigWidth(){ + if( origwidth == 0){ + if( cid != null || tid != null){ + java.awt.Dimension dim = ImgdecClient.query_imagesize( cid, tid); + if( dim != null){ + origwidth = dim.width; + origheight = dim.height; + } + } + else + System.err.println("Neither cid or tid obtained before to get Original Image Dimension"); + } + return origwidth; + } + public int getOrigHeight(){ return origheight;} public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT) { @@ -106,6 +123,7 @@ public class ImageManager extends JPIPHttpClient } return xmldata; } + public void closeChannel() { if( cid != null){ diff --git a/applications/jpip/util/opj_viewer/src/ImgdecClient.java b/applications/jpip/util/opj_viewer/src/ImgdecClient.java index 35c97128..f956d05b 100644 --- a/applications/jpip/util/opj_viewer/src/ImgdecClient.java +++ b/applications/jpip/util/opj_viewer/src/ImgdecClient.java @@ -253,6 +253,49 @@ public class ImgdecClient{ return id; } + + public static java.awt.Dimension query_imagesize( String cid, String tid) + { + java.awt.Dimension dim = null; + + try{ + Socket imgdecSocket = new Socket( "localhost", 5000); + DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream()); + DataInputStream is = new DataInputStream( imgdecSocket.getInputStream()); + byte []header = new byte[3]; + + os.writeBytes( "SIZ request\n"); + if( tid == null) + os.writeBytes( "0\n"); + else + os.writeBytes( tid + "\n"); + if( cid == null) + os.writeBytes( "0\n"); + else + os.writeBytes( cid + "\n"); + + read_stream( is, header, 3); + + if( header[0] == 83 && header[1] == 73 && header[2] == 90){ + + byte []data = new byte[ 3]; + read_stream( is, data, 3); + int w = (data[0]&0xff)<<16 | (data[1]&0xff)<<8 | (data[2]&0xff); + read_stream( is, data, 3); + int h = (data[0]&0xff)<<16 | (data[1]&0xff)<<8 | (data[2]&0xff); + dim = new java.awt.Dimension( w, h); + } + else + System.err.println("Error in query_imagesize("+ cid + ", " + tid + "), wrong to start with " + header); + } + catch (UnknownHostException e) { + System.err.println("Trying to connect to unknown host: " + e); + } catch (IOException e) { + System.err.println("IOException: " + e); + } + + return dim; + } public static void read_stream( DataInputStream is, byte []stream, int length) { diff --git a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111010.jar b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111010.jar deleted file mode 100644 index e2f78889..00000000 Binary files a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111010.jar and /dev/null differ diff --git a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111026.jar b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar similarity index 72% rename from applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111026.jar rename to applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar index f67cfb5b..0c3e0dbb 100644 Binary files a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111026.jar and b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar differ diff --git a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces.jar b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces.jar index f1df7c26..7e661773 120000 --- a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces.jar +++ b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces.jar @@ -1 +1 @@ -opj_viewer_xerces-20111026.jar \ No newline at end of file +opj_viewer_xerces-20111116.jar \ No newline at end of file