[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 October 10, 2011
* [vincent] fix 'distcheck' rule * [vincent] fix 'distcheck' rule
* [antonin] modified indexer for JPIP, JPP-stream
October 7, 2011 October 7, 2011
+ [mickael] enhance non regression test suite generation (and some test names). It is based on a file as encoder previously. + [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 ! : changed
+ : added + : added
October 10, 2011
+ [antonin] enabled JPP-stream
September 16, 2011 September 16, 2011
+ [kaori] enabled stateless requests from the opj_viewers + [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: OpenJPEG:
http://www.openjpeg.org 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) ( 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). The current implementation uses some results from the 2KAN project (http://www.2kan.org).
First Version 1.0 covers: First Version 2.0 covers:
- JPT-stream (Tile based) media types - JPT-stream (Tile) and JPP-stream (Precinct) media types
- Session, channels, cache model managements - Session, channels, cache model managements
- JPIP over HTTP - JPIP over HTTP
- Indexing JPEG 2000 files - 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) - 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) - FastCGI development kit (C libraries) at server (http://www.fastcgi.com)
- Java application launcher at client - 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> <Optional>
- Xerces2 java XML parser on the client for accessing embedded image metadata (http://xerces.apache.org/xerces2-j) - 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. 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) 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): The documentation can be build this way (requires doxygen utility):
cd doc cd doc
doxygen Doxyfile doxygen Doxyfile
@ -128,12 +125,7 @@ Client:
---------- ----------
An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale. An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale.
% ./image_to_j2k -i copenhague1.tif -o copenhague1.jp2 -p RPCL -c [64,64] -t 640,480 -jpip
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
<Option> <Option>
3. Embed metadata into JP2 file 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}/mhixbox_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/target_manager.c ${CMAKE_CURRENT_SOURCE_DIR}/target_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/cachemodel_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 # Build the library

View File

@ -22,6 +22,8 @@ manfbox_manager.c \
mhixbox_manager.c \ mhixbox_manager.c \
target_manager.c \ target_manager.c \
cachemodel_manager.c \ cachemodel_manager.c \
j2kheader_manager.c \
jp2k_encoder.c \
bool.h \ bool.h \
boxheader_manager.h \ boxheader_manager.h \
box_manager.h \ box_manager.h \
@ -38,7 +40,9 @@ mhixbox_manager.h \
msgqueue_manager.h \ msgqueue_manager.h \
placeholder_manager.h \ placeholder_manager.h \
target_manager.h \ target_manager.h \
cachemodel_manager.h cachemodel_manager.h \
j2kheader_manager.h \
jp2k_encoder.h
libopenjpip_server_la_CPPFLAGS = \ libopenjpip_server_la_CPPFLAGS = \
-I. \ -I. \

View File

@ -145,3 +145,11 @@ Byte8_t big8( Byte_t *buf)
return (((Byte8_t) big4 (buf)) << 32) return (((Byte8_t) big4 (buf)) << 32)
+ ((Byte8_t) big4 (buf + 4)); + ((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); 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_ */ #endif /* !BYTE_MANAGER_H_ */

View File

@ -59,7 +59,10 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
{ {
cachemodel_param_t *cachemodel; cachemodel_param_t *cachemodel;
faixbox_param_t *tilepart; faixbox_param_t *tilepart;
faixbox_param_t *precpacket;
size_t numOfelem; size_t numOfelem;
Byte8_t numOftiles;
int i;
cachemodel = (cachemodel_param_t *)malloc( sizeof(cachemodel_param_t)); 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; cachemodel->mhead_model = false;
tilepart = target->codeidx->tilepart; 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->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; cachemodel->next = NULL;
if( cachemodellist){ if( cachemodellist){
@ -89,24 +98,39 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
void print_cachemodel( cachemodel_param_t cachemodel) void print_cachemodel( cachemodel_param_t cachemodel)
{ {
target_param_t *target;
Byte8_t TPnum; // num of tile parts in each tile Byte8_t TPnum; // num of tile parts in each tile
Byte8_t Pmax; // max num of packets per tile
int i, j, k, n; 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 main header model: %d\n", cachemodel.mhead_model);
fprintf( logstream, "\t tile part model:\n"); 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<target->codeidx->SIZ.YTnum; i++){
for( j=0; j<target->codeidx->SIZ.XTnum; j++){
for( i=0, n=0; i<cachemodel.target->codeidx->YTnum; i++){
for( j=0; j<cachemodel.target->codeidx->XTnum; j++){
for( k=0; k<TPnum; k++) for( k=0; k<TPnum; k++)
fprintf( logstream, "%d", cachemodel.tp_model[n++]); fprintf( logstream, "%d", cachemodel.tp_model[n++]);
fprintf( logstream, " "); fprintf( logstream, " ");
} }
fprintf( logstream, "\n"); 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) 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) void delete_cachemodel( cachemodel_param_t **cachemodel)
{ {
int i;
unrefer_target( (*cachemodel)->target); unrefer_target( (*cachemodel)->target);
free( (*cachemodel)->tp_model); 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 #ifndef SERVER
fprintf( logstream, "local log: cachemodel deleted\n"); 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 target_param_t *target; //!< reference pointer to the target
bool mhead_model; //!< main header model, if sent, 1, else 0 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 *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 struct cachemodel_param *next; //!< pointer to the next cache model
} cachemodel_param_t; } 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 \ $(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 \ 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 $@ $^ ar r $@ $^
clean: clean:

View File

@ -32,7 +32,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "ihdrbox_manager.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; ihdrbox_param_t *ihdrbox;
metadata_param_t *meta; metadata_param_t *meta;
@ -53,7 +53,7 @@ ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptst
return NULL; 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){ if( !ihdr){
fprintf( stderr, "ihdr box not found\n"); 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 = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
ihdrbox->height = big4( jptstream+get_DBoxoff(ihdr)); ihdrbox->height = big4( jpipstream+get_DBoxoff(ihdr));
ihdrbox->width = big4( jptstream+get_DBoxoff(ihdr)+4); ihdrbox->width = big4( jpipstream+get_DBoxoff(ihdr)+4);
ihdrbox->nc = big2( jptstream+get_DBoxoff(ihdr)+8); ihdrbox->nc = big2( jpipstream+get_DBoxoff(ihdr)+8);
ihdrbox->bpc = *(jptstream+get_DBoxoff(ihdr)+10)+1; ihdrbox->bpc = *(jpipstream+get_DBoxoff(ihdr)+10)+1;
free( ihdr); free( ihdr);

View File

@ -35,14 +35,22 @@
#include "box_manager.h" #include "box_manager.h"
#include "metadata_manager.h" #include "metadata_manager.h"
//! I.5.3.1 Image Header box
typedef struct ihdrbox_param{ typedef struct ihdrbox_param{
Byte4_t height; Byte4_t height;
Byte4_t width; Byte4_t width;
Byte2_t nc; Byte2_t nc; //!< number of components
Byte_t bpc; Byte_t bpc; //!< bits per component
} ihdrbox_param_t; } 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_ */ #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 rw, const int rh,
const int XOsiz, const int YOsiz, const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz, const int Xsiz, const int Ysiz,
const int numOfdecomp) const int numOfreslev)
{ {
imgreg_param_t imgreg; imgreg_param_t imgreg;
int px,py; int px,py;
@ -61,7 +61,7 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
xmax = Xsiz; xmax = Xsiz;
ymax = Ysiz; 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){ if( rx == -1 || ry == -1){
imgreg.ox = 0; imgreg.ox = 0;
@ -79,6 +79,12 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
else{ else{
px = ceil((double)((rx+rw)*imgreg.fx)/(double)fx); px = ceil((double)((rx+rw)*imgreg.fx)/(double)fx);
py = ceil((double)((ry+rh)*imgreg.fy)/(double)fy); 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.sx = px - imgreg.ox;
imgreg.sy = py - imgreg.oy; 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) 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] 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] 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] 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 * @return structure of image region parameters
*/ */
imgreg_param_t map_viewin2imgreg( const int fx, const int fy, 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 rw, const int rh,
const int XOsiz, const int YOsiz, const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz, 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); 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 * 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, "\tCodestream Offset: %#llx\n", index.offset);
fprintf( logstream, "\t Length: %#llx\n", index.length); fprintf( logstream, "\t Length: %#llx\n", index.length);
fprintf( logstream, "\tMain header Length: %#llx\n", index.mhead_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++) print_SIZ( index.SIZ);
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_COD( index.COD);
fprintf( logstream, "Tile part information: \n");
print_faixbox( index.tilepart); 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); 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) void delete_index( index_param_t **index)
{ {
int i;
delete_metadatalist( &((*index)->metadatalist)); delete_metadatalist( &((*index)->metadatalist));
free( (*index)->COD.XPsiz);
free( (*index)->COD.YPsiz);
delete_faixbox( &((*index)->tilepart)); 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); 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); 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) bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
{ {
box_param_t *manf_box; 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); set_tpixdata( cidx_box, jp2idx);
#ifdef NO_NEED_YET
if( !search_boxheader( "thix", manf)){ if( !search_boxheader( "thix", manf)){
fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n"); fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
free(jp2idx);
return false; return false;
} }
set_thixdata( cidx_box, jp2idx); 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); delete_manfbox( &manf);
free( manf_box); 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 Fixed information marker segment
* A.5.1 Image and tile size (SIZ) * A.5.1 Image and tile size (SIZ)
* *
* @param[in] sizmkidx pointer to SIZ marker index in mhix box * @param[in] sizmkidx pointer to SIZ marker index in mhix box
* @param[in] codestream codestream parameters * @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) * @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) bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx)
{ {
box_param_t *mhix_box; box_param_t *mhix_box;
mhixbox_param_t *mhix; mhixbox_param_t *mhix;
markeridx_param_t *sizmkidx; 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"))) if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
return false; return false;
@ -352,7 +431,10 @@ bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, ind
free( mhix_box); free( mhix_box);
sizmkidx = search_markeridx( 0xff51, mhix); 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); 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 *tpix_box; //!< tpix box
box_param_t *faix_box; //!< faix 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; 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; return false;
}
jp2idx->tilepart = gene_faixbox( faix_box); 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; boxheader_param_t *ptr;
mhixbox_param_t *mhix; mhixbox_param_t *mhix;
Byte8_t pos, mhixseqoff; 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; return false;
}
if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){ 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); free( thix_box);
return false; return false;
} }
@ -398,16 +488,24 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
ptr = manf->first; ptr = manf->first;
mhixseqoff = manf_box->offset+manf_box->length; mhixseqoff = manf_box->offset+manf_box->length;
pos = 0; pos = 0;
tile_no = 0;
jp2idx->tileheader = (mhixbox_param_t **)malloc( jp2idx->SIZ.XTnum*jp2idx->SIZ.YTnum*sizeof(mhixbox_param_t *));
while( ptr){ 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); mhix = gene_mhixbox( mhix_box);
pos += mhix_box->length; pos += mhix_box->length;
ptr = ptr->next; ptr = ptr->next;
free( mhix_box); free( mhix_box);
delete_mhixbox( &mhix); jp2idx->tileheader[tile_no++] = mhix;
} }
delete_manfbox( &manf); delete_manfbox( &manf);
@ -417,37 +515,131 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
return true; 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; marker_param_t sizmkr;
int i; int i;
sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length); 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); fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
return false; return false;
} }
jp2idx->Rsiz = fetch_marker2bytebigendian( sizmkr, 2); SIZ->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
jp2idx->Xsiz = fetch_marker4bytebigendian( sizmkr, 4); SIZ->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
jp2idx->Ysiz = fetch_marker4bytebigendian( sizmkr, 8); SIZ->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
jp2idx->XOsiz = fetch_marker4bytebigendian( sizmkr, 12); SIZ->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
jp2idx->YOsiz = fetch_marker4bytebigendian( sizmkr, 16); SIZ->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
jp2idx->XTsiz = fetch_marker4bytebigendian( sizmkr, 20); SIZ->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
jp2idx->YTsiz = fetch_marker4bytebigendian( sizmkr, 24); SIZ->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
jp2idx->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28); SIZ->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
jp2idx->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32); SIZ->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
jp2idx->Csiz = fetch_marker2bytebigendian( sizmkr, 36); SIZ->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
jp2idx->XTnum = ( jp2idx->Xsiz-jp2idx->XTOsiz+jp2idx->XTsiz-1)/jp2idx->XTsiz; SIZ->XTnum = ( SIZ->Xsiz-SIZ->XTOsiz+SIZ->XTsiz-1)/SIZ->XTsiz;
jp2idx->YTnum = ( jp2idx->Ysiz-jp2idx->YTOsiz+jp2idx->YTsiz-1)/jp2idx->YTsiz; SIZ->YTnum = ( SIZ->Ysiz-SIZ->YTOsiz+SIZ->YTsiz-1)/SIZ->YTsiz;
for( i=0; i<(int)jp2idx->Csiz; i++){ for( i=0; i<(int)SIZ->Csiz; i++){
jp2idx->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3); SIZ->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
jp2idx->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3); SIZ->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
jp2idx->YRsiz[i] = fetch_marker1byte( sizmkr, 40+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; 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 max( Byte4_t n1, Byte4_t n2);
Byte4_t min( 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; range_param_t range;
int n; int n;
range.minvalue = max( Osiz, TOsiz+tile_id*Tsiz); range.minvalue = max( Osiz, TOsiz+tile_XYid*Tsiz);
range.maxvalue = min( siz, TOsiz+(tile_id+1)*Tsiz); range.maxvalue = min( siz, TOsiz+(tile_XYid+1)*Tsiz);
for( n=0; n<level; n++){ for( n=0; n<level; n++){
range.minvalue = ceil(range.minvalue/2.0); 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; 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) Byte4_t max( Byte4_t n1, Byte4_t n2)
{ {
if( n1 < n2) if( n1 < n2)

View File

@ -34,42 +34,60 @@
#include "byte_manager.h" #include "byte_manager.h"
#include "faixbox_manager.h" #include "faixbox_manager.h"
#include "metadata_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 //! index parameters
typedef struct index_param{ typedef struct index_param{
metadatalist_param_t *metadatalist; //!< metadata-bin list metadatalist_param_t *metadatalist; //!< metadata-bin list
Byte8_t offset; //!< codestream offset Byte8_t offset; //!< codestream offset
Byte8_t length; //!< codestream length Byte8_t length; //!< codestream length
Byte8_t mhead_length; //!< main header length Byte8_t mhead_length; //!< main header length
//! A.5.1 Image and tile size (SIZ) SIZmarker_param_t SIZ; // !< SIZ marker information
Byte2_t Rsiz; //!< capabilities that a decoder needs CODmarker_param_t COD; // !< COD marker information
Byte4_t Xsiz; //!< width of the reference grid faixbox_param_t *tilepart; //!< tile part information from tpix box
Byte4_t Ysiz; //!< height of the reference grid mhixbox_param_t **tileheader; //!< dynamic array of tile header information from thix box
Byte4_t XOsiz; //!< horizontal offset from the origin of faixbox_param_t **precpacket; //!< dynamic array of precint packet information from ppix box
//!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
} index_param_t; } index_param_t;
@ -89,6 +107,19 @@ index_param_t * parse_jp2file( int fd);
*/ */
void print_index( index_param_t index); 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 * delete index
@ -106,22 +137,33 @@ typedef struct range_param{
/** /**
* get horizontal range of the tile in reference grid * get horizontal range of the tile in reference grid
* *
* @param[in] index index parameters * @param[in] SIZ SIZ marker information
* @param[in] tile_xid tile id in x-direction (0<= <XTnum) * @param[in] tile_id tile id
* @param[in] level decomposition level * @param[in] level decomposition level
* @return structured range parameter * @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 * get vertical range of the tile in reference grid
* *
* @param[in] index index parameters * @param[in] SIZ SIZ marker information
* @param[in] tile_yid tile id in y-direction (0<= <YTnum) * @param[in] tile_id tile id
* @param[in] level decomposition level * @param[in] level decomposition level
* @return structured range parameter * @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_ */ #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 * @param[in] metadatalist metadata list pointer
*/ */
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist); void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist);
#endif /* !METADATA_MANAGER_H_ */ #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, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -30,16 +31,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "msgqueue_manager.h" #include "msgqueue_manager.h"
#include "metadata_manager.h" #include "metadata_manager.h"
#include "index_manager.h"
#ifdef SERVER #ifdef SERVER
#include "fcgi_stdio.h" #include "fcgi_stdio.h"
@ -50,14 +49,6 @@
#define logstream stderr #define logstream stderr
#endif //SERVER #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 * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel)
{ {
msgqueue_param_t *msgqueue; msgqueue_param_t *msgqueue;
@ -96,6 +87,7 @@ void delete_msgqueue( msgqueue_param_t **msgqueue)
void print_msgqueue( msgqueue_param_t *msgqueue) void print_msgqueue( msgqueue_param_t *msgqueue)
{ {
message_param_t *ptr; message_param_t *ptr;
char *message_class[] = { "Precinct", "Ext-Prec", "TileHead", "non", "Tile", "Ext-Tile", "Main", "non", "Meta"};
if( !msgqueue) if( !msgqueue)
return; return;
@ -104,7 +96,7 @@ void print_msgqueue( msgqueue_param_t *msgqueue)
ptr = msgqueue->first; ptr = msgqueue->first;
while( ptr){ 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 in_class_id: %lld\n", ptr->in_class_id );
fprintf( logstream, "\t csn: %lld\n", ptr->csn ); fprintf( logstream, "\t csn: %lld\n", ptr->csn );
fprintf( logstream, "\t bin_offset: %#llx\n", ptr->bin_offset ); 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; cachemodel_param_t *cachemodel;
target_param_t *target; target_param_t *target;
index_param_t *codeidx;
message_param_t *msg; message_param_t *msg;
cachemodel = msgqueue->cachemodel; cachemodel = msgqueue->cachemodel;
target = cachemodel->target; target = cachemodel->target;
codeidx = target->codeidx;
msg = (message_param_t *)malloc( sizeof(message_param_t)); msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = true; msg->last_byte = true;
@ -139,9 +133,9 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
msg->class_id = MAINHEADER_MSG; msg->class_id = MAINHEADER_MSG;
msg->csn = target->csn; msg->csn = target->csn;
msg->bin_offset = 0; msg->bin_offset = 0;
msg->length = target->codeidx->mhead_length; msg->length = codeidx->mhead_length;
msg->aux = 0; // non exist msg->aux = 0; // non exist
msg->res_offset = target->codeidx->offset; msg->res_offset = codeidx->offset;
msg->phld = NULL; msg->phld = NULL;
msg->next = NULL; msg->next = NULL;
@ -150,6 +144,35 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
cachemodel->mhead_model = true; 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) void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
{ {
cachemodel_param_t *cachemodel; 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_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_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); 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; return;
msg = msgqueue->first; msg = msgqueue->first;
class_id = 0; class_id = -1;
csn = 0; csn = -1;
while( msg){ while( msg){
if( msg->csn == csn){ if( msg->csn == csn){
if( msg->class_id == class_id) if( msg->class_id == class_id)
@ -472,6 +532,7 @@ void emit_bigendian_bytes( Byte8_t code, int bytelength)
n--; n--;
} }
} }
void print_binarycode( Byte8_t n, int segmentlen) void print_binarycode( Byte8_t n, int segmentlen)
{ {
char buf[256]; 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; Byte8_t class_id, csn;
class_id = -1; // dummy class_id = -1; // dummy
csn = 0; csn = -1;
ptr = JPIPstream; ptr = JPIPstream;
while( ptr-JPIPstream < streamlen){ while( ptr-JPIPstream < streamlen){
msg = (message_param_t *)malloc( sizeof(message_param_t)); 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; msg->last_byte = c == 1 ? true : false;
if( bb >= 2){ if( bb >= 2)
ptr = parse_vbas( ptr, &class_id); ptr = parse_vbas( ptr, &class_id);
// fprintf( stdout, "class_id: %lld\n", class_id);
}
msg->class_id = class_id; msg->class_id = class_id;
if (bb == 3) if (bb == 3)
@ -646,183 +706,6 @@ Byte_t * parse_vbas( Byte_t *streamptr, Byte8_t *elem)
return ptr; 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) void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgqueue)
{ {
message_param_t *ptr; message_param_t *ptr;
@ -845,139 +728,3 @@ void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgque
} }
free( *msg); 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, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,6 +37,14 @@
#include "cachemodel_manager.h" #include "cachemodel_manager.h"
#include "placeholder_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 //! message parameters
typedef struct message_param{ typedef struct message_param{
bool last_byte; //!< if message contains the last byte of the data-bin 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); 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 * print message queue
* *
@ -90,6 +107,15 @@ void print_msgqueue( msgqueue_param_t *msgqueue);
void enqueue_mainheader( 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 * 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); 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 * 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); 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] t tile index
* @param[in] jpipstream original jpt- jpp- stream * @param[in] c component index
* @param[in] csn codestream number * @param[in] s sequence number
* @param[in] minlev minimum decomposition level * @param[in] num_components total number of components
* @param[out] j2klen pointer to the j2k codestream length * @param[in] num_tiles total number of tiles
* @return generated reconstructed j2k codestream * @return precicnt id
*/ */
Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *j2klen); Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles);
/**
* 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 /* !MSGQUEUE_MANAGER_H_ */ #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){
if( (*ihdrbox)->nc != image->numcomps) if( (*ihdrbox)->nc != image->numcomps)
fprintf( stderr, "Exception: num of components not identical, codestream: %d, ihdrbox: %d\n", image->numcomps, (*ihdrbox)->nc); fprintf( stderr, "Exception: num of components not identical, codestream: %d, ihdrbox: %d\n", image->numcomps, (*ihdrbox)->nc);
if( (*ihdrbox)->width != image->comps[0].w) 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) 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) 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); 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 <string.h>
#include <time.h> #include <time.h>
#include "jpipstream_manager.h" #include "jpipstream_manager.h"
#include "jp2k_encoder.h"
#include "jp2k_decoder.h" #include "jp2k_decoder.h"
#include "imgreg_manager.h"
Byte_t * update_JPIPstream( Byte_t *newstream, int newstreamlen, Byte_t *cache_stream, int *streamlen) Byte_t * 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 *pnmstream;
Byte_t *j2kstream; // j2k or jp2 codestream Byte_t *j2kstream; // j2k or jp2 codestream
Byte8_t j2klen; Byte8_t j2klen;
int level = 0;
if( *ihdrbox){ j2kstream = recons_j2k( msgqueue, jpipstream, csn, fw, fh, &j2klen);
// 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);
pnmstream = j2k_to_pnm( j2kstream, j2klen, ihdrbox); pnmstream = j2k_to_pnm( j2kstream, j2klen, ihdrbox);
free( j2kstream); free( j2kstream);

View File

@ -54,6 +54,7 @@
#include "imgsock_manager.h" #include "imgsock_manager.h"
#include "jpipstream_manager.h" #include "jpipstream_manager.h"
#include "cache_manager.h" #include "cache_manager.h"
#include "jp2k_encoder.h"
#ifdef _WIN32 #ifdef _WIN32
WSADATA initialisation_win32; WSADATA initialisation_win32;
@ -237,15 +238,15 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
metadatalist_param_t *metadatalist; metadatalist_param_t *metadatalist;
newjpipstream = receive_JPIPstream( connected_socket, target, tid, cid, &newstreamlen); newjpipstream = receive_JPIPstream( connected_socket, target, tid, cid, &newstreamlen);
parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue); parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
*jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen); *jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
free( newjpipstream); free( newjpipstream);
metadatalist = gene_metadatalist(); metadatalist = gene_metadatalist();
parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist); parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist);
// cid registration // cid registration
if( target[0] != 0){ if( target[0] != 0){
if((cache = search_cache( target, cachelist))){ if((cache = search_cache( target, cachelist))){
@ -265,7 +266,7 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
if( cache->metadatalist) if( cache->metadatalist)
delete_metadatalist( &cache->metadatalist); delete_metadatalist( &cache->metadatalist);
cache->metadatalist = metadatalist; cache->metadatalist = metadatalist;
response_signal( connected_socket, true); 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]; char cid[MAX_LENOFCID], tmp[10];
cache_param_t *cache; cache_param_t *cache;
int fw, fh; int fw, fh;
receive_line( connected_socket, cid); receive_line( connected_socket, cid);
if(!(cache = search_cacheBycid( cid, cachelist))) if(!(cache = search_cacheBycid( cid, cachelist)))
if(!(cache = search_cacheBytid( 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); pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox);
ihdrbox = cache->ihdrbox; ihdrbox = cache->ihdrbox;
send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1); send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1);
free( pnmstream); 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; pnmimage = null;
} }
public int getOrigWidth(){ return pnmimage.width;} public int getOrigWidth(){ return pnmimage.get_width();}
public int getOrigHeight(){ return pnmimage.height;} public int getOrigHeight(){ return pnmimage.get_height();}
public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew) 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); jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew);
System.err.println( "decoding to PNM image"); System.err.println( "decoding to PNM image");
pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh); if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){
System.err.println( " done"); System.err.println( " done");
return pnmimage.createROIImage( rx, ry, rw, rh);
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) 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); byte[] jpipstream = super.requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh);
System.err.println( "decoding to PNM image"); System.err.println( "decoding to PNM image");
pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh); if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh)) != null){
System.err.println( " done"); System.err.println( " done");
return pnmimage.createROIImage( rx, ry, rw, rh);
return pnmimage.createROIImage( rx, ry, rw, rh); }
else{
System.err.println( " failed");
return null;
}
} }
public byte[] getXML() public byte[] getXML()

