[1.5] enabled JPP stream in JPIP (result of GSoC program)

This commit is contained in:
Antonin Descampe 2011-10-10 09:50:18 +00:00
parent 9e60c2f8e9
commit 8a2af121a4
47 changed files with 1955 additions and 640 deletions

View File

@ -7,6 +7,7 @@ What's New for OpenJPEG
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.

View File

@ -5,6 +5,9 @@ What's New for OpenJPIP
! : changed
+ : added
October 10, 2011
+ [antonin] enabled JPP-stream
September 16, 2011
+ [kaori] enabled stateless requests from the opj_viewers

View File

@ -1,5 +1,5 @@
========================================================================
OpenJPIP software 1.0 ReadMe
OpenJPIP software 2.0 ReadMe
OpenJPEG:
http://www.openjpeg.org
@ -26,8 +26,8 @@ OpenJPIP software is an implementation of JPEG 2000 Part9: Interactivity tools,
( 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
@ -49,7 +49,6 @@ Neither the author, nor the university accept any responsibility for any kind of
- 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)
@ -62,8 +61,6 @@ We tested this software with a virtual server running on the same Linux machine
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
@ -128,12 +125,7 @@ Client:
----------
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

View File

@ -22,6 +22,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/manfbox_manager.c
${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

View File

@ -22,6 +22,8 @@ manfbox_manager.c \
mhixbox_manager.c \
target_manager.c \
cachemodel_manager.c \
j2kheader_manager.c \
jp2k_encoder.c \
bool.h \
boxheader_manager.h \
box_manager.h \
@ -38,7 +40,9 @@ mhixbox_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. \

View File

@ -145,3 +145,11 @@ Byte8_t big8( Byte_t *buf)
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);
}

View File

@ -116,5 +116,12 @@ Byte4_t big4( Byte_t *buf);
*/
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_ */

View File

@ -59,7 +59,10 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
{
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));
@ -67,9 +70,15 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
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){
@ -89,24 +98,39 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
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)
@ -140,9 +164,17 @@ void delete_cachemodellist( 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");

View File

@ -39,6 +39,8 @@ typedef struct cachemodel_param{
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;

View File

@ -10,7 +10,8 @@ all: $(LIBNAME)
$(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:

View File

@ -32,7 +32,7 @@
#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;
@ -53,7 +53,7 @@ ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptst
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");
@ -62,10 +62,10 @@ ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptst
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);

View File

@ -35,14 +35,22 @@
#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_ */

View File

@ -47,7 +47,7 @@ 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)
{
imgreg_param_t imgreg;
int px,py;
@ -61,7 +61,7 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
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;
@ -79,6 +79,12 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
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;
}
@ -120,6 +126,20 @@ void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, i
}
}
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)
{

View File

@ -50,7 +50,7 @@ typedef struct imgreg_param{
* @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,
@ -58,7 +58,7 @@ 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);
/**
@ -78,6 +78,18 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
*/
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
*

View File

@ -131,26 +131,76 @@ void print_index( index_param_t index)
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);
}
@ -250,6 +300,16 @@ bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx);
*/
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;
@ -277,13 +337,19 @@ bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
}
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);
@ -326,23 +392,36 @@ bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx)
/**
* 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, index_param_t *jp2idx);
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_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;
@ -352,7 +431,10 @@ bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, ind
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);
@ -364,11 +446,15 @@ bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx)
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);
@ -385,11 +471,15 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
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;
}
@ -398,16 +488,24 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
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);
@ -417,37 +515,131 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
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;
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx)
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, 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);
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);
jp2idx->XTnum = ( jp2idx->Xsiz-jp2idx->XTOsiz+jp2idx->XTsiz-1)/jp2idx->XTsiz;
jp2idx->YTnum = ( jp2idx->Ysiz-jp2idx->YTOsiz+jp2idx->YTsiz-1)/jp2idx->YTsiz;
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)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);
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);
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;
}
@ -456,25 +648,25 @@ bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream,
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);
@ -483,6 +675,22 @@ range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t
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)

View File

@ -34,42 +34,60 @@
#include "byte_manager.h"
#include "faixbox_manager.h"
#include "metadata_manager.h"
#include "mhixbox_manager.h"
//! 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 XTnum; //!< number of tiles in horizontal 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;
//! 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
//! A.5.1 Image and tile size (SIZ)
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 XTnum; //!< number of tiles in horizontal 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
faixbox_param_t *tilepart; //!< tile part information from tpix box
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;
@ -89,6 +107,19 @@ index_param_t * parse_jp2file( int fd);
*/
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
@ -106,22 +137,33 @@ typedef struct range_param{
/**
* 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_ */

View File

@ -0,0 +1,286 @@
/*
* $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;
}

View File

@ -0,0 +1,73 @@
/*
* $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_ */

View File

@ -0,0 +1,539 @@
/*
* $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;
}

View File

@ -0,0 +1,64 @@
/*
* $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_ */

View File

@ -147,4 +147,5 @@ int search_metadataidx( char boxtype[4], metadatalist_param_t *list);
* @param[in] metadatalist metadata list pointer
*/
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist);
#endif /* !METADATA_MANAGER_H_ */

