[1.5] enabled JPP stream in JPIP (result of GSoC program)
This commit is contained in:
parent
9e60c2f8e9
commit
8a2af121a4
1
CHANGES
1
CHANGES
|
@ -7,6 +7,7 @@ What's New for OpenJPEG
|
|||
|
||||
October 10, 2011
|
||||
* [vincent] fix 'distcheck' rule
|
||||
* [antonin] modified indexer for JPIP, JPP-stream
|
||||
|
||||
October 7, 2011
|
||||
+ [mickael] enhance non regression test suite generation (and some test names). It is based on a file as encoder previously.
|
||||
|
|
|
@ -5,6 +5,9 @@ What's New for OpenJPIP
|
|||
! : changed
|
||||
+ : added
|
||||
|
||||
October 10, 2011
|
||||
+ [antonin] enabled JPP-stream
|
||||
|
||||
September 16, 2011
|
||||
+ [kaori] enabled stateless requests from the opj_viewers
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
========================================================================
|
||||
OpenJPIP software 1.0 ReadMe
|
||||
OpenJPIP software 2.0 ReadMe
|
||||
|
||||
OpenJPEG:
|
||||
http://www.openjpeg.org
|
||||
|
@ -26,8 +26,8 @@ OpenJPIP software is an implementation of JPEG 2000 Part9: Interactivity tools,
|
|||
( For more info about JPIP, check the website: http://www.jpeg.org/jpeg2000/j2kpart9.html)
|
||||
The current implementation uses some results from the 2KAN project (http://www.2kan.org).
|
||||
|
||||
First Version 1.0 covers:
|
||||
- JPT-stream (Tile based) media types
|
||||
First Version 2.0 covers:
|
||||
- JPT-stream (Tile) and JPP-stream (Precinct) media types
|
||||
- Session, channels, cache model managements
|
||||
- JPIP over HTTP
|
||||
- Indexing JPEG 2000 files
|
||||
|
@ -49,7 +49,6 @@ Neither the author, nor the university accept any responsibility for any kind of
|
|||
- OpenJPEG library (currently assumes it is installed on the system => will not use the one built higher in the directory structure)
|
||||
- FastCGI development kit (C libraries) at server (http://www.fastcgi.com)
|
||||
- Java application launcher at client
|
||||
- Kakadu software ( http://www.kakadusoftware.com). Currently required to encode jpeg 2000 images with tile-parts. This will be implemented soon in openjpeg, making this requirement obsolete.
|
||||
<Optional>
|
||||
- Xerces2 java XML parser on the client for accessing embedded image metadata (http://xerces.apache.org/xerces2-j)
|
||||
|
||||
|
@ -62,8 +61,6 @@ We tested this software with a virtual server running on the same Linux machine
|
|||
A Makefile is available in the same directory as this README file. Simply type 'make' and it will build all the required C-executables.
|
||||
Concerning the java-based opj_viewer, simply type 'ant' in the corresponding directory (requires 'ant' utility of course)
|
||||
|
||||
CMake files ar planned to be included ASAP.
|
||||
|
||||
The documentation can be build this way (requires doxygen utility):
|
||||
cd doc
|
||||
doxygen Doxyfile
|
||||
|
@ -128,12 +125,7 @@ Client:
|
|||
----------
|
||||
|
||||
An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale.
|
||||
|
||||
1. J2K encoding using Kakadu with an option which introduces the tile-part flag at each resolution level
|
||||
% ./kdu_compress -i copenhague1.tif -o copenhague1.j2k Corder=RPCL ORGtparts=R Stiles={256,256}
|
||||
|
||||
2. JP2 encoding with embedding indexing data
|
||||
% ./j2k_to_idxjp2 copenhague1.j2k copenhague1.jp2
|
||||
% ./image_to_j2k -i copenhague1.tif -o copenhague1.jp2 -p RPCL -c [64,64] -t 640,480 -jpip
|
||||
|
||||
<Option>
|
||||
3. Embed metadata into JP2 file
|
||||
|
|
|
@ -22,6 +22,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/manfbox_manager.c
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/mhixbox_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/target_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cachemodel_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/j2kheader_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/jp2k_encoder.c
|
||||
)
|
||||
|
||||
# Build the library
|
||||
|
|
|
@ -22,6 +22,8 @@ manfbox_manager.c \
|
|||
mhixbox_manager.c \
|
||||
target_manager.c \
|
||||
cachemodel_manager.c \
|
||||
j2kheader_manager.c \
|
||||
jp2k_encoder.c \
|
||||
bool.h \
|
||||
boxheader_manager.h \
|
||||
box_manager.h \
|
||||
|
@ -38,7 +40,9 @@ mhixbox_manager.h \
|
|||
msgqueue_manager.h \
|
||||
placeholder_manager.h \
|
||||
target_manager.h \
|
||||
cachemodel_manager.h
|
||||
cachemodel_manager.h \
|
||||
j2kheader_manager.h \
|
||||
jp2k_encoder.h
|
||||
|
||||
libopenjpip_server_la_CPPFLAGS = \
|
||||
-I. \
|
||||
|
|
|
@ -145,3 +145,11 @@ Byte8_t big8( Byte_t *buf)
|
|||
return (((Byte8_t) big4 (buf)) << 32)
|
||||
+ ((Byte8_t) big4 (buf + 4));
|
||||
}
|
||||
|
||||
void modify_4Bytecode( Byte4_t code, Byte_t *stream)
|
||||
{
|
||||
*stream = (Byte_t) ((Byte4_t)(code & 0xff000000) >> 24);
|
||||
*(stream+1) = (Byte_t) ((Byte4_t)(code & 0x00ff0000) >> 16);
|
||||
*(stream+2) = (Byte_t) ((Byte4_t)(code & 0x0000ff00) >> 8);
|
||||
*(stream+3) = (Byte_t) (code & 0x000000ff);
|
||||
}
|
||||
|
|
|
@ -116,5 +116,12 @@ Byte4_t big4( Byte_t *buf);
|
|||
*/
|
||||
Byte8_t big8( Byte_t *buf);
|
||||
|
||||
/**
|
||||
* modify 4Byte code in a codestream
|
||||
*
|
||||
* @param[in] code code value
|
||||
* @param[out] stream modifying codestream
|
||||
*/
|
||||
void modify_4Bytecode( Byte4_t code, Byte_t *stream);
|
||||
|
||||
#endif /* !BYTE_MANAGER_H_ */
|
||||
|
|
|
@ -59,7 +59,10 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
|
|||
{
|
||||
cachemodel_param_t *cachemodel;
|
||||
faixbox_param_t *tilepart;
|
||||
faixbox_param_t *precpacket;
|
||||
size_t numOfelem;
|
||||
Byte8_t numOftiles;
|
||||
int i;
|
||||
|
||||
cachemodel = (cachemodel_param_t *)malloc( sizeof(cachemodel_param_t));
|
||||
|
||||
|
@ -67,9 +70,15 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
|
|||
cachemodel->mhead_model = false;
|
||||
|
||||
tilepart = target->codeidx->tilepart;
|
||||
numOfelem = get_nmax( tilepart)*get_m( tilepart);
|
||||
numOftiles = get_m( tilepart);
|
||||
numOfelem = get_nmax( tilepart)*numOftiles;
|
||||
cachemodel->tp_model = (bool *)calloc( 1, numOfelem*sizeof(bool));
|
||||
|
||||
cachemodel->th_model = (bool *)calloc( 1, numOftiles*sizeof(bool));
|
||||
cachemodel->pp_model = (bool **)malloc( target->codeidx->SIZ.Csiz*sizeof(bool *));
|
||||
for( i=0; i<target->codeidx->SIZ.Csiz; i++){
|
||||
precpacket = target->codeidx->precpacket[i];
|
||||
cachemodel->pp_model[i] = (bool *)calloc( 1, get_nmax(precpacket)*get_m(precpacket)*sizeof(bool));
|
||||
}
|
||||
cachemodel->next = NULL;
|
||||
|
||||
if( cachemodellist){
|
||||
|
@ -89,24 +98,39 @@ cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, ta
|
|||
|
||||
void print_cachemodel( cachemodel_param_t cachemodel)
|
||||
{
|
||||
target_param_t *target;
|
||||
Byte8_t TPnum; // num of tile parts in each tile
|
||||
Byte8_t Pmax; // max num of packets per tile
|
||||
int i, j, k, n;
|
||||
|
||||
target = cachemodel.target;
|
||||
|
||||
fprintf( logstream, "target: %s\n", cachemodel.target->filename);
|
||||
fprintf( logstream, "target: %s\n", target->filename);
|
||||
fprintf( logstream, "\t main header model: %d\n", cachemodel.mhead_model);
|
||||
|
||||
fprintf( logstream, "\t tile part model:\n");
|
||||
TPnum = get_nmax( target->codeidx->tilepart);
|
||||
|
||||
TPnum = get_nmax( cachemodel.target->codeidx->tilepart);
|
||||
|
||||
for( i=0, n=0; i<cachemodel.target->codeidx->YTnum; i++){
|
||||
for( j=0; j<cachemodel.target->codeidx->XTnum; j++){
|
||||
for( i=0, n=0; i<target->codeidx->SIZ.YTnum; i++){
|
||||
for( j=0; j<target->codeidx->SIZ.XTnum; j++){
|
||||
for( k=0; k<TPnum; k++)
|
||||
fprintf( logstream, "%d", cachemodel.tp_model[n++]);
|
||||
fprintf( logstream, " ");
|
||||
}
|
||||
fprintf( logstream, "\n");
|
||||
}
|
||||
|
||||
fprintf( logstream, "\t tile header and precinct packet model:\n");
|
||||
for( i=0; i<target->codeidx->SIZ.XTnum*target->codeidx->SIZ.YTnum; i++){
|
||||
fprintf( logstream, "\t tile.%d %d\n", i, cachemodel.th_model[i]);
|
||||
for( j=0; j<target->codeidx->SIZ.Csiz; j++){
|
||||
fprintf( logstream, "\t compo.%d: ", j);
|
||||
Pmax = get_nmax( target->codeidx->precpacket[j]);
|
||||
for( k=0; k<Pmax; k++)
|
||||
fprintf( logstream, "%d", cachemodel.pp_model[j][i*Pmax+k]);
|
||||
fprintf( logstream, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cachemodel_param_t * search_cachemodel( target_param_t *target, cachemodellist_param_t *cachemodellist)
|
||||
|
@ -140,9 +164,17 @@ void delete_cachemodellist( cachemodellist_param_t **cachemodellist)
|
|||
|
||||
void delete_cachemodel( cachemodel_param_t **cachemodel)
|
||||
{
|
||||
int i;
|
||||
|
||||
unrefer_target( (*cachemodel)->target);
|
||||
|
||||
free( (*cachemodel)->tp_model);
|
||||
free( (*cachemodel)->th_model);
|
||||
|
||||
if( (*cachemodel)->target->codeidx->SIZ.Csiz > 1)
|
||||
for( i=0; i<(*cachemodel)->target->codeidx->SIZ.Csiz; i++)
|
||||
free( (*cachemodel)->pp_model[i]);
|
||||
free( (*cachemodel)->pp_model);
|
||||
|
||||
#ifndef SERVER
|
||||
fprintf( logstream, "local log: cachemodel deleted\n");
|
||||
|
|
|
@ -39,6 +39,8 @@ typedef struct cachemodel_param{
|
|||
target_param_t *target; //!< reference pointer to the target
|
||||
bool mhead_model; //!< main header model, if sent, 1, else 0
|
||||
bool *tp_model; //!< dynamic array pointer of tile part model, if sent, 1, else 0
|
||||
bool *th_model; //!< dynamic array pointer of tile header model
|
||||
bool **pp_model; //!< dynamic array pointer of precint packet model
|
||||
struct cachemodel_param *next; //!< pointer to the next cache model
|
||||
} cachemodel_param_t;
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ all: $(LIBNAME)
|
|||
|
||||
$(LIBNAME): target_manager.o byte_manager.o box_manager.o boxheader_manager.o manfbox_manager.o \
|
||||
mhixbox_manager.o marker_manager.o codestream_manager.o faixbox_manager.o index_manager.o \
|
||||
msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o cachemodel_manager.o
|
||||
msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
|
||||
cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o
|
||||
ar r $@ $^
|
||||
|
||||
clean:
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <stdlib.h>
|
||||
#include "ihdrbox_manager.h"
|
||||
|
||||
ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream)
|
||||
ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream)
|
||||
{
|
||||
ihdrbox_param_t *ihdrbox;
|
||||
metadata_param_t *meta;
|
||||
|
@ -53,7 +53,7 @@ ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptst
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ihdr = gene_boxbyTypeinStream( jptstream, get_DBoxoff( jp2h), get_DBoxlen( jp2h), "ihdr");
|
||||
ihdr = gene_boxbyTypeinStream( jpipstream, get_DBoxoff( jp2h), get_DBoxlen( jp2h), "ihdr");
|
||||
|
||||
if( !ihdr){
|
||||
fprintf( stderr, "ihdr box not found\n");
|
||||
|
@ -62,10 +62,10 @@ ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptst
|
|||
|
||||
ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
|
||||
|
||||
ihdrbox->height = big4( jptstream+get_DBoxoff(ihdr));
|
||||
ihdrbox->width = big4( jptstream+get_DBoxoff(ihdr)+4);
|
||||
ihdrbox->nc = big2( jptstream+get_DBoxoff(ihdr)+8);
|
||||
ihdrbox->bpc = *(jptstream+get_DBoxoff(ihdr)+10)+1;
|
||||
ihdrbox->height = big4( jpipstream+get_DBoxoff(ihdr));
|
||||
ihdrbox->width = big4( jpipstream+get_DBoxoff(ihdr)+4);
|
||||
ihdrbox->nc = big2( jpipstream+get_DBoxoff(ihdr)+8);
|
||||
ihdrbox->bpc = *(jpipstream+get_DBoxoff(ihdr)+10)+1;
|
||||
|
||||
free( ihdr);
|
||||
|
||||
|
|
|
@ -35,14 +35,22 @@
|
|||
#include "box_manager.h"
|
||||
#include "metadata_manager.h"
|
||||
|
||||
//! I.5.3.1 Image Header box
|
||||
typedef struct ihdrbox_param{
|
||||
Byte4_t height;
|
||||
Byte4_t width;
|
||||
Byte2_t nc;
|
||||
Byte_t bpc;
|
||||
Byte2_t nc; //!< number of components
|
||||
Byte_t bpc; //!< bits per component
|
||||
} ihdrbox_param_t;
|
||||
|
||||
ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream);
|
||||
/**
|
||||
* generate ihdr box
|
||||
*
|
||||
* @param[in] metadatalist metadata list pointer
|
||||
* @param[in] jpipstream JPT/JPP stream
|
||||
* @return pointer to generated ihdr box
|
||||
*/
|
||||
ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream);
|
||||
|
||||
|
||||
#endif /* !IHDRBOX_MANAGER_H_ */
|
||||
|
|
|
@ -47,7 +47,7 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
|||
const int rw, const int rh,
|
||||
const int XOsiz, const int YOsiz,
|
||||
const int Xsiz, const int Ysiz,
|
||||
const int numOfdecomp)
|
||||
const int numOfreslev)
|
||||
{
|
||||
imgreg_param_t imgreg;
|
||||
int px,py;
|
||||
|
@ -61,7 +61,7 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
|||
xmax = Xsiz;
|
||||
ymax = Ysiz;
|
||||
|
||||
find_level( numOfdecomp, &imgreg.level, &imgreg.fx, &imgreg.fy, &imgreg.xosiz, &imgreg.yosiz, &xmax, &ymax);
|
||||
find_level( numOfreslev, &imgreg.level, &imgreg.fx, &imgreg.fy, &imgreg.xosiz, &imgreg.yosiz, &xmax, &ymax);
|
||||
|
||||
if( rx == -1 || ry == -1){
|
||||
imgreg.ox = 0;
|
||||
|
@ -79,6 +79,12 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
|||
else{
|
||||
px = ceil((double)((rx+rw)*imgreg.fx)/(double)fx);
|
||||
py = ceil((double)((ry+rh)*imgreg.fy)/(double)fy);
|
||||
|
||||
if( imgreg.fx < px)
|
||||
px = imgreg.fx;
|
||||
if( imgreg.fy < py)
|
||||
py = imgreg.fy;
|
||||
|
||||
imgreg.sx = px - imgreg.ox;
|
||||
imgreg.sy = py - imgreg.oy;
|
||||
}
|
||||
|
@ -120,6 +126,20 @@ void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, i
|
|||
}
|
||||
}
|
||||
|
||||
int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz)
|
||||
{
|
||||
int level;
|
||||
int xmin, xmax, ymin, ymax;
|
||||
|
||||
level = 0;
|
||||
xmin = ymin = 0;
|
||||
xmax = Xsiz;
|
||||
ymax = Ysiz;
|
||||
|
||||
find_level( 1000, &level, &fw, &fh, &xmin, &ymin, &xmax, &ymax);
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
void print_imgreg( imgreg_param_t imgreg)
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct imgreg_param{
|
|||
* @param[in] rw,rh size of region
|
||||
* @param[in] XOsiz,YOsiz offset from the origin of the reference grid to the left side of the image area
|
||||
* @param[in] Xsiz,Ysiz size of the reference grid
|
||||
* @param[in] numOfdecomp number of decomposition levels
|
||||
* @param[in] numOfreslev number of resolution levels
|
||||
* @return structure of image region parameters
|
||||
*/
|
||||
imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
||||
|
@ -58,7 +58,7 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
|||
const int rw, const int rh,
|
||||
const int XOsiz, const int YOsiz,
|
||||
const int Xsiz, const int Ysiz,
|
||||
const int numOfdecomp);
|
||||
const int numOfreslev);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -78,6 +78,18 @@ imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
|
|||
*/
|
||||
void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, int *xmax, int *ymax);
|
||||
|
||||
/**
|
||||
* compute decomposition level (only to get the level
|
||||
* use find_level for all parameters
|
||||
*
|
||||
* @param[in] fx horizontal frame size
|
||||
* @param[in] fy vertical frame size
|
||||
* @param[in] Xsiz image width
|
||||
* @param[in] Ysiz image height
|
||||
* @return decomposition level
|
||||
*/
|
||||
int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz);
|
||||
|
||||
/**
|
||||
* print image region parameters
|
||||
*
|
||||
|
|
|
@ -131,26 +131,76 @@ void print_index( index_param_t index)
|
|||
fprintf( logstream, "\tCodestream Offset: %#llx\n", index.offset);
|
||||
fprintf( logstream, "\t Length: %#llx\n", index.length);
|
||||
fprintf( logstream, "\tMain header Length: %#llx\n", index.mhead_length);
|
||||
fprintf( logstream, "\t Rsiz: %#x\n", index.Rsiz);
|
||||
fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", index.Xsiz, index.Ysiz, index.Xsiz, index.Ysiz);
|
||||
fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", index.XOsiz, index.YOsiz, index.XOsiz, index.YOsiz);
|
||||
fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", index.XTsiz, index.YTsiz, index.XTsiz, index.YTsiz);
|
||||
fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", index.XTOsiz, index.YTOsiz, index.XTOsiz, index.YTOsiz);
|
||||
fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", index.XTnum, index.YTnum);
|
||||
fprintf( logstream, "\t Num of Components: %d\n", index.Csiz);
|
||||
|
||||
for( i=0; i<index.Csiz; i++)
|
||||
fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, index.Ssiz[i], index.XRsiz[i], index.YRsiz[i], index.Ssiz[i], index.XRsiz[i], index.YRsiz[i]);
|
||||
|
||||
print_SIZ( index.SIZ);
|
||||
print_COD( index.COD);
|
||||
|
||||
fprintf( logstream, "Tile part information: \n");
|
||||
print_faixbox( index.tilepart);
|
||||
|
||||
fprintf( logstream, "Tile header information: \n");
|
||||
for( i=0; i<index.SIZ.XTnum*index.SIZ.YTnum ;i++)
|
||||
print_mhixbox( index.tileheader[i]);
|
||||
|
||||
fprintf( logstream, "Precinct packet information: \n");
|
||||
for( i=0; i<index.SIZ.Csiz; i++){
|
||||
fprintf( logstream, "Component %d\n", i);
|
||||
print_faixbox( index.precpacket[i]);
|
||||
}
|
||||
|
||||
print_allmetadata( index.metadatalist);
|
||||
}
|
||||
|
||||
void print_SIZ( SIZmarker_param_t SIZ)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf( logstream, "\tImage and Tile SIZ parameters\n");
|
||||
fprintf( logstream, "\t Rsiz: %#x\n", SIZ.Rsiz);
|
||||
fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", SIZ.Xsiz, SIZ.Ysiz, SIZ.Xsiz, SIZ.Ysiz);
|
||||
fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XOsiz, SIZ.YOsiz, SIZ.XOsiz, SIZ.YOsiz);
|
||||
fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTsiz, SIZ.YTsiz, SIZ.XTsiz, SIZ.YTsiz);
|
||||
fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTOsiz, SIZ.YTOsiz, SIZ.XTOsiz, SIZ.YTOsiz);
|
||||
fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", SIZ.XTnum, SIZ.YTnum);
|
||||
fprintf( logstream, "\t Num of Components: %d\n", SIZ.Csiz);
|
||||
|
||||
for( i=0; i<SIZ.Csiz; i++)
|
||||
fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i], SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i]);
|
||||
}
|
||||
|
||||
void print_COD( CODmarker_param_t COD)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf( logstream, "\tCoding style default COD parameters\n");
|
||||
fprintf( logstream, "\t Progression order: %d [ LRCP=0, RLCP=1, RPCL=2, PCRL=3, CPRL=4]\n", COD.prog_order);
|
||||
fprintf( logstream, "\t Num of layers: %d\n", COD.numOflayers);
|
||||
fprintf( logstream, "\t Decomposition lvl: %d\n", COD.numOfdecomp);
|
||||
|
||||
for( i=0; i<=((COD.Scod & 0x01) ? COD.numOfdecomp:0); i++){
|
||||
fprintf( logstream, "\t [%d] XPsiz, YPsiz: (%d,%d) = (%#x, %#x)\n",i, COD.XPsiz[i], COD.YPsiz[i], COD.XPsiz[i], COD.YPsiz[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void delete_index( index_param_t **index)
|
||||
{
|
||||
int i;
|
||||
|
||||
delete_metadatalist( &((*index)->metadatalist));
|
||||
|
||||
free( (*index)->COD.XPsiz);
|
||||
free( (*index)->COD.YPsiz);
|
||||
|
||||
delete_faixbox( &((*index)->tilepart));
|
||||
|
||||
for( i=0; i< (*index)->SIZ.XTnum*(*index)->SIZ.YTnum ;i++)
|
||||
delete_mhixbox( &((*index)->tileheader[i]));
|
||||
free( (*index)->tileheader);
|
||||
|
||||
for( i=0; i<(*index)->SIZ.Csiz; i++)
|
||||
delete_faixbox( &((*index)->precpacket[i]));
|
||||
free( (*index)->precpacket);
|
||||
|
||||
free(*index);
|
||||
}
|
||||
|
||||
|
@ -250,6 +300,16 @@ bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx);
|
|||
*/
|
||||
bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx);
|
||||
|
||||
/**
|
||||
* set code index parameters from ppix box
|
||||
* I.3.2.4.6 Precinct Packet Index Table box
|
||||
*
|
||||
* @param[in] cidx_box pointer to the reference cidx_box
|
||||
* @param[out] jp2idx pointer to index parameters
|
||||
* @return if succeeded (true) or failed (false)
|
||||
*/
|
||||
bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx);
|
||||
|
||||
bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
||||
{
|
||||
box_param_t *manf_box;
|
||||
|
@ -277,13 +337,19 @@ bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
}
|
||||
set_tpixdata( cidx_box, jp2idx);
|
||||
|
||||
#ifdef NO_NEED_YET
|
||||
if( !search_boxheader( "thix", manf)){
|
||||
fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
|
||||
free(jp2idx);
|
||||
return false;
|
||||
}
|
||||
set_thixdata( cidx_box, jp2idx);
|
||||
#endif
|
||||
|
||||
if( !search_boxheader( "ppix", manf)){
|
||||
fprintf( FCGI_stderr, "Error: ppix box not present in manfbox\n");
|
||||
free(jp2idx);
|
||||
return false;
|
||||
}
|
||||
set_ppixdata( cidx_box, jp2idx);
|
||||
|
||||
delete_manfbox( &manf);
|
||||
free( manf_box);
|
||||
|
@ -326,23 +392,36 @@ bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
|
||||
|
||||
/**
|
||||
* set code index parameters from SIZ marker in codestream
|
||||
* set SIZ marker information
|
||||
* A.5 Fixed information marker segment
|
||||
* A.5.1 Image and tile size (SIZ)
|
||||
*
|
||||
* @param[in] sizmkidx pointer to SIZ marker index in mhix box
|
||||
* @param[in] codestream codestream parameters
|
||||
* @param[out] jp2idx pointer to index parameters
|
||||
* @param[out] SIZ SIZ marker parameters pointer
|
||||
* @return if succeeded (true) or failed (false)
|
||||
*/
|
||||
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx);
|
||||
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ);
|
||||
|
||||
/**
|
||||
* set code index parameters from COD marker in codestream
|
||||
* A.6 Functional marker segments
|
||||
* A.6.1 Coding style default (COD)
|
||||
*
|
||||
* @param[in] codmkidx pointer to COD marker index in mhix box
|
||||
* @param[in] codestream codestream parameters
|
||||
* @param[out] COD COD marker parameters pointer
|
||||
* @return if succeeded (true) or failed (false)
|
||||
*/
|
||||
bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD);
|
||||
|
||||
bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx)
|
||||
{
|
||||
box_param_t *mhix_box;
|
||||
mhixbox_param_t *mhix;
|
||||
markeridx_param_t *sizmkidx;
|
||||
|
||||
markeridx_param_t *codmkidx;
|
||||
|
||||
if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
|
||||
return false;
|
||||
|
||||
|
@ -352,7 +431,10 @@ bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, ind
|
|||
free( mhix_box);
|
||||
|
||||
sizmkidx = search_markeridx( 0xff51, mhix);
|
||||
set_SIZmkrdata( sizmkidx, codestream, jp2idx);
|
||||
set_SIZmkrdata( sizmkidx, codestream, &(jp2idx->SIZ));
|
||||
|
||||
codmkidx = search_markeridx( 0xff52, mhix);
|
||||
set_CODmkrdata( codmkidx, codestream, &(jp2idx->COD));
|
||||
|
||||
delete_mhixbox( &mhix);
|
||||
|
||||
|
@ -364,11 +446,15 @@ bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
box_param_t *tpix_box; //!< tpix box
|
||||
box_param_t *faix_box; //!< faix box
|
||||
|
||||
if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix")))
|
||||
if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix"))){
|
||||
fprintf( FCGI_stderr, "Error: tpix box not present in cidx box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix")))
|
||||
if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix"))){
|
||||
fprintf( FCGI_stderr, "Error: faix box not present in tpix box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
jp2idx->tilepart = gene_faixbox( faix_box);
|
||||
|
||||
|
@ -385,11 +471,15 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
boxheader_param_t *ptr;
|
||||
mhixbox_param_t *mhix;
|
||||
Byte8_t pos, mhixseqoff;
|
||||
Byte2_t tile_no;
|
||||
|
||||
if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix")))
|
||||
if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix"))){
|
||||
fprintf( FCGI_stderr, "Error: thix box not present in cidx box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){
|
||||
fprintf( FCGI_stderr, "Error: manf box not present in thix box\n");
|
||||
free( thix_box);
|
||||
return false;
|
||||
}
|
||||
|
@ -398,16 +488,24 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
ptr = manf->first;
|
||||
mhixseqoff = manf_box->offset+manf_box->length;
|
||||
pos = 0;
|
||||
tile_no = 0;
|
||||
jp2idx->tileheader = (mhixbox_param_t **)malloc( jp2idx->SIZ.XTnum*jp2idx->SIZ.YTnum*sizeof(mhixbox_param_t *));
|
||||
|
||||
while( ptr){
|
||||
mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix");
|
||||
if( !(mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix"))){
|
||||
fprintf( FCGI_stderr, "Error: mhix box not present in thix box\n");
|
||||
delete_manfbox( &manf);
|
||||
free( manf_box);
|
||||
free( thix_box);
|
||||
return false;
|
||||
}
|
||||
mhix = gene_mhixbox( mhix_box);
|
||||
|
||||
pos += mhix_box->length;
|
||||
ptr = ptr->next;
|
||||
|
||||
free( mhix_box);
|
||||
delete_mhixbox( &mhix);
|
||||
jp2idx->tileheader[tile_no++] = mhix;
|
||||
}
|
||||
|
||||
delete_manfbox( &manf);
|
||||
|
@ -417,37 +515,131 @@ bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx)
|
||||
{
|
||||
box_param_t *ppix_box, *faix_box, *manf_box;
|
||||
manfbox_param_t *manf; //!< manf
|
||||
boxheader_param_t *bh; //!< box headers
|
||||
faixbox_param_t *faix; //!< faix
|
||||
Byte8_t inbox_offset;
|
||||
int comp_idx;
|
||||
|
||||
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx)
|
||||
if( !(ppix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "ppix"))){
|
||||
fprintf( FCGI_stderr, "Error: ppix box not present in cidx box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
inbox_offset = get_DBoxoff( ppix_box);
|
||||
if( !(manf_box = gene_boxbyType( ppix_box->fd, inbox_offset, get_DBoxlen( ppix_box), "manf"))){
|
||||
fprintf( FCGI_stderr, "Error: manf box not present in ppix box\n");
|
||||
free( ppix_box);
|
||||
return false;
|
||||
}
|
||||
|
||||
free( ppix_box);
|
||||
|
||||
manf = gene_manfbox( manf_box);
|
||||
bh = search_boxheader( "faix", manf);
|
||||
inbox_offset = manf_box->offset + manf_box->length;
|
||||
|
||||
free( manf_box);
|
||||
|
||||
jp2idx->precpacket = (faixbox_param_t **)malloc( jp2idx->SIZ.Csiz*sizeof(faixbox_param_t *));
|
||||
|
||||
for( comp_idx=0; bh!=NULL; bh=bh->next, comp_idx++){
|
||||
if( jp2idx->SIZ.Csiz <= comp_idx ){
|
||||
fprintf( FCGI_stderr, "Error: num of faix boxes is not identical to num of components in ppix box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !(faix_box = gene_boxbyOffset( cidx_box->fd, inbox_offset))){
|
||||
fprintf( FCGI_stderr, "Error: faix box not present in ppix box\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
faix = gene_faixbox( faix_box);
|
||||
jp2idx->precpacket[comp_idx] = faix;
|
||||
|
||||
inbox_offset = faix_box->offset + faix_box->length;
|
||||
free( faix_box);
|
||||
}
|
||||
|
||||
free(manf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ)
|
||||
{
|
||||
marker_param_t sizmkr;
|
||||
int i;
|
||||
|
||||
sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length);
|
||||
|
||||
if( sizmkidx->length != fetch_marker2bytebigendian( sizmkr, 0)){
|
||||
SIZ->Lsiz = fetch_marker2bytebigendian( sizmkr, 0);
|
||||
|
||||
if( sizmkidx->length != SIZ->Lsiz){
|
||||
fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
|
||||
return false;
|
||||
}
|
||||
|
||||
jp2idx->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
|
||||
jp2idx->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
|
||||
jp2idx->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
|
||||
jp2idx->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
|
||||
jp2idx->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
|
||||
jp2idx->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
|
||||
jp2idx->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
|
||||
jp2idx->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
|
||||
jp2idx->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
|
||||
jp2idx->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
|
||||
SIZ->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
|
||||
SIZ->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
|
||||
SIZ->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
|
||||
SIZ->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
|
||||
SIZ->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
|
||||
SIZ->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
|
||||
SIZ->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
|
||||
SIZ->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
|
||||
SIZ->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
|
||||
SIZ->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
|
||||
|
||||
jp2idx->XTnum = ( jp2idx->Xsiz-jp2idx->XTOsiz+jp2idx->XTsiz-1)/jp2idx->XTsiz;
|
||||
jp2idx->YTnum = ( jp2idx->Ysiz-jp2idx->YTOsiz+jp2idx->YTsiz-1)/jp2idx->YTsiz;
|
||||
SIZ->XTnum = ( SIZ->Xsiz-SIZ->XTOsiz+SIZ->XTsiz-1)/SIZ->XTsiz;
|
||||
SIZ->YTnum = ( SIZ->Ysiz-SIZ->YTOsiz+SIZ->YTsiz-1)/SIZ->YTsiz;
|
||||
|
||||
for( i=0; i<(int)jp2idx->Csiz; i++){
|
||||
jp2idx->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
|
||||
jp2idx->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
|
||||
jp2idx->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
|
||||
for( i=0; i<(int)SIZ->Csiz; i++){
|
||||
SIZ->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
|
||||
SIZ->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
|
||||
SIZ->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD)
|
||||
{
|
||||
marker_param_t codmkr;
|
||||
int i;
|
||||
|
||||
codmkr = set_marker( codestream, codmkidx->code, codmkidx->offset, codmkidx->length);
|
||||
|
||||
COD->Lcod = fetch_marker2bytebigendian( codmkr, 0);
|
||||
|
||||
if( codmkidx->length != COD->Lcod){
|
||||
fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", codmkidx->code);
|
||||
return false;
|
||||
}
|
||||
|
||||
COD->Scod = fetch_marker1byte( codmkr, 2);
|
||||
COD->prog_order = fetch_marker1byte( codmkr, 3);
|
||||
COD->numOflayers = fetch_marker2bytebigendian( codmkr, 4);
|
||||
COD->numOfdecomp = fetch_marker1byte( codmkr, 7);
|
||||
|
||||
if(COD->Scod & 0x01){
|
||||
COD->XPsiz = (Byte4_t *)malloc( (COD->numOfdecomp+1)*sizeof(Byte4_t));
|
||||
COD->YPsiz = (Byte4_t *)malloc( (COD->numOfdecomp+1)*sizeof(Byte4_t));
|
||||
|
||||
for( i=0; i<=COD->numOfdecomp; i++){
|
||||
//precinct size
|
||||
COD->XPsiz[i] = pow( 2, fetch_marker1byte( codmkr, 12+i) & 0x0F);
|
||||
COD->YPsiz[i] = pow( 2,(fetch_marker1byte( codmkr, 12+i) & 0xF0) >> 4);
|
||||
}
|
||||
}
|
||||
else{
|
||||
COD->XPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
|
||||
COD->YPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
|
||||
|
||||
COD->XPsiz[0] = COD->YPsiz[0] = pow(2,15);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -456,25 +648,25 @@ bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream,
|
|||
Byte4_t max( Byte4_t n1, Byte4_t n2);
|
||||
Byte4_t min( Byte4_t n1, Byte4_t n2);
|
||||
|
||||
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level);
|
||||
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level);
|
||||
|
||||
range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level)
|
||||
range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
|
||||
{
|
||||
return get_tile_range( index.XOsiz, index.Xsiz, index.XTOsiz, index.XTsiz, tile_xid, level);
|
||||
return get_tile_range( SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz, tile_id%SIZ.XTnum, level);
|
||||
}
|
||||
|
||||
range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level)
|
||||
range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
|
||||
{
|
||||
return get_tile_range( index.YOsiz, index.Ysiz, index.YTOsiz, index.YTsiz, tile_yid, level);
|
||||
return get_tile_range( SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz, tile_id/SIZ.XTnum, level);
|
||||
}
|
||||
|
||||
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level)
|
||||
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level)
|
||||
{
|
||||
range_param_t range;
|
||||
int n;
|
||||
|
||||
range.minvalue = max( Osiz, TOsiz+tile_id*Tsiz);
|
||||
range.maxvalue = min( siz, TOsiz+(tile_id+1)*Tsiz);
|
||||
range.minvalue = max( Osiz, TOsiz+tile_XYid*Tsiz);
|
||||
range.maxvalue = min( siz, TOsiz+(tile_XYid+1)*Tsiz);
|
||||
|
||||
for( n=0; n<level; n++){
|
||||
range.minvalue = ceil(range.minvalue/2.0);
|
||||
|
@ -483,6 +675,22 @@ range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t
|
|||
return range;
|
||||
}
|
||||
|
||||
Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
|
||||
{
|
||||
range_param_t tile_Xrange;
|
||||
|
||||
tile_Xrange = get_tile_Xrange( SIZ, tile_id, level);
|
||||
return tile_Xrange.maxvalue - tile_Xrange.minvalue;
|
||||
}
|
||||
|
||||
Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
|
||||
{
|
||||
range_param_t tile_Yrange;
|
||||
|
||||
tile_Yrange = get_tile_Yrange( SIZ, tile_id, level);
|
||||
return tile_Yrange.maxvalue - tile_Yrange.minvalue;
|
||||
}
|
||||
|
||||
Byte4_t max( Byte4_t n1, Byte4_t n2)
|
||||
{
|
||||
if( n1 < n2)
|
||||
|
|
|
@ -34,42 +34,60 @@
|
|||
#include "byte_manager.h"
|
||||
#include "faixbox_manager.h"
|
||||
#include "metadata_manager.h"
|
||||
#include "mhixbox_manager.h"
|
||||
|
||||
//! progression order
|
||||
typedef enum porder {
|
||||
PROG_UNKNOWN = -1, /**< place-holder */
|
||||
LRCP = 0, /**< layer-resolution-component-precinct order */
|
||||
RLCP = 1, /**< resolution-layer-component-precinct order */
|
||||
RPCL = 2, /**< resolution-precinct-component-layer order */
|
||||
PCRL = 3, /**< precinct-component-resolution-layer order */
|
||||
CPRL = 4 /**< component-precinct-resolution-layer order */
|
||||
} porder_t;
|
||||
|
||||
//! A.5.1 Image and tile size (SIZ)
|
||||
typedef struct SIZmarker_param{
|
||||
Byte2_t Lsiz; //!< length of marker segment excluding the marker
|
||||
Byte2_t Rsiz; //!< capabilities that a decoder needs
|
||||
Byte4_t Xsiz; //!< width of the reference grid
|
||||
Byte4_t Ysiz; //!< height of the reference grid
|
||||
Byte4_t XOsiz; //!< horizontal offset from the origin of the reference grid to the left side of the image area
|
||||
Byte4_t YOsiz; //!< vertical offset from the origin of the reference grid to the top side of the image area
|
||||
Byte4_t XTsiz; //!< width of one reference tile with respect to the reference grid
|
||||
Byte4_t YTsiz; //!< height of one reference tile with respect to the reference grid
|
||||
Byte4_t XTOsiz; //!< horizontal offset from the origin of the reference grid to the left side of the first tile
|
||||
Byte4_t YTOsiz; //!< vertical offset from the origin of the reference grid to the top side of the first tile
|
||||
Byte4_t XTnum; //!< number of tiles in horizontal direction
|
||||
Byte4_t YTnum; //!< number of tiles in vertical direction
|
||||
Byte2_t Csiz; //!< number of the components in the image
|
||||
Byte_t Ssiz[3]; //!< precision (depth) in bits and sign of the component samples
|
||||
Byte_t XRsiz[3]; //!< horizontal separation of a sample of component with respect to the reference grid
|
||||
Byte_t YRsiz[3]; //!< vertical separation of a sample of component with respect to the reference grid
|
||||
} SIZmarker_param_t;
|
||||
|
||||
//! A.6.1 Coding style default (COD)
|
||||
typedef struct CODmarker_param{
|
||||
Byte2_t Lcod; //!< length of marker segment excluding the marker
|
||||
Byte_t Scod; //!< Coding style for all components
|
||||
porder_t prog_order; //!< progression order
|
||||
Byte2_t numOflayers; //!< number of layers
|
||||
Byte_t numOfdecomp; //!< number of decompositions levels
|
||||
Byte4_t *XPsiz; //!< dynamic array of precinct width at successive resolution level in order
|
||||
Byte4_t *YPsiz; //!< dynamic array of precinct height at successive resolution level in order
|
||||
} CODmarker_param_t;
|
||||
|
||||
//! index parameters
|
||||
typedef struct index_param{
|
||||
metadatalist_param_t *metadatalist; //!< metadata-bin list
|
||||
Byte8_t offset; //!< codestream offset
|
||||
Byte8_t length; //!< codestream length
|
||||
Byte8_t mhead_length; //!< main header length
|
||||
//! A.5.1 Image and tile size (SIZ)
|
||||
Byte2_t Rsiz; //!< capabilities that a decoder needs
|
||||
Byte4_t Xsiz; //!< width of the reference grid
|
||||
Byte4_t Ysiz; //!< height of the reference grid
|
||||
Byte4_t XOsiz; //!< horizontal offset from the origin of
|
||||
//!the reference grid to the left side of the image area
|
||||
Byte4_t YOsiz; //!< vertical offset from the origin of
|
||||
//!the reference grid to the top side of the image area
|
||||
Byte4_t XTsiz; //!< width of one reference tile with
|
||||
//!respect to the reference grid
|
||||
Byte4_t YTsiz; //!< height of one reference tile with
|
||||
//!respect to the reference grid
|
||||
Byte4_t XTOsiz; //!< horizontal offset from the origin of
|
||||
//!the reference grid to the left side of the first tile
|
||||
Byte4_t YTOsiz; //!< vertical offset from the origin of
|
||||
//!the reference grid to the top side of
|
||||
//!the first tile
|
||||
Byte4_t XTnum; //!< number of tiles in horizontal direction
|
||||
Byte4_t YTnum; //!< number of tiles in vertical
|
||||
//!direction
|
||||
Byte2_t Csiz; //!< number of the components in the image
|
||||
|
||||
Byte_t Ssiz[3]; //!< precision (depth) in bits and sign
|
||||
//!of the component samples
|
||||
Byte_t XRsiz[3]; //!< horizontal separation of a sample of
|
||||
//!component with respect to the reference grid
|
||||
Byte_t YRsiz[3]; //!< vertical separation of a sample of
|
||||
//!component with respect to the reference grid
|
||||
faixbox_param_t *tilepart; //!< tile part information from tpix box
|
||||
Byte8_t mhead_length; //!< main header length
|
||||
SIZmarker_param_t SIZ; // !< SIZ marker information
|
||||
CODmarker_param_t COD; // !< COD marker information
|
||||
faixbox_param_t *tilepart; //!< tile part information from tpix box
|
||||
mhixbox_param_t **tileheader; //!< dynamic array of tile header information from thix box
|
||||
faixbox_param_t **precpacket; //!< dynamic array of precint packet information from ppix box
|
||||
} index_param_t;
|
||||
|
||||
|
||||
|
@ -89,6 +107,19 @@ index_param_t * parse_jp2file( int fd);
|
|||
*/
|
||||
void print_index( index_param_t index);
|
||||
|
||||
/**
|
||||
* print Image and Tile SIZ parameters
|
||||
*
|
||||
* @param[in] SIZ SIZ marker information
|
||||
*/
|
||||
void print_SIZ( SIZmarker_param_t SIZ);
|
||||
|
||||
/**
|
||||
* print Coding style default COD parameters
|
||||
*
|
||||
* @param[in] COD COD marker information
|
||||
*/
|
||||
void print_COD( CODmarker_param_t COD);
|
||||
|
||||
/**
|
||||
* delete index
|
||||
|
@ -106,22 +137,33 @@ typedef struct range_param{
|
|||
/**
|
||||
* get horizontal range of the tile in reference grid
|
||||
*
|
||||
* @param[in] index index parameters
|
||||
* @param[in] tile_xid tile id in x-direction (0<= <XTnum)
|
||||
* @param[in] SIZ SIZ marker information
|
||||
* @param[in] tile_id tile id
|
||||
* @param[in] level decomposition level
|
||||
* @return structured range parameter
|
||||
*/
|
||||
range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level);
|
||||
range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
|
||||
|
||||
/**
|
||||
* get vertical range of the tile in reference grid
|
||||
*
|
||||
* @param[in] index index parameters
|
||||
* @param[in] tile_yid tile id in y-direction (0<= <YTnum)
|
||||
* @param[in] SIZ SIZ marker information
|
||||
* @param[in] tile_id tile id
|
||||
* @param[in] level decomposition level
|
||||
* @return structured range parameter
|
||||
*/
|
||||
range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level);
|
||||
range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
|
||||
|
||||
|
||||
/**
|
||||
* get tile wdith at the decomposition level
|
||||
*
|
||||
* @param[in] SIZ SIZ marker information
|
||||
* @param[in] tile_id tile id
|
||||
* @param[in] level decomposition level
|
||||
* @return tile width
|
||||
*/
|
||||
Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
|
||||
Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
|
||||
|
||||
#endif /* !INDEX_MANAGER_H_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -147,4 +147,5 @@ int search_metadataidx( char boxtype[4], metadatalist_param_t *list);
|
|||
* @param[in] metadatalist metadata list pointer
|
||||
*/
|
||||
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist);
|
||||
|
||||
#endif /* !METADATA_MANAGER_H_ */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2011, Professor Benoit Macq
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2011, Lucian Corlaciu, GSoC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -30,16 +31,14 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "msgqueue_manager.h"
|
||||
#include "metadata_manager.h"
|
||||
|
||||
#include "index_manager.h"
|
||||
|
||||
#ifdef SERVER
|
||||
#include "fcgi_stdio.h"
|
||||
|
@ -50,14 +49,6 @@
|
|||
#define logstream stderr
|
||||
#endif //SERVER
|
||||
|
||||
#define PRECINCT_MSG 0
|
||||
#define EXT_PRECINCT_MSG 1
|
||||
#define TILE_HEADER_MSG 2
|
||||
#define TILE_MSG 4
|
||||
#define EXT_TILE_MSG 5
|
||||
#define MAINHEADER_MSG 6
|
||||
#define METADATA_MSG 8
|
||||
|
||||
msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel)
|
||||
{
|
||||
msgqueue_param_t *msgqueue;
|
||||
|
@ -96,6 +87,7 @@ void delete_msgqueue( msgqueue_param_t **msgqueue)
|
|||
void print_msgqueue( msgqueue_param_t *msgqueue)
|
||||
{
|
||||
message_param_t *ptr;
|
||||
char *message_class[] = { "Precinct", "Ext-Prec", "TileHead", "non", "Tile", "Ext-Tile", "Main", "non", "Meta"};
|
||||
|
||||
if( !msgqueue)
|
||||
return;
|
||||
|
@ -104,7 +96,7 @@ void print_msgqueue( msgqueue_param_t *msgqueue)
|
|||
ptr = msgqueue->first;
|
||||
|
||||
while( ptr){
|
||||
fprintf( logstream, "\t class_id: %lld\n", ptr->class_id );
|
||||
fprintf( logstream, "\t class_id: %lld %s\n", ptr->class_id, message_class[ptr->class_id]);
|
||||
fprintf( logstream, "\t in_class_id: %lld\n", ptr->in_class_id );
|
||||
fprintf( logstream, "\t csn: %lld\n", ptr->csn );
|
||||
fprintf( logstream, "\t bin_offset: %#llx\n", ptr->bin_offset );
|
||||
|
@ -127,11 +119,13 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
|
|||
{
|
||||
cachemodel_param_t *cachemodel;
|
||||
target_param_t *target;
|
||||
index_param_t *codeidx;
|
||||
message_param_t *msg;
|
||||
|
||||
cachemodel = msgqueue->cachemodel;
|
||||
target = cachemodel->target;
|
||||
|
||||
codeidx = target->codeidx;
|
||||
|
||||
msg = (message_param_t *)malloc( sizeof(message_param_t));
|
||||
|
||||
msg->last_byte = true;
|
||||
|
@ -139,9 +133,9 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
|
|||
msg->class_id = MAINHEADER_MSG;
|
||||
msg->csn = target->csn;
|
||||
msg->bin_offset = 0;
|
||||
msg->length = target->codeidx->mhead_length;
|
||||
msg->length = codeidx->mhead_length;
|
||||
msg->aux = 0; // non exist
|
||||
msg->res_offset = target->codeidx->offset;
|
||||
msg->res_offset = codeidx->offset;
|
||||
msg->phld = NULL;
|
||||
msg->next = NULL;
|
||||
|
||||
|
@ -150,6 +144,35 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue)
|
|||
cachemodel->mhead_model = true;
|
||||
}
|
||||
|
||||
void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
cachemodel_param_t *cachemodel;
|
||||
target_param_t *target;
|
||||
index_param_t *codeidx;
|
||||
message_param_t *msg;
|
||||
|
||||
cachemodel = msgqueue->cachemodel;
|
||||
target = cachemodel->target;
|
||||
codeidx = target->codeidx;
|
||||
|
||||
if( !cachemodel->th_model[ tile_id]){
|
||||
msg = (message_param_t *)malloc( sizeof(message_param_t));
|
||||
msg->last_byte = true;
|
||||
msg->in_class_id = tile_id;
|
||||
msg->class_id = TILE_HEADER_MSG;
|
||||
msg->csn = target->csn;
|
||||
msg->bin_offset = 0;
|
||||
msg->length = codeidx->tileheader[tile_id]->tlen;
|
||||
msg->aux = 0; // non exist
|
||||
msg->res_offset = codeidx->offset + get_elemOff( codeidx->tilepart, 0, tile_id); // Changed from Lucian's
|
||||
msg->phld = NULL;
|
||||
msg->next = NULL;
|
||||
|
||||
enqueue_message( msg, msgqueue);
|
||||
cachemodel->th_model[ tile_id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
cachemodel_param_t *cachemodel;
|
||||
|
@ -208,6 +231,43 @@ void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
|
|||
}
|
||||
}
|
||||
|
||||
void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
cachemodel_param_t *cachemodel;
|
||||
index_param_t *codeidx;
|
||||
faixbox_param_t *precpacket;
|
||||
message_param_t *msg;
|
||||
Byte8_t nmax;
|
||||
|
||||
cachemodel = msgqueue->cachemodel;
|
||||
codeidx = cachemodel->target->codeidx;
|
||||
precpacket = codeidx->precpacket[ comp_id];
|
||||
|
||||
nmax = get_nmax(precpacket);
|
||||
|
||||
if( !cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id]){
|
||||
msg = (message_param_t *)malloc( sizeof(message_param_t));
|
||||
msg->last_byte = true;
|
||||
msg->in_class_id = comp_precinct_id( tile_id, comp_id, seq_id, codeidx->SIZ.Csiz, codeidx->SIZ.XTnum * codeidx->SIZ.YTnum);
|
||||
msg->class_id = PRECINCT_MSG;
|
||||
msg->csn = cachemodel->target->csn;
|
||||
msg->bin_offset = 0;
|
||||
msg->length = get_elemLen( precpacket, seq_id, tile_id);
|
||||
msg->aux = 0;
|
||||
msg->res_offset = codeidx->offset+get_elemOff( precpacket, seq_id, tile_id);
|
||||
msg->phld = NULL;
|
||||
msg->next = NULL;
|
||||
|
||||
enqueue_message( msg, msgqueue);
|
||||
cachemodel->pp_model[comp_id][ tile_id*nmax+seq_id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles)
|
||||
{
|
||||
return t + (c + s * num_components ) * num_tiles;
|
||||
}
|
||||
|
||||
void enqueue_box( int meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
|
||||
void enqueue_phld( int meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
|
||||
void enqueue_boxcontents( int meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
|
||||
|
@ -327,8 +387,8 @@ void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
|
|||
return;
|
||||
|
||||
msg = msgqueue->first;
|
||||
class_id = 0;
|
||||
csn = 0;
|
||||
class_id = -1;
|
||||
csn = -1;
|
||||
while( msg){
|
||||
if( msg->csn == csn){
|
||||
if( msg->class_id == class_id)
|
||||
|
@ -472,6 +532,7 @@ void emit_bigendian_bytes( Byte8_t code, int bytelength)
|
|||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
void print_binarycode( Byte8_t n, int segmentlen)
|
||||
{
|
||||
char buf[256];
|
||||
|
@ -503,7 +564,7 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
|
|||
Byte8_t class_id, csn;
|
||||
|
||||
class_id = -1; // dummy
|
||||
csn = 0;
|
||||
csn = -1;
|
||||
ptr = JPIPstream;
|
||||
while( ptr-JPIPstream < streamlen){
|
||||
msg = (message_param_t *)malloc( sizeof(message_param_t));
|
||||
|
@ -512,10 +573,9 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
|
|||
|
||||
msg->last_byte = c == 1 ? true : false;
|
||||
|
||||
if( bb >= 2){
|
||||
if( bb >= 2)
|
||||
ptr = parse_vbas( ptr, &class_id);
|
||||
// fprintf( stdout, "class_id: %lld\n", class_id);
|
||||
}
|
||||
|
||||
msg->class_id = class_id;
|
||||
|
||||
if (bb == 3)
|
||||
|
@ -646,183 +706,6 @@ Byte_t * parse_vbas( Byte_t *streamptr, Byte8_t *elem)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* search a message by class_id
|
||||
*
|
||||
* @param[in] class_id class identifiers
|
||||
* @param[in] in_class_id in-class identifiers, -1 means any
|
||||
* @param[in] csn codestream number
|
||||
* @param[in] msg first message pointer of the searching list
|
||||
* @return found message pointer
|
||||
*/
|
||||
message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg);
|
||||
|
||||
|
||||
/**
|
||||
* delete a message in msgqueue
|
||||
*
|
||||
* @param[in] message address of the deleting message pointer
|
||||
* @param[in] msgqueue message queue pointer
|
||||
*/
|
||||
void delete_message_in_msgqueue( message_param_t **message, msgqueue_param_t *msgqueue);
|
||||
|
||||
/**
|
||||
* reconstruct j2k codestream from JPT- (in future, JPP-) stream
|
||||
*
|
||||
* @param[in] msgqueue message queue pointer
|
||||
* @param[in] jpipstream original JPT- JPP- stream
|
||||
* @param[in] csn codestream number
|
||||
* @param[in] minlev minimum decomposition level
|
||||
* @param[out] codelen codestream length
|
||||
* @return generated reconstructed j2k codestream
|
||||
*/
|
||||
Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *codelen);
|
||||
|
||||
Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *j2klen)
|
||||
{
|
||||
Byte_t *j2kstream = NULL;
|
||||
|
||||
if( !msgqueue)
|
||||
return NULL;
|
||||
|
||||
j2kstream = recons_codestream( msgqueue, jpipstream, csn, minlev, j2klen);
|
||||
|
||||
return j2kstream;
|
||||
}
|
||||
|
||||
Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len);
|
||||
Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen);
|
||||
|
||||
Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len)
|
||||
{
|
||||
message_param_t *ptr;
|
||||
Byte_t *jp2stream = NULL;
|
||||
Byte_t *codestream = NULL;
|
||||
Byte8_t codelen;
|
||||
Byte8_t jp2cDBoxOffset = 0, jp2cDBoxlen = 0;
|
||||
|
||||
*jp2len = 0;
|
||||
|
||||
if( !msgqueue)
|
||||
return NULL;
|
||||
|
||||
ptr = msgqueue->first;
|
||||
while(( ptr = search_message( METADATA_MSG, -1, csn, ptr))!=NULL){
|
||||
if( ptr->phld){
|
||||
if( strncmp( (char *)ptr->phld->OrigBH+4, "jp2c", 4) == 0){
|
||||
jp2cDBoxOffset = *jp2len + ptr->phld->OrigBHlen;
|
||||
jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
|
||||
jp2cDBoxlen = *jp2len - jp2cDBoxOffset;
|
||||
}
|
||||
else
|
||||
jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
|
||||
}
|
||||
jp2stream = add_msgstream( ptr, jpipstream, jp2stream, jp2len);
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
codestream = recons_codestream( msgqueue, jpipstream, csn, 0, &codelen);
|
||||
|
||||
if( jp2cDBoxOffset != 0 && codelen <= jp2cDBoxlen)
|
||||
memcpy( jp2stream+jp2cDBoxOffset, codestream, codelen);
|
||||
|
||||
free( codestream);
|
||||
|
||||
return jp2stream;
|
||||
}
|
||||
|
||||
int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn);
|
||||
Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen);
|
||||
Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen);
|
||||
|
||||
// usable only to JPT-stream messages
|
||||
// PRECINCT_MSG, EXT_PRECINCT_MSG, TILE_HEADER_MSG need to be handled
|
||||
Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *codelen)
|
||||
{
|
||||
message_param_t *ptr;
|
||||
Byte_t *codestream = NULL;
|
||||
int last_tileID;
|
||||
int tileID;
|
||||
bool found;
|
||||
Byte8_t binOffset;
|
||||
|
||||
*codelen = 0;
|
||||
|
||||
// main header first
|
||||
ptr = msgqueue->first;
|
||||
binOffset = 0;
|
||||
while(( ptr = search_message( MAINHEADER_MSG, -1, csn, ptr))!=NULL){
|
||||
if( ptr->bin_offset == binOffset){
|
||||
codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
|
||||
binOffset += ptr->length;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
last_tileID = get_last_tileID( msgqueue, csn);
|
||||
|
||||
for( tileID=0; tileID <= last_tileID; tileID++){
|
||||
found = false;
|
||||
binOffset = 0;
|
||||
|
||||
ptr = msgqueue->first;
|
||||
while(( ptr = search_message( TILE_MSG, tileID, csn, ptr))!=NULL){
|
||||
if( ptr->bin_offset == binOffset){
|
||||
found = true;
|
||||
codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
|
||||
binOffset += ptr->length;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
ptr = msgqueue->first;
|
||||
while(( ptr = search_message( EXT_TILE_MSG, tileID, csn, ptr))!=NULL){
|
||||
if( ptr->aux >= minlev){
|
||||
if( ptr->bin_offset == binOffset){
|
||||
found = true;
|
||||
codestream = add_msgstream( ptr, jpipstream, codestream, codelen);
|
||||
binOffset += ptr->length;
|
||||
}
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if(!found)
|
||||
codestream = add_emptytilestream( tileID, codestream, codelen);
|
||||
}
|
||||
codestream = add_EOC( codestream, codelen);
|
||||
|
||||
return codestream;
|
||||
}
|
||||
|
||||
int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn)
|
||||
{
|
||||
int last_tileID = 0;
|
||||
message_param_t *msg;
|
||||
|
||||
msg = msgqueue->first;
|
||||
while( msg){
|
||||
if((msg->class_id == TILE_MSG || msg->class_id == EXT_TILE_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
|
||||
last_tileID = msg->in_class_id;
|
||||
msg = msg->next;
|
||||
}
|
||||
return last_tileID;
|
||||
}
|
||||
|
||||
message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg)
|
||||
{
|
||||
while( msg != NULL){
|
||||
if( in_class_id == -1){
|
||||
if( msg->class_id == class_id && msg->csn == csn)
|
||||
return msg;
|
||||
}
|
||||
else{
|
||||
if( msg->class_id == class_id && msg->in_class_id == in_class_id && msg->csn == csn)
|
||||
return msg;
|
||||
}
|
||||
msg = msg->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
message_param_t *ptr;
|
||||
|
@ -845,139 +728,3 @@ void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgque
|
|||
}
|
||||
free( *msg);
|
||||
}
|
||||
|
||||
Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length);
|
||||
Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length);
|
||||
|
||||
|
||||
Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen)
|
||||
{
|
||||
Byte_t *newstream;
|
||||
Byte8_t newlen;
|
||||
Byte_t *buf;
|
||||
|
||||
if( !message)
|
||||
return NULL;
|
||||
|
||||
newstream = gene_msgstream( message, origstream, &newlen);
|
||||
|
||||
buf = (Byte_t *)malloc(( *j2klen)+newlen);
|
||||
|
||||
memcpy( buf, j2kstream, *j2klen);
|
||||
memcpy( buf+(*j2klen), newstream, newlen);
|
||||
|
||||
*j2klen += newlen;
|
||||
|
||||
free( newstream);
|
||||
if(j2kstream) free(j2kstream);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len)
|
||||
{
|
||||
Byte_t *newstream;
|
||||
Byte8_t newlen;
|
||||
Byte_t *buf;
|
||||
|
||||
if( phld->OrigBHlen == 8)
|
||||
newlen = big4(phld->OrigBH);
|
||||
else
|
||||
newlen = big8(phld->OrigBH+8);
|
||||
|
||||
newstream = (Byte_t *)malloc( newlen);
|
||||
memset( newstream, 0, newlen);
|
||||
memcpy( newstream, phld->OrigBH, phld->OrigBHlen);
|
||||
|
||||
buf = (Byte_t *)malloc(( *jp2len)+newlen);
|
||||
|
||||
memcpy( buf, jp2stream, *jp2len);
|
||||
memcpy( buf+(*jp2len), newstream, newlen);
|
||||
|
||||
*jp2len += newlen;
|
||||
|
||||
free( newstream);
|
||||
if(jp2stream) free(jp2stream);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen)
|
||||
{
|
||||
Byte_t *newstream;
|
||||
Byte8_t newlen;
|
||||
Byte_t *buf;
|
||||
|
||||
newstream = gene_emptytilestream( tileID, &newlen);
|
||||
|
||||
buf = (Byte_t *)malloc(( *j2klen)+newlen);
|
||||
|
||||
memcpy( buf, j2kstream, *j2klen);
|
||||
memcpy( buf+(*j2klen), newstream, newlen);
|
||||
|
||||
*j2klen += newlen;
|
||||
|
||||
free( newstream);
|
||||
if(j2kstream) free(j2kstream);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen)
|
||||
{
|
||||
Byte2_t EOC = 0xd9ff;
|
||||
|
||||
Byte_t *buf;
|
||||
|
||||
buf = (Byte_t *)malloc(( *j2klen)+2);
|
||||
|
||||
memcpy( buf, j2kstream, *j2klen);
|
||||
memcpy( buf+(*j2klen), &EOC, 2);
|
||||
|
||||
*j2klen += 2;
|
||||
|
||||
if(j2kstream) free(j2kstream);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length)
|
||||
{
|
||||
Byte_t *buf;
|
||||
|
||||
if( !message)
|
||||
return NULL;
|
||||
|
||||
*length = message->length;
|
||||
buf = (Byte_t *)malloc( *length);
|
||||
memcpy( buf, stream+message->res_offset, *length);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length)
|
||||
{
|
||||
Byte_t *buf;
|
||||
const Byte2_t SOT = 0x90ff;
|
||||
const Byte2_t Lsot = 0xa << 8;
|
||||
Byte2_t Isot;
|
||||
const Byte4_t Psot = 0xe << 24;
|
||||
const Byte_t TPsot = 0, TNsot = 0;
|
||||
const Byte2_t SOD = 0x93ff;
|
||||
|
||||
*length = 14;
|
||||
buf = (Byte_t *)malloc(*length);
|
||||
|
||||
Isot = tileID << 8;
|
||||
|
||||
memcpy( buf, &SOT, 2);
|
||||
memcpy( buf+2, &Lsot, 2);
|
||||
memcpy( buf+4, &Isot, 2);
|
||||
memcpy( buf+6, &Psot, 4);
|
||||
memcpy( buf+10, &TPsot, 1);
|
||||
memcpy( buf+11, &TNsot, 1);
|
||||
memcpy( buf+12, &SOD, 2);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2011, Professor Benoit Macq
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2011, Lucian Corlaciu, GSoC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -36,6 +37,14 @@
|
|||
#include "cachemodel_manager.h"
|
||||
#include "placeholder_manager.h"
|
||||
|
||||
#define PRECINCT_MSG 0
|
||||
#define EXT_PRECINCT_MSG 1
|
||||
#define TILE_HEADER_MSG 2
|
||||
#define TILE_MSG 4
|
||||
#define EXT_TILE_MSG 5
|
||||
#define MAINHEADER_MSG 6
|
||||
#define METADATA_MSG 8
|
||||
|
||||
//! message parameters
|
||||
typedef struct message_param{
|
||||
bool last_byte; //!< if message contains the last byte of the data-bin
|
||||
|
@ -74,6 +83,14 @@ msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel
|
|||
*/
|
||||
void delete_msgqueue( msgqueue_param_t **msgqueue);
|
||||
|
||||
/**
|
||||
* delete a message in msgqueue
|
||||
*
|
||||
* @param[in] message address of the deleting message pointer
|
||||
* @param[in] msgqueue message queue pointer
|
||||
*/
|
||||
void delete_message_in_msgqueue( message_param_t **message, msgqueue_param_t *msgqueue);
|
||||
|
||||
/**
|
||||
* print message queue
|
||||
*
|
||||
|
@ -90,6 +107,15 @@ void print_msgqueue( msgqueue_param_t *msgqueue);
|
|||
void enqueue_mainheader( msgqueue_param_t *msgqueue);
|
||||
|
||||
|
||||
/**
|
||||
* enqueue tile headers data-bin into message queue
|
||||
*
|
||||
* @param[in] tile_id tile id starting from 0
|
||||
* @param[in,out] msgqueue message queue pointer
|
||||
*/
|
||||
void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue);
|
||||
|
||||
|
||||
/**
|
||||
* enqueue tile data-bin into message queue
|
||||
*
|
||||
|
@ -99,6 +125,16 @@ void enqueue_mainheader( msgqueue_param_t *msgqueue);
|
|||
*/
|
||||
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue);
|
||||
|
||||
/**
|
||||
* enqueue precinct data-bin into message queue
|
||||
*
|
||||
* @param[in] seq_id precinct sequence number within its tile
|
||||
* @param[in] tile_id tile index
|
||||
* @param[in] comp_id component number
|
||||
* @param[in,out] msgqueue message queue
|
||||
*/
|
||||
void enqueue_precinct( int seq_id, int tile_id, int comp_id, msgqueue_param_t *msgqueue);
|
||||
|
||||
|
||||
/**
|
||||
* enqueue Metadata-bin into message queue
|
||||
|
@ -137,30 +173,16 @@ void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, Byte8_t offset, ms
|
|||
*/
|
||||
void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t streamlen, metadatalist_param_t *metadatalist);
|
||||
|
||||
|
||||
/**
|
||||
* reconstruct j2k codestream from message queue
|
||||
* compute precinct ID A.3.2.1
|
||||
*
|
||||
* @param[in] msgqueue message queue pointer
|
||||
* @param[in] jpipstream original jpt- jpp- stream
|
||||
* @param[in] csn codestream number
|
||||
* @param[in] minlev minimum decomposition level
|
||||
* @param[out] j2klen pointer to the j2k codestream length
|
||||
* @return generated reconstructed j2k codestream
|
||||
* @param[in] t tile index
|
||||
* @param[in] c component index
|
||||
* @param[in] s sequence number
|
||||
* @param[in] num_components total number of components
|
||||
* @param[in] num_tiles total number of tiles
|
||||
* @return precicnt id
|
||||
*/
|
||||
Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int minlev, Byte8_t *j2klen);
|
||||
|
||||
|
||||
/**
|
||||
* reconstruct jp2 file codestream from message queue
|
||||
*
|
||||
* @param[in] msgqueue message queue pointer
|
||||
* @param[in] jpipstream original jpt- jpp- stream
|
||||
* @param[in] csn codestream number
|
||||
* @param[out] jp2len pointer to the jp2 codestream length
|
||||
* @return generated reconstructed jp2 codestream
|
||||
*/
|
||||
Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *jp2len);
|
||||
|
||||
Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles);
|
||||
|
||||
#endif /* !MSGQUEUE_MANAGER_H_ */
|
||||
|
|
|
@ -135,13 +135,13 @@ Byte_t * imagetopnm(opj_image_t *image, ihdrbox_param_t **ihdrbox)
|
|||
if(*ihdrbox){
|
||||
if( (*ihdrbox)->nc != image->numcomps)
|
||||
fprintf( stderr, "Exception: num of components not identical, codestream: %d, ihdrbox: %d\n", image->numcomps, (*ihdrbox)->nc);
|
||||
|
||||
|
||||
if( (*ihdrbox)->width != image->comps[0].w)
|
||||
fprintf( stderr, "Exception: width value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].w, (*ihdrbox)->width);
|
||||
(*ihdrbox)->width = image->comps[0].w;
|
||||
|
||||
if( (*ihdrbox)->height != image->comps[0].h)
|
||||
fprintf( stderr, "Exception: heigth value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].h, (*ihdrbox)->height);
|
||||
|
||||
(*ihdrbox)->height = image->comps[0].h;
|
||||
|
||||
if( (*ihdrbox)->bpc != image->comps[0].prec)
|
||||
fprintf( stderr, "Exception: bits per component not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].prec, (*ihdrbox)->bpc);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "jpipstream_manager.h"
|
||||
#include "jp2k_encoder.h"
|
||||
#include "jp2k_decoder.h"
|
||||
#include "imgreg_manager.h"
|
||||
|
||||
Byte_t * update_JPIPstream( Byte_t *newstream, int newstreamlen, Byte_t *cache_stream, int *streamlen)
|
||||
{
|
||||
|
@ -73,17 +73,8 @@ Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte
|
|||
Byte_t *pnmstream;
|
||||
Byte_t *j2kstream; // j2k or jp2 codestream
|
||||
Byte8_t j2klen;
|
||||
int level = 0;
|
||||
|
||||
if( *ihdrbox){
|
||||
// infinit value is set for maxmum level
|
||||
int fx = fw, fy = fh;
|
||||
int xmin = 0, ymin = 0;
|
||||
int xmax = (*ihdrbox)->width, ymax = (*ihdrbox)->height;
|
||||
find_level( 1000, &level, &fx, &fy, &xmin, &ymin, &xmax, &ymax);
|
||||
}
|
||||
|
||||
j2kstream = recons_j2k( msgqueue, jpipstream, csn, level+1, &j2klen);
|
||||
j2kstream = recons_j2k( msgqueue, jpipstream, csn, fw, fh, &j2klen);
|
||||
|
||||
pnmstream = j2k_to_pnm( j2kstream, j2klen, ihdrbox);
|
||||
free( j2kstream);
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "imgsock_manager.h"
|
||||
#include "jpipstream_manager.h"
|
||||
#include "cache_manager.h"
|
||||
#include "jp2k_encoder.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA initialisation_win32;
|
||||
|
@ -237,15 +238,15 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
|
|||
metadatalist_param_t *metadatalist;
|
||||
|
||||
newjpipstream = receive_JPIPstream( connected_socket, target, tid, cid, &newstreamlen);
|
||||
|
||||
|
||||
parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
|
||||
|
||||
|
||||
*jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
|
||||
free( newjpipstream);
|
||||
|
||||
metadatalist = gene_metadatalist();
|
||||
parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist);
|
||||
|
||||
|
||||
// cid registration
|
||||
if( target[0] != 0){
|
||||
if((cache = search_cache( target, cachelist))){
|
||||
|
@ -265,7 +266,7 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
|
|||
if( cache->metadatalist)
|
||||
delete_metadatalist( &cache->metadatalist);
|
||||
cache->metadatalist = metadatalist;
|
||||
|
||||
|
||||
response_signal( connected_socket, true);
|
||||
}
|
||||
|
||||
|
@ -276,7 +277,7 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par
|
|||
char cid[MAX_LENOFCID], tmp[10];
|
||||
cache_param_t *cache;
|
||||
int fw, fh;
|
||||
|
||||
|
||||
receive_line( connected_socket, cid);
|
||||
if(!(cache = search_cacheBycid( cid, cachelist)))
|
||||
if(!(cache = search_cacheBytid( cid, cachelist)))
|
||||
|
@ -290,6 +291,7 @@ void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_par
|
|||
|
||||
pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox);
|
||||
ihdrbox = cache->ihdrbox;
|
||||
|
||||
send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1);
|
||||
|
||||
free( pnmstream);
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
opj_viewer-20110916.jar
|
||||
opj_viewer-20110930.jar
|
|
@ -40,8 +40,8 @@ public class ImageManager extends JPIPHttpClient
|
|||
pnmimage = null;
|
||||
}
|
||||
|
||||
public int getOrigWidth(){ return pnmimage.width;}
|
||||
public int getOrigHeight(){ return pnmimage.height;}
|
||||
public int getOrigWidth(){ return pnmimage.get_width();}
|
||||
public int getOrigHeight(){ return pnmimage.get_height();}
|
||||
|
||||
public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew)
|
||||
{
|
||||
|
@ -64,10 +64,14 @@ public class ImageManager extends JPIPHttpClient
|
|||
jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew);
|
||||
|
||||
System.err.println( "decoding to PNM image");
|
||||
pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh);
|
||||
System.err.println( " done");
|
||||
|
||||
return pnmimage.createROIImage( rx, ry, rw, rh);
|
||||
if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){
|
||||
System.err.println( " done");
|
||||
return pnmimage.createROIImage( rx, ry, rw, rh);
|
||||
}
|
||||
else{
|
||||
System.err.println( " failed");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Image getImage( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
|
||||
|
@ -77,10 +81,14 @@ public class ImageManager extends JPIPHttpClient
|
|||
byte[] jpipstream = super.requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh);
|
||||
|
||||
System.err.println( "decoding to PNM image");
|
||||
pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh);
|
||||
System.err.println( " done");
|
||||
|
||||
return pnmimage.createROIImage( rx, ry, rw, rh);
|
||||
if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, tid, cid, fw, fh)) != null){
|
||||
System.err.println( " done");
|
||||
return pnmimage.createROIImage( rx, ry, rw, rh);
|
||||
}
|
||||
else{
|
||||
System.err.println( " failed");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getXML()
|
||||
|
|
|
@ -40,8 +40,6 @@ import java.io.*;
|
|||
|
||||
public class ImageViewer extends JPanel
|
||||
{
|
||||
private MML myMML;
|
||||
private ResizeListener myRL;
|
||||
private ImageManager imgmanager;
|
||||
private int vw, vh;
|
||||
private int iw, ih;
|
||||
|
@ -58,8 +56,9 @@ public class ImageViewer extends JPanel
|
|||
public ImageViewer( String j2kfilename, ImageManager manager, boolean session)
|
||||
{
|
||||
String str;
|
||||
|
||||
this.setSize( 200, 200);
|
||||
MML myMML;
|
||||
|
||||
this.setSize( 170, 170);
|
||||
Dimension asz = this.getSize();
|
||||
|
||||
vw = asz.width;
|
||||
|
@ -67,14 +66,14 @@ public class ImageViewer extends JPanel
|
|||
|
||||
setBackground(Color.black);
|
||||
myMML = new MML(this);
|
||||
myRL = new ResizeListener(this);
|
||||
|
||||
imgmanager = manager;
|
||||
|
||||
img = imgmanager.getImage( j2kfilename, vw, vh, session);
|
||||
|
||||
addMouseListener(myMML);
|
||||
addMouseMotionListener(myMML);
|
||||
addComponentListener(myRL);
|
||||
addComponentListener( new ResizeListener(this));
|
||||
}
|
||||
|
||||
public Image getImage()
|
||||
|
@ -87,8 +86,8 @@ public class ImageViewer extends JPanel
|
|||
roirect = null;
|
||||
roiname = null;
|
||||
|
||||
double scalex = vw/(double)rect.width;
|
||||
double scaley = vh/(double)rect.height;
|
||||
double scalex = (double)vw/(double)rect.width;
|
||||
double scaley = (double)vh/(double)rect.height;
|
||||
|
||||
int fw = (int)(imgmanager.getFw()*scalex);
|
||||
int fh = (int)(imgmanager.getFh()*scaley);
|
||||
|
@ -108,12 +107,12 @@ public class ImageViewer extends JPanel
|
|||
{
|
||||
roirect = null;
|
||||
roiname = null;
|
||||
|
||||
|
||||
Dimension asz = this.getSize();
|
||||
|
||||
vw = asz.width;
|
||||
vh = asz.height;
|
||||
|
||||
|
||||
double scalex = vw/(double)imgmanager.getRw();
|
||||
double scaley = vh/(double)imgmanager.getRh();
|
||||
|
||||
|
@ -121,9 +120,9 @@ public class ImageViewer extends JPanel
|
|||
int fh = (int)(imgmanager.getFh()*scaley);
|
||||
int rx = (int)(imgmanager.getRx()*scalex);
|
||||
int ry = (int)(imgmanager.getRy()*scaley);
|
||||
|
||||
|
||||
img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
|
||||
|
||||
|
||||
fullRefresh = true;
|
||||
repaint();
|
||||
}
|
||||
|
|
|
@ -108,10 +108,11 @@ public class ImgdecClient{
|
|||
System.err.println("IOException: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static PnmImage get_PNMstream( String cid, String tid, int fw, int fh)
|
||||
{
|
||||
PnmImage pnmstream = new PnmImage();
|
||||
PnmImage pnmstream = null;
|
||||
|
||||
try {
|
||||
Socket imgdecSocket = new Socket( "localhost", 5000);
|
||||
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
|
||||
|
@ -130,25 +131,20 @@ public class ImgdecClient{
|
|||
os.writeBytes( fh + "\n");
|
||||
|
||||
read_stream( is, header, 7);
|
||||
|
||||
|
||||
if( header[0] == 80){
|
||||
// P5: gray, P6: color
|
||||
byte magicknum = header[1];
|
||||
if( magicknum == 5 || magicknum == 6){
|
||||
int length;
|
||||
boolean iscolor = magicknum==6 ? true:false;
|
||||
if( iscolor)
|
||||
pnmstream.channel = 3;
|
||||
else
|
||||
pnmstream.channel = 1;
|
||||
pnmstream.width = (header[2]&0xff)<<8 | (header[3]&0xff);
|
||||
pnmstream.height = (header[4]&0xff)<<8 | (header[5]&0xff);
|
||||
int c = magicknum==6 ? 3: 1;
|
||||
int w = (header[2]&0xff)<<8 | (header[3]&0xff);
|
||||
int h = (header[4]&0xff)<<8 | (header[5]&0xff);
|
||||
int maxval = header[6]&0xff;
|
||||
|
||||
if( maxval == 255){
|
||||
length = pnmstream.width*pnmstream.height*pnmstream.channel;
|
||||
pnmstream.data = new byte [ length];
|
||||
read_stream( is, pnmstream.data, length);
|
||||
int length = w*h*c;
|
||||
|
||||
if( maxval == 255 && length != 0){
|
||||
pnmstream = new PnmImage( c, w, h);
|
||||
read_stream( is, pnmstream.get_data(), length);
|
||||
}
|
||||
else
|
||||
System.err.println("Error in get_PNMstream(), only 255 is accepted");
|
||||
|
@ -158,6 +154,7 @@ public class ImgdecClient{
|
|||
}
|
||||
else
|
||||
System.err.println("Error in get_PNMstream(), Not starting with P");
|
||||
|
||||
os.close();
|
||||
is.close();
|
||||
imgdecSocket.close();
|
||||
|
@ -265,7 +262,7 @@ public class ImgdecClient{
|
|||
try{
|
||||
while( remlen > 0){
|
||||
int redlen = is.read( stream, off, remlen);
|
||||
|
||||
|
||||
if( redlen == -1){
|
||||
System.err.println(" failed to read_stream()");
|
||||
break;
|
||||
|
|
|
@ -312,6 +312,11 @@ public class JPIPHttpClient
|
|||
urlstring = urlstring.concat( "&");
|
||||
urlstring = urlstring.concat( "cnew=http");
|
||||
}
|
||||
|
||||
if( !urlstring.endsWith("?"))
|
||||
urlstring = urlstring.concat( "&");
|
||||
urlstring = urlstring.concat( "type=jpp-stream");
|
||||
|
||||
return urlstring;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,57 +35,20 @@ import java.util.regex.*;
|
|||
|
||||
public class PnmImage extends Component
|
||||
{
|
||||
public byte[] data = null;
|
||||
public int width = 0;
|
||||
public int height = 0;
|
||||
public int channel = 0;
|
||||
private byte[] data = null;
|
||||
private int width = 0;
|
||||
private int height = 0;
|
||||
private int channel = 0;
|
||||
|
||||
public Image createROIImage( int rx, int ry, int rw, int rh)
|
||||
public PnmImage( int c, int w, int h)
|
||||
{
|
||||
int []pix = new int[ rw*rh];
|
||||
|
||||
for( int i=0; i<rh; i++)
|
||||
for( int j=0; j<rw; j++){
|
||||
pix[i*rw+j] = 0xFF << 24; // transparency
|
||||
if( channel == 1){
|
||||
Byte lum = data[(ry+i)*width+rx+j];
|
||||
short slum;
|
||||
|
||||
if( lum < 0)
|
||||
slum = (short)(2*128+lum);
|
||||
else
|
||||
slum = (short)lum;
|
||||
|
||||
for( int c=0; c<3; c++){
|
||||
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
|
||||
}
|
||||
}
|
||||
else
|
||||
for( int c=0; c<3; c++){
|
||||
Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
|
||||
short slum;
|
||||
|
||||
if( lum < 0)
|
||||
slum = (short)(2*128+lum);
|
||||
else
|
||||
slum = (short)lum;
|
||||
|
||||
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
|
||||
}
|
||||
}
|
||||
return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
|
||||
channel = c;
|
||||
width = w;
|
||||
height = h;
|
||||
data = new byte [ w*h*c];
|
||||
}
|
||||
|
||||
public Image createScaleImage( double scale)
|
||||
{
|
||||
Image src = createROIImage( 0, 0, width, height);
|
||||
ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
|
||||
ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
|
||||
|
||||
return createImage(prod);
|
||||
}
|
||||
|
||||
public void openimage( String filename)
|
||||
|
||||
public PnmImage( String filename)
|
||||
{
|
||||
String str;
|
||||
Pattern pat;
|
||||
|
@ -137,5 +100,55 @@ public class PnmImage extends Component
|
|||
}
|
||||
fis.close();
|
||||
} catch (IOException e) { e.printStackTrace(); }
|
||||
}
|
||||
}
|
||||
|
||||
public byte [] get_data(){ return data;}
|
||||
public int get_width() { return width;}
|
||||
public int get_height(){ return height;}
|
||||
|
||||
public Image createROIImage( int rx, int ry, int rw, int rh)
|
||||
{
|
||||
int []pix = new int[ rw*rh];
|
||||
|
||||
for( int i=0; i<rh; i++)
|
||||
for( int j=0; j<rw; j++){
|
||||
pix[i*rw+j] = 0xFF << 24; // transparency
|
||||
if( channel == 1){
|
||||
Byte lum = data[(ry+i)*width+rx+j];
|
||||
short slum;
|
||||
|
||||
if( lum < 0)
|
||||
slum = (short)(2*128+lum);
|
||||
else
|
||||
slum = (short)lum;
|
||||
|
||||
for( int c=0; c<3; c++){
|
||||
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
|
||||
}
|
||||
}
|
||||
else
|
||||
for( int c=0; c<3; c++){
|
||||
Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
|
||||
short slum;
|
||||
|
||||
if( lum < 0)
|
||||
slum = (short)(2*128+lum);
|
||||
else
|
||||
slum = (short)lum;
|
||||
|
||||
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
|
||||
}
|
||||
}
|
||||
|
||||
return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
|
||||
}
|
||||
|
||||
public Image createScaleImage( double scale)
|
||||
{
|
||||
Image src = createROIImage( 0, 0, width, height);
|
||||
ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
|
||||
ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
|
||||
|
||||
return createImage(prod);
|
||||
}
|
||||
}
|
|
@ -44,8 +44,7 @@ public class RegimViewer extends JPanel
|
|||
|
||||
public RegimViewer( String refname, double[] mat)
|
||||
{
|
||||
refpnm = new PnmImage();
|
||||
refpnm.openimage(refname.replaceFirst("jp2", "pgm")); // decoding not realized
|
||||
refpnm = new PnmImage( refname.replaceFirst("jp2", "pgm")); // decoding not realized
|
||||
affine_matrix = new double[6];
|
||||
|
||||
affine_matrix[0] = mat[0];
|
||||
|
|
|
@ -50,10 +50,18 @@ class ResizeListener implements ComponentListener
|
|||
public void componentResized(ComponentEvent e) {
|
||||
Dimension cursize = iv.getSize();
|
||||
if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){
|
||||
largest = cursize;
|
||||
update_largest( cursize);
|
||||
iv.enlarge();
|
||||
}
|
||||
}
|
||||
|
||||
private void update_largest( Dimension cursize)
|
||||
{
|
||||
if( largest.getWidth() < cursize.getWidth())
|
||||
largest.setSize( cursize.getWidth(), largest.getHeight());
|
||||
if( largest.getHeight() < cursize.getHeight())
|
||||
largest.setSize( largest.getWidth(), cursize.getHeight());
|
||||
}
|
||||
|
||||
public void componentShown(ComponentEvent e) {}
|
||||
}
|
Binary file not shown.
BIN
applications/jpip/opj_client/opj_viewer_xerces/dist/opj_viewer_xerces-20110930.jar
vendored
Normal file
BIN
applications/jpip/opj_client/opj_viewer_xerces/dist/opj_viewer_xerces-20110930.jar
vendored
Normal file
Binary file not shown.
|
@ -1 +1 @@
|
|||
opj_viewer_xerces-20110916.jar
|
||||
opj_viewer_xerces-20110930.jar
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2011, Professor Benoit Macq
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2011, Lucian Corlaciu, GSoC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "query_parser.h"
|
||||
#include "channel_manager.h"
|
||||
|
@ -108,14 +110,21 @@ int main(void)
|
|||
|
||||
if( strcmp( query_string, QUIT_SIGNAL) == 0)
|
||||
break;
|
||||
|
||||
fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
|
||||
|
||||
|
||||
query_param_t query_param;
|
||||
msgqueue_param_t *msgqueue;
|
||||
|
||||
parse_query( query_string, &query_param);
|
||||
|
||||
switch( query_param.return_type){
|
||||
case JPPstream:
|
||||
fprintf( FCGI_stdout, "Content-type: image/jpp-stream\r\n");
|
||||
break;
|
||||
default:
|
||||
fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef SERVER
|
||||
print_queryparam( query_param);
|
||||
#endif
|
||||
|
@ -206,10 +215,10 @@ bool close_channel( query_param_t query_param,
|
|||
* @param[in] target requested target pointer
|
||||
* @param[in,out] cursession associated session pointer
|
||||
* @param[in,out] curchannel associated channel pointer
|
||||
* @param[in,out] msgqueue address of the message queue pointer
|
||||
* @param[out] msgqueue address of the message queue pointer
|
||||
* @return if succeeded (true) or failed (false)
|
||||
*/
|
||||
bool gene_JPTstream( query_param_t query_param,
|
||||
bool gene_JPIPstream( query_param_t query_param,
|
||||
target_param_t *target,
|
||||
session_param_t *cursession,
|
||||
channel_param_t *curchannel,
|
||||
|
@ -243,9 +252,9 @@ bool parse_JPIPrequest( query_param_t query_param,
|
|||
return false;
|
||||
|
||||
if( (query_param.fx > 0 && query_param.fy > 0) || query_param.box_type[0][0] != 0)
|
||||
if( !gene_JPTstream( query_param, target, cursession, curchannel, msgqueue))
|
||||
if( !gene_JPIPstream( query_param, target, cursession, curchannel, msgqueue))
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -368,13 +377,12 @@ bool close_channel( query_param_t query_param,
|
|||
|
||||
|
||||
/**
|
||||
* enqueue tiles into the message queue
|
||||
* enqueue tiles or precincts into the message queue
|
||||
*
|
||||
* @param[in] query_param structured query
|
||||
* @param[in] codeidx pointer to index parameters
|
||||
* @param[in,out] msgqueue message queue pointer
|
||||
* @param[in] query_param structured query
|
||||
* @param[in] msgqueue message queue pointer
|
||||
*/
|
||||
void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue);
|
||||
void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue);
|
||||
|
||||
/**
|
||||
* enqueue metadata bins into the message queue
|
||||
|
@ -386,11 +394,11 @@ void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_
|
|||
void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
|
||||
|
||||
|
||||
bool gene_JPTstream( query_param_t query_param,
|
||||
target_param_t *target,
|
||||
session_param_t *cursession,
|
||||
channel_param_t *curchannel,
|
||||
msgqueue_param_t **msgqueue)
|
||||
bool gene_JPIPstream( query_param_t query_param,
|
||||
target_param_t *target,
|
||||
session_param_t *cursession,
|
||||
channel_param_t *curchannel,
|
||||
msgqueue_param_t **msgqueue)
|
||||
{
|
||||
index_param_t *codeidx;
|
||||
cachemodel_param_t *cachemodel;
|
||||
|
@ -418,28 +426,60 @@ bool gene_JPTstream( query_param_t query_param,
|
|||
if( query_param.fx > 0 && query_param.fy > 0){
|
||||
if( !cachemodel->mhead_model)
|
||||
enqueue_mainheader( *msgqueue);
|
||||
enqueue_tiles( query_param, codeidx, *msgqueue);
|
||||
enqueue_imagedata( query_param, *msgqueue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue)
|
||||
|
||||
/**
|
||||
* enqueue precinct data-bins into the queue
|
||||
*
|
||||
* @param[in] xmin min x coordinate in the tile at the decomposition level
|
||||
* @param[in] xmax max x coordinate in the tile at the decomposition level
|
||||
* @param[in] ymin min y coordinate in the tile at the decomposition level
|
||||
* @param[in] ymax max y coordinate in the tile at the decomposition level
|
||||
* @param[in] tile_id tile index
|
||||
* @param[in] level decomposition level
|
||||
* @param[in] lastcomp last component number
|
||||
* @param[in] comps pointer to the array that stores the requested components
|
||||
* @param[in] msgqueue message queue
|
||||
* @return
|
||||
*/
|
||||
void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue);
|
||||
|
||||
/**
|
||||
* enqueue all precincts inside a tile into the queue
|
||||
*
|
||||
* @param[in] tile_id tile index
|
||||
* @param[in] level decomposition level
|
||||
* @param[in] lastcomp last component number
|
||||
* @param[in] comps pointer to the array that stores the requested components
|
||||
* @param[in] msgqueue message queue
|
||||
* @return
|
||||
*/
|
||||
void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue);
|
||||
|
||||
void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
index_param_t *codeidx;
|
||||
imgreg_param_t imgreg;
|
||||
range_param_t tile_Xrange, tile_Yrange;
|
||||
int u, v, tile_id;
|
||||
int xmin, xmax, ymin, ymax;
|
||||
|
||||
codeidx = msgqueue->cachemodel->target->codeidx;
|
||||
|
||||
imgreg = map_viewin2imgreg( query_param.fx, query_param.fy,
|
||||
query_param.rx, query_param.ry, query_param.rw, query_param.rh,
|
||||
codeidx->XOsiz, codeidx->YOsiz, codeidx->Xsiz, codeidx->Ysiz,
|
||||
get_nmax( codeidx->tilepart));
|
||||
codeidx->SIZ.XOsiz, codeidx->SIZ.YOsiz, codeidx->SIZ.Xsiz, codeidx->SIZ.Ysiz,
|
||||
codeidx->COD.numOfdecomp+1);
|
||||
|
||||
|
||||
for( u=0, tile_id=0; u<codeidx->YTnum; u++){
|
||||
tile_Yrange = get_tile_Yrange( *codeidx, u, imgreg.level);
|
||||
for( u=0, tile_id=0; u<codeidx->SIZ.YTnum; u++){
|
||||
tile_Yrange = get_tile_Yrange( codeidx->SIZ, tile_id, imgreg.level);
|
||||
|
||||
for( v=0; v<codeidx->XTnum; v++, tile_id++){
|
||||
tile_Xrange = get_tile_Xrange( *codeidx, v, imgreg.level);
|
||||
for( v=0; v<codeidx->SIZ.XTnum; v++, tile_id++){
|
||||
tile_Xrange = get_tile_Xrange( codeidx->SIZ, tile_id, imgreg.level);
|
||||
|
||||
if( tile_Xrange.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
|
||||
if( tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox ||
|
||||
|
@ -456,19 +496,115 @@ void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_
|
|||
// Tile completely contained within view-window
|
||||
// high priority
|
||||
//printf("Tile completely contained within view-window %d\n", tile_id);
|
||||
enqueue_tile( tile_id, imgreg.level, msgqueue);
|
||||
if( query_param.return_type == JPPstream){
|
||||
enqueue_tileheader( tile_id, msgqueue);
|
||||
enqueue_allprecincts( tile_id, imgreg.level, query_param.lastcomp, query_param.comps, msgqueue);
|
||||
}
|
||||
else
|
||||
enqueue_tile( tile_id, imgreg.level, msgqueue);
|
||||
}
|
||||
else{
|
||||
// Tile partially overlaps view-window
|
||||
// low priority
|
||||
//printf("Tile partially overlaps view-window %d\n", tile_id);
|
||||
enqueue_tile( tile_id, imgreg.level, msgqueue);
|
||||
if( query_param.return_type == JPPstream){
|
||||
enqueue_tileheader( tile_id, msgqueue);
|
||||
xmin = tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox ? 0 : imgreg.xosiz + imgreg.ox - tile_Xrange.minvalue;
|
||||
xmax = tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx ? tile_Xrange.maxvalue - tile_Xrange.minvalue -1 : imgreg.xosiz + imgreg.ox + imgreg.sx - tile_Xrange.minvalue -1;
|
||||
ymin = tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy ? 0 : imgreg.yosiz + imgreg.oy - tile_Yrange.minvalue;
|
||||
ymax = tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy ? tile_Yrange.maxvalue - tile_Yrange.minvalue -1 : imgreg.yosiz + imgreg.oy + imgreg.sy - tile_Yrange.minvalue -1;
|
||||
enqueue_precincts( xmin, xmax, ymin, ymax, tile_id, imgreg.level, query_param.lastcomp, query_param.comps, msgqueue);
|
||||
}
|
||||
else
|
||||
enqueue_tile( tile_id, imgreg.level, msgqueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
index_param_t *codeidx;
|
||||
int c, u, v, res_lev, dec_lev;
|
||||
int seq_id;
|
||||
Byte4_t XTsiz, YTsiz;
|
||||
Byte4_t XPsiz, YPsiz;
|
||||
Byte4_t xminP, xmaxP, yminP, ymaxP;
|
||||
|
||||
codeidx = msgqueue->cachemodel->target->codeidx;
|
||||
|
||||
for( c=0; c<codeidx->SIZ.Csiz; c++)
|
||||
if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
|
||||
seq_id = 0;
|
||||
for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
|
||||
|
||||
XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
|
||||
YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
|
||||
|
||||
XPsiz = codeidx->COD.XPsiz[ res_lev];
|
||||
YPsiz = codeidx->COD.YPsiz[ res_lev];
|
||||
|
||||
for( u=0; u<ceil((double)YTsiz/(double)YPsiz); u++){
|
||||
yminP = u*YPsiz;
|
||||
ymaxP = (u+1)*YPsiz-1;
|
||||
if( YTsiz <= ymaxP)
|
||||
ymaxP = YTsiz-1;
|
||||
|
||||
for( v=0; v<ceil((double)XTsiz/(double)XPsiz); v++, seq_id++){
|
||||
xminP = v*XPsiz;
|
||||
xmaxP = (v+1)*XPsiz-1;
|
||||
if( XTsiz <= xmaxP)
|
||||
xmaxP = XTsiz-1;
|
||||
|
||||
if( xmaxP < xmin || xminP > xmax || ymaxP < ymin || yminP > ymax){
|
||||
// Precinct completely excluded from view-window
|
||||
}
|
||||
else if( xminP >= xmin && xmaxP <= xmax && yminP >= ymin && ymaxP <= ymax){
|
||||
// Precinct completely contained within view-window
|
||||
// high priority
|
||||
enqueue_precinct( seq_id, tile_id, c, msgqueue);
|
||||
}
|
||||
else{
|
||||
// Precinct partially overlaps view-window
|
||||
// low priority
|
||||
enqueue_precinct( seq_id, tile_id, c, msgqueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
index_param_t *codeidx;
|
||||
int c, i, res_lev, dec_lev;
|
||||
int seq_id;
|
||||
Byte4_t XTsiz, YTsiz;
|
||||
Byte4_t XPsiz, YPsiz;
|
||||
|
||||
codeidx = msgqueue->cachemodel->target->codeidx;
|
||||
|
||||
for( c=0; c<codeidx->SIZ.Csiz; c++)
|
||||
if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
|
||||
seq_id = 0;
|
||||
for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
|
||||
|
||||
XTsiz = get_tile_XSiz( codeidx->SIZ, tile_id, dec_lev);
|
||||
YTsiz = get_tile_YSiz( codeidx->SIZ, tile_id, dec_lev);
|
||||
|
||||
XPsiz = codeidx->COD.XPsiz[ res_lev];
|
||||
YPsiz = codeidx->COD.YPsiz[ res_lev];
|
||||
|
||||
for( i=0; i<ceil((double)YTsiz/(double)YPsiz)*ceil((double)XTsiz/(double)XPsiz); i++, seq_id++){
|
||||
enqueue_precinct( seq_id, tile_id, c, msgqueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
*
|
||||
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2011, Professor Benoit Macq
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2011, Lucian Corlaciu, GSoC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -77,6 +78,10 @@ void str2cclose( char *src, char cclose[][MAX_LENOFCID]);
|
|||
|
||||
void parse_metareq( char *field, query_param_t *query_param);
|
||||
|
||||
// parse the requested components (parses forms like:a; a,b; a-b; a-b,c; a,b-c)
|
||||
void parse_comps( char *field, query_param_t *query_param);
|
||||
|
||||
|
||||
//! maximum length of field name
|
||||
#define MAX_LENOFFIELDNAME 10
|
||||
|
||||
|
@ -122,6 +127,16 @@ void parse_query( char *query_string, query_param_t *query_param)
|
|||
|
||||
else if( strcasecmp( fieldname, "metareq") == 0)
|
||||
parse_metareq( fieldval, query_param);
|
||||
|
||||
else if( strcasecmp( fieldname, "comps") == 0)
|
||||
parse_comps( fieldval, query_param);
|
||||
|
||||
else if( strcasecmp( fieldname, "type") == 0){
|
||||
if( strncasecmp( fieldval, "jpp-stream", 10) == 0)
|
||||
query_param->return_type = JPPstream;
|
||||
else if( strncasecmp( fieldval, "jpt-stream", 10) == 0)
|
||||
query_param->return_type = JPTstream;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +153,8 @@ void init_queryparam( query_param_t *query_param)
|
|||
query_param->ry=-1;
|
||||
query_param->rw=-1;
|
||||
query_param->rh=-1;
|
||||
query_param->lastcomp = -1;
|
||||
query_param->comps = NULL;
|
||||
query_param->cid[0]='\0';
|
||||
query_param->cnew=false;
|
||||
memset( query_param->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
|
||||
|
@ -153,6 +170,7 @@ void init_queryparam( query_param_t *query_param)
|
|||
query_param->root_bin = 0;
|
||||
query_param->max_depth = -1;
|
||||
query_param->metadata_only = false;
|
||||
query_param->return_type = UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,6 +208,15 @@ void print_queryparam( query_param_t query_param)
|
|||
fprintf( logstream, "\t tid: %s\n", query_param.tid);
|
||||
fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy);
|
||||
fprintf( logstream, "\t rx,ry: %d, %d \t rw,rh: %d, %d\n", query_param.rx, query_param.ry, query_param.rw, query_param.rh);
|
||||
fprintf( logstream, "\t components: ");
|
||||
if( query_param.lastcomp == -1)
|
||||
fprintf( logstream, "ALL\n");
|
||||
else{
|
||||
for( i=0; i<=query_param.lastcomp; i++)
|
||||
if( query_param.comps[i])
|
||||
fprintf( logstream, "%d ", i);
|
||||
fprintf( logstream, "\n");
|
||||
}
|
||||
fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
|
||||
fprintf( logstream, "\t cid: %s\n", query_param.cid);
|
||||
|
||||
|
@ -206,6 +233,7 @@ void print_queryparam( query_param_t query_param)
|
|||
fprintf( logstream, "\t root-bin: %d\n", query_param.root_bin);
|
||||
fprintf( logstream, "\t max-depth: %d\n", query_param.max_depth);
|
||||
fprintf( logstream, "\t metadata-only: %d\n", query_param.metadata_only);
|
||||
fprintf( logstream, "\t image return type: %d, [JPP-stream=0, JPT-stream=1, UNKNOWN=-1]\n", query_param.return_type);
|
||||
}
|
||||
|
||||
void str2cclose( char *src, char cclose[][MAX_LENOFCID])
|
||||
|
@ -301,3 +329,39 @@ void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param
|
|||
|
||||
idx++;
|
||||
}
|
||||
|
||||
void parse_comps( char *field, query_param_t *query_param)
|
||||
{
|
||||
int i,start,stop,aux = -1;
|
||||
char *ptr1,*ptr2;
|
||||
|
||||
ptr1 = strchr( field, '-');
|
||||
ptr2 = strchr( field, ',');
|
||||
|
||||
if( ptr1 && ptr2)
|
||||
if( ptr1 > ptr2)
|
||||
sscanf( field, "%d,%d-%d",&aux, &start, &stop);
|
||||
else
|
||||
sscanf( field, "%d-%d,%d", &start, &stop, &aux);
|
||||
else
|
||||
if(ptr1)
|
||||
sscanf( field, "%d-%d", &start, &stop);
|
||||
else if(ptr2){
|
||||
sscanf( field, "%d,%d", &start, &stop);
|
||||
aux = start;
|
||||
start = stop;
|
||||
}
|
||||
else{
|
||||
sscanf( field, "%d", &stop);
|
||||
start = stop;
|
||||
}
|
||||
|
||||
query_param->lastcomp = stop > aux ? stop : aux;
|
||||
query_param->comps = (bool *)calloc( 1, (query_param->lastcomp+1)*sizeof(bool));
|
||||
|
||||
for( i=start; i<=stop; i++)
|
||||
query_param->comps[i]=true;
|
||||
|
||||
if(aux!=-1)
|
||||
query_param->comps[aux] = true;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
|
||||
* Copyright (c) 2002-2011, Professor Benoit Macq
|
||||
* Copyright (c) 2010-2011, Kaori Hagihara
|
||||
* Copyright (c) 2011, Lucian Corlaciu, GSoC
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,12 +49,17 @@
|
|||
//! maximum number of meta request box
|
||||
#define MAX_NUMOFBOX 10
|
||||
|
||||
//! image return type
|
||||
typedef enum image_return { JPPstream, JPTstream, UNKNOWN=-1} image_return_t;
|
||||
|
||||
//! Query parameters
|
||||
typedef struct query_param{
|
||||
char target[MAX_LENOFTARGET]; //!< target name
|
||||
char tid[MAX_LENOFTID]; //!< target identifier
|
||||
int fx, fy; //!< frame size (fx,fy)
|
||||
int rx, ry, rw, rh; //!< roi region
|
||||
int lastcomp; //!< last component number
|
||||
bool *comps; //!< components for jpp-stream, null means all components
|
||||
char cid[MAX_LENOFCID]; //!< channel identifier
|
||||
bool cnew; //!< if there is new channel request(true) or not (false)
|
||||
char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers
|
||||
|
@ -67,6 +73,7 @@ typedef struct query_param{
|
|||
int root_bin; //!< root-bin
|
||||
int max_depth; //!< max-depth
|
||||
bool metadata_only; //!< metadata-only request
|
||||
image_return_t return_type; //!< image return type
|
||||
} query_param_t;
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "msgqueue_manager.h"
|
||||
|
||||
#include "jp2k_encoder.h"
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ int main(int argc,char *argv[])
|
|||
|
||||
//print_msgqueue( msgqueue);
|
||||
|
||||
j2kstream = recons_j2k( msgqueue, jpipstream, msgqueue->first->csn, 0, &j2klen);
|
||||
j2kstream = recons_j2k( msgqueue, jpipstream, msgqueue->first->csn, 0, 0, &j2klen);
|
||||
|
||||
delete_msgqueue( &msgqueue);
|
||||
free( jpipstream);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "byte_manager.h"
|
||||
#include "ihdrbox_manager.h"
|
||||
#include "metadata_manager.h"
|
||||
#include "jp2k_encoder.h"
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
|
@ -95,7 +96,7 @@ int main(int argc,char *argv[])
|
|||
print_msgqueue( msgqueue);
|
||||
//print_allmetadata( metadatalist);
|
||||
|
||||
ihdrbox = get_ihdrbox( metadatalist, jpipstream);
|
||||
ihdrbox = gene_ihdrbox( metadatalist, jpipstream);
|
||||
|
||||
printf("W*H: %d*%d\n", ihdrbox->height, ihdrbox->width);
|
||||
printf("NC: %d, bpc: %d\n", ihdrbox->nc, ihdrbox->bpc);
|
||||
|
|
|
@ -961,7 +961,7 @@ static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int len
|
|||
cio_skip( cio, 4); /* L [at the end] */
|
||||
cio_write( cio, JPIP_FIDX, 4); /* IPTR */
|
||||
|
||||
write_prxy( offset_jp2c, length_jp2c, offset_idx, offset_jp2c, cio);
|
||||
write_prxy( offset_jp2c, length_jp2c, offset_idx, length_idx, cio);
|
||||
|
||||
len = cio_tell( cio)-lenp;
|
||||
cio_seek( cio, lenp);
|
||||
|
@ -1154,7 +1154,7 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_
|
|||
|
||||
opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) {
|
||||
|
||||
int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, end_pos, pos_fidx, len_fidx;
|
||||
int pos_iptr, pos_cidx, pos_jp2c, len_jp2c, len_cidx, end_pos, pos_fidx, len_fidx;
|
||||
|
||||
/* JP2 encoding */
|
||||
|
||||
|
@ -1181,10 +1181,10 @@ opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_
|
|||
if( jp2->jpip_on){
|
||||
pos_cidx = cio_tell( cio);
|
||||
|
||||
write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
|
||||
len_cidx = write_cidx( pos_jp2c+8, cio, image, *cstr_info, len_jp2c-8);
|
||||
|
||||
pos_fidx = cio_tell( cio);
|
||||
len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, cio_tell(cio), cio);
|
||||
len_fidx = write_fidx( pos_jp2c, len_jp2c, pos_cidx, len_cidx, cio);
|
||||
|
||||
end_pos = cio_tell( cio);
|
||||
|
||||
|
|
|
@ -88,7 +88,10 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
|
|||
int size_of_coding; // 4 or 8
|
||||
int version;
|
||||
int tileno, resno, precno, layno, num_packet=0;
|
||||
|
||||
int i,nmax=0;
|
||||
opj_tile_info_t *tile_Idx;
|
||||
opj_packet_info_t packet;
|
||||
|
||||
if( j2klen > pow( 2, 32)){
|
||||
size_of_coding = 8;
|
||||
version = 1;
|
||||
|
@ -102,20 +105,23 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
|
|||
cio_skip( cio, 4); /* L [at the end] */
|
||||
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
|
||||
cio_write( cio, version,1); /* Version 0 = 4 bytes */
|
||||
|
||||
cio_write( cio, cstr_info.packno, size_of_coding); /* NMAX */
|
||||
|
||||
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
|
||||
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
|
||||
|
||||
cio_write( cio, nmax, size_of_coding); /* NMAX */
|
||||
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
|
||||
|
||||
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
|
||||
|
||||
opj_tile_info_t *tile_Idx = &cstr_info.tile[ tileno];
|
||||
tile_Idx = &cstr_info.tile[ tileno];
|
||||
// int correction = EPHused ? 3 : 1;
|
||||
num_packet = 0;
|
||||
|
||||
for( resno=0; resno<cstr_info.numdecompos[compno]+1; resno++){
|
||||
for( resno=0; resno<=cstr_info.numdecompos[compno]; resno++){
|
||||
for( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
|
||||
for( layno=0; layno<cstr_info.numlayers; layno++){
|
||||
opj_packet_info_t packet = tile_Idx->packet[num_packet];
|
||||
for( layno=0; layno<cstr_info.numlayers; layno++){
|
||||
packet = tile_Idx->packet[num_packet * cstr_info.numcomps + compno];
|
||||
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
|
||||
cio_write( cio, packet.end_ph_pos-packet.start_pos+1, size_of_coding); /* length */
|
||||
|
||||
|
@ -125,7 +131,7 @@ int write_phixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
|
|||
}
|
||||
|
||||
/* PADDING */
|
||||
while( num_packet < cstr_info.packno){
|
||||
while( num_packet < nmax){
|
||||
cio_write( cio, 0, size_of_coding); /* start position */
|
||||
cio_write( cio, 0, size_of_coding); /* length */
|
||||
num_packet++;
|
||||
|
|
|
@ -85,13 +85,15 @@ int write_ppix( int coff, opj_codestream_info_t cstr_info, opj_bool EPHused, int
|
|||
return len;
|
||||
}
|
||||
|
||||
// NMAX might be wrong , phix too, do sth to correction
|
||||
int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_bool EPHused, int j2klen, opj_cio_t *cio)
|
||||
{
|
||||
int len, lenp;
|
||||
int tileno, resno, precno, layno, num_packet=0;
|
||||
int size_of_coding; // 4 or 8
|
||||
int version;
|
||||
int i,nmax=0;
|
||||
opj_tile_info_t *tile_Idx;
|
||||
opj_packet_info_t packet;
|
||||
|
||||
if( j2klen > pow( 2, 32)){
|
||||
size_of_coding = 8;
|
||||
|
@ -107,19 +109,22 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
|
|||
cio_write( cio, JPIP_FAIX, 4); /* FAIX */
|
||||
cio_write( cio, version, 1); /* Version 0 = 4 bytes */
|
||||
|
||||
cio_write( cio, cstr_info.packno, size_of_coding); /* NMAX */
|
||||
for( i=0; i<=cstr_info.numdecompos[compno]; i++)
|
||||
nmax += cstr_info.tile[0].ph[i] * cstr_info.tile[0].pw[i] * cstr_info.numlayers;
|
||||
|
||||
cio_write( cio, nmax, size_of_coding); /* NMAX */
|
||||
cio_write( cio, cstr_info.tw*cstr_info.th, size_of_coding); /* M */
|
||||
|
||||
for( tileno=0; tileno<cstr_info.tw*cstr_info.th; tileno++){
|
||||
|
||||
opj_tile_info_t *tile_Idx = &cstr_info.tile[ tileno];
|
||||
|
||||
tile_Idx = &cstr_info.tile[ tileno];
|
||||
// int correction = EPHused ? 3 : 1;
|
||||
num_packet=0;
|
||||
|
||||
for( resno=0; resno< cstr_info.numdecompos[compno]+1; resno++){
|
||||
for( resno=0; resno<=cstr_info.numdecompos[compno]; resno++){
|
||||
for( precno=0; precno<tile_Idx->pw[resno]*tile_Idx->ph[resno]; precno++){
|
||||
for( layno=0; layno<cstr_info.numlayers; layno++){
|
||||
opj_packet_info_t packet = tile_Idx->packet[num_packet];
|
||||
packet = tile_Idx->packet[num_packet * cstr_info.numcomps + compno];
|
||||
cio_write( cio, packet.start_pos-coff, size_of_coding); /* start position */
|
||||
cio_write( cio, packet.end_pos-packet.start_pos+1, size_of_coding); /* length */
|
||||
|
||||
|
@ -129,7 +134,7 @@ int write_ppixfaix( int coff, int compno, opj_codestream_info_t cstr_info, opj_b
|
|||
}
|
||||
|
||||
/* PADDING */
|
||||
while( num_packet < cstr_info.packno){
|
||||
while( num_packet < nmax){
|
||||
cio_write( cio, 0, size_of_coding); /* start position */
|
||||
cio_write( cio, 0, size_of_coding); /* length */
|
||||
num_packet++;
|
||||
|
|
Loading…
Reference in New Issue