View File

@ -40,8 +40,6 @@ import java.io.*;
public class ImageViewer extends JPanel public class ImageViewer extends JPanel
{ {
private MML myMML;
private ResizeListener myRL;
private ImageManager imgmanager; private ImageManager imgmanager;
private int vw, vh; private int vw, vh;
private int iw, ih; private int iw, ih;
@ -58,8 +56,9 @@ public class ImageViewer extends JPanel
public ImageViewer( String j2kfilename, ImageManager manager, boolean session) public ImageViewer( String j2kfilename, ImageManager manager, boolean session)
{ {
String str; String str;
MML myMML;
this.setSize( 200, 200);
this.setSize( 170, 170);
Dimension asz = this.getSize(); Dimension asz = this.getSize();
vw = asz.width; vw = asz.width;
@ -67,14 +66,14 @@ public class ImageViewer extends JPanel
setBackground(Color.black); setBackground(Color.black);
myMML = new MML(this); myMML = new MML(this);
myRL = new ResizeListener(this);
imgmanager = manager; imgmanager = manager;
img = imgmanager.getImage( j2kfilename, vw, vh, session); img = imgmanager.getImage( j2kfilename, vw, vh, session);
addMouseListener(myMML); addMouseListener(myMML);
addMouseMotionListener(myMML); addMouseMotionListener(myMML);
addComponentListener(myRL); addComponentListener( new ResizeListener(this));
} }
public Image getImage() public Image getImage()
@ -87,8 +86,8 @@ public class ImageViewer extends JPanel
roirect = null; roirect = null;
roiname = null; roiname = null;
double scalex = vw/(double)rect.width; double scalex = (double)vw/(double)rect.width;
double scaley = vh/(double)rect.height; double scaley = (double)vh/(double)rect.height;
int fw = (int)(imgmanager.getFw()*scalex); int fw = (int)(imgmanager.getFw()*scalex);
int fh = (int)(imgmanager.getFh()*scaley); int fh = (int)(imgmanager.getFh()*scaley);
@ -108,12 +107,12 @@ public class ImageViewer extends JPanel
{ {
roirect = null; roirect = null;
roiname = null; roiname = null;
Dimension asz = this.getSize(); Dimension asz = this.getSize();
vw = asz.width; vw = asz.width;
vh = asz.height; vh = asz.height;
double scalex = vw/(double)imgmanager.getRw(); double scalex = vw/(double)imgmanager.getRw();
double scaley = vh/(double)imgmanager.getRh(); double scaley = vh/(double)imgmanager.getRh();
@ -121,9 +120,9 @@ public class ImageViewer extends JPanel
int fh = (int)(imgmanager.getFh()*scaley); int fh = (int)(imgmanager.getFh()*scaley);
int rx = (int)(imgmanager.getRx()*scalex); int rx = (int)(imgmanager.getRx()*scalex);
int ry = (int)(imgmanager.getRy()*scaley); int ry = (int)(imgmanager.getRy()*scaley);
img = imgmanager.getImage( fw, fh, rx, ry, vw, vh); img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
fullRefresh = true; fullRefresh = true;
repaint(); repaint();
} }

View File

@ -108,10 +108,11 @@ public class ImgdecClient{
System.err.println("IOException: " + e); System.err.println("IOException: " + e);
} }
} }
public static PnmImage get_PNMstream( String cid, String tid, int fw, int fh) public static PnmImage get_PNMstream( String cid, String tid, int fw, int fh)
{ {
PnmImage pnmstream = new PnmImage(); PnmImage pnmstream = null;
try { try {
Socket imgdecSocket = new Socket( "localhost", 5000); Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream()); DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
@ -130,25 +131,20 @@ public class ImgdecClient{
os.writeBytes( fh + "\n"); os.writeBytes( fh + "\n");
read_stream( is, header, 7); read_stream( is, header, 7);
if( header[0] == 80){ if( header[0] == 80){
// P5: gray, P6: color // P5: gray, P6: color
byte magicknum = header[1]; byte magicknum = header[1];
if( magicknum == 5 || magicknum == 6){ if( magicknum == 5 || magicknum == 6){
int length; int c = magicknum==6 ? 3: 1;
boolean iscolor = magicknum==6 ? true:false; int w = (header[2]&0xff)<<8 | (header[3]&0xff);
if( iscolor) int h = (header[4]&0xff)<<8 | (header[5]&0xff);
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 maxval = header[6]&0xff; int maxval = header[6]&0xff;
int length = w*h*c;
if( maxval == 255){
length = pnmstream.width*pnmstream.height*pnmstream.channel; if( maxval == 255 && length != 0){
pnmstream.data = new byte [ length]; pnmstream = new PnmImage( c, w, h);
read_stream( is, pnmstream.data, length); read_stream( is, pnmstream.get_data(), length);
} }
else else
System.err.println("Error in get_PNMstream(), only 255 is accepted"); System.err.println("Error in get_PNMstream(), only 255 is accepted");
@ -158,6 +154,7 @@ public class ImgdecClient{
} }
else else
System.err.println("Error in get_PNMstream(), Not starting with P"); System.err.println("Error in get_PNMstream(), Not starting with P");
os.close(); os.close();
is.close(); is.close();
imgdecSocket.close(); imgdecSocket.close();
@ -265,7 +262,7 @@ public class ImgdecClient{
try{ try{
while( remlen > 0){ while( remlen > 0){
int redlen = is.read( stream, off, remlen); int redlen = is.read( stream, off, remlen);
if( redlen == -1){ if( redlen == -1){
System.err.println(" failed to read_stream()"); System.err.println(" failed to read_stream()");
break; break;

View File

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

View File

@ -35,57 +35,20 @@ import java.util.regex.*;
public class PnmImage extends Component public class PnmImage extends Component
{ {
public byte[] data = null; private byte[] data = null;
public int width = 0; private int width = 0;
public int height = 0; private int height = 0;
public int channel = 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]; channel = c;
width = w;
for( int i=0; i<rh; i++) height = h;
for( int j=0; j<rw; j++){ data = new byte [ w*h*c];
pix[i*rw+j] = 0xFF << 24; // transparency
if( channel == 1){
Byte lum = data[(ry+i)*width+rx+j];
short slum;
if( lum < 0)
slum = (short)(2*128+lum);
else
slum = (short)lum;
for( int c=0; c<3; c++){
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
}
}
else
for( int c=0; c<3; c++){
Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
short slum;
if( lum < 0)
slum = (short)(2*128+lum);
else
slum = (short)lum;
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
}
}
return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
} }
public Image createScaleImage( double scale) public PnmImage( String filename)
{
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)
{ {
String str; String str;
Pattern pat; Pattern pat;
@ -137,5 +100,55 @@ public class PnmImage extends Component
} }
fis.close(); fis.close();
} catch (IOException e) { e.printStackTrace(); } } 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) public RegimViewer( String refname, double[] mat)
{ {
refpnm = new PnmImage(); refpnm = new PnmImage( refname.replaceFirst("jp2", "pgm")); // decoding not realized
refpnm.openimage(refname.replaceFirst("jp2", "pgm")); // decoding not realized
affine_matrix = new double[6]; affine_matrix = new double[6];
affine_matrix[0] = mat[0]; affine_matrix[0] = mat[0];

View File

@ -50,10 +50,18 @@ class ResizeListener implements ComponentListener
public void componentResized(ComponentEvent e) { public void componentResized(ComponentEvent e) {
Dimension cursize = iv.getSize(); Dimension cursize = iv.getSize();
if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){ if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){
largest = cursize; update_largest( cursize);
iv.enlarge(); 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) {} 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, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -47,6 +48,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include "query_parser.h" #include "query_parser.h"
#include "channel_manager.h" #include "channel_manager.h"
@ -108,14 +110,21 @@ int main(void)
if( strcmp( query_string, QUIT_SIGNAL) == 0) if( strcmp( query_string, QUIT_SIGNAL) == 0)
break; break;
fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
query_param_t query_param; query_param_t query_param;
msgqueue_param_t *msgqueue; msgqueue_param_t *msgqueue;
parse_query( query_string, &query_param); 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 #ifndef SERVER
print_queryparam( query_param); print_queryparam( query_param);
#endif #endif
@ -206,10 +215,10 @@ bool close_channel( query_param_t query_param,
* @param[in] target requested target pointer * @param[in] target requested target pointer
* @param[in,out] cursession associated session pointer * @param[in,out] cursession associated session pointer
* @param[in,out] curchannel associated channel 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) * @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, target_param_t *target,
session_param_t *cursession, session_param_t *cursession,
channel_param_t *curchannel, channel_param_t *curchannel,
@ -243,9 +252,9 @@ bool parse_JPIPrequest( query_param_t query_param,
return false; return false;
if( (query_param.fx > 0 && query_param.fy > 0) || query_param.box_type[0][0] != 0) 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 false;
return true; 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] query_param structured query
* @param[in] codeidx pointer to index parameters * @param[in] msgqueue message queue pointer
* @param[in,out] 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 * 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); void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
bool gene_JPTstream( query_param_t query_param, bool gene_JPIPstream( query_param_t query_param,
target_param_t *target, target_param_t *target,
session_param_t *cursession, session_param_t *cursession,
channel_param_t *curchannel, channel_param_t *curchannel,
msgqueue_param_t **msgqueue) msgqueue_param_t **msgqueue)
{ {
index_param_t *codeidx; index_param_t *codeidx;
cachemodel_param_t *cachemodel; 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( query_param.fx > 0 && query_param.fy > 0){
if( !cachemodel->mhead_model) if( !cachemodel->mhead_model)
enqueue_mainheader( *msgqueue); enqueue_mainheader( *msgqueue);
enqueue_tiles( query_param, codeidx, *msgqueue); enqueue_imagedata( query_param, *msgqueue);
} }
return true; 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; imgreg_param_t imgreg;
range_param_t tile_Xrange, tile_Yrange; range_param_t tile_Xrange, tile_Yrange;
int u, v, tile_id; int u, v, tile_id;
int xmin, xmax, ymin, ymax;
codeidx = msgqueue->cachemodel->target->codeidx;
imgreg = map_viewin2imgreg( query_param.fx, query_param.fy, imgreg = map_viewin2imgreg( query_param.fx, query_param.fy,
query_param.rx, query_param.ry, query_param.rw, query_param.rh, query_param.rx, query_param.ry, query_param.rw, query_param.rh,
codeidx->XOsiz, codeidx->YOsiz, codeidx->Xsiz, codeidx->Ysiz, codeidx->SIZ.XOsiz, codeidx->SIZ.YOsiz, codeidx->SIZ.Xsiz, codeidx->SIZ.Ysiz,
get_nmax( codeidx->tilepart)); codeidx->COD.numOfdecomp+1);
for( u=0, tile_id=0; u<codeidx->SIZ.YTnum; u++){
for( u=0, tile_id=0; u<codeidx->YTnum; u++){ tile_Yrange = get_tile_Yrange( codeidx->SIZ, tile_id, imgreg.level);
tile_Yrange = get_tile_Yrange( *codeidx, u, imgreg.level);
for( v=0; v<codeidx->XTnum; v++, tile_id++){ for( v=0; v<codeidx->SIZ.XTnum; v++, tile_id++){
tile_Xrange = get_tile_Xrange( *codeidx, v, imgreg.level); 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.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
if( tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox || 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 // Tile completely contained within view-window
// high priority // high priority
//printf("Tile completely contained within view-window %d\n", tile_id); //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{ else{
// Tile partially overlaps view-window // Tile partially overlaps view-window
// low priority // low priority
//printf("Tile partially overlaps view-window %d\n", tile_id); //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) void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
{ {
int i; 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, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * 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); 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 //! maximum length of field name
#define MAX_LENOFFIELDNAME 10 #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) else if( strcasecmp( fieldname, "metareq") == 0)
parse_metareq( fieldval, query_param); 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->ry=-1;
query_param->rw=-1; query_param->rw=-1;
query_param->rh=-1; query_param->rh=-1;
query_param->lastcomp = -1;
query_param->comps = NULL;
query_param->cid[0]='\0'; query_param->cid[0]='\0';
query_param->cnew=false; query_param->cnew=false;
memset( query_param->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID); 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->root_bin = 0;
query_param->max_depth = -1; query_param->max_depth = -1;
query_param->metadata_only = false; 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 tid: %s\n", query_param.tid);
fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy); 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 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 cnew: %d\n", query_param.cnew);
fprintf( logstream, "\t cid: %s\n", query_param.cid); 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 root-bin: %d\n", query_param.root_bin);
fprintf( logstream, "\t max-depth: %d\n", query_param.max_depth); 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 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]) 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++; 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, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
* Copyright (c) 2002-2011, Professor Benoit Macq * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -48,12 +49,17 @@
//! maximum number of meta request box //! maximum number of meta request box
#define MAX_NUMOFBOX 10 #define MAX_NUMOFBOX 10
//! image return type
typedef enum image_return { JPPstream, JPTstream, UNKNOWN=-1} image_return_t;
//! Query parameters //! Query parameters
typedef struct query_param{ typedef struct query_param{
char target[MAX_LENOFTARGET]; //!< target name char target[MAX_LENOFTARGET]; //!< target name
char tid[MAX_LENOFTID]; //!< target identifier char tid[MAX_LENOFTID]; //!< target identifier
int fx, fy; //!< frame size (fx,fy) int fx, fy; //!< frame size (fx,fy)
int rx, ry, rw, rh; //!< roi region 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 char cid[MAX_LENOFCID]; //!< channel identifier
bool cnew; //!< if there is new channel request(true) or not (false) bool cnew; //!< if there is new channel request(true) or not (false)
char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers
@ -67,6 +73,7 @@ typedef struct query_param{
int root_bin; //!< root-bin int root_bin; //!< root-bin
int max_depth; //!< max-depth int max_depth; //!< max-depth
bool metadata_only; //!< metadata-only request bool metadata_only; //!< metadata-only request
image_return_t return_type; //!< image return type
} query_param_t; } query_param_t;

View File

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

View File

@ -50,6 +50,7 @@
#include "byte_manager.h" #include "byte_manager.h"
#include "ihdrbox_manager.h" #include "ihdrbox_manager.h"
#include "metadata_manager.h" #include "metadata_manager.h"
#include "jp2k_encoder.h"
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
@ -95,7 +96,7 @@ int main(int argc,char *argv[])
print_msgqueue( msgqueue); print_msgqueue( msgqueue);
//print_allmetadata( metadatalist); //print_allmetadata( metadatalist);
ihdrbox = get_ihdrbox( metadatalist, jpipstream); ihdrbox = gene_ihdrbox( metadatalist, jpipstream);
printf("W*H: %d*%d\n", ihdrbox->height, ihdrbox->width); printf("W*H: %d*%d\n", ihdrbox->height, ihdrbox->width);
printf("NC: %d, bpc: %d\n", ihdrbox->nc, ihdrbox->bpc); 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_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FIDX, 4); /* IPTR */ 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; len = cio_tell( cio)-lenp;
cio_seek( 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) { 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 */ /* 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){ if( jp2->jpip_on){
pos_cidx = cio_tell( cio); 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); 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); 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 size_of_coding; // 4 or 8
int version; int version;
int tileno, resno, precno, layno, num_packet=0; 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)){ if( j2klen > pow( 2, 32)){
size_of_coding = 8; size_of_coding = 8;
version = 1; 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_skip( cio, 4); /* L [at the end] */
cio_write( cio, JPIP_FAIX, 4); /* FAIX */ cio_write( cio, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version,1); /* Version 0 = 4 bytes */ 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 */ cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){ 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; // int correction = EPHused ? 3 : 1;
num_packet = 0; 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( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
for( layno=0; layno<cstr_info.numlayers; layno++){ 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.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */ 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 */ /* 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); /* start position */
cio_write( cio, 0, size_of_coding); /* length */ cio_write( cio, 0, size_of_coding); /* length */
num_packet++; 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; 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 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 len, lenp;
int tileno, resno, precno, layno, num_packet=0; int tileno, resno, precno, layno, num_packet=0;
int size_of_coding; // 4 or 8 int size_of_coding; // 4 or 8
int version; int version;
int i,nmax=0;
opj_tile_info_t *tile_Idx;
opj_packet_info_t packet;
if( j2klen > pow( 2, 32)){ if( j2klen > pow( 2, 32)){
size_of_coding = 8; 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, JPIP_FAIX, 4); /* FAIX */
cio_write( cio, version, 1); /* Version 0 = 4 bytes */ 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 */ cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){ 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; // int correction = EPHused ? 3 : 1;
num_packet=0; 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( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
for( layno=0; layno<cstr_info.numlayers; layno++){ 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.start_pos-coff, size_of_coding); /* start position */
cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */ 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 */ /* 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); /* start position */
cio_write( cio, 0, size_of_coding); /* length */ cio_write( cio, 0, size_of_coding); /* length */
num_packet++; num_packet++;