October 10, 2011
* [vincent] fix 'distcheck' rule
+* [antonin] modified indexer for JPIP, JPP-stream
October 7, 2011
+ [mickael] enhance non regression test suite generation (and some test names). It is based on a file as encoder previously.
! : changed
+ : added
+October 10, 2011
++ [antonin] enabled JPP-stream
+
September 16, 2011
+ [kaori] enabled stateless requests from the opj_viewers
========================================================================
- OpenJPIP software 1.0 ReadMe
+ OpenJPIP software 2.0 ReadMe
OpenJPEG:
http://www.openjpeg.org
( For more info about JPIP, check the website: http://www.jpeg.org/jpeg2000/j2kpart9.html)
The current implementation uses some results from the 2KAN project (http://www.2kan.org).
-First Version 1.0 covers:
- - JPT-stream (Tile based) media types
+First Version 2.0 covers:
+ - JPT-stream (Tile) and JPP-stream (Precinct) media types
- Session, channels, cache model managements
- JPIP over HTTP
- Indexing JPEG 2000 files
- OpenJPEG library (currently assumes it is installed on the system => will not use the one built higher in the directory structure)
- FastCGI development kit (C libraries) at server (http://www.fastcgi.com)
- Java application launcher at client
- - Kakadu software ( http://www.kakadusoftware.com). Currently required to encode jpeg 2000 images with tile-parts. This will be implemented soon in openjpeg, making this requirement obsolete.
<Optional>
- Xerces2 java XML parser on the client for accessing embedded image metadata (http://xerces.apache.org/xerces2-j)
A Makefile is available in the same directory as this README file. Simply type 'make' and it will build all the required C-executables.
Concerning the java-based opj_viewer, simply type 'ant' in the corresponding directory (requires 'ant' utility of course)
-CMake files ar planned to be included ASAP.
-
The documentation can be build this way (requires doxygen utility):
cd doc
doxygen Doxyfile
----------
An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale.
-
- 1. J2K encoding using Kakadu with an option which introduces the tile-part flag at each resolution level
- % ./kdu_compress -i copenhague1.tif -o copenhague1.j2k Corder=RPCL ORGtparts=R Stiles={256,256}
-
- 2. JP2 encoding with embedding indexing data
- % ./j2k_to_idxjp2 copenhague1.j2k copenhague1.jp2
+ % ./image_to_j2k -i copenhague1.tif -o copenhague1.jp2 -p RPCL -c [64,64] -t 640,480 -jpip
<Option>
3. Embed metadata into JP2 file
${CMAKE_CURRENT_SOURCE_DIR}/mhixbox_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/target_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/cachemodel_manager.c
+${CMAKE_CURRENT_SOURCE_DIR}/j2kheader_manager.c
+${CMAKE_CURRENT_SOURCE_DIR}/jp2k_encoder.c
)
# Build the library
mhixbox_manager.c \
target_manager.c \
cachemodel_manager.c \
+j2kheader_manager.c \
+jp2k_encoder.c \
bool.h \
boxheader_manager.h \
box_manager.h \
msgqueue_manager.h \
placeholder_manager.h \
target_manager.h \
-cachemodel_manager.h
+cachemodel_manager.h \
+j2kheader_manager.h \
+jp2k_encoder.h
libopenjpip_server_la_CPPFLAGS = \
-I. \
return (((Byte8_t) big4 (buf)) << 32)
+ ((Byte8_t) big4 (buf + 4));
}
+
+void modify_4Bytecode( Byte4_t code, Byte_t *stream)
+{
+ *stream = (Byte_t) ((Byte4_t)(code & 0xff000000) >> 24);
+ *(stream+1) = (Byte_t) ((Byte4_t)(code & 0x00ff0000) >> 16);
+ *(stream+2) = (Byte_t) ((Byte4_t)(code & 0x0000ff00) >> 8);
+ *(stream+3) = (Byte_t) (code & 0x000000ff);
+}
*/
Byte8_t big8( Byte_t *buf);
+/**
+ * modify 4Byte code in a codestream
+ *
+ * @param[in] code code value
+ * @param[out] stream modifying codestream
+ */
+void modify_4Bytecode( Byte4_t code, Byte_t *stream);
#endif /* !BYTE_MANAGER_H_ */
{
cachemodel_param_t *cachemodel;
faixbox_param_t *tilepart;
+ faixbox_param_t *precpacket;
size_t numOfelem;
+ Byte8_t numOftiles;
+ int i;
cachemodel = (cachemodel_param_t *)malloc( sizeof(cachemodel_param_t));
cachemodel->mhead_model = false;
tilepart = target->codeidx->tilepart;
- numOfelem = get_nmax( tilepart)*get_m( tilepart);
+ numOftiles = get_m( tilepart);
+ numOfelem = get_nmax( tilepart)*numOftiles;
cachemodel->tp_model = (bool *)calloc( 1, numOfelem*sizeof(bool));
-
+ cachemodel->th_model = (bool *)calloc( 1, numOftiles*sizeof(bool));
+ cachemodel->pp_model = (bool **)malloc( target->codeidx->SIZ.Csiz*sizeof(bool *));
+ for( i=0; i<target->codeidx->SIZ.Csiz; i++){
+ precpacket = target->codeidx->precpacket[i];
+ cachemodel->pp_model[i] = (bool *)calloc( 1, get_nmax(precpacket)*get_m(precpacket)*sizeof(bool));
+ }
cachemodel->next = NULL;
if( cachemodellist){
void print_cachemodel( cachemodel_param_t cachemodel)
{
+ target_param_t *target;
Byte8_t TPnum; // num of tile parts in each tile
+ Byte8_t Pmax; // max num of packets per tile
int i, j, k, n;
+
+ target = cachemodel.target;
- fprintf( logstream, "target: %s\n", cachemodel.target->filename);
+ fprintf( logstream, "target: %s\n", target->filename);
fprintf( logstream, "\t main header model: %d\n", cachemodel.mhead_model);
fprintf( logstream, "\t tile part model:\n");
+ TPnum = get_nmax( target->codeidx->tilepart);
- TPnum = get_nmax( cachemodel.target->codeidx->tilepart);
-
- for( i=0, n=0; i<cachemodel.target->codeidx->YTnum; i++){
- for( j=0; j<cachemodel.target->codeidx->XTnum; j++){
+ for( i=0, n=0; i<target->codeidx->SIZ.YTnum; i++){
+ for( j=0; j<target->codeidx->SIZ.XTnum; j++){
for( k=0; k<TPnum; k++)
fprintf( logstream, "%d", cachemodel.tp_model[n++]);
fprintf( logstream, " ");
}
fprintf( logstream, "\n");
}
+
+ fprintf( logstream, "\t tile header and precinct packet model:\n");
+ for( i=0; i<target->codeidx->SIZ.XTnum*target->codeidx->SIZ.YTnum; i++){
+ fprintf( logstream, "\t tile.%d %d\n", i, cachemodel.th_model[i]);
+ for( j=0; j<target->codeidx->SIZ.Csiz; j++){
+ fprintf( logstream, "\t compo.%d: ", j);
+ Pmax = get_nmax( target->codeidx->precpacket[j]);
+ for( k=0; k<Pmax; k++)
+ fprintf( logstream, "%d", cachemodel.pp_model[j][i*Pmax+k]);
+ fprintf( logstream, "\n");
+ }
+ }
}
cachemodel_param_t * search_cachemodel( target_param_t *target, cachemodellist_param_t *cachemodellist)
void delete_cachemodel( cachemodel_param_t **cachemodel)
{
+ int i;
+
unrefer_target( (*cachemodel)->target);
free( (*cachemodel)->tp_model);
+ free( (*cachemodel)->th_model);
+
+ if( (*cachemodel)->target->codeidx->SIZ.Csiz > 1)
+ for( i=0; i<(*cachemodel)->target->codeidx->SIZ.Csiz; i++)
+ free( (*cachemodel)->pp_model[i]);
+ free( (*cachemodel)->pp_model);
#ifndef SERVER
fprintf( logstream, "local log: cachemodel deleted\n");
target_param_t *target; //!< reference pointer to the target
bool mhead_model; //!< main header model, if sent, 1, else 0
bool *tp_model; //!< dynamic array pointer of tile part model, if sent, 1, else 0
+ bool *th_model; //!< dynamic array pointer of tile header model
+ bool **pp_model; //!< dynamic array pointer of precint packet model
struct cachemodel_param *next; //!< pointer to the next cache model
} cachemodel_param_t;
$(LIBNAME): target_manager.o byte_manager.o box_manager.o boxheader_manager.o manfbox_manager.o \
mhixbox_manager.o marker_manager.o codestream_manager.o faixbox_manager.o index_manager.o \
- msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o cachemodel_manager.o
+ msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
+ cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o
ar r $@ $^
clean:
#include <stdlib.h>
#include "ihdrbox_manager.h"
-ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream)
+ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream)
{
ihdrbox_param_t *ihdrbox;
metadata_param_t *meta;
return NULL;
}
- ihdr = gene_boxbyTypeinStream( jptstream, get_DBoxoff( jp2h), get_DBoxlen( jp2h), "ihdr");
+ ihdr = gene_boxbyTypeinStream( jpipstream, get_DBoxoff( jp2h), get_DBoxlen( jp2h), "ihdr");
if( !ihdr){
fprintf( stderr, "ihdr box not found\n");
ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
- ihdrbox->height = big4( jptstream+get_DBoxoff(ihdr));
- ihdrbox->width = big4( jptstream+get_DBoxoff(ihdr)+4);
- ihdrbox->nc = big2( jptstream+get_DBoxoff(ihdr)+8);
- ihdrbox->bpc = *(jptstream+get_DBoxoff(ihdr)+10)+1;
+ ihdrbox->height = big4( jpipstream+get_DBoxoff(ihdr));
+ ihdrbox->width = big4( jpipstream+get_DBoxoff(ihdr)+4);
+ ihdrbox->nc = big2( jpipstream+get_DBoxoff(ihdr)+8);
+ ihdrbox->bpc = *(jpipstream+get_DBoxoff(ihdr)+10)+1;
free( ihdr);
#include "box_manager.h"
#include "metadata_manager.h"
+//! I.5.3.1 Image Header box
typedef struct ihdrbox_param{
Byte4_t height;
Byte4_t width;
- Byte2_t nc;
- Byte_t bpc;
+ Byte2_t nc; //!< number of components
+ Byte_t bpc; //!< bits per component
} ihdrbox_param_t;
-ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream);
+/**
+ * generate ihdr box
+ *
+ * @param[in] metadatalist metadata list pointer
+ * @param[in] jpipstream JPT/JPP stream
+ * @return pointer to generated ihdr box
+ */
+ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream);
#endif /* !IHDRBOX_MANAGER_H_ */
const int rw, const int rh,
const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz,
- const int numOfdecomp)
+ const int numOfreslev)
{
imgreg_param_t imgreg;
int px,py;
xmax = Xsiz;
ymax = Ysiz;
- find_level( numOfdecomp, &imgreg.level, &imgreg.fx, &imgreg.fy, &imgreg.xosiz, &imgreg.yosiz, &xmax, &ymax);
+ find_level( numOfreslev, &imgreg.level, &imgreg.fx, &imgreg.fy, &imgreg.xosiz, &imgreg.yosiz, &xmax, &ymax);
if( rx == -1 || ry == -1){
imgreg.ox = 0;
else{
px = ceil((double)((rx+rw)*imgreg.fx)/(double)fx);
py = ceil((double)((ry+rh)*imgreg.fy)/(double)fy);
+
+ if( imgreg.fx < px)
+ px = imgreg.fx;
+ if( imgreg.fy < py)
+ py = imgreg.fy;
+
imgreg.sx = px - imgreg.ox;
imgreg.sy = py - imgreg.oy;
}
}
}
+int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz)
+{
+ int level;
+ int xmin, xmax, ymin, ymax;
+
+ level = 0;
+ xmin = ymin = 0;
+ xmax = Xsiz;
+ ymax = Ysiz;
+
+ find_level( 1000, &level, &fw, &fh, &xmin, &ymin, &xmax, &ymax);
+
+ return level;
+}
void print_imgreg( imgreg_param_t imgreg)
{
* @param[in] rw,rh size of region
* @param[in] XOsiz,YOsiz offset from the origin of the reference grid to the left side of the image area
* @param[in] Xsiz,Ysiz size of the reference grid
- * @param[in] numOfdecomp number of decomposition levels
+ * @param[in] numOfreslev number of resolution levels
* @return structure of image region parameters
*/
imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
const int rw, const int rh,
const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz,
- const int numOfdecomp);
+ const int numOfreslev);
/**
*/
void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, int *xmax, int *ymax);
+/**
+ * compute decomposition level (only to get the level
+ * use find_level for all parameters
+ *
+ * @param[in] fx horizontal frame size
+ * @param[in] fy vertical frame size
+ * @param[in] Xsiz image width
+ * @param[in] Ysiz image height
+ * @return decomposition level
+ */
+int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz);
+
/**
* print image region parameters
*
fprintf( logstream, "\tCodestream Offset: %#llx\n", index.offset);
fprintf( logstream, "\t Length: %#llx\n", index.length);
fprintf( logstream, "\tMain header Length: %#llx\n", index.mhead_length);
- fprintf( logstream, "\t Rsiz: %#x\n", index.Rsiz);
- fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", index.Xsiz, index.Ysiz, index.Xsiz, index.Ysiz);
- fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", index.XOsiz, index.YOsiz, index.XOsiz, index.YOsiz);
- fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", index.XTsiz, index.YTsiz, index.XTsiz, index.YTsiz);
- fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", index.XTOsiz, index.YTOsiz, index.XTOsiz, index.YTOsiz);
- fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", index.XTnum, index.YTnum);
- fprintf( logstream, "\t Num of Components: %d\n", index.Csiz);
- for( i=0; i<index.Csiz; i++)
- fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, index.Ssiz[i], index.XRsiz[i], index.YRsiz[i], index.Ssiz[i], index.XRsiz[i], index.YRsiz[i]);
-
+ print_SIZ( index.SIZ);
+ print_COD( index.COD);
+
+ fprintf( logstream, "Tile part information: \n");
print_faixbox( index.tilepart);
+ fprintf( logstream, "Tile header information: \n");
+ for( i=0; i<index.SIZ.XTnum*index.SIZ.YTnum ;i++)
+ print_mhixbox( index.tileheader[i]);
+
+ fprintf( logstream, "Precinct packet information: \n");
+ for( i=0; i<index.SIZ.Csiz; i++){
+ fprintf( logstream, "Component %d\n", i);
+ print_faixbox( index.precpacket[i]);
+ }
+
print_allmetadata( index.metadatalist);
}
+void print_SIZ( SIZmarker_param_t SIZ)
+{
+ int i;
+
+ fprintf( logstream, "\tImage and Tile SIZ parameters\n");
+ fprintf( logstream, "\t Rsiz: %#x\n", SIZ.Rsiz);
+ fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", SIZ.Xsiz, SIZ.Ysiz, SIZ.Xsiz, SIZ.Ysiz);
+ fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XOsiz, SIZ.YOsiz, SIZ.XOsiz, SIZ.YOsiz);
+ fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTsiz, SIZ.YTsiz, SIZ.XTsiz, SIZ.YTsiz);
+ fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTOsiz, SIZ.YTOsiz, SIZ.XTOsiz, SIZ.YTOsiz);
+ fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", SIZ.XTnum, SIZ.YTnum);
+ fprintf( logstream, "\t Num of Components: %d\n", SIZ.Csiz);
+
+ for( i=0; i<SIZ.Csiz; i++)
+ fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i], SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i]);
+}
+
+void print_COD( CODmarker_param_t COD)
+{
+ int i;
+
+ fprintf( logstream, "\tCoding style default COD parameters\n");
+ fprintf( logstream, "\t Progression order: %d [ LRCP=0, RLCP=1, RPCL=2, PCRL=3, CPRL=4]\n", COD.prog_order);
+ fprintf( logstream, "\t Num of layers: %d\n", COD.numOflayers);
+ fprintf( logstream, "\t Decomposition lvl: %d\n", COD.numOfdecomp);
+
+ for( i=0; i<=((COD.Scod & 0x01) ? COD.numOfdecomp:0); i++){
+ fprintf( logstream, "\t [%d] XPsiz, YPsiz: (%d,%d) = (%#x, %#x)\n",i, COD.XPsiz[i], COD.YPsiz[i], COD.XPsiz[i], COD.YPsiz[i]);
+ }
+}
+
void delete_index( index_param_t **index)
{
+ int i;
+
delete_metadatalist( &((*index)->metadatalist));
+
+ free( (*index)->COD.XPsiz);
+ free( (*index)->COD.YPsiz);
+
delete_faixbox( &((*index)->tilepart));
+
+ for( i=0; i< (*index)->SIZ.XTnum*(*index)->SIZ.YTnum ;i++)
+ delete_mhixbox( &((*index)->tileheader[i]));
+ free( (*index)->tileheader);
+
+ for( i=0; i<(*index)->SIZ.Csiz; i++)
+ delete_faixbox( &((*index)->precpacket[i]));
+ free( (*index)->precpacket);
+
free(*index);
}
*/
bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx);
+/**
+ * set code index parameters from ppix box
+ * I.3.2.4.6 Precinct Packet Index Table box
+ *
+ * @param[in] cidx_box pointer to the reference cidx_box
+ * @param[out] jp2idx pointer to index parameters
+ * @return if succeeded (true) or failed (false)
+ */
+bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx);
+
bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
{
box_param_t *manf_box;
}
set_tpixdata( cidx_box, jp2idx);
-#ifdef NO_NEED_YET
if( !search_boxheader( "thix", manf)){
fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
+ free(jp2idx);
return false;
}
set_thixdata( cidx_box, jp2idx);
-#endif
+
+ if( !search_boxheader( "ppix", manf)){
+ fprintf( FCGI_stderr, "Error: ppix box not present in manfbox\n");
+ free(jp2idx);
+ return false;
+ }
+ set_ppixdata( cidx_box, jp2idx);
delete_manfbox( &manf);
free( manf_box);
/**
- * set code index parameters from SIZ marker in codestream
+ * set SIZ marker information
* A.5 Fixed information marker segment
* A.5.1 Image and tile size (SIZ)
*
* @param[in] sizmkidx pointer to SIZ marker index in mhix box
* @param[in] codestream codestream parameters
- * @param[out] jp2idx pointer to index parameters
+ * @param[out] SIZ SIZ marker parameters pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ);
+
+/**
+ * set code index parameters from COD marker in codestream
+ * A.6 Functional marker segments
+ * A.6.1 Coding style default (COD)
+ *
+ * @param[in] codmkidx pointer to COD marker index in mhix box
+ * @param[in] codestream codestream parameters
+ * @param[out] COD COD marker parameters pointer
* @return if succeeded (true) or failed (false)
*/
-bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx);
+bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD);
bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx)
{
box_param_t *mhix_box;
mhixbox_param_t *mhix;
markeridx_param_t *sizmkidx;
-
+ markeridx_param_t *codmkidx;
+
if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
return false;
free( mhix_box);
sizmkidx = search_markeridx( 0xff51, mhix);
- set_SIZmkrdata( sizmkidx, codestream, jp2idx);
+ set_SIZmkrdata( sizmkidx, codestream, &(jp2idx->SIZ));
+
+ codmkidx = search_markeridx( 0xff52, mhix);
+ set_CODmkrdata( codmkidx, codestream, &(jp2idx->COD));
delete_mhixbox( &mhix);
box_param_t *tpix_box; //!< tpix box
box_param_t *faix_box; //!< faix box
- if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix")))
+ if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix"))){
+ fprintf( FCGI_stderr, "Error: tpix box not present in cidx box\n");
return false;
+ }
- if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix")))
+ if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix"))){
+ fprintf( FCGI_stderr, "Error: faix box not present in tpix box\n");
return false;
+ }
jp2idx->tilepart = gene_faixbox( faix_box);
boxheader_param_t *ptr;
mhixbox_param_t *mhix;
Byte8_t pos, mhixseqoff;
+ Byte2_t tile_no;
- if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix")))
+ if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix"))){
+ fprintf( FCGI_stderr, "Error: thix box not present in cidx box\n");
return false;
+ }
if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){
+ fprintf( FCGI_stderr, "Error: manf box not present in thix box\n");
free( thix_box);
return false;
}
ptr = manf->first;
mhixseqoff = manf_box->offset+manf_box->length;
pos = 0;
+ tile_no = 0;
+ jp2idx->tileheader = (mhixbox_param_t **)malloc( jp2idx->SIZ.XTnum*jp2idx->SIZ.YTnum*sizeof(mhixbox_param_t *));
while( ptr){
- mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix");
+ if( !(mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix"))){
+ fprintf( FCGI_stderr, "Error: mhix box not present in thix box\n");
+ delete_manfbox( &manf);
+ free( manf_box);
+ free( thix_box);
+ return false;
+ }
mhix = gene_mhixbox( mhix_box);
pos += mhix_box->length;
ptr = ptr->next;
free( mhix_box);
- delete_mhixbox( &mhix);
+ jp2idx->tileheader[tile_no++] = mhix;
}
delete_manfbox( &manf);
return true;
}
+bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx)
+{
+ box_param_t *ppix_box, *faix_box, *manf_box;
+ manfbox_param_t *manf; //!< manf
+ boxheader_param_t *bh; //!< box headers
+ faixbox_param_t *faix; //!< faix
+ Byte8_t inbox_offset;
+ int comp_idx;
+
+ if( !(ppix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "ppix"))){
+ fprintf( FCGI_stderr, "Error: ppix box not present in cidx box\n");
+ return false;
+ }
+
+ inbox_offset = get_DBoxoff( ppix_box);
+ if( !(manf_box = gene_boxbyType( ppix_box->fd, inbox_offset, get_DBoxlen( ppix_box), "manf"))){
+ fprintf( FCGI_stderr, "Error: manf box not present in ppix box\n");
+ free( ppix_box);
+ return false;
+ }
+
+ free( ppix_box);
+
+ manf = gene_manfbox( manf_box);
+ bh = search_boxheader( "faix", manf);
+ inbox_offset = manf_box->offset + manf_box->length;
+
+ free( manf_box);
+
+ jp2idx->precpacket = (faixbox_param_t **)malloc( jp2idx->SIZ.Csiz*sizeof(faixbox_param_t *));
+
+ for( comp_idx=0; bh!=NULL; bh=bh->next, comp_idx++){
+ if( jp2idx->SIZ.Csiz <= comp_idx ){
+ fprintf( FCGI_stderr, "Error: num of faix boxes is not identical to num of components in ppix box\n");
+ return false;
+ }
+
+ if( !(faix_box = gene_boxbyOffset( cidx_box->fd, inbox_offset))){
+ fprintf( FCGI_stderr, "Error: faix box not present in ppix box\n");
+ return false;
+ }
+
+ faix = gene_faixbox( faix_box);
+ jp2idx->precpacket[comp_idx] = faix;
+
+ inbox_offset = faix_box->offset + faix_box->length;
+ free( faix_box);
+ }
+
+ free(manf);
+
+ return true;
+}
+
-bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx)
+bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ)
{
marker_param_t sizmkr;
int i;
sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length);
- if( sizmkidx->length != fetch_marker2bytebigendian( sizmkr, 0)){
+ SIZ->Lsiz = fetch_marker2bytebigendian( sizmkr, 0);
+
+ if( sizmkidx->length != SIZ->Lsiz){
fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
return false;
}
- jp2idx->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
- jp2idx->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
- jp2idx->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
- jp2idx->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
- jp2idx->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
- jp2idx->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
- jp2idx->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
- jp2idx->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
- jp2idx->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
- jp2idx->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
-
- jp2idx->XTnum = ( jp2idx->Xsiz-jp2idx->XTOsiz+jp2idx->XTsiz-1)/jp2idx->XTsiz;
- jp2idx->YTnum = ( jp2idx->Ysiz-jp2idx->YTOsiz+jp2idx->YTsiz-1)/jp2idx->YTsiz;
+ SIZ->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
+ SIZ->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
+ SIZ->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
+ SIZ->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
+ SIZ->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
+ SIZ->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
+ SIZ->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
+ SIZ->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
+ SIZ->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
+ SIZ->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
+
+ SIZ->XTnum = ( SIZ->Xsiz-SIZ->XTOsiz+SIZ->XTsiz-1)/SIZ->XTsiz;
+ SIZ->YTnum = ( SIZ->Ysiz-SIZ->YTOsiz+SIZ->YTsiz-1)/SIZ->YTsiz;
+
+ for( i=0; i<(int)SIZ->Csiz; i++){
+ SIZ->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
+ SIZ->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
+ SIZ->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
+ }
+ return true;
+}
+
+bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD)
+{
+ marker_param_t codmkr;
+ int i;
+
+ codmkr = set_marker( codestream, codmkidx->code, codmkidx->offset, codmkidx->length);
+
+ COD->Lcod = fetch_marker2bytebigendian( codmkr, 0);
+
+ if( codmkidx->length != COD->Lcod){
+ fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", codmkidx->code);
+ return false;
+ }
+
+ COD->Scod = fetch_marker1byte( codmkr, 2);
+ COD->prog_order = fetch_marker1byte( codmkr, 3);
+ COD->numOflayers = fetch_marker2bytebigendian( codmkr, 4);
+ COD->numOfdecomp = fetch_marker1byte( codmkr, 7);
- for( i=0; i<(int)jp2idx->Csiz; i++){
- jp2idx->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
- jp2idx->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
- jp2idx->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
+ if(COD->Scod & 0x01){
+ COD->XPsiz = (Byte4_t *)malloc( (COD->numOfdecomp+1)*sizeof(Byte4_t));
+ COD->YPsiz = (Byte4_t *)malloc( (COD->numOfdecomp+1)*sizeof(Byte4_t));
+
+ for( i=0; i<=COD->numOfdecomp; i++){
+ //precinct size
+ COD->XPsiz[i] = pow( 2, fetch_marker1byte( codmkr, 12+i) & 0x0F);
+ COD->YPsiz[i] = pow( 2,(fetch_marker1byte( codmkr, 12+i) & 0xF0) >> 4);
+ }
+ }
+ else{
+ COD->XPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD->YPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+
+ COD->XPsiz[0] = COD->YPsiz[0] = pow(2,15);
}
return true;
}
Byte4_t max( Byte4_t n1, Byte4_t n2);
Byte4_t min( Byte4_t n1, Byte4_t n2);
-range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level);
+range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level);
-range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level)
+range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
{
- return get_tile_range( index.XOsiz, index.Xsiz, index.XTOsiz, index.XTsiz, tile_xid, level);
+ return get_tile_range( SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz, tile_id%SIZ.XTnum, level);
}
-range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level)
+range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
{
- return get_tile_range( index.YOsiz, index.Ysiz, index.YTOsiz, index.YTsiz, tile_yid, level);
+ return get_tile_range( SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz, tile_id/SIZ.XTnum, level);
}
-range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level)
+range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level)
{
range_param_t range;
int n;
- range.minvalue = max( Osiz, TOsiz+tile_id*Tsiz);
- range.maxvalue = min( siz, TOsiz+(tile_id+1)*Tsiz);
+ range.minvalue = max( Osiz, TOsiz+tile_XYid*Tsiz);
+ range.maxvalue = min( siz, TOsiz+(tile_XYid+1)*Tsiz);
for( n=0; n<level; n++){
range.minvalue = ceil(range.minvalue/2.0);
return range;
}
+Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ range_param_t tile_Xrange;
+
+ tile_Xrange = get_tile_Xrange( SIZ, tile_id, level);
+ return tile_Xrange.maxvalue - tile_Xrange.minvalue;
+}
+
+Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ range_param_t tile_Yrange;
+
+ tile_Yrange = get_tile_Yrange( SIZ, tile_id, level);
+ return tile_Yrange.maxvalue - tile_Yrange.minvalue;
+}
+
Byte4_t max( Byte4_t n1, Byte4_t n2)
{
if( n1 < n2)
#include "byte_manager.h"
#include "faixbox_manager.h"
#include "metadata_manager.h"
+#include "mhixbox_manager.h"
-//! index parameters
-typedef struct index_param{
- metadatalist_param_t *metadatalist; //!< metadata-bin list
- Byte8_t offset; //!< codestream offset
- Byte8_t length; //!< codestream length
- Byte8_t mhead_length; //!< main header length
- //! A.5.1 Image and tile size (SIZ)
+//! progression order
+typedef enum porder {
+ PROG_UNKNOWN = -1, /**< place-holder */
+ LRCP = 0, /**< layer-resolution-component-precinct order */
+ RLCP = 1, /**< resolution-layer-component-precinct order */
+ RPCL = 2, /**< resolution-precinct-component-layer order */
+ PCRL = 3, /**< precinct-component-resolution-layer order */
+ CPRL = 4 /**< component-precinct-resolution-layer order */
+} porder_t;
+
+//! A.5.1 Image and tile size (SIZ)
+typedef struct SIZmarker_param{
+ Byte2_t Lsiz; //!< length of marker segment excluding the marker
Byte2_t Rsiz; //!< capabilities that a decoder needs
Byte4_t Xsiz; //!< width of the reference grid
Byte4_t Ysiz; //!< height of the reference grid
- Byte4_t XOsiz; //!< horizontal offset from the origin of
- //!the reference grid to the left side of the image area
- Byte4_t YOsiz; //!< vertical offset from the origin of
- //!the reference grid to the top side of the image area
- Byte4_t XTsiz; //!< width of one reference tile with
- //!respect to the reference grid
- Byte4_t YTsiz; //!< height of one reference tile with
- //!respect to the reference grid
- Byte4_t XTOsiz; //!< horizontal offset from the origin of
- //!the reference grid to the left side of the first tile
- Byte4_t YTOsiz; //!< vertical offset from the origin of
- //!the reference grid to the top side of
- //!the first tile
+ Byte4_t XOsiz; //!< horizontal offset from the origin of the reference grid to the left side of the image area
+ Byte4_t YOsiz; //!< vertical offset from the origin of the reference grid to the top side of the image area
+ Byte4_t XTsiz; //!< width of one reference tile with respect to the reference grid
+ Byte4_t YTsiz; //!< height of one reference tile with respect to the reference grid
+ Byte4_t XTOsiz; //!< horizontal offset from the origin of the reference grid to the left side of the first tile
+ Byte4_t YTOsiz; //!< vertical offset from the origin of the reference grid to the top side of the first tile
Byte4_t XTnum; //!< number of tiles in horizontal direction
- Byte4_t YTnum; //!< number of tiles in vertical
- //!direction
+ Byte4_t YTnum; //!< number of tiles in vertical direction
Byte2_t Csiz; //!< number of the components in the image
+ Byte_t Ssiz[3]; //!< precision (depth) in bits and sign of the component samples
+ Byte_t XRsiz[3]; //!< horizontal separation of a sample of component with respect to the reference grid
+ Byte_t YRsiz[3]; //!< vertical separation of a sample of component with respect to the reference grid
+} SIZmarker_param_t;
- Byte_t Ssiz[3]; //!< precision (depth) in bits and sign
- //!of the component samples
- Byte_t XRsiz[3]; //!< horizontal separation of a sample of
- //!component with respect to the reference grid
- Byte_t YRsiz[3]; //!< vertical separation of a sample of
- //!component with respect to the reference grid
- faixbox_param_t *tilepart; //!< tile part information from tpix box
+//! A.6.1 Coding style default (COD)
+typedef struct CODmarker_param{
+ Byte2_t Lcod; //!< length of marker segment excluding the marker
+ Byte_t Scod; //!< Coding style for all components
+ porder_t prog_order; //!< progression order
+ Byte2_t numOflayers; //!< number of layers
+ Byte_t numOfdecomp; //!< number of decompositions levels
+ Byte4_t *XPsiz; //!< dynamic array of precinct width at successive resolution level in order
+ Byte4_t *YPsiz; //!< dynamic array of precinct height at successive resolution level in order
+} CODmarker_param_t;
+
+//! index parameters
+typedef struct index_param{
+ metadatalist_param_t *metadatalist; //!< metadata-bin list
+ Byte8_t offset; //!< codestream offset
+ Byte8_t length; //!< codestream length
+ Byte8_t mhead_length; //!< main header length
+ SIZmarker_param_t SIZ; // !< SIZ marker information
+ CODmarker_param_t COD; // !< COD marker information
+ faixbox_param_t *tilepart; //!< tile part information from tpix box
+ mhixbox_param_t **tileheader; //!< dynamic array of tile header information from thix box
+ faixbox_param_t **precpacket; //!< dynamic array of precint packet information from ppix box
} index_param_t;
*/
void print_index( index_param_t index);
+/**
+ * print Image and Tile SIZ parameters
+ *
+ * @param[in] SIZ SIZ marker information
+ */
+void print_SIZ( SIZmarker_param_t SIZ);
+
+/**
+ * print Coding style default COD parameters
+ *
+ * @param[in] COD COD marker information
+ */
+void print_COD( CODmarker_param_t COD);
/**
* delete index
/**
* get horizontal range of the tile in reference grid
*
- * @param[in] index index parameters
- * @param[in] tile_xid tile id in x-direction (0<= <XTnum)
+ * @param[in] SIZ SIZ marker information
+ * @param[in] tile_id tile id
* @param[in] level decomposition level
* @return structured range parameter
*/
-range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level);
+range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
/**
* get vertical range of the tile in reference grid
*
- * @param[in] index index parameters
- * @param[in] tile_yid tile id in y-direction (0<= <YTnum)
+ * @param[in] SIZ SIZ marker information
+ * @param[in] tile_id tile id
* @param[in] level decomposition level
* @return structured range parameter
*/
-range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level);
+range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+
+/**
+ * get tile wdith at the decomposition level
+ *
+ * @param[in] SIZ SIZ marker information
+ * @param[in] tile_id tile id
+ * @param[in] level decomposition level
+ * @return tile width
+ */
+Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
#endif /* !INDEX_MANAGER_H_ */
--- /dev/null
+/*
+ * $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 <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "j2kheader_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
+
+
+SIZmarker_param_t get_SIZmkrdata_from_j2kstream( Byte_t *SIZstream);
+CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream);
+
+bool get_mainheader_from_j2kstream( Byte_t *j2kstream, SIZmarker_param_t *SIZ, CODmarker_param_t *COD)
+{
+ if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
+ fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
+ return false;
+ }
+
+ if( SIZ){
+ *SIZ = get_SIZmkrdata_from_j2kstream( j2kstream);
+ if( SIZ->Lsiz == 0)
+ return false;
+
+ j2kstream += (SIZ->Lsiz+2);
+ }
+
+ if( COD){
+ if( !SIZ)
+ j2kstream += (big2( j2kstream+2) + 2);
+
+ *COD = get_CODmkrdata_from_j2kstream( j2kstream);
+ if( COD->Lcod == 0)
+ return false;
+ }
+ return true;
+}
+
+SIZmarker_param_t get_SIZmkrdata_from_j2kstream( Byte_t *SIZstream)
+{
+ SIZmarker_param_t SIZ ={0};
+ int i;
+
+ if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
+ fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
+ return SIZ;
+ }
+
+ SIZ.Lsiz = big2( SIZstream);
+ SIZ.Rsiz = big2( SIZstream+2);
+ SIZ.Xsiz = big4( SIZstream+4);
+ SIZ.Ysiz = big4( SIZstream+8);
+ SIZ.XOsiz = big4( SIZstream+12);
+ SIZ.YOsiz = big4( SIZstream+16);
+ SIZ.XTsiz = big4( SIZstream+20);
+ SIZ.YTsiz = big4( SIZstream+24);
+ SIZ.XTOsiz = big4( SIZstream+28);
+ SIZ.YTOsiz = big4( SIZstream+32);
+ SIZ.Csiz = big2( SIZstream+36);
+
+ SIZ.XTnum = ( SIZ.Xsiz-SIZ.XTOsiz+SIZ.XTsiz-1)/SIZ.XTsiz;
+ SIZ.YTnum = ( SIZ.Ysiz-SIZ.YTOsiz+SIZ.YTsiz-1)/SIZ.YTsiz;
+
+ for( i=0; i<(int)SIZ.Csiz; i++){
+ SIZ.Ssiz[i] = *(SIZstream+(38+i*3));
+ SIZ.XRsiz[i] = *(SIZstream+(39+i*3));
+ SIZ.YRsiz[i] = *(SIZstream+(40+i*3));
+ }
+
+ return SIZ;
+}
+
+CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream)
+{
+ CODmarker_param_t COD;
+ int i;
+
+ if( *CODstream++ != 0xff || *CODstream++ != 0x52){
+ fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
+ return COD;
+ }
+
+ COD.Lcod = big2( CODstream);
+ COD.Scod = *( CODstream+2);
+ COD.prog_order = *( CODstream+3);
+ COD.numOflayers = big2( CODstream+4);
+ COD.numOfdecomp = *( CODstream+7);
+
+ if(COD.Scod & 0x01){
+ COD.XPsiz = (Byte4_t *)malloc( (COD.numOfdecomp+1)*sizeof(Byte4_t));
+ COD.YPsiz = (Byte4_t *)malloc( (COD.numOfdecomp+1)*sizeof(Byte4_t));
+
+ for( i=0; i<=COD.numOfdecomp; i++){
+ //precinct size
+ COD.XPsiz[i] = pow( 2, *( CODstream+12+i) & 0x0F);
+ COD.YPsiz[i] = pow( 2, (*( CODstream+12+i) & 0xF0) >> 4);
+ }
+ }
+ else{
+ COD.XPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD.YPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD.XPsiz[0] = COD.YPsiz[0] = pow(2,15);
+ }
+ return COD;
+}
+
+
+bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream);
+Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream);
+
+bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen)
+{
+ Byte2_t newLcod;
+
+ if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
+ fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
+ return false;
+ }
+
+ if(!modify_SIZmkrstream( SIZ, COD.numOfdecomp-numOfdecomp, j2kstream))
+ return false;
+
+ j2kstream += SIZ.Lsiz+2;
+ 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));
+ *j2klen -= ( COD.Lcod - newLcod);
+
+ return true;
+}
+
+bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream)
+{
+ int i;
+
+ if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
+ fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
+ return false;
+ }
+
+ for( i=0; i<difOfdecomplev; i++){
+ SIZ.Xsiz = ceil( (double)SIZ.Xsiz/2.0);
+ SIZ.Ysiz = ceil( (double)SIZ.Ysiz/2.0);
+ SIZ.XOsiz = ceil( (double)SIZ.XOsiz/2.0);
+ SIZ.YOsiz = ceil( (double)SIZ.YOsiz/2.0);
+ SIZ.XTsiz = ceil( (double)SIZ.XTsiz/2.0);
+ SIZ.YTsiz = ceil( (double)SIZ.YTsiz/2.0);
+ SIZ.XTOsiz = ceil( (double)SIZ.XTOsiz/2.0);
+ SIZ.YTOsiz = ceil( (double)SIZ.YTOsiz/2.0);
+ }
+
+ SIZstream += 4; // skip Lsiz + Rsiz
+
+ modify_4Bytecode( SIZ.Xsiz, SIZstream);
+ modify_4Bytecode( SIZ.Ysiz, SIZstream+4);
+ modify_4Bytecode( SIZ.XOsiz, SIZstream+8);
+ modify_4Bytecode( SIZ.YOsiz, SIZstream+12);
+ modify_4Bytecode( SIZ.XTsiz, SIZstream+16);
+ modify_4Bytecode( SIZ.YTsiz, SIZstream+20);
+ modify_4Bytecode( SIZ.XTOsiz, SIZstream+24);
+ modify_4Bytecode( SIZ.YTOsiz, SIZstream+28);
+
+ return true;
+}
+
+Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream)
+{
+ Byte2_t newLcod;
+
+ if( *CODstream++ != 0xff || *CODstream++ != 0x52){
+ fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
+ return 0;
+ }
+
+ newLcod = 13+numOfdecomp;
+
+ *CODstream++ = (Byte_t)((Byte2_t)(newLcod & 0xff00) >> 8);
+ *CODstream++ = (Byte_t)(newLcod & 0x00ff);
+
+ CODstream += 5; // skip Scod & SGcod
+
+ // SPcod
+ *CODstream++ = (Byte_t) numOfdecomp;
+
+ return newLcod;
+}
+
+bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc);
+
+bool modify_tileheader( Byte_t *j2kstream, Byte8_t SOToffset, int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen)
+{
+ Byte4_t Psot; // tile part length ref A.4.2 Start of tile-part SOT
+ Byte_t *thstream, *SOTstream, *Psot_stream;
+ Byte2_t oldLcoc, newLcoc;
+
+ SOTstream = thstream = j2kstream+SOToffset;
+
+ if( *SOTstream++ != 0xff || *SOTstream++ != 0x90){
+ fprintf( FCGI_stderr, "Error, thstream is not starting with SOT marker\n");
+ return false;
+ }
+
+ SOTstream += 4; // skip Lsot & Isot
+ Psot = (SOTstream[0]<<24)+(SOTstream[1]<<16)+(SOTstream[2]<<8)+(SOTstream[3]);
+ Psot_stream = SOTstream;
+
+ thstream += 12; // move to next marker (SOT always 12bytes)
+
+ while( !( *thstream == 0xff && *(thstream+1) == 0x93)){ // search SOD
+ if( numOfdecomp != -1 && *thstream == 0xff && *(thstream+1) == 0x53){ // COC
+ if( !modify_COCmkrstream( numOfdecomp, thstream, Csiz, &oldLcoc, &newLcoc))
+ return false;
+
+ memmove( thstream+newLcoc+2, thstream+oldLcoc+2, (*j2klen)-(thstream-j2kstream+oldLcoc+2));
+ *j2klen -= ( oldLcoc - newLcoc);
+ }
+ thstream += 2;
+ thstream += ((thstream[0]<<8)+(thstream[1])); // marker length
+ }
+
+ if( (*j2klen)-SOToffset < Psot){
+ Psot = (*j2klen)-SOToffset;
+ modify_4Bytecode( Psot, Psot_stream);
+ }
+ return true;
+}
+
+bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc)
+{
+ if( *COCstream++ != 0xff || *COCstream++ != 0x53){
+ fprintf( FCGI_stderr, "Error, COC marker not found in the reconstructed j2kstream\n");
+ return false;
+ }
+
+ *oldLcoc = big2( COCstream);
+ *newLcoc = (Csiz < 257 ? 10 : 11) + numOfdecomp;
+ *COCstream++ = (Byte_t)((Byte2_t)((*newLcoc) & 0xff00) >> 8);
+ *COCstream++ = (Byte_t)((*newLcoc) & 0x00ff);
+
+ if( Csiz < 257) COCstream +=2; // skip Ccoc & Scoc
+ else COCstream += 3;
+
+ *COCstream = numOfdecomp;
+
+ return true;
+}
--- /dev/null
+/*
+ * $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 J2KHEADER_MANAGER_H_
+# define J2KHEADER_MANAGER_H_
+
+#include "bool.h"
+#include "byte_manager.h"
+#include "index_manager.h"
+
+/**
+ * get main header information from j2k codestream
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[out] SIZ SIZ marker pointer
+ * @param[out] COD COD marker pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool get_mainheader_from_j2kstream( Byte_t *j2kstream, SIZmarker_param_t *SIZ, CODmarker_param_t *COD);
+
+/**
+ * modify main header in j2k codestream to fit with the new number of decompositions
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[in] numOfdecomp the New number of decompositions
+ * @param[in] SIZ original SIZ marker information
+ * @param[in] COD original COD marker information
+ * @param[out] j2klen pointer to the length of j2k code stream
+ * @return if succeeded (true) or failed (false)
+ */
+bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen);
+
+/**
+ * modify tile header in j2k codestream to fit with the tile part length, and new number of decompositions for multi-componet images
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[in] SOToffset offset of SOT marker from the beginning of j2kstream
+ * @param[in] numOfdecomp the New number of decompositions, -1 if the same as original
+ * @param[in] Csiz number of components
+ * @param[out] j2klen pointer to the length of j2k code stream
+ * @return if succeeded (true) or failed (false)
+ */
+bool modify_tileheader( Byte_t *j2kstream, Byte8_t SOToffset, int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen);
+
+#endif /* !J2KHEADER_MANAGER_H_ */
--- /dev/null
+/*
+ * $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 <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "jp2k_encoder.h"
+#include "j2kheader_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
+
+
+/**
+ * search a message by class_id
+ *
+ * @param[in] class_id class identifiers
+ * @param[in] in_class_id in-class identifiers, -1 means any
+ * @param[in] csn codestream number
+ * @param[in] msg first message pointer of the searching list
+ * @return found message pointer
+ */
+message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg);
+
+/**
+ * reconstruct j2k codestream from JPT- (in future, JPP-) stream
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original JPT- JPP- stream
+ * @param[in] csn codestream number
+ * @param[in] fw reconstructing image frame width
+ * @param[in] fh reconstructing image frame height
+ * @param[out] codelen codestream length
+ * @return generated reconstructed j2k codestream
+ */
+Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *codelen);
+
+Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+
+ if( !msgqueue)
+ return NULL;
+
+ j2kstream = recons_codestream( msgqueue, jpipstream, csn, fw, fh, j2klen);
+
+ return j2kstream;
+}
+
+Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len);
+Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len)
+{
+ message_param_t *ptr;
+ Byte_t *jp2stream = NULL;
+ Byte_t *codestream = NULL;
+ Byte8_t codelen;
+ Byte8_t jp2cDBoxOffset = 0, jp2cDBoxlen = 0;
+
+ *jp2len = 0;
+
+ if( !msgqueue)
+ return NULL;
+
+ ptr = msgqueue->first;
+ while(( ptr = search_message( METADATA_MSG, -1, csn, ptr))!=NULL){
+ if( ptr->phld){
+ if( strncmp( (char *)ptr->phld->OrigBH+4, "jp2c", 4) == 0){
+ jp2cDBoxOffset = *jp2len + ptr->phld->OrigBHlen;
+ jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
+ jp2cDBoxlen = *jp2len - jp2cDBoxOffset;
+ }
+ else
+ jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
+ }
+ jp2stream = add_msgstream( ptr, jpipstream, jp2stream, jp2len);
+ ptr = ptr->next;
+ }
+
+ codestream = recons_codestream( msgqueue, jpipstream, csn, 0, 0, &codelen);
+
+ if( jp2cDBoxOffset != 0 && codelen <= jp2cDBoxlen)
+ memcpy( jp2stream+jp2cDBoxOffset, codestream, codelen);
+
+ free( codestream);
+
+ return jp2stream;
+}
+
+bool isJPPstream( Byte8_t csn, msgqueue_param_t *msgqueue);
+
+Byte_t * recons_codestream_from_JPTstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, 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);
+
+Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *codelen)
+{
+ if( isJPPstream( csn, msgqueue))
+ return recons_codestream_from_JPPstream( msgqueue, jpipstream, csn, fw, fh, codelen);
+ else
+ return recons_codestream_from_JPTstream( msgqueue, jpipstream, csn, fw, fh, codelen);
+}
+
+bool isJPPstream( Byte8_t csn, msgqueue_param_t *msgqueue)
+{
+ message_param_t *msg;
+
+ msg = msgqueue->first;
+ while( msg){
+ if( msg->csn == csn){
+ if( msg->class_id <= 2)
+ return true;
+ else
+ if( msg->class_id == 4 || msg->class_id == 5)
+ return false;
+ }
+ msg = msg->next;
+ }
+
+ fprintf( FCGI_stderr, "Error, message of csn %lld not found\n", csn);
+
+ return false;
+}
+
+Byte_t * add_mainhead_msgstream( msgqueue_param_t *msgqueue, Byte_t *origstream, Byte_t *j2kstream, Byte8_t csn, Byte8_t *j2klen);
+Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, bool isJPPstream);
+Byte_t * add_emptytilestream( const Byte8_t tileID, Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_codestream_from_JPTstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+ Byte8_t last_tileID, tileID;
+ bool found;
+ Byte8_t binOffset;
+ message_param_t *ptr;
+ SIZmarker_param_t SIZ;
+ int mindeclev;
+
+ *j2klen = 0;
+ j2kstream = add_mainhead_msgstream( msgqueue, jpipstream, j2kstream, csn, j2klen);
+
+ if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, NULL))
+ return j2kstream;
+
+ if( fw <= 0 || fh <= 0)
+ mindeclev = 0;
+ else
+ mindeclev = comp_decomplev( fw, fh, SIZ.Xsiz, SIZ.Ysiz);
+
+ last_tileID = get_last_tileID( msgqueue, csn, false);
+
+ for( tileID=0; tileID <= last_tileID; tileID++){
+ found = false;
+ binOffset = 0;
+
+ ptr = msgqueue->first;
+ while(( ptr = search_message( TILE_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ found = true;
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+ ptr = msgqueue->first;
+ while(( ptr = search_message( EXT_TILE_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->aux > mindeclev){
+ if( ptr->bin_offset == binOffset){
+ found = true;
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ }
+ ptr = ptr->next;
+ }
+ if(!found)
+ j2kstream = add_emptytilestream( tileID, j2kstream, j2klen);
+ }
+
+ j2kstream = add_EOC( j2kstream, j2klen);
+
+ 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 * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+ Byte8_t tileID, last_tileID;
+ Byte8_t SOToffset;
+ bool foundTH;
+ Byte8_t binOffset;
+ message_param_t *ptr;
+ SIZmarker_param_t SIZ;
+ CODmarker_param_t COD;
+ int max_reslev, mindeclev;
+
+ *j2klen = 0;
+ j2kstream = add_mainhead_msgstream( msgqueue, jpipstream, j2kstream, csn, j2klen);
+
+ 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
+ mindeclev = comp_decomplev( fw, fh, SIZ.Xsiz, SIZ.Ysiz);
+
+ max_reslev = -1;
+ last_tileID = get_last_tileID( msgqueue, csn, true);
+
+ for( tileID=0; tileID <= last_tileID; tileID++){
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+ foundTH = false;
+ SOToffset = *j2klen;
+ while(( ptr = search_message( TILE_HEADER_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ foundTH = true;
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+
+ if( foundTH){
+ j2kstream = recons_RPCLbitstream( 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;
+}
+
+Byte_t * add_mainhead_msgstream( msgqueue_param_t *msgqueue, Byte_t *origstream, Byte_t *j2kstream, Byte8_t csn, Byte8_t *j2klen)
+{
+ message_param_t *ptr;
+ Byte8_t binOffset;
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+
+ while(( ptr = search_message( MAINHEADER_MSG, -1, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ j2kstream = add_msgstream( ptr, origstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+ return j2kstream;
+}
+
+Byte_t * add_padding( Byte8_t padding, Byte_t *j2kstream, 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;
+ bool foundPrec;
+ Byte8_t binOffset, precID, seqID;
+ Byte4_t XTsiz, YTsiz;
+ message_param_t *ptr;
+
+ for( r=0, seqID=0; r<=(COD.numOfdecomp-mindeclev); r++){
+ XTsiz = get_tile_XSiz( SIZ, tileID, COD.numOfdecomp-r);
+ YTsiz = get_tile_YSiz( SIZ, tileID, COD.numOfdecomp-r);
+
+ for( p=0; p<ceil((double)XTsiz/(double)COD.XPsiz[r])*ceil((double)YTsiz/(double)COD.YPsiz[r]); 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)
+ j2kstream = add_padding( 1, j2kstream, j2klen);
+ }
+ }
+ }
+ return j2kstream;
+}
+
+Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, bool isJPPstream)
+{
+ Byte8_t last_tileID = 0;
+ message_param_t *msg;
+
+ msg = msgqueue->first;
+ while( msg){
+ if( isJPPstream){
+ if((msg->class_id == TILE_HEADER_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
+ last_tileID = msg->in_class_id;
+ }
+ else{
+ if((msg->class_id == TILE_MSG || msg->class_id == EXT_TILE_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
+ last_tileID = msg->in_class_id;
+ }
+ msg = msg->next;
+ }
+ return last_tileID;
+}
+
+
+message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg)
+{
+ while( msg != NULL){
+ if( in_class_id == -1){
+ if( msg->class_id == class_id && msg->csn == csn)
+ return msg;
+ }
+ else{
+ if( msg->class_id == class_id && msg->in_class_id == in_class_id && msg->csn == csn)
+ return msg;
+ }
+ msg = msg->next;
+ }
+ return NULL;
+}
+
+
+Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length);
+Byte_t * gene_emptytilestream( const Byte8_t tileID, Byte8_t *length);
+
+Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte_t *newstream;
+ Byte8_t newlen;
+ Byte_t *buf;
+
+ if( !message)
+ return NULL;
+
+ newstream = gene_msgstream( message, origstream, &newlen);
+
+ buf = (Byte_t *)malloc(( *j2klen)+newlen);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memcpy( buf+(*j2klen), newstream, newlen);
+
+ *j2klen += newlen;
+
+ free( newstream);
+ if(j2kstream) free(j2kstream);
+
+ return buf;
+}
+
+
+Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len)
+{
+ Byte_t *newstream;
+ Byte8_t newlen;
+ Byte_t *buf;
+
+ if( phld->OrigBHlen == 8)
+ newlen = big4(phld->OrigBH);
+ else
+ newlen = big8(phld->OrigBH+8);
+
+ newstream = (Byte_t *)malloc( newlen);
+ memset( newstream, 0, newlen);
+ memcpy( newstream, phld->OrigBH, phld->OrigBHlen);
+
+ buf = (Byte_t *)malloc(( *jp2len)+newlen);
+
+ memcpy( buf, jp2stream, *jp2len);
+ memcpy( buf+(*jp2len), newstream, newlen);
+
+ *jp2len += newlen;
+
+ free( newstream);
+ if(jp2stream) free(jp2stream);
+
+ return buf;
+}
+
+Byte_t * add_emptytilestream( const Byte8_t tileID, Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte_t *newstream;
+ Byte8_t newlen;
+ Byte_t *buf;
+
+ newstream = gene_emptytilestream( tileID, &newlen);
+
+ buf = (Byte_t *)malloc(( *j2klen)+newlen);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memcpy( buf+(*j2klen), newstream, newlen);
+
+ *j2klen += newlen;
+
+ free( newstream);
+ if(j2kstream) free(j2kstream);
+
+ return buf;
+}
+
+Byte_t * add_padding( Byte8_t padding, Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte_t *buf;
+
+ buf = (Byte_t *)malloc(( *j2klen)+padding);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memset( buf+(*j2klen), 0, padding);
+
+ *j2klen += padding;
+
+ if(j2kstream) free(j2kstream);
+
+ return buf;
+}
+
+Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte2_t EOC = 0xd9ff;
+
+ Byte_t *buf;
+
+ buf = (Byte_t *)malloc(( *j2klen)+2);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memcpy( buf+(*j2klen), &EOC, 2);
+
+ *j2klen += 2;
+
+ if(j2kstream) free(j2kstream);
+
+ return buf;
+}
+
+Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length)
+{
+ Byte_t *buf;
+
+ if( !message)
+ return NULL;
+
+ *length = message->length;
+ buf = (Byte_t *)malloc( *length);
+ memcpy( buf, stream+message->res_offset, *length);
+
+ return buf;
+}
+
+Byte_t * gene_emptytilestream( const Byte8_t tileID, Byte8_t *length)
+{
+ Byte_t *buf;
+ const Byte2_t SOT = 0x90ff;
+ const Byte2_t Lsot = 0xa << 8;
+ Byte2_t Isot;
+ const Byte4_t Psot = 0xe << 24;
+ const Byte_t TPsot = 0, TNsot = 1;
+ const Byte2_t SOD = 0x93ff;
+
+ *length = 14;
+ buf = (Byte_t *)malloc(*length);
+
+ Isot = (((Byte2_t)tileID) << 8) | ((((Byte2_t)tileID) & 0xf0) >> 8);
+
+ memcpy( buf, &SOT, 2);
+ memcpy( buf+2, &Lsot, 2);
+ memcpy( buf+4, &Isot, 2);
+ memcpy( buf+6, &Psot, 4);
+ memcpy( buf+10, &TPsot, 1);
+ memcpy( buf+11, &TNsot, 1);
+ memcpy( buf+12, &SOD, 2);
+
+ return buf;
+}
--- /dev/null
+/*
+ * $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 JP2K_ENCODER_H_
+# define JP2K_ENCODER_H_
+
+#include "byte_manager.h"
+#include "msgqueue_manager.h"
+
+/**
+ * reconstruct j2k codestream from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original jpt- jpp- stream
+ * @param[in] csn codestream number
+ * @param[in] fw reconstructing image frame width
+ * @param[in] fh reconstructing image frame height
+ * @param[out] j2klen pointer to the j2k codestream length
+ * @return generated reconstructed j2k codestream
+ */
+Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen);
+
+
+/**
+ * reconstruct jp2 file codestream from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original jpt- jpp- stream
+ * @param[in] csn codestream number
+ * @param[out] jp2len pointer to the jp2 codestream length
+ * @return generated reconstructed jp2 codestream
+ */
+Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len);
+
+
+#endif /* !JP2K_ENCODER_H_ */
* @param[in] metadatalist metadata list pointer
*/
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist);
+
#endif /* !METADATA_MANAGER_H_ */
* 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
#include <stdio.h>
#include <stdlib.h>
-#include <math.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
-#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "msgqueue_manager.h"
#include "metadata_manager.h"
-
+#include "index_manager.h"
#ifdef SERVER
#include "fcgi_stdio.h"
#define logstream stderr
#endif //SERVER
-#define PRECINCT_MSG 0
-#define EXT_PRECINCT_MSG 1
-#define TILE_HEADER_MSG 2
-#define TILE_MSG 4
-#define EXT_TILE_MSG 5
-#define MAINHEADER_MSG 6
-#define METADATA_MSG 8
-
msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel)
{
msgqueue_param_t *msgqueue;
void print_msgqueue( msgqueue_param_t *msgqueue)
{
message_param_t *ptr;
+ char *message_class[] = { "Precinct", "Ext-Prec", "TileHead", "non", "Tile", "Ext-Tile", "Main", "non", "Meta"};
if( !msgqueue)
return;
ptr = msgqueue->first;
while( ptr){
- fprintf( logstream, "\t class_id: %lld\n", ptr->class_id );
+ fprintf( logstream, "\t class_id: %lld %s\n", ptr->class_id, message_class[ptr->class_id]);
fprintf( logstream, "\t in_class_id: %lld\n", ptr->in_class_id );
fprintf( logstream, "\t csn: %lld\n", ptr->csn );
fprintf( logstream, "\t bin_offset: %#llx\n", ptr->bin_offset );
{
cachemodel_param_t *cachemodel;
target_param_t *target;
+ index_param_t *codeidx;
message_param_t *msg;
cachemodel = msgqueue->cachemodel;
target = cachemodel->target;
-
+ codeidx = target->codeidx;
+
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = true;
msg->class_id = MAINHEADER_MSG;
msg->csn = target->csn;
msg->bin_offset = 0;
- msg->length = target->codeidx->mhead_length;
+ msg->length = codeidx->mhead_length;
msg->aux = 0; // non exist
- msg->res_offset = target->codeidx->offset;
+ msg->res_offset = codeidx->offset;
msg->phld = NULL;
msg->next = NULL;
cachemodel->mhead_model = true;
}
+void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue)
+{
+ cachemodel_param_t *cachemodel;
+ target_param_t *target;
+ index_param_t *codeidx;
+ message_param_t *msg;
+
+ cachemodel = msgqueue->cachemodel;
+ target = cachemodel->target;
+ codeidx = target->codeidx;
+
+ if( !cachemodel->th_model[ tile_id]){
+ msg = (message_param_t *)malloc( sizeof(message_param_t));
+ msg->last_byte = true;
+ msg->in_class_id = tile_id;
+ msg->class_id = TILE_HEADER_MSG;
+ msg->csn = target->csn;
+ msg->bin_offset = 0;
+ msg->length = codeidx->tileheader[tile_id]->tlen;
+ msg->aux = 0; // non exist
+ msg->res_offset = codeidx->offset + get_elemOff( codeidx->tilepart, 0, tile_id); // Changed from Lucian's
+ msg->phld = NULL;
+ msg->next = NULL;
+
+ enqueue_message( msg, msgqueue);
+ cachemodel->th_model[ tile_id] = true;
+ }
+}
+
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
{
cachemodel_param_t *cachemodel;
}
}
+void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue)
+{
+ cachemodel_param_t *cachemodel;
+ index_param_t *codeidx;
+ faixbox_param_t *precpacket;
+ message_param_t *msg;
+ Byte8_t nmax;
+
+ cachemodel = msgqueue->cachemodel;
+ codeidx = cachemodel->target->codeidx;
+ precpacket = codeidx->precpacket[ comp_id];
+
+ nmax = get_nmax(precpacket);
+
+ 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;
+
+ enqueue_message( msg, msgqueue);
+ cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id] = true;
+ }
+}
+
+Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles)
+{
+ return t + (c + s * num_components ) * num_tiles;
+}
+
void enqueue_box( int meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
void enqueue_phld( int meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
void enqueue_boxcontents( int meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
return;
msg = msgqueue->first;
- class_id = 0;
- csn = 0;
+ class_id = -1;
+ csn = -1;
while( msg){
if( msg->csn == csn){
if( msg->class_id == class_id)
n--;
}
}
+
void print_binarycode( Byte8_t n, int segmentlen)
{
char buf[256];
Byte8_t class_id, csn;
class_id = -1; // dummy
- csn = 0;
+ csn = -1;
ptr = JPIPstream;
while( ptr-JPIPstream < streamlen){
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = c == 1 ? true : false;
- if( bb >= 2){
+ if( bb >= 2)
ptr = parse_vbas( ptr, &class_id);
- // fprintf( stdout, "class_id: %lld\n", class_id);
- }
+
msg->class_id = class_id;
if (bb == 3)
return ptr;
}
-/**
- * search a message by class_id
- *
- * @param[in] class_id class identifiers
- * @param[in] in_class_id in-class identifiers, -1 means any
- * @param[in] csn codestream number
- * @param[in] msg first message pointer of the searching list
- * @return found message pointer
- */
-message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg);
-
-
-/**
- * delete a message in msgqueue
- *
- * @param[in] message address of the deleting message pointer
- * @param[in] msgqueue message queue pointer
- */
-void delete_message_in_msgqueue( message_param_t **message, msgqueue_param_t *msgqueue);
-
-/**
- * reconstruct j2k codestream from JPT- (in future, JPP-) stream
- *
- * @param[in] msgqueue message queue pointer
- * @param[in] jpipstream original JPT- JPP- stream
- * @param[in] csn codestream number
- * @param[in] minlev minimum decomposition level
- * @param[out] codelen codestream length
- * @return generated reconstructed j2k codestream
- */
-Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *codelen);
-
-Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *j2klen)
-{
- Byte_t *j2kstream = NULL;
-
- if( !msgqueue)
- return NULL;
-
- j2kstream = recons_codestream( msgqueue, jpipstream, csn, minlev, j2klen);
-
- return j2kstream;
-}
-
-Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len);
-Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen);
-
-Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len)
-{
- message_param_t *ptr;
- Byte_t *jp2stream = NULL;
- Byte_t *codestream = NULL;
- Byte8_t codelen;
- Byte8_t jp2cDBoxOffset = 0, jp2cDBoxlen = 0;
-
- *jp2len = 0;
-
- if( !msgqueue)
- return NULL;
-
- ptr = msgqueue->first;
- while(( ptr = search_message( METADATA_MSG, -1, csn, ptr))!=NULL){
- if( ptr->phld){
- if( strncmp( (char *)ptr->phld->OrigBH+4, "jp2c", 4) == 0){
- jp2cDBoxOffset = *jp2len + ptr->phld->OrigBHlen;
- jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
- jp2cDBoxlen = *jp2len - jp2cDBoxOffset;
- }
- else
- jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
- }
- jp2stream = add_msgstream( ptr, jpipstream, jp2stream, jp2len);
- ptr = ptr->next;
- }
-
- codestream = recons_codestream( msgqueue, jpipstream, csn, 0, &codelen);
-
- if( jp2cDBoxOffset != 0 && codelen <= jp2cDBoxlen)
- memcpy( jp2stream+jp2cDBoxOffset, codestream, codelen);
-
- free( codestream);
-
- return jp2stream;
-}
-
-int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn);
-Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen);
-Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen);
-
-// usable only to JPT-stream messages
-// PRECINCT_MSG, EXT_PRECINCT_MSG, TILE_HEADER_MSG need to be handled
-Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *codelen)
-{
- message_param_t *ptr;
- Byte_t *codestream = NULL;
- int last_tileID;
- int tileID;
- bool found;
- Byte8_t binOffset;
-
- *codelen = 0;
-
- // main header first
- ptr = msgqueue->first;
- binOffset = 0;
- while(( ptr = search_message( MAINHEADER_MSG, -1, csn, ptr))!=NULL){
- if( ptr->bin_offset == binOffset){
- codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
- binOffset += ptr->length;
- }
- ptr = ptr->next;
- }
-
- last_tileID = get_last_tileID( msgqueue, csn);
-
- for( tileID=0; tileID <= last_tileID; tileID++){
- found = false;
- binOffset = 0;
-
- ptr = msgqueue->first;
- while(( ptr = search_message( TILE_MSG, tileID, csn, ptr))!=NULL){
- if( ptr->bin_offset == binOffset){
- found = true;
- codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
- binOffset += ptr->length;
- }
- ptr = ptr->next;
- }
- ptr = msgqueue->first;
- while(( ptr = search_message( EXT_TILE_MSG, tileID, csn, ptr))!=NULL){
- if( ptr->aux >= minlev){
- if( ptr->bin_offset == binOffset){
- found = true;
- codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
- binOffset += ptr->length;
- }
- }
- ptr = ptr->next;
- }
- if(!found)
- codestream = add_emptytilestream( tileID, codestream, codelen);
- }
- codestream = add_EOC( codestream, codelen);
-
- return codestream;
-}
-
-int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn)
-{
- int last_tileID = 0;
- message_param_t *msg;
-
- msg = msgqueue->first;
- while( msg){
- if((msg->class_id == TILE_MSG || msg->class_id == EXT_TILE_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
- last_tileID = msg->in_class_id;
- msg = msg->next;
- }
- return last_tileID;
-}
-
-message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg)
-{
- while( msg != NULL){
- if( in_class_id == -1){
- if( msg->class_id == class_id && msg->csn == csn)
- return msg;
- }
- else{
- if( msg->class_id == class_id && msg->in_class_id == in_class_id && msg->csn == csn)
- return msg;
- }
- msg = msg->next;
- }
- return NULL;
-}
-
void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgqueue)
{
message_param_t *ptr;
}
free( *msg);
}
-
-Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length);
-Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length);
-
-
-Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen)
-{
- Byte_t *newstream;
- Byte8_t newlen;
- Byte_t *buf;
-
- if( !message)
- return NULL;
-
- newstream = gene_msgstream( message, origstream, &newlen);
-
- buf = (Byte_t *)malloc(( *j2klen)+newlen);
-
- memcpy( buf, j2kstream, *j2klen);
- memcpy( buf+(*j2klen), newstream, newlen);
-
- *j2klen += newlen;
-
- free( newstream);
- if(j2kstream) free(j2kstream);
-
- return buf;
-}
-
-
-Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len)
-{
- Byte_t *newstream;
- Byte8_t newlen;
- Byte_t *buf;
-
- if( phld->OrigBHlen == 8)
- newlen = big4(phld->OrigBH);
- else
- newlen = big8(phld->OrigBH+8);
-
- newstream = (Byte_t *)malloc( newlen);
- memset( newstream, 0, newlen);
- memcpy( newstream, phld->OrigBH, phld->OrigBHlen);
-
- buf = (Byte_t *)malloc(( *jp2len)+newlen);
-
- memcpy( buf, jp2stream, *jp2len);
- memcpy( buf+(*jp2len), newstream, newlen);
-
- *jp2len += newlen;
-
- free( newstream);
- if(jp2stream) free(jp2stream);
-
- return buf;
-}
-
-Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen)
-{
- Byte_t *newstream;
- Byte8_t newlen;
- Byte_t *buf;
-
- newstream = gene_emptytilestream( tileID, &newlen);
-
- buf = (Byte_t *)malloc(( *j2klen)+newlen);
-
- memcpy( buf, j2kstream, *j2klen);
- memcpy( buf+(*j2klen), newstream, newlen);
-
- *j2klen += newlen;
-
- free( newstream);
- if(j2kstream) free(j2kstream);
-
- return buf;
-}
-
-Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen)
-{
- Byte2_t EOC = 0xd9ff;
-
- Byte_t *buf;
-
- buf = (Byte_t *)malloc(( *j2klen)+2);
-
- memcpy( buf, j2kstream, *j2klen);
- memcpy( buf+(*j2klen), &EOC, 2);
-
- *j2klen += 2;
-
- if(j2kstream) free(j2kstream);
-
- return buf;
-}
-
-Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length)
-{
- Byte_t *buf;
-
- if( !message)
- return NULL;
-
- *length = message->length;
- buf = (Byte_t *)malloc( *length);
- memcpy( buf, stream+message->res_offset, *length);
-
- return buf;
-}
-
-Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length)
-{
- Byte_t *buf;
- const Byte2_t SOT = 0x90ff;
- const Byte2_t Lsot = 0xa << 8;
- Byte2_t Isot;
- const Byte4_t Psot = 0xe << 24;
- const Byte_t TPsot = 0, TNsot = 0;
- const Byte2_t SOD = 0x93ff;
-
- *length = 14;
- buf = (Byte_t *)malloc(*length);
-
- Isot = tileID << 8;
-
- memcpy( buf, &SOT, 2);
- memcpy( buf+2, &Lsot, 2);
- memcpy( buf+4, &Isot, 2);
- memcpy( buf+6, &Psot, 4);
- memcpy( buf+10, &TPsot, 1);
- memcpy( buf+11, &TNsot, 1);
- memcpy( buf+12, &SOD, 2);
-
- return buf;
-}
*
* 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) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "cachemodel_manager.h"
#include "placeholder_manager.h"
+#define PRECINCT_MSG 0
+#define EXT_PRECINCT_MSG 1
+#define TILE_HEADER_MSG 2
+#define TILE_MSG 4
+#define EXT_TILE_MSG 5
+#define MAINHEADER_MSG 6
+#define METADATA_MSG 8
+
//! message parameters
typedef struct message_param{
bool last_byte; //!< if message contains the last byte of the data-bin
*/
void delete_msgqueue( msgqueue_param_t **msgqueue);
+/**
+ * delete a message in msgqueue
+ *
+ * @param[in] message address of the deleting message pointer
+ * @param[in] msgqueue message queue pointer
+ */
+void delete_message_in_msgqueue( message_param_t **message, msgqueue_param_t *msgqueue);
+
/**
* print message queue
*
void enqueue_mainheader( msgqueue_param_t *msgqueue);
+/**
+ * enqueue tile headers data-bin into message queue
+ *
+ * @param[in] tile_id tile id starting from 0
+ * @param[in,out] msgqueue message queue pointer
+ */
+void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue);
+
+
/**
* enqueue tile data-bin into message queue
*
*/
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue);
+/**
+ * enqueue precinct data-bin into message queue
+ *
+ * @param[in] seq_id precinct sequence number within its tile
+ * @param[in] tile_id tile index
+ * @param[in] comp_id component number
+ * @param[in,out] msgqueue message queue
+ */
+void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue);
+
/**
* enqueue Metadata-bin into message queue
*/
void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t streamlen, metadatalist_param_t *metadatalist);
-
/**
- * reconstruct j2k codestream from message queue
- *
- * @param[in] msgqueue message queue pointer
- * @param[in] jpipstream original jpt- jpp- stream
- * @param[in] csn codestream number
- * @param[in] minlev minimum decomposition level
- * @param[out] j2klen pointer to the j2k codestream length
- * @return generated reconstructed j2k codestream
- */
-Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *j2klen);
-
-
-/**
- * reconstruct jp2 file codestream from message queue
+ * compute precinct ID A.3.2.1
*
- * @param[in] msgqueue message queue pointer
- * @param[in] jpipstream original jpt- jpp- stream
- * @param[in] csn codestream number
- * @param[out] jp2len pointer to the jp2 codestream length
- * @return generated reconstructed jp2 codestream
+ * @param[in] t tile index
+ * @param[in] c component index
+ * @param[in] s sequence number
+ * @param[in] num_components total number of components
+ * @param[in] num_tiles total number of tiles
+ * @return precicnt id
*/
-Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len);
-
+Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles);
#endif /* !MSGQUEUE_MANAGER_H_ */
if(*ihdrbox){
if( (*ihdrbox)->nc != image->numcomps)
fprintf( stderr, "Exception: num of components not identical, codestream: %d, ihdrbox: %d\n", image->numcomps, (*ihdrbox)->nc);
-
+
if( (*ihdrbox)->width != image->comps[0].w)
- fprintf( stderr, "Exception: width value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].w, (*ihdrbox)->width);
+ (*ihdrbox)->width = image->comps[0].w;
if( (*ihdrbox)->height != image->comps[0].h)
- fprintf( stderr, "Exception: heigth value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].h, (*ihdrbox)->height);
-
+ (*ihdrbox)->height = image->comps[0].h;
+
if( (*ihdrbox)->bpc != image->comps[0].prec)
fprintf( stderr, "Exception: bits per component not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].prec, (*ihdrbox)->bpc);
}
#include <string.h>
#include <time.h>
#include "jpipstream_manager.h"
+#include "jp2k_encoder.h"
#include "jp2k_decoder.h"
-#include "imgreg_manager.h"
Byte_t * update_JPIPstream( Byte_t *newstream, int newstreamlen, Byte_t *cache_stream, int *streamlen)
{
Byte_t *pnmstream;
Byte_t *j2kstream; // j2k or jp2 codestream
Byte8_t j2klen;
- int level = 0;
- if( *ihdrbox){
- // infinit value is set for maxmum level
- int fx = fw, fy = fh;
- int xmin = 0, ymin = 0;
- int xmax = (*ihdrbox)->width, ymax = (*ihdrbox)->height;
- find_level( 1000, &level, &fx, &fy, &xmin, &ymin, &xmax, &ymax);
- }
-
- j2kstream = recons_j2k( msgqueue, jpipstream, csn, level+1, &j2klen);
+ j2kstream = recons_j2k( msgqueue, jpipstream, csn, fw, fh, &j2klen);
pnmstream = j2k_to_pnm( j2kstream, j2klen, ihdrbox);
free( j2kstream);
#include "imgsock_manager.h"
#include "jpipstream_manager.h"
#include "cache_manager.h"
+#include "jp2k_encoder.h"
#ifdef _WIN32
WSADATA initialisation_win32;
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( cache->metadatalist)
delete_metadatalist( &cache->metadatalist);
cache->metadatalist = metadatalist;
-
+
response_signal( connected_socket, true);
}
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)))
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);
-opj_viewer-20110916.jar
\ No newline at end of file
+opj_viewer-20110930.jar
\ No newline at end of file
pnmimage = null;
}
- public int getOrigWidth(){ return pnmimage.width;}
- public int getOrigHeight(){ return pnmimage.height;}
+ public int getOrigWidth(){ return pnmimage.get_width();}
+ public int getOrigHeight(){ return pnmimage.get_height();}
public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew)
{
jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew);
System.err.println( "decoding to PNM image");
- pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh);
- System.err.println( " done");
-
- return pnmimage.createROIImage( rx, ry, rw, rh);
+ if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){
+ System.err.println( " done");
+ return pnmimage.createROIImage( rx, ry, rw, rh);
+ }
+ else{
+ System.err.println( " failed");
+ return null;
+ }
}
public Image getImage( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
byte[] jpipstream = super.requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh);
System.err.println( "decoding to PNM image");
- pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh);
- System.err.println( " done");
-
- return pnmimage.createROIImage( rx, ry, rw, rh);
+ if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh)) != null){
+ System.err.println( " done");
+ return pnmimage.createROIImage( rx, ry, rw, rh);
+ }
+ else{
+ System.err.println( " failed");
+ return null;
+ }
}
public byte[] getXML()
public class ImageViewer extends JPanel
{
- private MML myMML;
- private ResizeListener myRL;
private ImageManager imgmanager;
private int vw, vh;
private int iw, ih;
public ImageViewer( String j2kfilename, ImageManager manager, boolean session)
{
String str;
-
- this.setSize( 200, 200);
+ MML myMML;
+
+ this.setSize( 170, 170);
Dimension asz = this.getSize();
vw = asz.width;
setBackground(Color.black);
myMML = new MML(this);
- myRL = new ResizeListener(this);
imgmanager = manager;
+
img = imgmanager.getImage( j2kfilename, vw, vh, session);
addMouseListener(myMML);
addMouseMotionListener(myMML);
- addComponentListener(myRL);
+ addComponentListener( new ResizeListener(this));
}
public Image getImage()
roirect = null;
roiname = null;
- double scalex = vw/(double)rect.width;
- double scaley = vh/(double)rect.height;
+ double scalex = (double)vw/(double)rect.width;
+ double scaley = (double)vh/(double)rect.height;
int fw = (int)(imgmanager.getFw()*scalex);
int fh = (int)(imgmanager.getFh()*scaley);
{
roirect = null;
roiname = null;
-
+
Dimension asz = this.getSize();
vw = asz.width;
vh = asz.height;
-
+
double scalex = vw/(double)imgmanager.getRw();
double scaley = vh/(double)imgmanager.getRh();
int fh = (int)(imgmanager.getFh()*scaley);
int rx = (int)(imgmanager.getRx()*scalex);
int ry = (int)(imgmanager.getRy()*scaley);
-
+
img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
-
+
fullRefresh = true;
repaint();
}
System.err.println("IOException: " + e);
}
}
-
+
public static PnmImage get_PNMstream( String cid, String tid, int fw, int fh)
{
- PnmImage pnmstream = new PnmImage();
+ PnmImage pnmstream = null;
+
try {
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
os.writeBytes( fh + "\n");
read_stream( is, header, 7);
-
+
if( header[0] == 80){
// P5: gray, P6: color
byte magicknum = header[1];
if( magicknum == 5 || magicknum == 6){
- int length;
- boolean iscolor = magicknum==6 ? true:false;
- if( iscolor)
- pnmstream.channel = 3;
- else
- pnmstream.channel = 1;
- pnmstream.width = (header[2]&0xff)<<8 | (header[3]&0xff);
- pnmstream.height = (header[4]&0xff)<<8 | (header[5]&0xff);
+ int c = magicknum==6 ? 3: 1;
+ int w = (header[2]&0xff)<<8 | (header[3]&0xff);
+ int h = (header[4]&0xff)<<8 | (header[5]&0xff);
int maxval = header[6]&0xff;
-
- if( maxval == 255){
- length = pnmstream.width*pnmstream.height*pnmstream.channel;
- pnmstream.data = new byte [ length];
- read_stream( is, pnmstream.data, length);
+ int length = w*h*c;
+
+ if( maxval == 255 && length != 0){
+ pnmstream = new PnmImage( c, w, h);
+ read_stream( is, pnmstream.get_data(), length);
}
else
System.err.println("Error in get_PNMstream(), only 255 is accepted");
}
else
System.err.println("Error in get_PNMstream(), Not starting with P");
+
os.close();
is.close();
imgdecSocket.close();
try{
while( remlen > 0){
int redlen = is.read( stream, off, remlen);
-
+
if( redlen == -1){
System.err.println(" failed to read_stream()");
break;
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "cnew=http");
}
+
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "type=jpp-stream");
+
return urlstring;
}
public class PnmImage extends Component
{
- public byte[] data = null;
- public int width = 0;
- public int height = 0;
- public int channel = 0;
+ private byte[] data = null;
+ private int width = 0;
+ private int height = 0;
+ private int channel = 0;
- public Image createROIImage( int rx, int ry, int rw, int rh)
- {
- int []pix = new int[ rw*rh];
-
- for( int i=0; i<rh; i++)
- for( int j=0; j<rw; j++){
- pix[i*rw+j] = 0xFF << 24; // transparency
- if( channel == 1){
- Byte lum = data[(ry+i)*width+rx+j];
- short slum;
-
- if( lum < 0)
- slum = (short)(2*128+lum);
- else
- slum = (short)lum;
-
- for( int c=0; c<3; c++){
- pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
- }
- }
- else
- for( int c=0; c<3; c++){
- Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
- short slum;
-
- if( lum < 0)
- slum = (short)(2*128+lum);
- else
- slum = (short)lum;
-
- pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
- }
- }
- return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
- }
-
- public Image createScaleImage( double scale)
+ public PnmImage( int c, int w, int h)
{
- Image src = createROIImage( 0, 0, width, height);
- ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
- ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
-
- return createImage(prod);
+ channel = c;
+ width = w;
+ height = h;
+ data = new byte [ w*h*c];
}
-
- public void openimage( String filename)
+
+ public PnmImage( String filename)
{
String str;
Pattern pat;
}
fis.close();
} catch (IOException e) { e.printStackTrace(); }
- }
+ }
+
+ public byte [] get_data(){ return data;}
+ public int get_width() { return width;}
+ public int get_height(){ return height;}
+
+ public Image createROIImage( int rx, int ry, int rw, int rh)
+ {
+ int []pix = new int[ rw*rh];
+
+ for( int i=0; i<rh; i++)
+ for( int j=0; j<rw; j++){
+ pix[i*rw+j] = 0xFF << 24; // transparency
+ if( channel == 1){
+ Byte lum = data[(ry+i)*width+rx+j];
+ short slum;
+
+ if( lum < 0)
+ slum = (short)(2*128+lum);
+ else
+ slum = (short)lum;
+
+ for( int c=0; c<3; c++){
+ pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
+ }
+ }
+ else
+ for( int c=0; c<3; c++){
+ Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
+ short slum;
+
+ if( lum < 0)
+ slum = (short)(2*128+lum);
+ else
+ slum = (short)lum;
+
+ pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
+ }
+ }
+
+ return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
+ }
+
+ public Image createScaleImage( double scale)
+ {
+ Image src = createROIImage( 0, 0, width, height);
+ ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
+ ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
+
+ return createImage(prod);
+ }
}
\ No newline at end of file
public RegimViewer( String refname, double[] mat)
{
- refpnm = new PnmImage();
- refpnm.openimage(refname.replaceFirst("jp2", "pgm")); // decoding not realized
+ refpnm = new PnmImage( refname.replaceFirst("jp2", "pgm")); // decoding not realized
affine_matrix = new double[6];
affine_matrix[0] = mat[0];
public void componentResized(ComponentEvent e) {
Dimension cursize = iv.getSize();
if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){
- largest = cursize;
+ update_largest( cursize);
iv.enlarge();
}
}
+
+ private void update_largest( Dimension cursize)
+ {
+ if( largest.getWidth() < cursize.getWidth())
+ largest.setSize( cursize.getWidth(), largest.getHeight());
+ if( largest.getHeight() < cursize.getHeight())
+ largest.setSize( largest.getWidth(), cursize.getHeight());
+ }
public void componentShown(ComponentEvent e) {}
}
\ No newline at end of file
-opj_viewer_xerces-20110916.jar
\ No newline at end of file
+opj_viewer_xerces-20110930.jar
\ No newline at end of file
*
* 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) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <math.h>
#include "query_parser.h"
#include "channel_manager.h"
if( strcmp( query_string, QUIT_SIGNAL) == 0)
break;
-
- fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
-
+
query_param_t query_param;
msgqueue_param_t *msgqueue;
parse_query( query_string, &query_param);
+ switch( query_param.return_type){
+ case JPPstream:
+ fprintf( FCGI_stdout, "Content-type: image/jpp-stream\r\n");
+ break;
+ default:
+ fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
+ break;
+ }
+
#ifndef SERVER
print_queryparam( query_param);
#endif
* @param[in] target requested target pointer
* @param[in,out] cursession associated session pointer
* @param[in,out] curchannel associated channel pointer
- * @param[in,out] msgqueue address of the message queue pointer
+ * @param[out] msgqueue address of the message queue pointer
* @return if succeeded (true) or failed (false)
*/
-bool gene_JPTstream( query_param_t query_param,
+bool gene_JPIPstream( query_param_t query_param,
target_param_t *target,
session_param_t *cursession,
channel_param_t *curchannel,
return false;
if( (query_param.fx > 0 && query_param.fy > 0) || query_param.box_type[0][0] != 0)
- if( !gene_JPTstream( query_param, target, cursession, curchannel, msgqueue))
+ if( !gene_JPIPstream( query_param, target, cursession, curchannel, msgqueue))
return false;
-
+
return true;
}
/**
- * enqueue tiles into the message queue
+ * enqueue tiles or precincts into the message queue
*
- * @param[in] query_param structured query
- * @param[in] codeidx pointer to index parameters
- * @param[in,out] msgqueue message queue pointer
+ * @param[in] query_param structured query
+ * @param[in] msgqueue message queue pointer
*/
-void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue);
+void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue);
/**
* enqueue metadata bins into the message queue
void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
-bool gene_JPTstream( query_param_t query_param,
- target_param_t *target,
- session_param_t *cursession,
- channel_param_t *curchannel,
- 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( query_param.fx > 0 && query_param.fy > 0){
if( !cachemodel->mhead_model)
enqueue_mainheader( *msgqueue);
- enqueue_tiles( query_param, codeidx, *msgqueue);
+ enqueue_imagedata( query_param, *msgqueue);
}
return true;
}
-void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue)
+
+/**
+ * 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;
+
+ codeidx = msgqueue->cachemodel->target->codeidx;
imgreg = map_viewin2imgreg( query_param.fx, query_param.fy,
query_param.rx, query_param.ry, query_param.rw, query_param.rh,
- codeidx->XOsiz, codeidx->YOsiz, codeidx->Xsiz, codeidx->Ysiz,
- get_nmax( codeidx->tilepart));
+ codeidx->SIZ.XOsiz, codeidx->SIZ.YOsiz, codeidx->SIZ.Xsiz, codeidx->SIZ.Ysiz,
+ codeidx->COD.numOfdecomp+1);
-
- for( u=0, tile_id=0; u<codeidx->YTnum; u++){
- tile_Yrange = get_tile_Yrange( *codeidx, u, imgreg.level);
+ 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->XTnum; v++, tile_id++){
- tile_Xrange = get_tile_Xrange( *codeidx, v, 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 completely contained within view-window
// high priority
//printf("Tile completely contained within view-window %d\n", tile_id);
- enqueue_tile( tile_id, imgreg.level, msgqueue);
+ if( query_param.return_type == 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);
- enqueue_tile( tile_id, imgreg.level, msgqueue);
+ if( query_param.return_type == 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.XPsiz[ res_lev];
+ YPsiz = codeidx->COD.YPsiz[ res_lev];
+
+ 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.XPsiz[ res_lev];
+ YPsiz = codeidx->COD.YPsiz[ res_lev];
+
+ 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;
*
* 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) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
void parse_metareq( char *field, query_param_t *query_param);
+// parse the requested components (parses forms like:a; a,b; a-b; a-b,c; a,b-c)
+void parse_comps( char *field, query_param_t *query_param);
+
+
//! maximum length of field name
#define MAX_LENOFFIELDNAME 10
else if( strcasecmp( fieldname, "metareq") == 0)
parse_metareq( fieldval, query_param);
+
+ else if( strcasecmp( fieldname, "comps") == 0)
+ parse_comps( fieldval, query_param);
+
+ else if( strcasecmp( fieldname, "type") == 0){
+ if( strncasecmp( fieldval, "jpp-stream", 10) == 0)
+ query_param->return_type = JPPstream;
+ else if( strncasecmp( fieldval, "jpt-stream", 10) == 0)
+ query_param->return_type = JPTstream;
+ }
}
}
}
query_param->ry=-1;
query_param->rw=-1;
query_param->rh=-1;
+ query_param->lastcomp = -1;
+ query_param->comps = NULL;
query_param->cid[0]='\0';
query_param->cnew=false;
memset( query_param->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
query_param->root_bin = 0;
query_param->max_depth = -1;
query_param->metadata_only = false;
+ query_param->return_type = UNKNOWN;
}
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 components: ");
+ if( query_param.lastcomp == -1)
+ fprintf( logstream, "ALL\n");
+ else{
+ for( i=0; i<=query_param.lastcomp; i++)
+ if( query_param.comps[i])
+ fprintf( logstream, "%d ", i);
+ fprintf( logstream, "\n");
+ }
fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
fprintf( logstream, "\t cid: %s\n", query_param.cid);
fprintf( logstream, "\t root-bin: %d\n", query_param.root_bin);
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);
}
void str2cclose( char *src, char cclose[][MAX_LENOFCID])
idx++;
}
+
+void parse_comps( char *field, query_param_t *query_param)
+{
+ int i,start,stop,aux = -1;
+ char *ptr1,*ptr2;
+
+ ptr1 = strchr( field, '-');
+ ptr2 = strchr( field, ',');
+
+ if( ptr1 && ptr2)
+ if( ptr1 > ptr2)
+ sscanf( field, "%d,%d-%d",&aux, &start, &stop);
+ else
+ sscanf( field, "%d-%d,%d", &start, &stop, &aux);
+ else
+ if(ptr1)
+ sscanf( field, "%d-%d", &start, &stop);
+ else if(ptr2){
+ sscanf( field, "%d,%d", &start, &stop);
+ aux = start;
+ start = stop;
+ }
+ else{
+ sscanf( field, "%d", &stop);
+ start = stop;
+ }
+
+ query_param->lastcomp = stop > aux ? stop : aux;
+ query_param->comps = (bool *)calloc( 1, (query_param->lastcomp+1)*sizeof(bool));
+
+ for( i=start; i<=stop; i++)
+ query_param->comps[i]=true;
+
+ if(aux!=-1)
+ query_param->comps[aux] = true;
+}
* 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
//! maximum number of meta request box
#define MAX_NUMOFBOX 10
+//! image return type
+typedef enum image_return { JPPstream, JPTstream, UNKNOWN=-1} image_return_t;
+
//! Query parameters
typedef struct query_param{
char target[MAX_LENOFTARGET]; //!< target name
char tid[MAX_LENOFTID]; //!< target identifier
int fx, fy; //!< frame size (fx,fy)
int rx, ry, rw, rh; //!< roi region
+ int lastcomp; //!< last component number
+ bool *comps; //!< components for jpp-stream, null means all components
char cid[MAX_LENOFCID]; //!< channel identifier
bool cnew; //!< if there is new channel request(true) or not (false)
char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers
int root_bin; //!< root-bin
int max_depth; //!< max-depth
bool metadata_only; //!< metadata-only request
+ image_return_t return_type; //!< image return type
} query_param_t;
#include <unistd.h>
#include <stdlib.h>
#include "msgqueue_manager.h"
-
+#include "jp2k_encoder.h"
int main(int argc,char *argv[])
{
//print_msgqueue( msgqueue);
- j2kstream = recons_j2k( msgqueue, jpipstream, msgqueue->first->csn, 0, &j2klen);
+ j2kstream = recons_j2k( msgqueue, jpipstream, msgqueue->first->csn, 0, 0, &j2klen);
delete_msgqueue( &msgqueue);
free( jpipstream);
#include "byte_manager.h"
#include "ihdrbox_manager.h"
#include "metadata_manager.h"
+#include "jp2k_encoder.h"
int main(int argc,char *argv[])
{
print_msgqueue( msgqueue);
//print_allmetadata( metadatalist);
- ihdrbox = get_ihdrbox( metadatalist, jpipstream);
+ ihdrbox = gene_ihdrbox( metadatalist, jpipstream);
printf("W*H: %d*%d\n", ihdrbox->height, ihdrbox->width);
printf("NC: %d, bpc: %d\n", ihdrbox->nc, ihdrbox->bpc);
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FIDX, 4); /* IPTR */
- write_prxy( offset_jp2c, length_jp2c, offset_idx, offset_jp2c, cio);
+ write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
len = cio_tell( cio)-lenp;
cio_seek( cio, lenp);
opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
- int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, end_pos, pos_fidx, len_fidx;
+ int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
/* JP2 encoding */
if( jp2->jpip_on){
pos_cidx = cio_tell( cio);
- write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
+ len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
pos_fidx = cio_tell( cio);
- len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, cio_tell(cio), cio);
+ len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
end_pos = cio_tell( cio);
int size_of_coding; // 4 or 8
int version;
int tileno, resno, precno, layno, num_packet=0;
-
+ int i,nmax=0;
+ opj_tile_info_t *tile_Idx;
+ opj_packet_info_t packet;
+
if( j2klen > pow( 2, 32)){
size_of_coding = 8;
version = 1;
cio_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version,1); /* Version 0 = 4 bytes */
-
- cio_write( cio, cstr_info.packno, size_of_coding); /* NMAX */
+
+ for( i=0; i<=cstr_info.numdecompos[compno]; i++)
+ nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
+
+ cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
- opj_tile_info_t *tile_Idx = &cstr_info.tile[ tileno];
+ tile_Idx = &cstr_info.tile[ tileno];
// int correction = EPHused ? 3 : 1;
num_packet = 0;
- for( resno=0; resno<cstr_info.numdecompos[compno]+1; resno++){
+ for( resno=0; resno<=cstr_info.numdecompos[compno]; resno++){
for( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
- for( layno=0; layno<cstr_info.numlayers; layno++){
- opj_packet_info_t packet = tile_Idx->packet[num_packet];
+ for( layno=0; layno<cstr_info.numlayers; layno++){
+ packet = tile_Idx->packet[num_packet * cstr_info.numcomps + compno];
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */
}
/* PADDING */
- while( num_packet < cstr_info.packno){
+ while( num_packet < nmax){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;
return len;
}
-// NMAX might be wrong , phix too, do sth to correction
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
{
int len, lenp;
int tileno, resno, precno, layno, num_packet=0;
int size_of_coding; // 4 or 8
int version;
+ int i,nmax=0;
+ opj_tile_info_t *tile_Idx;
+ opj_packet_info_t packet;
if( j2klen > pow( 2, 32)){
size_of_coding = 8;
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
- cio_write( cio, cstr_info.packno, size_of_coding); /* NMAX */
+ for( i=0; i<=cstr_info.numdecompos[compno]; i++)
+ nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
+
+ cio_write( cio, nmax, size_of_coding); /* NMAX */
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
-
- opj_tile_info_t *tile_Idx = &cstr_info.tile[ tileno];
+
+ tile_Idx = &cstr_info.tile[ tileno];
// int correction = EPHused ? 3 : 1;
num_packet=0;
- for( resno=0; resno< cstr_info.numdecompos[compno]+1; resno++){
+ for( resno=0; resno<=cstr_info.numdecompos[compno]; resno++){
for( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
for( layno=0; layno<cstr_info.numlayers; layno++){
- opj_packet_info_t packet = tile_Idx->packet[num_packet];
+ packet = tile_Idx->packet[num_packet * cstr_info.numcomps + compno];
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */
}
/* PADDING */
- while( num_packet < cstr_info.packno){
+ while( num_packet < nmax){
cio_write( cio, 0, size_of_coding); /* start position */
cio_write( cio, 0, size_of_coding); /* length */
num_packet++;