View File

@ -4,6 +4,7 @@
* 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
@ -30,16 +31,14 @@
#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"
@ -50,14 +49,6 @@
#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;
@ -96,6 +87,7 @@ void delete_msgqueue( 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;
@ -104,7 +96,7 @@ void print_msgqueue( msgqueue_param_t *msgqueue)
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 );
@ -127,11 +119,13 @@ void enqueue_mainheader( 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;
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = true;
@ -139,9 +133,9 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
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;
@ -150,6 +144,35 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
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;
@ -208,6 +231,43 @@ void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
}
}
void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue)
{
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);
@ -327,8 +387,8 @@ void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
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)
@ -472,6 +532,7 @@ void emit_bigendian_bytes( Byte8_t code, int bytelength)
n--;
}
}
void print_binarycode( Byte8_t n, int segmentlen)
{
char buf[256];
@ -503,7 +564,7 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
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));
@ -512,10 +573,9 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
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)
@ -646,183 +706,6 @@ Byte_t * parse_vbas( Byte_t *streamptr, Byte8_t *elem)
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;
@ -845,139 +728,3 @@ void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgque
}
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;
}

View File

@ -3,7 +3,8 @@
*
* 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
@ -36,6 +37,14 @@
#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
@ -74,6 +83,14 @@ msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel
*/
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
*
@ -90,6 +107,15 @@ void print_msgqueue( msgqueue_param_t *msgqueue);
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
*
@ -99,6 +125,16 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue);
*/
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
@ -137,30 +173,16 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
*/
void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t streamlen, metadatalist_param_t *metadatalist);
/**
* reconstruct j2k 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[in] minlev minimum decomposition level
* @param[out] j2klen pointer to the j2k codestream length
* @return generated reconstructed j2k 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_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, 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);
Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles);
#endif /* !MSGQUEUE_MANAGER_H_ */

View File

@ -135,13 +135,13 @@ Byte_t * imagetopnm(opj_image_t *image, ihdrbox_param_t **ihdrbox)
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);
}

View File

@ -33,8 +33,8 @@
#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)
{
@ -73,17 +73,8 @@ Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte
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);

View File

@ -54,6 +54,7 @@
#include "imgsock_manager.h"
#include "jpipstream_manager.h"
#include "cache_manager.h"
#include "jp2k_encoder.h"
#ifdef _WIN32
WSADATA initialisation_win32;
@ -237,15 +238,15 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
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))){
@ -265,7 +266,7 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
if( cache->metadatalist)
delete_metadatalist( &cache->metadatalist);
cache->metadatalist = metadatalist;
response_signal( connected_socket, true);
}
@ -276,7 +277,7 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par
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)))
@ -290,6 +291,7 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par
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);

View File

@ -1 +1 @@
opj_viewer-20110916.jar
opj_viewer-20110930.jar

View File

@ -40,8 +40,8 @@ public class ImageManager extends JPIPHttpClient
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)
{
@ -64,10 +64,14 @@ public class ImageManager extends JPIPHttpClient
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)
@ -77,10 +81,14 @@ public class ImageManager extends JPIPHttpClient
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()

View File

@ -40,8 +40,6 @@ import java.io.*;
public class ImageViewer extends JPanel
{
private MML myMML;
private ResizeListener myRL;
private ImageManager imgmanager;
private int vw, vh;
private int iw, ih;
@ -58,8 +56,9 @@ public class ImageViewer extends JPanel
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;
@ -67,14 +66,14 @@ public class ImageViewer extends JPanel
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()
@ -87,8 +86,8 @@ public class ImageViewer extends JPanel
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);
@ -108,12 +107,12 @@ public class ImageViewer extends JPanel
{
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();
@ -121,9 +120,9 @@ public class ImageViewer extends JPanel
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();
}

View File

@ -108,10 +108,11 @@ public class ImgdecClient{
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());
@ -130,25 +131,20 @@ public class ImgdecClient{
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");
@ -158,6 +154,7 @@ public class ImgdecClient{
}
else
System.err.println("Error in get_PNMstream(), Not starting with P");
os.close();
is.close();
imgdecSocket.close();
@ -265,7 +262,7 @@ public class ImgdecClient{
try{
while( remlen > 0){
int redlen = is.read( stream, off, remlen);
if( redlen == -1){
System.err.println(" failed to read_stream()");
break;

View File

@ -312,6 +312,11 @@ public class JPIPHttpClient
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "cnew=http");
}
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "type=jpp-stream");
return urlstring;
}

View File

@ -35,57 +35,20 @@ import java.util.regex.*;
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)
public PnmImage( int c, int w, int h)
{
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));
channel = c;
width = w;
height = h;
data = new byte [ w*h*c];
}
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);
}
public void openimage( String filename)
public PnmImage( String filename)
{
String str;
Pattern pat;
@ -137,5 +100,55 @@ public class PnmImage extends Component
}
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);
}
}

View File

@ -44,8 +44,7 @@ public class RegimViewer extends JPanel
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];

View File

@ -50,10 +50,18 @@ class ResizeListener implements ComponentListener
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) {}
}

View File

@ -1 +1 @@
opj_viewer_xerces-20110916.jar
opj_viewer_xerces-20110930.jar

View File

@ -3,7 +3,8 @@
*
* 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
@ -47,6 +48,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "query_parser.h"
#include "channel_manager.h"
@ -108,14 +110,21 @@ int main(void)
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
@ -206,10 +215,10 @@ bool close_channel( query_param_t query_param,
* @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,
@ -243,9 +252,9 @@ bool parse_JPIPrequest( query_param_t query_param,
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;
}
@ -368,13 +377,12 @@ bool close_channel( query_param_t query_param,
/**
* 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
@ -386,11 +394,11 @@ void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_
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;
@ -418,28 +426,60 @@ bool gene_JPTstream( query_param_t query_param,
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 ||
@ -456,19 +496,115 @@ void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_
// 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;

View File

@ -3,7 +3,8 @@
*
* 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
@ -77,6 +78,10 @@ void str2cclose( char *src, char cclose[][MAX_LENOFCID]);
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
@ -122,6 +127,16 @@ void parse_query( char *query_string, query_param_t *query_param)
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;
}
}
}
}
@ -138,6 +153,8 @@ void init_queryparam( query_param_t *query_param)
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);
@ -153,6 +170,7 @@ void init_queryparam( query_param_t *query_param)
query_param->root_bin = 0;
query_param->max_depth = -1;
query_param->metadata_only = false;
query_param->return_type = UNKNOWN;
}
@ -190,6 +208,15 @@ void print_queryparam( query_param_t query_param)
fprintf( logstream, "\t tid: %s\n", query_param.tid);
fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy);
fprintf( logstream, "\t rx,ry: %d, %d \t rw,rh: %d, %d\n", query_param.rx, query_param.ry, query_param.rw, query_param.rh);
fprintf( logstream, "\t 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);
@ -206,6 +233,7 @@ void print_queryparam( query_param_t query_param)
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])
@ -301,3 +329,39 @@ void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param
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;
}

View File

@ -4,6 +4,7 @@
* 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
@ -48,12 +49,17 @@
//! 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
@ -67,6 +73,7 @@ typedef struct query_param{
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;

View File

@ -47,7 +47,7 @@
#include <unistd.h>
#include <stdlib.h>
#include "msgqueue_manager.h"
#include "jp2k_encoder.h"
int main(int argc,char *argv[])
{
@ -89,7 +89,7 @@ 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);

View File

@ -50,6 +50,7 @@
#include "byte_manager.h"
#include "ihdrbox_manager.h"
#include "metadata_manager.h"
#include "jp2k_encoder.h"
int main(int argc,char *argv[])
{
@ -95,7 +96,7 @@ 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);

View File

@ -961,7 +961,7 @@ static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int len
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);
@ -1154,7 +1154,7 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
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 */
@ -1181,10 +1181,10 @@ opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_
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);

View File

@ -88,7 +88,10 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
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;
@ -102,20 +105,23 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
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 */
@ -125,7 +131,7 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
}
/* 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++;

View File

@ -85,13 +85,15 @@ int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int
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;
@ -107,19 +109,22 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
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 */
@ -129,7 +134,7 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
}
/* 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++;