Work In Progress: insert elements from V2 framework into the trunk
This commit is contained in:
parent
93f3e2b007
commit
b551844cc2
3
CHANGES
3
CHANGES
|
@ -5,6 +5,9 @@ What's New for OpenJPEG
|
|||
! : changed
|
||||
+ : added
|
||||
|
||||
September 19, 2011
|
||||
+ [mickael] Work In Progress: insert elements from V2 framework into the trunk.
|
||||
|
||||
September 9, 2011
|
||||
+ [antonin] added a new indexer functionality to the library. With the new '-jpip' option at encoding, the user can now generate a JP2 file including an XML box with the index used when browsing the image with JPIP.
|
||||
|
||||
|
|
|
@ -93,9 +93,9 @@ void decode_help_display(void) {
|
|||
fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
|
||||
fprintf(stdout," is identified based on its suffix.\n");
|
||||
fprintf(stdout," -o <output file>\n");
|
||||
fprintf(stdout," OPTIONAL\n");
|
||||
fprintf(stdout," Output file where file info will be dump.\n");
|
||||
fprintf(stdout," By default it will be in the stdout.\n");
|
||||
fprintf(stdout," OPTIONAL\n");
|
||||
fprintf(stdout," Output file where file info will be dump.\n");
|
||||
fprintf(stdout," By default it will be in the stdout.\n");
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
|
||||
|
@ -317,26 +317,30 @@ void info_callback(const char *msg, void *client_data) {
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
opj_dparameters_t parameters; /* decompression parameters */
|
||||
img_fol_t img_fol;
|
||||
opj_event_mgr_t event_mgr; /* event manager */
|
||||
opj_image_t *image = NULL;
|
||||
FILE *fsrc = NULL, *fout = NULL;
|
||||
unsigned char *src = NULL;
|
||||
int file_length;
|
||||
opj_bool bResult;
|
||||
int num_images;
|
||||
int i,imageno;
|
||||
dircnt_t *dirptr = NULL;
|
||||
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
|
||||
opj_cio_t *cio = NULL;
|
||||
opj_codec_t* dinfo = NULL; /* handle to a decompressor */
|
||||
opj_stream_t *cio = NULL;
|
||||
opj_codestream_info_t cstr_info; /* Codestream information structure */
|
||||
char indexfilename[OPJ_PATH_LEN]; /* index file name */
|
||||
OPJ_INT32 l_tile_x0,l_tile_y0;
|
||||
OPJ_UINT32 l_tile_width,l_tile_height,l_nb_tiles_x,l_nb_tiles_y;
|
||||
|
||||
/* configure the event callbacks (not required) */
|
||||
|
||||
/* FIXME configure the event callbacks (not required) */
|
||||
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
|
||||
event_mgr.error_handler = error_callback;
|
||||
event_mgr.warning_handler = warning_callback;
|
||||
event_mgr.info_handler = info_callback;
|
||||
event_mgr.client_data = stderr;
|
||||
|
||||
/* set decoding parameters to default values */
|
||||
opj_set_default_decoder_parameters(¶meters);
|
||||
|
@ -347,7 +351,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
/* parse input and get user encoding parameters */
|
||||
if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize reading of directory */
|
||||
|
@ -360,39 +364,36 @@ int main(int argc, char *argv[])
|
|||
dirptr->filename = (char**) malloc(num_images*sizeof(char*));
|
||||
|
||||
if(!dirptr->filename_buf){
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
for(i=0;i<num_images;i++){
|
||||
dirptr->filename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN;
|
||||
}
|
||||
}
|
||||
if(load_images(dirptr,img_fol.imgdirpath)==1){
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (num_images==0){
|
||||
fprintf(stdout,"Folder is empty\n");
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}else{
|
||||
num_images=1;
|
||||
}
|
||||
|
||||
//
|
||||
if (parameters.outfile[0] != 0)
|
||||
{
|
||||
fout = fopen(parameters.outfile,"w");
|
||||
if (!fout)
|
||||
{
|
||||
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.outfile);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (parameters.outfile[0] != 0){
|
||||
fout = fopen(parameters.outfile,"w");
|
||||
if (!fout){
|
||||
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.outfile);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
fout = stdout;
|
||||
fout = stdout;
|
||||
|
||||
/*Encoding image one by one*/
|
||||
for(imageno = 0; imageno < num_images ; imageno++)
|
||||
{
|
||||
for(imageno = 0; imageno < num_images ; imageno++){
|
||||
image = NULL;
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
|
@ -403,182 +404,118 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
/*NEW V2 STYLE*/
|
||||
/* read the input file and put it in memory */
|
||||
/* ---------------------------------------- */
|
||||
fsrc = fopen(parameters.infile, "rb");
|
||||
if (!fsrc) {
|
||||
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fseek(fsrc, 0, SEEK_END);
|
||||
file_length = ftell(fsrc);
|
||||
fseek(fsrc, 0, SEEK_SET);
|
||||
src = (unsigned char *) malloc(file_length);
|
||||
if (fread(src, 1, file_length, fsrc) != (size_t)file_length)
|
||||
{
|
||||
free(src);
|
||||
fclose(fsrc);
|
||||
fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n");
|
||||
return 1;
|
||||
}
|
||||
fclose(fsrc);
|
||||
|
||||
|
||||
cio = opj_stream_create_default_file_stream(fsrc,1);
|
||||
|
||||
|
||||
/* decode the code-stream */
|
||||
/* ---------------------- */
|
||||
|
||||
switch(parameters.decod_format) {
|
||||
case J2K_CFMT:
|
||||
{
|
||||
/* JPEG-2000 codestream */
|
||||
case J2K_CFMT:
|
||||
{ /* JPEG-2000 codestream */
|
||||
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress(CODEC_J2K);
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress_v2(CODEC_J2K);
|
||||
break;
|
||||
}
|
||||
case JP2_CFMT:
|
||||
{ /* JPEG 2000 compressed image data */
|
||||
|
||||
/* catch events using our callbacks and give a local context */
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress_v2(CODEC_JP2);
|
||||
break;
|
||||
}
|
||||
case JPT_CFMT:
|
||||
{ /* JPEG 2000, JPIP */
|
||||
|
||||
/* setup the decoder decoding parameters using user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress_v2(CODEC_JPT);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "skipping file..\n");
|
||||
opj_stream_destroy(cio);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
/* FIXME catch events using our callbacks and give a local context */
|
||||
//opj_set_event_mgr_v2(dinfo, &event_mgr, stderr);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
if (*indexfilename) // If need to extract codestream information
|
||||
|
||||
|
||||
/* setup the decoder decoding parameters using user parameters */
|
||||
opj_setup_decoder_v2(dinfo, ¶meters, &event_mgr);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
/* if (*indexfilename) // If need to extract codestream information
|
||||
image = opj_decode_with_info(dinfo, cio, &cstr_info);
|
||||
else
|
||||
image = opj_decode(dinfo, cio);
|
||||
if(!image) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
bResult = opj_read_header( dinfo,
|
||||
&image,
|
||||
&l_tile_x0,
|
||||
&l_tile_y0,
|
||||
&l_tile_width,
|
||||
&l_tile_height,
|
||||
&l_nb_tiles_x,
|
||||
&l_nb_tiles_y,
|
||||
cio);
|
||||
|
||||
if(!bResult){
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to read header\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (parameters.decod_format == J2K_CFMT){
|
||||
/* dump image */
|
||||
j2k_dump_image(fout, image);
|
||||
|
||||
j2k_dump_image(fout, image);
|
||||
/* dump cp */
|
||||
j2k_dump_cp(fout, image, ((opj_j2k_t*)dinfo->j2k_handle)->cp);
|
||||
|
||||
/* close the byte stream */
|
||||
opj_cio_close(cio);
|
||||
|
||||
/* Write the index to disk */
|
||||
if (*indexfilename) {
|
||||
opj_bool bSuccess;
|
||||
bSuccess = write_index_file(&cstr_info, indexfilename);
|
||||
if (bSuccess) {
|
||||
fprintf(stderr, "Failed to output index file\n");
|
||||
}
|
||||
}
|
||||
//j2k_dump_cp(stdout, image, dinfo->m_codec);
|
||||
//j2k_dump_cp(fout, image, ((opj_j2k_t*)dinfo->j2k_handle)->cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case JP2_CFMT:
|
||||
{
|
||||
/* JPEG 2000 compressed image data */
|
||||
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress(CODEC_JP2);
|
||||
|
||||
/* catch events using our callbacks and give a local context */
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
|
||||
/* setup the decoder decoding parameters using the current image and user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
if (*indexfilename) // If need to extract codestream information
|
||||
image = opj_decode_with_info(dinfo, cio, &cstr_info);
|
||||
else
|
||||
image = opj_decode(dinfo, cio);
|
||||
if(!image) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
return 1;
|
||||
}
|
||||
else if (parameters.decod_format == JP2_CFMT){
|
||||
/* dump image */
|
||||
if(image->icc_profile_buf)
|
||||
{
|
||||
free(image->icc_profile_buf); image->icc_profile_buf = NULL;
|
||||
}
|
||||
j2k_dump_image(fout, image);
|
||||
|
||||
if(image->icc_profile_buf){
|
||||
free(image->icc_profile_buf);
|
||||
image->icc_profile_buf = NULL;
|
||||
}
|
||||
j2k_dump_image(fout, image);
|
||||
/* dump cp */
|
||||
j2k_dump_cp(fout, image, ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp);
|
||||
|
||||
/* close the byte stream */
|
||||
opj_cio_close(cio);
|
||||
|
||||
/* Write the index to disk */
|
||||
if (*indexfilename) {
|
||||
opj_bool bSuccess;
|
||||
bSuccess = write_index_file(&cstr_info, indexfilename);
|
||||
if (bSuccess) {
|
||||
fprintf(stderr, "Failed to output index file\n");
|
||||
}
|
||||
}
|
||||
//j2k_dump_cp(stdout, image, dinfo->m_codec);
|
||||
//j2k_dump_cp(fout, image, ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp);
|
||||
}
|
||||
break;
|
||||
|
||||
case JPT_CFMT:
|
||||
{
|
||||
/* JPEG 2000, JPIP */
|
||||
/* close the byte stream */
|
||||
opj_stream_destroy(cio);
|
||||
fclose(fsrc);
|
||||
|
||||
/* get a decoder handle */
|
||||
dinfo = opj_create_decompress(CODEC_JPT);
|
||||
|
||||
/* catch events using our callbacks and give a local context */
|
||||
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
|
||||
|
||||
/* setup the decoder decoding parameters using user parameters */
|
||||
opj_setup_decoder(dinfo, ¶meters);
|
||||
|
||||
/* open a byte stream */
|
||||
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
|
||||
|
||||
/* decode the stream and fill the image structure */
|
||||
if (*indexfilename) // If need to extract codestream information
|
||||
image = opj_decode_with_info(dinfo, cio, &cstr_info);
|
||||
/* Write the index to disk */
|
||||
if (*indexfilename) {
|
||||
char bSuccess;
|
||||
bSuccess = write_index_file(&cstr_info, indexfilename);
|
||||
if (bSuccess) {
|
||||
fprintf(stderr, "Failed to output index file\n");
|
||||
ret = EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
image = opj_decode(dinfo, cio);
|
||||
if(!image) {
|
||||
fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
|
||||
opj_destroy_decompress(dinfo);
|
||||
opj_cio_close(cio);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* close the byte stream */
|
||||
opj_cio_close(cio);
|
||||
|
||||
/* Write the index to disk */
|
||||
if (*indexfilename) {
|
||||
opj_bool bSuccess;
|
||||
bSuccess = write_index_file(&cstr_info, indexfilename);
|
||||
if (bSuccess) {
|
||||
fprintf(stderr, "Failed to output index file\n");
|
||||
}
|
||||
}
|
||||
ret = EXIT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "skipping file..\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* free the memory containing the code-stream */
|
||||
free(src);
|
||||
src = NULL;
|
||||
else
|
||||
ret = EXIT_SUCCESS;
|
||||
|
||||
/* free remaining structures */
|
||||
if(dinfo) {
|
||||
opj_destroy_decompress(dinfo);
|
||||
if (dinfo) {
|
||||
opj_destroy_codec(dinfo);
|
||||
}
|
||||
/* free codestream information structure */
|
||||
if (*indexfilename)
|
||||
|
@ -587,10 +524,11 @@ int main(int argc, char *argv[])
|
|||
opj_image_destroy(image);
|
||||
|
||||
}
|
||||
/*NEW V2 STYLE*/
|
||||
|
||||
fclose(fout);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -662,9 +600,9 @@ static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) {
|
|||
fprintf(fd, "\n");
|
||||
}
|
||||
fprintf(fd, " }\n");
|
||||
}
|
||||
} /*end of component*/
|
||||
fprintf(fd, " }\n");
|
||||
}
|
||||
} /*end of tile */
|
||||
fprintf(fd, "}\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ SET(OPENJPEG_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/ppix_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/thix_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tpix_manager.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/function_list.c
|
||||
)
|
||||
|
||||
# Build the library
|
||||
|
|
|
@ -188,4 +188,790 @@ void cio_skip(opj_cio_t *cio, int n) {
|
|||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
*/
|
||||
void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
memcpy(p_buffer,l_data_ptr,p_nb_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
* @return the number of bytes written or -1 if an error occured
|
||||
*/
|
||||
void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1;
|
||||
OPJ_UINT32 i;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
for (i=0;i<p_nb_bytes;++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occured.
|
||||
*/
|
||||
void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
*p_value = 0;
|
||||
memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occured.
|
||||
*/
|
||||
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1;
|
||||
OPJ_UINT32 i;
|
||||
|
||||
assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32));
|
||||
|
||||
*p_value = 0;
|
||||
for (i=0;i<p_nb_bytes;++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @return the number of bytes written or -1 if an error occured
|
||||
*/
|
||||
void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
|
||||
memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT64));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT64) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT64));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT64)-1;
|
||||
OPJ_UINT32 i;
|
||||
for (i=0;i<sizeof(OPJ_FLOAT64);++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @return the number of bytes written or -1 if an error occured
|
||||
*/
|
||||
void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value);
|
||||
memcpy(p_buffer,l_data_ptr,sizeof(OPJ_FLOAT32));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value)
|
||||
{
|
||||
const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + sizeof(OPJ_FLOAT32) - 1;
|
||||
OPJ_UINT32 i;
|
||||
for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
|
||||
*(p_buffer++) = *(l_data_ptr--);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value);
|
||||
memcpy(l_data_ptr,p_buffer,sizeof(OPJ_FLOAT32));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value)
|
||||
{
|
||||
OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + sizeof(OPJ_FLOAT32)-1;
|
||||
OPJ_UINT32 i;
|
||||
for (i=0;i<sizeof(OPJ_FLOAT32);++i) {
|
||||
*(l_data_ptr--) = *(p_buffer++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
|
||||
* @return a stream object.
|
||||
*/
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size,opj_bool l_is_input)
|
||||
{
|
||||
opj_stream_private_t * l_stream = 00;
|
||||
l_stream = (opj_stream_private_t*) opj_malloc(sizeof(opj_stream_private_t));
|
||||
if (! l_stream) {
|
||||
return 00;
|
||||
}
|
||||
|
||||
memset(l_stream,0,sizeof(opj_stream_private_t));
|
||||
l_stream->m_buffer_size = p_size;
|
||||
l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_size);
|
||||
if (! l_stream->m_stored_data) {
|
||||
opj_free(l_stream);
|
||||
return 00;
|
||||
}
|
||||
|
||||
l_stream->m_current_data = l_stream->m_stored_data;
|
||||
|
||||
if (l_is_input) {
|
||||
l_stream->m_status |= opj_stream_e_input;
|
||||
l_stream->m_opj_skip = opj_stream_read_skip;
|
||||
l_stream->m_opj_seek = opj_stream_read_seek;
|
||||
}
|
||||
else {
|
||||
l_stream->m_status |= opj_stream_e_output;
|
||||
l_stream->m_opj_skip = opj_stream_write_skip;
|
||||
l_stream->m_opj_seek = opj_stream_write_seek;
|
||||
}
|
||||
|
||||
l_stream->m_read_fn = opj_stream_default_read;
|
||||
l_stream->m_write_fn = opj_stream_default_write;
|
||||
l_stream->m_skip_fn = opj_stream_default_skip;
|
||||
l_stream->m_seek_fn = opj_stream_default_seek;
|
||||
|
||||
return (opj_stream_t *) l_stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
|
||||
* @return a stream object.
|
||||
*/
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_default_create(opj_bool l_is_input)
|
||||
{
|
||||
return opj_stream_create(J2K_STREAM_CHUNK_SIZE,l_is_input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
|
||||
* close its own implementation of the stream.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if (l_stream) {
|
||||
opj_free(l_stream->m_stored_data);
|
||||
l_stream->m_stored_data = 00;
|
||||
opj_free(l_stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a read function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a read function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if
|
||||
((!l_stream) || (! (l_stream->m_status & opj_stream_e_input)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
l_stream->m_read_fn = p_function;
|
||||
}
|
||||
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if
|
||||
(!l_stream)
|
||||
{
|
||||
return;
|
||||
}
|
||||
l_stream->m_seek_fn = p_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a write function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a write function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if
|
||||
((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
l_stream->m_write_fn = p_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a skip function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a skip function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
if
|
||||
(! l_stream)
|
||||
{
|
||||
return;
|
||||
}
|
||||
l_stream->m_skip_fn = p_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given data to be used as a user data for the stream.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_data the data to set.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data)
|
||||
{
|
||||
opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream;
|
||||
l_stream->m_user_data = p_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads some bytes from the stream.
|
||||
* @param p_stream the stream to read data from.
|
||||
* @param p_buffer pointer to the data buffer that will receive the data.
|
||||
* @param p_size number of bytes to read.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_UINT32 l_read_nb_bytes = 0;
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer >= p_size)
|
||||
{
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
l_read_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += p_size;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
|
||||
// we are now in the case when the remaining data if not sufficient
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_end)
|
||||
{
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : -1;
|
||||
}
|
||||
|
||||
// the flag is not set, we copy data and then do an actual read on the stream
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer)
|
||||
{
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* case where we are already at the end of the buffer
|
||||
so reset the m_current_data to point to the start of the
|
||||
stored buffer to get ready to read from disk*/
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
}
|
||||
|
||||
|
||||
while(1){
|
||||
// we should read less than a chunk -> read a chunk
|
||||
if
|
||||
(p_size < p_stream->m_buffer_size)
|
||||
{
|
||||
// we should do an actual read on the media
|
||||
p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,p_stream->m_buffer_size,p_stream->m_user_data);
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer == -1)
|
||||
{
|
||||
// end of stream
|
||||
#ifdef TODO_MSD
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
#endif
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_status |= opj_stream_e_end;
|
||||
// end of stream
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : -1;
|
||||
}
|
||||
else if
|
||||
(p_stream->m_bytes_in_buffer < p_size)
|
||||
{
|
||||
// not enough data
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_read_nb_bytes += p_size;
|
||||
memcpy(p_buffer,p_stream->m_current_data,p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
p_stream->m_byte_offset += p_size;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// direct read on the dest buffer
|
||||
p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data);
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer == -1)
|
||||
{
|
||||
// end of stream
|
||||
#ifdef TODO_MSD
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
#endif
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_status |= opj_stream_e_end;
|
||||
// end of stream
|
||||
return l_read_nb_bytes ? l_read_nb_bytes : -1;
|
||||
}
|
||||
else if
|
||||
(p_stream->m_bytes_in_buffer < p_size)
|
||||
{
|
||||
// not enough data
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += p_stream->m_bytes_in_buffer;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have read the exact size
|
||||
l_read_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_byte_offset += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
return l_read_nb_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes some bytes from the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_buffer pointer to the data buffer holds the data to be writtent.
|
||||
* @param p_size number of bytes to write.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes writtent, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_UINT32 l_remaining_bytes = 0;
|
||||
OPJ_UINT32 l_write_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_error)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer;
|
||||
// we have more memory than required
|
||||
if
|
||||
(l_remaining_bytes >= p_size)
|
||||
{
|
||||
memcpy(p_stream->m_current_data,p_buffer,p_size);
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer += p_size;
|
||||
l_write_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += p_size;
|
||||
return l_write_nb_bytes;
|
||||
}
|
||||
|
||||
// we copy data and then do an actual read on the stream
|
||||
if
|
||||
(l_remaining_bytes)
|
||||
{
|
||||
l_write_nb_bytes += l_remaining_bytes;
|
||||
memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes);
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_buffer += l_remaining_bytes;
|
||||
p_size -= l_remaining_bytes;
|
||||
p_stream->m_bytes_in_buffer += l_remaining_bytes;
|
||||
p_stream->m_byte_offset += l_remaining_bytes;
|
||||
}
|
||||
if
|
||||
(! opj_stream_flush(p_stream, p_event_mgr))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the content of the stream buffer to the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes written, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
// the number of bytes written on the media.
|
||||
OPJ_UINT32 l_current_write_nb_bytes = 0;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
|
||||
while
|
||||
(p_stream->m_bytes_in_buffer)
|
||||
{
|
||||
// we should do an actual write on the media
|
||||
l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,p_stream->m_bytes_in_buffer,p_stream->m_user_data);
|
||||
if
|
||||
(l_current_write_nb_bytes == -1)
|
||||
{
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
#ifdef TODO_MSD
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Error on writting stream!\n");
|
||||
#endif
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
p_stream->m_current_data += l_current_write_nb_bytes;
|
||||
p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes;
|
||||
}
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
OPJ_SIZE_T l_skip_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_current_skip_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer >= p_size)
|
||||
{
|
||||
p_stream->m_current_data += p_size;
|
||||
p_stream->m_bytes_in_buffer -= p_size;
|
||||
l_skip_nb_bytes += p_size;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
// we are now in the case when the remaining data if not sufficient
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_end)
|
||||
{
|
||||
l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
|
||||
}
|
||||
|
||||
// the flag is not set, we copy data and then do an actual skip on the stream
|
||||
if
|
||||
(p_stream->m_bytes_in_buffer)
|
||||
{
|
||||
l_skip_nb_bytes += p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_size -= p_stream->m_bytes_in_buffer;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
}
|
||||
|
||||
while
|
||||
(p_size > 0)
|
||||
{
|
||||
// we should do an actual skip on the media
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
if
|
||||
(l_current_skip_nb_bytes == (OPJ_SIZE_T) -1)
|
||||
{
|
||||
#ifdef TODO_MSD
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n");
|
||||
# endif
|
||||
p_stream->m_status |= opj_stream_e_end;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
// end if stream
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
}
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
opj_bool l_is_written = 0;
|
||||
OPJ_SIZE_T l_current_skip_nb_bytes = 0;
|
||||
OPJ_SIZE_T l_skip_nb_bytes = 0;
|
||||
|
||||
if
|
||||
(p_stream->m_status & opj_stream_e_error)
|
||||
{
|
||||
return (OPJ_SIZE_T) -1;
|
||||
}
|
||||
|
||||
// we should flush data
|
||||
l_is_written = opj_stream_flush (p_stream, p_event_mgr);
|
||||
if
|
||||
(! l_is_written)
|
||||
{
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
p_stream->m_current_data = p_stream->m_current_data;
|
||||
return (OPJ_SIZE_T) -1;
|
||||
}
|
||||
// then skip
|
||||
|
||||
while
|
||||
(p_size > 0)
|
||||
{
|
||||
// we should do an actual skip on the media
|
||||
l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data);
|
||||
if
|
||||
(l_current_skip_nb_bytes == (OPJ_SIZE_T)-1)
|
||||
{
|
||||
#ifdef TODO_MSD
|
||||
opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n");
|
||||
#endif
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
// end if stream
|
||||
return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1;
|
||||
}
|
||||
p_size -= l_current_skip_nb_bytes;
|
||||
l_skip_nb_bytes += l_current_skip_nb_bytes;
|
||||
}
|
||||
p_stream->m_byte_offset += l_skip_nb_bytes;
|
||||
return l_skip_nb_bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the byte offset on the stream (similar to ftell).
|
||||
*
|
||||
* @param p_stream the stream to get the information from.
|
||||
*
|
||||
* @return the current position of the stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_byte_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
if
|
||||
(! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
|
||||
{
|
||||
p_stream->m_status |= opj_stream_e_end;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset stream status
|
||||
p_stream->m_status &= (~opj_stream_e_end);
|
||||
p_stream->m_byte_offset = p_size;
|
||||
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr)
|
||||
{
|
||||
if
|
||||
(! opj_stream_flush(p_stream,p_event_mgr))
|
||||
{
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
p_stream->m_current_data = p_stream->m_stored_data;
|
||||
p_stream->m_bytes_in_buffer = 0;
|
||||
|
||||
if
|
||||
(! p_stream->m_seek_fn(p_size,p_stream->m_user_data))
|
||||
{
|
||||
p_stream->m_status |= opj_stream_e_error;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_stream->m_byte_offset = p_size;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Seeks a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr)
|
||||
{
|
||||
return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the given stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream)
|
||||
{
|
||||
return p_stream->m_seek_fn != opj_stream_default_seek;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return (OPJ_UINT32) -1;
|
||||
}
|
||||
OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return (OPJ_UINT32) -1;
|
||||
}
|
||||
OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return (OPJ_SIZE_T) -1;
|
||||
}
|
||||
|
||||
opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ The functions in CIO.C have for goal to realize a byte input / output process.
|
|||
/** @defgroup CIO CIO - byte input-output stream */
|
||||
/*@{*/
|
||||
|
||||
#include "opj_config.h"
|
||||
|
||||
/** @name Exported functions (see also openjpeg.h) */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -82,5 +84,312 @@ void cio_skip(opj_cio_t *cio, int n);
|
|||
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(OPJ_BIG_ENDIAN)
|
||||
#if !defined(OPJ_LITTLE_ENDIAN)
|
||||
#define opj_write_bytes opj_write_bytes_BE
|
||||
#define opj_read_bytes opj_read_bytes_BE
|
||||
#define opj_write_double opj_write_double_BE
|
||||
#define opj_read_double opj_read_double_BE
|
||||
#define opj_write_float opj_write_float_BE
|
||||
#define opj_read_float opj_read_float_BE
|
||||
#else
|
||||
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both."
|
||||
#endif
|
||||
#else
|
||||
#if defined(OPJ_LITTLE_ENDIAN)
|
||||
#define opj_write_bytes opj_write_bytes_LE
|
||||
#define opj_read_bytes opj_read_bytes_LE
|
||||
#define opj_write_double opj_write_double_LE
|
||||
#define opj_read_double opj_read_double_LE
|
||||
#define opj_write_float opj_write_float_LE
|
||||
#define opj_read_float opj_read_float_LE
|
||||
#else
|
||||
#error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not none."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
opj_stream_e_output = 0x1,
|
||||
opj_stream_e_input = 0x2,
|
||||
opj_stream_e_end = 0x4,
|
||||
opj_stream_e_error = 0x8
|
||||
}
|
||||
opj_stream_flag ;
|
||||
|
||||
/**
|
||||
Byte input-output stream.
|
||||
*/
|
||||
typedef struct opj_stream_private
|
||||
{
|
||||
/**
|
||||
* User data, be it files, ... The actual data depends on the type of the stream.
|
||||
*/
|
||||
void * m_user_data;
|
||||
|
||||
/**
|
||||
* Pointer to actual read function (NULL at the initialization of the cio.
|
||||
*/
|
||||
opj_stream_read_fn m_read_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual write function (NULL at the initialization of the cio.
|
||||
*/
|
||||
opj_stream_write_fn m_write_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual skip function (NULL at the initialization of the cio.
|
||||
* There is no seek function to prevent from back and forth slow procedures.
|
||||
*/
|
||||
opj_stream_skip_fn m_skip_fn;
|
||||
|
||||
/**
|
||||
* Pointer to actual seek function (if available).
|
||||
*/
|
||||
opj_stream_seek_fn m_seek_fn;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Actual data stored into the stream if readed from. Data is read by chunk of fixed size.
|
||||
* you should never access this data directly.
|
||||
*/
|
||||
OPJ_BYTE * m_stored_data;
|
||||
|
||||
/**
|
||||
* Pointer to the current read data.
|
||||
*/
|
||||
OPJ_BYTE * m_current_data;
|
||||
|
||||
OPJ_SIZE_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_SIZE_T , struct opj_event_mgr *);
|
||||
|
||||
opj_bool (* m_opj_seek) (struct opj_stream_private * , OPJ_SIZE_T , struct opj_event_mgr *);
|
||||
|
||||
/**
|
||||
* number of bytes containing in the buffer.
|
||||
*/
|
||||
OPJ_UINT32 m_bytes_in_buffer;
|
||||
|
||||
/**
|
||||
* The number of bytes read/written.
|
||||
*/
|
||||
OPJ_SIZE_T m_byte_offset;
|
||||
|
||||
/**
|
||||
* The size of the buffer.
|
||||
*/
|
||||
OPJ_UINT32 m_buffer_size;
|
||||
|
||||
/**
|
||||
* Flags to tell the status of the stream.
|
||||
*/
|
||||
OPJ_UINT32 m_status;
|
||||
|
||||
}
|
||||
opj_stream_private_t;
|
||||
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
*/
|
||||
void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occured.
|
||||
*/
|
||||
void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
* @param p_nb_bytes the number of bytes to write
|
||||
* @return the number of bytes written or -1 if an error occured
|
||||
*/
|
||||
void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
* @param p_nb_bytes the nb bytes to read.
|
||||
* @return the number of bytes read or -1 if an error occured.
|
||||
*/
|
||||
void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes);
|
||||
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
|
||||
|
||||
/***
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to read data from.
|
||||
* @param p_value pointer to the value that will store the data.
|
||||
*/
|
||||
void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value);
|
||||
|
||||
/**
|
||||
* Write some bytes to the given data buffer, this function is used in Little Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
|
||||
|
||||
/***
|
||||
* Write some bytes to the given data buffer, this function is used in Big Endian cpus.
|
||||
* @param p_buffer pointer the data buffer to write data to.
|
||||
* @param p_value the value to write
|
||||
*/
|
||||
void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value);
|
||||
|
||||
/**
|
||||
* Reads some bytes from the stream.
|
||||
* @param p_stream the stream to read data from.
|
||||
* @param p_buffer pointer to the data buffer that will receive the data.
|
||||
* @param p_size number of bytes to read.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes read, or -1 if an error occured or if the stream is at the end.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes some bytes to the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_buffer pointer to the data buffer holds the data to be writtent.
|
||||
* @param p_size number of bytes to write.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes writtent, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Writes the content of the stream buffer to the stream.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the data could be flushed, false else.
|
||||
*/
|
||||
opj_bool opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells the byte offset on the stream (similar to ftell).
|
||||
*
|
||||
* @param p_stream the stream to get the information from.
|
||||
*
|
||||
* @return the current position o fthe stream.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Skips a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return the number of bytes skipped, or -1 if an error occured.
|
||||
*/
|
||||
opj_bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Seeks a number of bytes from the stream.
|
||||
* @param p_stream the stream to skip data from.
|
||||
* @param p_size the number of bytes to skip.
|
||||
* @param p_event_mgr the user event manager to be notified of special events.
|
||||
* @return true if the stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr);
|
||||
|
||||
/**
|
||||
* Tells if the given stream is seekable.
|
||||
*/
|
||||
opj_bool opj_stream_has_seek (const opj_stream_private_t * p_stream);
|
||||
|
||||
OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data);
|
||||
OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data);
|
||||
OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
opj_bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data);
|
||||
|
||||
|
||||
|
||||
#endif /* __CIO_H */
|
||||
|
||||
|
|
|
@ -118,7 +118,11 @@ static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno
|
|||
/**
|
||||
Inverse wavelet transform in 2-D.
|
||||
*/
|
||||
#ifdef OPJ_V1
|
||||
static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn);
|
||||
#endif
|
||||
static opj_bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
@ -375,13 +379,21 @@ void dwt_encode(opj_tcd_tilecomp_t * tilec) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPJ_V1
|
||||
/* <summary> */
|
||||
/* Inverse 5-3 wavelet transform in 2-D. */
|
||||
/* </summary> */
|
||||
void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) {
|
||||
dwt_decode_tile(tilec, numres, &dwt_decode_1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <summary> */
|
||||
/* Inverse 5-3 wavelet transform in 2-D. */
|
||||
/* </summary> */
|
||||
opj_bool dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
|
||||
return dwt_decode_tile(tilec, numres, &dwt_decode_1);
|
||||
}
|
||||
|
||||
|
||||
/* <summary> */
|
||||
|
@ -495,7 +507,7 @@ void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPJ_V1
|
||||
/* <summary> */
|
||||
/* Determine maximum computed resolution level for inverse wavelet transform */
|
||||
/* </summary> */
|
||||
|
@ -511,8 +523,24 @@ static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) {
|
|||
}
|
||||
return mr ;
|
||||
}
|
||||
#endif
|
||||
/* <summary> */
|
||||
/* Determine maximum computed resolution level for inverse wavelet transform */
|
||||
/* </summary> */
|
||||
static OPJ_UINT32 dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) {
|
||||
OPJ_UINT32 mr = 0;
|
||||
OPJ_UINT32 w;
|
||||
while( --i ) {
|
||||
++r;
|
||||
if( mr < ( w = r->x1 - r->x0 ) )
|
||||
mr = w ;
|
||||
if( mr < ( w = r->y1 - r->y0 ) )
|
||||
mr = w ;
|
||||
}
|
||||
return mr ;
|
||||
}
|
||||
|
||||
|
||||
#ifdef OPJ_V1
|
||||
/* <summary> */
|
||||
/* Inverse wavelet transform in 2-D. */
|
||||
/* </summary> */
|
||||
|
@ -527,7 +555,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
|
|||
|
||||
int w = tilec->x1 - tilec->x0;
|
||||
|
||||
h.mem = (int*)opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int));
|
||||
h.mem = (int*)opj_aligned_malloc(dwt_max_resolution(tr, numres) * sizeof(int));
|
||||
v.mem = h.mem;
|
||||
|
||||
while( --numres) {
|
||||
|
@ -564,6 +592,67 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1
|
|||
}
|
||||
opj_aligned_free(h.mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* <summary> */
|
||||
/* Inverse wavelet transform in 2-D. */
|
||||
/* </summary> */
|
||||
static opj_bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
|
||||
dwt_t h;
|
||||
dwt_t v;
|
||||
|
||||
opj_tcd_resolution_t* tr = tilec->resolutions;
|
||||
|
||||
OPJ_UINT32 rw = tr->x1 - tr->x0; /* width of the resolution level computed */
|
||||
OPJ_UINT32 rh = tr->y1 - tr->y0; /* height of the resolution level computed */
|
||||
|
||||
OPJ_UINT32 w = tilec->x1 - tilec->x0;
|
||||
|
||||
h.mem = (OPJ_INT32*)
|
||||
opj_aligned_malloc(dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
|
||||
if
|
||||
(! h.mem)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
v.mem = h.mem;
|
||||
|
||||
while( --numres) {
|
||||
OPJ_INT32 * restrict tiledp = tilec->data;
|
||||
OPJ_UINT32 j;
|
||||
|
||||
++tr;
|
||||
h.sn = rw;
|
||||
v.sn = rh;
|
||||
|
||||
rw = tr->x1 - tr->x0;
|
||||
rh = tr->y1 - tr->y0;
|
||||
|
||||
h.dn = rw - h.sn;
|
||||
h.cas = tr->x0 % 2;
|
||||
|
||||
for(j = 0; j < rh; ++j) {
|
||||
dwt_interleave_h(&h, &tiledp[j*w]);
|
||||
(dwt_1D)(&h);
|
||||
memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
|
||||
}
|
||||
|
||||
v.dn = rh - v.sn;
|
||||
v.cas = tr->y0 % 2;
|
||||
|
||||
for(j = 0; j < rw; ++j){
|
||||
OPJ_UINT32 k;
|
||||
dwt_interleave_v(&v, &tiledp[j], w);
|
||||
(dwt_1D)(&v);
|
||||
for(k = 0; k < rh; ++k) {
|
||||
tiledp[k * w + j] = v.mem[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
opj_aligned_free(h.mem);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){
|
||||
float* restrict bi = (float*) (w->wavelet + w->cas);
|
||||
|
@ -769,10 +858,13 @@ static void v4dwt_decode(v4dwt_t* restrict dwt){
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// KEEP TRUNK VERSION + return type of v2 because rev557
|
||||
/* <summary> */
|
||||
/* Inverse 9-7 wavelet transform in 2-D. */
|
||||
/* </summary> */
|
||||
void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
|
||||
// V1 void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
|
||||
opj_bool dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
|
||||
v4dwt_t h;
|
||||
v4dwt_t v;
|
||||
|
||||
|
@ -783,7 +875,7 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
|
|||
|
||||
int w = tilec->x1 - tilec->x0;
|
||||
|
||||
h.wavelet = (v4*) opj_aligned_malloc((dwt_decode_max_resolution(res, numres)+5) * sizeof(v4));
|
||||
h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution(res, numres)+5) * sizeof(v4));
|
||||
v.wavelet = h.wavelet;
|
||||
|
||||
while( --numres) {
|
||||
|
@ -854,5 +946,6 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
|
|||
}
|
||||
|
||||
opj_aligned_free(h.wavelet);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,12 @@ Apply a reversible inverse DWT transform to a component of an image.
|
|||
@param tilec Tile component information (current tile)
|
||||
@param numres Number of resolution levels to decode
|
||||
*/
|
||||
#ifdef OPJ_V1
|
||||
void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres);
|
||||
#endif
|
||||
opj_bool dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres);
|
||||
|
||||
|
||||
/**
|
||||
Get the gain of a subband for the reversible 5-3 DWT.
|
||||
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
|
||||
|
@ -80,12 +85,14 @@ Apply an irreversible DWT transform to a component of an image.
|
|||
*/
|
||||
void dwt_encode_real(opj_tcd_tilecomp_t * tilec);
|
||||
/**
|
||||
KEEP TRUNK VERSION + return type of v2 because rev557
|
||||
Inverse 9-7 wavelet transform in 2-D.
|
||||
Apply an irreversible inverse DWT transform to a component of an image.
|
||||
@param tilec Tile component information (current tile)
|
||||
@param numres Number of resolution levels to decode
|
||||
*/
|
||||
void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres);
|
||||
// V1 void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres);
|
||||
opj_bool dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres);
|
||||
/**
|
||||
Get the gain of a subband for the irreversible 9-7 DWT.
|
||||
@param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH)
|
||||
|
|
|
@ -120,3 +120,48 @@ opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ..
|
|||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
opj_bool opj_event_msg_v2(opj_event_mgr_t* event_mgr, int event_type, const char *fmt, ...) {
|
||||
#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */
|
||||
opj_msg_callback msg_handler = NULL;
|
||||
|
||||
if(event_mgr != NULL) {
|
||||
switch(event_type) {
|
||||
case EVT_ERROR:
|
||||
msg_handler = event_mgr->error_handler;
|
||||
break;
|
||||
case EVT_WARNING:
|
||||
msg_handler = event_mgr->warning_handler;
|
||||
break;
|
||||
case EVT_INFO:
|
||||
msg_handler = event_mgr->info_handler;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(msg_handler == NULL) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
} else {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
if ((fmt != NULL) && (event_mgr != NULL)) {
|
||||
va_list arg;
|
||||
int str_length/*, i, j*/; /* UniPG */
|
||||
char message[MSG_SIZE];
|
||||
memset(message, 0, MSG_SIZE);
|
||||
/* initialize the optional parameter list */
|
||||
va_start(arg, fmt);
|
||||
/* check the length of the format string */
|
||||
str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt);
|
||||
/* parse the format string and put the result in 'message' */
|
||||
vsprintf(message, fmt, arg); /* UniPG */
|
||||
/* deinitialize the optional parameter list */
|
||||
va_end(arg);
|
||||
|
||||
/* output the message to the user program */
|
||||
msg_handler(message, event_mgr->client_data);
|
||||
}
|
||||
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
|
|
@ -46,10 +46,13 @@ The functions in EVENT.C have for goal to send output messages (errors, warnings
|
|||
Write formatted data to a string and send the string to a user callback.
|
||||
@param cinfo Codec context info
|
||||
@param event_type Event type or callback to use to send the message
|
||||
@param fmt Format-control string (plus optionnal arguments)
|
||||
@param fmt Format-control string (plus optional arguments)
|
||||
@return Returns true if successful, returns false otherwise
|
||||
*/
|
||||
opj_bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...);
|
||||
|
||||
|
||||
opj_bool opj_event_msg_v2(opj_event_mgr_t* event_mgr, int event_type, const char *fmt, ...);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
|
@ -87,3 +87,37 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the components of the image from the coding parameters.
|
||||
*
|
||||
* @param p_image the image to update.
|
||||
* @param p_cp the coding parameters from which to update the image.
|
||||
*/
|
||||
void opj_image_comp_update(opj_image_t * p_image,const opj_cp_v2_t * p_cp)
|
||||
{
|
||||
OPJ_UINT32 i, l_width, l_height;
|
||||
OPJ_INT32 l_x0,l_y0,l_x1,l_y1;
|
||||
OPJ_INT32 l_comp_x0,l_comp_y0,l_comp_x1,l_comp_y1;
|
||||
opj_image_comp_t * l_img_comp = 00;
|
||||
|
||||
l_x0 = int_max(p_cp->tx0 , p_image->x0);
|
||||
l_y0 = int_max(p_cp->ty0 , p_image->y0);
|
||||
l_x1 = int_min(p_cp->tx0 + p_cp->tw * p_cp->tdx, p_image->x1);
|
||||
l_y1 = int_min(p_cp->ty0 + p_cp->th * p_cp->tdy, p_image->y1);
|
||||
|
||||
l_img_comp = p_image->comps;
|
||||
for (i = 0; i < p_image->numcomps; ++i) {
|
||||
l_comp_x0 = int_ceildiv(l_x0, l_img_comp->dx);
|
||||
l_comp_y0 = int_ceildiv(l_y0, l_img_comp->dy);
|
||||
l_comp_x1 = int_ceildiv(l_x1, l_img_comp->dx);
|
||||
l_comp_y1 = int_ceildiv(l_y1, l_img_comp->dy);
|
||||
l_width = int_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor);
|
||||
l_height = int_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor);
|
||||
l_img_comp->w = l_width;
|
||||
l_img_comp->h = l_height;
|
||||
l_img_comp->x0 = l_x0;
|
||||
l_img_comp->y0 = l_y0;
|
||||
++l_img_comp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
The functions in IMAGE.C have for goal to realize operations on images.
|
||||
*/
|
||||
|
||||
struct opj_image;
|
||||
struct opj_cp_v2;
|
||||
|
||||
/** @defgroup IMAGE IMAGE - Implementation of operations on images */
|
||||
/*@{*/
|
||||
|
||||
|
@ -42,6 +45,14 @@ Create an empty image
|
|||
*/
|
||||
opj_image_t* opj_image_create0(void);
|
||||
|
||||
/**
|
||||
* Updates the components of the image from the coding parameters.
|
||||
*
|
||||
* @param p_image the image to update.
|
||||
* @param p_cp the coding parameters from which to update the image.
|
||||
*/
|
||||
void opj_image_comp_update(struct opj_image * p_image,const struct opj_cp_v2 * p_cp);
|
||||
|
||||
/*@}*/
|
||||
|
||||
#endif /* __IMAGE_H */
|
||||
|
|
|
@ -50,6 +50,15 @@ Get the minimum of two integers
|
|||
static INLINE int int_min(int a, int b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the minimum of two integers
|
||||
@return Returns a if a < b else b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 uint_min(OPJ_UINT32 a, OPJ_UINT32 b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the maximum of two integers
|
||||
@return Returns a if a > b else b
|
||||
|
@ -57,6 +66,15 @@ Get the maximum of two integers
|
|||
static INLINE int int_max(int a, int b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the maximum of two integers
|
||||
@return Returns a if a > b else b
|
||||
*/
|
||||
static INLINE OPJ_UINT32 uint_max(OPJ_UINT32 a, OPJ_UINT32 b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
Clamp an integer inside an interval
|
||||
@return
|
||||
|
@ -111,6 +129,19 @@ static INLINE int int_floorlog2(int a) {
|
|||
}
|
||||
return l;
|
||||
}
|
||||
/**
|
||||
Get logarithm of an integer and round downwards
|
||||
@return Returns log2(a)
|
||||
*/
|
||||
static INLINE OPJ_UINT32 uint_floorlog2(OPJ_UINT32 a) {
|
||||
OPJ_UINT32 l;
|
||||
for (l = 0; a > 1; ++l)
|
||||
{
|
||||
a >>= 1;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
3216
libopenjpeg/j2k.c
3216
libopenjpeg/j2k.c
File diff suppressed because it is too large
Load Diff
|
@ -77,6 +77,14 @@ The functions in J2K.C have for goal to read/write the several parts of the code
|
|||
#define J2K_MS_EPH 0xff92 /**< EPH marker value */
|
||||
#define J2K_MS_CRG 0xff63 /**< CRG marker value */
|
||||
#define J2K_MS_COM 0xff64 /**< COM marker value */
|
||||
|
||||
#ifdef TODO_MS
|
||||
#define J2K_MS_CBD 0xff78 /**< CBD marker value */
|
||||
#define J2K_MS_MCC 0xff75 /**< MCC marker value */
|
||||
#define J2K_MS_MCT 0xff74 /**< MCT marker value */
|
||||
#define J2K_MS_MCO 0xff77 /**< MCO marker value */
|
||||
#endif
|
||||
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
#define J2K_MS_EPC 0xff68 /**< EPC marker value (Part 11: JPEG 2000 for Wireless) */
|
||||
|
@ -91,6 +99,8 @@ The functions in J2K.C have for goal to read/write the several parts of the code
|
|||
/* <<UniPG */
|
||||
|
||||
|
||||
struct opj_stream_private;
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
@ -128,35 +138,70 @@ typedef struct opj_stepsize {
|
|||
int mant;
|
||||
} opj_stepsize_t;
|
||||
|
||||
//OPJ_V1/**
|
||||
//Tile-component coding parameters
|
||||
//*/
|
||||
//typedef struct opj_tccp {
|
||||
// /** coding style */
|
||||
// int csty;
|
||||
// /** number of resolutions */
|
||||
// int numresolutions;
|
||||
// /** code-blocks width */
|
||||
// int cblkw;
|
||||
// /** code-blocks height */
|
||||
// int cblkh;
|
||||
// /** code-block coding style */
|
||||
// int cblksty;
|
||||
// /** discrete wavelet transform identifier */
|
||||
// int qmfbid;
|
||||
// /** quantisation style */
|
||||
// int qntsty;
|
||||
// /** stepsizes used for quantization */
|
||||
// opj_stepsize_t stepsizes[J2K_MAXBANDS];
|
||||
// /** number of guard bits */
|
||||
// int numgbits;
|
||||
// /** Region Of Interest shift */
|
||||
// int roishift;
|
||||
// /** precinct width */
|
||||
// int prcw[J2K_MAXRLVLS];
|
||||
// /** precinct height */
|
||||
// int prch[J2K_MAXRLVLS];
|
||||
//} opj_tccp_t;
|
||||
|
||||
/**
|
||||
Tile-component coding parameters
|
||||
*/
|
||||
typedef struct opj_tccp {
|
||||
typedef struct opj_tccp
|
||||
{
|
||||
/** coding style */
|
||||
int csty;
|
||||
OPJ_UINT32 csty;
|
||||
/** number of resolutions */
|
||||
int numresolutions;
|
||||
OPJ_UINT32 numresolutions;
|
||||
/** code-blocks width */
|
||||
int cblkw;
|
||||
OPJ_UINT32 cblkw;
|
||||
/** code-blocks height */
|
||||
int cblkh;
|
||||
OPJ_UINT32 cblkh;
|
||||
/** code-block coding style */
|
||||
int cblksty;
|
||||
OPJ_UINT32 cblksty;
|
||||
/** discrete wavelet transform identifier */
|
||||
int qmfbid;
|
||||
OPJ_UINT32 qmfbid;
|
||||
/** quantisation style */
|
||||
int qntsty;
|
||||
OPJ_UINT32 qntsty;
|
||||
/** stepsizes used for quantization */
|
||||
opj_stepsize_t stepsizes[J2K_MAXBANDS];
|
||||
/** number of guard bits */
|
||||
int numgbits;
|
||||
OPJ_UINT32 numgbits;
|
||||
/** Region Of Interest shift */
|
||||
int roishift;
|
||||
OPJ_INT32 roishift;
|
||||
/** precinct width */
|
||||
int prcw[J2K_MAXRLVLS];
|
||||
OPJ_UINT32 prcw[J2K_MAXRLVLS];
|
||||
/** precinct height */
|
||||
int prch[J2K_MAXRLVLS];
|
||||
} opj_tccp_t;
|
||||
OPJ_UINT32 prch[J2K_MAXRLVLS];
|
||||
/** the dc_level_shift **/
|
||||
OPJ_INT32 m_dc_level_shift;
|
||||
}
|
||||
opj_tccp_t;
|
||||
|
||||
|
||||
/**
|
||||
Tile coding parameters :
|
||||
|
@ -198,6 +243,120 @@ typedef struct opj_tcp {
|
|||
opj_tccp_t *tccps;
|
||||
} opj_tcp_t;
|
||||
|
||||
|
||||
/**
|
||||
* Type of data for storing the MCT data
|
||||
*/
|
||||
typedef enum MCT_ELEMENT_TYPE
|
||||
{
|
||||
MCT_TYPE_INT16 = 0, /** MCT data is stored as signed shorts*/
|
||||
MCT_TYPE_INT32 = 1, /** MCT data is stored as signed integers*/
|
||||
MCT_TYPE_FLOAT = 2, /** MCT data is stored as floats*/
|
||||
MCT_TYPE_DOUBLE = 3 /** MCT data is stored as doubles*/
|
||||
} J2K_MCT_ELEMENT_TYPE;
|
||||
|
||||
/**
|
||||
* Type of data for storing the MCT data
|
||||
*/
|
||||
typedef enum MCT_ARRAY_TYPE
|
||||
{
|
||||
MCT_TYPE_DEPENDENCY = 0,
|
||||
MCT_TYPE_DECORRELATION = 1,
|
||||
MCT_TYPE_OFFSET = 2
|
||||
} J2K_MCT_ARRAY_TYPE;
|
||||
|
||||
typedef struct opj_mct_data
|
||||
{
|
||||
J2K_MCT_ELEMENT_TYPE m_element_type;
|
||||
J2K_MCT_ARRAY_TYPE m_array_type;
|
||||
OPJ_UINT32 m_index;
|
||||
OPJ_BYTE * m_data;
|
||||
OPJ_UINT32 m_data_size;
|
||||
}
|
||||
opj_mct_data_t;
|
||||
|
||||
typedef struct opj_simple_mcc_decorrelation_data
|
||||
{
|
||||
OPJ_UINT32 m_index;
|
||||
OPJ_UINT32 m_nb_comps;
|
||||
opj_mct_data_t * m_decorrelation_array;
|
||||
opj_mct_data_t * m_offset_array;
|
||||
OPJ_UINT32 m_is_irreversible : 1;
|
||||
}
|
||||
opj_simple_mcc_decorrelation_data_t;
|
||||
|
||||
/**
|
||||
Tile coding parameters :
|
||||
this structure is used to store coding/decoding parameters common to all
|
||||
tiles (information like COD, COC in main header)
|
||||
*/
|
||||
typedef struct opj_tcp_v2
|
||||
{
|
||||
/** coding style */
|
||||
OPJ_UINT32 csty;
|
||||
/** progression order */
|
||||
OPJ_PROG_ORDER prg;
|
||||
/** number of layers */
|
||||
OPJ_UINT32 numlayers;
|
||||
OPJ_UINT32 num_layers_to_decode;
|
||||
/** multi-component transform identifier */
|
||||
OPJ_UINT32 mct;
|
||||
/** rates of layers */
|
||||
OPJ_FLOAT32 rates[100];
|
||||
/** number of progression order changes */
|
||||
OPJ_UINT32 numpocs;
|
||||
/** progression order changes */
|
||||
opj_poc_t pocs[32];
|
||||
/** packet header store there for futur use in t2_decode_packet */
|
||||
OPJ_BYTE *ppt_data;
|
||||
/** used to keep a track of the allocated memory */
|
||||
OPJ_BYTE *ppt_buffer;
|
||||
/** Number of bytes stored inside ppt_data*/
|
||||
OPJ_UINT32 ppt_data_size;
|
||||
/** size of ppt_data*/
|
||||
OPJ_UINT32 ppt_len;
|
||||
/** add fixed_quality */
|
||||
OPJ_FLOAT32 distoratio[100];
|
||||
/** tile-component coding parameters */
|
||||
opj_tccp_t *tccps;
|
||||
/** number of tile parts for the tile. */
|
||||
OPJ_UINT32 m_nb_tile_parts;
|
||||
/** data for the tile */
|
||||
OPJ_BYTE * m_data;
|
||||
/** size of data */
|
||||
OPJ_UINT32 m_data_size;
|
||||
/** encoding norms */
|
||||
OPJ_FLOAT64 * mct_norms;
|
||||
/** the mct decoding matrix */
|
||||
OPJ_FLOAT32 * m_mct_decoding_matrix;
|
||||
/** the mct coding matrix */
|
||||
OPJ_FLOAT32 * m_mct_coding_matrix;
|
||||
/** mct records */
|
||||
opj_mct_data_t * m_mct_records;
|
||||
/** the number of mct records. */
|
||||
OPJ_UINT32 m_nb_mct_records;
|
||||
/** the max number of mct records. */
|
||||
OPJ_UINT32 m_nb_max_mct_records;
|
||||
/** mcc records */
|
||||
opj_simple_mcc_decorrelation_data_t * m_mcc_records;
|
||||
/** the number of mct records. */
|
||||
OPJ_UINT32 m_nb_mcc_records;
|
||||
/** the max number of mct records. */
|
||||
OPJ_UINT32 m_nb_max_mcc_records;
|
||||
|
||||
|
||||
|
||||
/***** FLAGS *******/
|
||||
/** If ppt == 1 --> there was a PPT marker for the present tile */
|
||||
OPJ_UINT32 ppt : 1;
|
||||
/** indicates if a POC marker has been used O:NO, 1:YES */
|
||||
OPJ_UINT32 POC : 1;
|
||||
} opj_tcp_v2_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Coding parameters
|
||||
*/
|
||||
|
@ -308,6 +467,198 @@ typedef struct opj_cp {
|
|||
/* <<UniPG */
|
||||
} opj_cp_t;
|
||||
|
||||
typedef struct opj_encoding_param
|
||||
{
|
||||
/** Digital cinema profile*/
|
||||
OPJ_CINEMA_MODE m_cinema;
|
||||
/** Maximum rate for each component. If == 0, component size limitation is not considered */
|
||||
OPJ_UINT32 m_max_comp_size;
|
||||
/** Position of tile part flag in progression order*/
|
||||
OPJ_INT32 m_tp_pos;
|
||||
/** fixed layer */
|
||||
OPJ_INT32 *m_matrice;
|
||||
/** Flag determining tile part generation*/
|
||||
OPJ_BYTE m_tp_flag;
|
||||
/** allocation by rate/distortion */
|
||||
OPJ_UINT32 m_disto_alloc : 1;
|
||||
/** allocation by fixed layer */
|
||||
OPJ_UINT32 m_fixed_alloc : 1;
|
||||
/** add fixed_quality */
|
||||
OPJ_UINT32 m_fixed_quality : 1;
|
||||
/** Enabling Tile part generation*/
|
||||
OPJ_UINT32 m_tp_on : 1;
|
||||
}
|
||||
opj_encoding_param_t;
|
||||
|
||||
typedef struct opj_decoding_param
|
||||
{
|
||||
/** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */
|
||||
OPJ_UINT32 m_reduce;
|
||||
/** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */
|
||||
OPJ_UINT32 m_layer;
|
||||
}
|
||||
opj_decoding_param_t;
|
||||
|
||||
|
||||
/**
|
||||
Coding parameters
|
||||
*/
|
||||
typedef struct opj_cp_v2
|
||||
{
|
||||
/** Size of the image in bits*/
|
||||
/*int img_size;*/
|
||||
/** Rsiz*/
|
||||
OPJ_RSIZ_CAPABILITIES rsiz;
|
||||
/** XTOsiz */
|
||||
OPJ_UINT32 tx0; // MSD see norm
|
||||
/** YTOsiz */
|
||||
OPJ_UINT32 ty0; // MSD see norm
|
||||
/** XTsiz */
|
||||
OPJ_UINT32 tdx;
|
||||
/** YTsiz */
|
||||
OPJ_UINT32 tdy;
|
||||
/** comment */
|
||||
OPJ_CHAR *comment;
|
||||
/** number of tiles in width */
|
||||
OPJ_UINT32 tw;
|
||||
/** number of tiles in heigth */
|
||||
OPJ_UINT32 th;
|
||||
/** packet header storage original buffer */
|
||||
OPJ_BYTE *ppm_buffer;
|
||||
/** packet header store there for futur use in t2_decode_packet */
|
||||
OPJ_BYTE *ppm_data;
|
||||
/** size of the ppm_data*/
|
||||
OPJ_UINT32 ppm_len;
|
||||
/** Number of bytes actually stored inside the ppm_data */
|
||||
OPJ_UINT32 ppm_data_size;
|
||||
/** tile coding parameters */
|
||||
opj_tcp_v2_t *tcps;
|
||||
union
|
||||
{
|
||||
opj_decoding_param_t m_dec;
|
||||
opj_encoding_param_t m_enc;
|
||||
}
|
||||
m_specific_param;
|
||||
|
||||
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
/** enables writing of EPC in MH, thus activating JPWL */
|
||||
bool epc_on;
|
||||
/** enables writing of EPB, in case of activated JPWL */
|
||||
bool epb_on;
|
||||
/** enables writing of ESD, in case of activated JPWL */
|
||||
bool esd_on;
|
||||
/** enables writing of informative techniques of ESD, in case of activated JPWL */
|
||||
bool info_on;
|
||||
/** enables writing of RED, in case of activated JPWL */
|
||||
bool red_on;
|
||||
/** error protection method for MH (0,1,16,32,37-128) */
|
||||
int hprot_MH;
|
||||
/** tile number of header protection specification (>=0) */
|
||||
int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS];
|
||||
/** error protection methods for TPHs (0,1,16,32,37-128) */
|
||||
int hprot_TPH[JPWL_MAX_NO_TILESPECS];
|
||||
/** tile number of packet protection specification (>=0) */
|
||||
int pprot_tileno[JPWL_MAX_NO_PACKSPECS];
|
||||
/** packet number of packet protection specification (>=0) */
|
||||
int pprot_packno[JPWL_MAX_NO_PACKSPECS];
|
||||
/** error protection methods for packets (0,1,16,32,37-128) */
|
||||
int pprot[JPWL_MAX_NO_PACKSPECS];
|
||||
/** enables writing of ESD, (0/2/4 bytes) */
|
||||
int sens_size;
|
||||
/** sensitivity addressing size (0=auto/2/4 bytes) */
|
||||
int sens_addr;
|
||||
/** sensitivity range (0-3) */
|
||||
int sens_range;
|
||||
/** sensitivity method for MH (-1,0-7) */
|
||||
int sens_MH;
|
||||
/** tile number of sensitivity specification (>=0) */
|
||||
int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS];
|
||||
/** sensitivity methods for TPHs (-1,0-7) */
|
||||
int sens_TPH[JPWL_MAX_NO_TILESPECS];
|
||||
/** enables JPWL correction at the decoder */
|
||||
bool correct;
|
||||
/** expected number of components at the decoder */
|
||||
int exp_comps;
|
||||
/** maximum number of tiles at the decoder */
|
||||
int max_tiles;
|
||||
#endif /* USE_JPWL */
|
||||
|
||||
/******** FLAGS *********/
|
||||
/** if ppm == 1 --> there was a PPM marker*/
|
||||
OPJ_UINT32 ppm : 1;
|
||||
/** tells if the parameter is a coding or decoding one */
|
||||
OPJ_UINT32 m_is_decoder : 1;
|
||||
/* <<UniPG */
|
||||
} opj_cp_v2_t;
|
||||
|
||||
|
||||
typedef struct opj_j2k_dec
|
||||
{
|
||||
/** locate in which part of the codestream the decoder is (main header, tile header, end) */
|
||||
OPJ_UINT32 m_state;
|
||||
/**
|
||||
* store decoding parameters common to all tiles (information like COD, COC in main header)
|
||||
*/
|
||||
opj_tcp_v2_t *m_default_tcp;
|
||||
OPJ_BYTE *m_header_data;
|
||||
OPJ_UINT32 m_header_data_size;
|
||||
/** to tell the tile part length */
|
||||
OPJ_UINT32 m_sot_length;
|
||||
/** Only tiles index in the correct range will be decoded.*/
|
||||
OPJ_UINT32 m_start_tile_x;
|
||||
OPJ_UINT32 m_start_tile_y;
|
||||
OPJ_UINT32 m_end_tile_x;
|
||||
OPJ_UINT32 m_end_tile_y;
|
||||
/** to tell that a tile can be decoded. */
|
||||
OPJ_UINT32 m_can_decode : 1;
|
||||
OPJ_UINT32 m_discard_tiles : 1;
|
||||
OPJ_UINT32 m_skip_data : 1;
|
||||
|
||||
} opj_j2k_dec_t;
|
||||
|
||||
typedef struct opj_j2k_enc
|
||||
{
|
||||
/** Tile part number, regardless of poc, for each new poc, tp is reset to 1*/
|
||||
OPJ_UINT32 m_current_poc_tile_part_number; // tp_num
|
||||
|
||||
/** Tile part number currently coding, taking into account POC. m_current_tile_part_number holds the total number of tile parts while encoding the last tile part.*/
|
||||
OPJ_UINT32 m_current_tile_part_number; //cur_tp_num
|
||||
|
||||
/**
|
||||
locate the start position of the TLM marker
|
||||
after encoding the tilepart, a jump (in j2k_write_sod) is done to the TLM marker to store the value of its length.
|
||||
*/
|
||||
OPJ_SIZE_T m_tlm_start;
|
||||
/**
|
||||
* Stores the sizes of the tlm.
|
||||
*/
|
||||
OPJ_BYTE * m_tlm_sot_offsets_buffer;
|
||||
/**
|
||||
* The current offset of the tlm buffer.
|
||||
*/
|
||||
OPJ_BYTE * m_tlm_sot_offsets_current;
|
||||
|
||||
/** Total num of tile parts in whole image = num tiles* num tileparts in each tile*/
|
||||
/** used in TLMmarker*/
|
||||
OPJ_UINT32 m_total_tile_parts; // totnum_tp
|
||||
|
||||
/* encoded data for a tile */
|
||||
OPJ_BYTE * m_encoded_tile_data;
|
||||
|
||||
/* size of the encoded_data */
|
||||
OPJ_UINT32 m_encoded_tile_size;
|
||||
|
||||
/* encoded data for a tile */
|
||||
OPJ_BYTE * m_header_tile_data;
|
||||
|
||||
/* size of the encoded_data */
|
||||
OPJ_UINT32 m_header_tile_data_size;
|
||||
|
||||
|
||||
} opj_j2k_enc_t;
|
||||
|
||||
/**
|
||||
JPEG-2000 codestream reader/writer
|
||||
*/
|
||||
|
@ -368,6 +719,49 @@ typedef struct opj_j2k {
|
|||
opj_cio_t *cio;
|
||||
} opj_j2k_t;
|
||||
|
||||
struct opj_tcd_v2;
|
||||
/**
|
||||
JPEG-2000 codestream reader/writer
|
||||
*/
|
||||
typedef struct opj_j2k_v2
|
||||
{
|
||||
union
|
||||
{
|
||||
opj_j2k_dec_t m_decoder;
|
||||
opj_j2k_enc_t m_encoder;
|
||||
}
|
||||
m_specific_param;
|
||||
|
||||
/** number of the tile curently concern by coding/decoding */
|
||||
OPJ_UINT32 m_current_tile_number;
|
||||
|
||||
/** pointer to the encoded / decoded image */
|
||||
opj_image_t *m_image;
|
||||
|
||||
/** Coding parameters */
|
||||
opj_cp_v2_t m_cp;
|
||||
|
||||
/** the list of procedures to exec **/
|
||||
struct opj_procedure_list * m_procedure_list;
|
||||
|
||||
/** the list of validation procedures to follow to make sure the code is valid **/
|
||||
struct opj_procedure_list * m_validation_list;
|
||||
|
||||
/** helper used to write the index file */
|
||||
opj_codestream_info_t *cstr_info;
|
||||
|
||||
/** the current tile coder/decoder **/
|
||||
struct opj_tcd_v2 * m_tcd;
|
||||
//opj_tcd_v2_t * m_tcd;
|
||||
|
||||
OPJ_UINT32 m_is_decoder : 1;
|
||||
|
||||
}
|
||||
opj_j2k_v2_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -443,4 +837,104 @@ opj_bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_code
|
|||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* Ends the decompression procedures and possibiliy add data to be read after the
|
||||
* codestream.
|
||||
*/
|
||||
opj_bool j2k_end_decompress(opj_j2k_t *j2k, struct opj_stream_private *cio, struct opj_event_mgr * p_manager);
|
||||
|
||||
/**
|
||||
* Reads a jpeg2000 codestream header structure.
|
||||
*
|
||||
* @param cio the stream to read data from.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_manager the user event manager.
|
||||
*
|
||||
* @return true if the box is valid.
|
||||
*/
|
||||
opj_bool j2k_read_header(
|
||||
opj_j2k_v2_t *p_j2k,
|
||||
struct opj_image ** p_image,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_UINT32 * p_tile_width,
|
||||
OPJ_UINT32 * p_tile_height,
|
||||
OPJ_UINT32 * p_nb_tiles_x,
|
||||
OPJ_UINT32 * p_nb_tiles_y,
|
||||
struct opj_stream_private *cio,
|
||||
struct opj_event_mgr * p_manager
|
||||
);
|
||||
|
||||
/**
|
||||
* Destroys a jpeg2000 codec.
|
||||
*
|
||||
* @param p_j2k the jpeg20000 structure to destroy.
|
||||
*/
|
||||
void j2k_destroy (opj_j2k_v2_t *p_j2k);
|
||||
|
||||
/**
|
||||
* Decode tile data.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
opj_bool j2k_decode_tile (
|
||||
opj_j2k_v2_t * p_j2k,
|
||||
OPJ_UINT32 p_tile_index,
|
||||
OPJ_BYTE * p_data,
|
||||
OPJ_UINT32 p_data_size,
|
||||
struct opj_stream_private *p_stream,
|
||||
struct opj_event_mgr * p_manager
|
||||
);
|
||||
|
||||
/**
|
||||
* Reads a tile header.
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_stream the stream to write data to.
|
||||
* @param p_manager the user event manager.
|
||||
*/
|
||||
opj_bool j2k_read_tile_header (
|
||||
opj_j2k_v2_t * p_j2k,
|
||||
OPJ_UINT32 * p_tile_index,
|
||||
OPJ_UINT32 * p_data_size,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_INT32 * p_tile_x1,
|
||||
OPJ_INT32 * p_tile_y1,
|
||||
OPJ_UINT32 * p_nb_comps,
|
||||
opj_bool * p_go_on,
|
||||
struct opj_stream_private *p_stream,
|
||||
struct opj_event_mgr * p_manager
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading.
|
||||
*
|
||||
* @param p_j2k the jpeg2000 codec.
|
||||
* @param p_start_x the left position of the rectangle to decode (in image coordinates).
|
||||
* @param p_end_x the right position of the rectangle to decode (in image coordinates).
|
||||
* @param p_start_y the up position of the rectangle to decode (in image coordinates).
|
||||
* @param p_end_y the bottom position of the rectangle to decode (in image coordinates).
|
||||
* @param p_manager the user event manager
|
||||
*
|
||||
* @return true if the area could be set.
|
||||
*/
|
||||
opj_bool j2k_set_decode_area(
|
||||
opj_j2k_v2_t *p_j2k,
|
||||
OPJ_INT32 p_start_x,
|
||||
OPJ_INT32 p_start_y,
|
||||
OPJ_INT32 p_end_x,
|
||||
OPJ_INT32 p_end_y,
|
||||
struct opj_event_mgr * p_manager
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a J2K decompression structure.
|
||||
*
|
||||
* @return a handle to a J2K decompressor if successful, NULL otherwise.
|
||||
*/
|
||||
opj_j2k_v2_t* j2k_create_decompress_v2();
|
||||
|
||||
|
||||
#endif /* __J2K_H */
|
||||
|
|
|
@ -188,3 +188,58 @@ void mct_decode_real(
|
|||
double mct_getnorm_real(int compno) {
|
||||
return mct_norms_real[compno];
|
||||
}
|
||||
|
||||
|
||||
opj_bool mct_decode_custom(
|
||||
// MCT data
|
||||
OPJ_BYTE * pDecodingData,
|
||||
// size of components
|
||||
OPJ_UINT32 n,
|
||||
// components
|
||||
OPJ_BYTE ** pData,
|
||||
// nb of components (i.e. size of pData)
|
||||
OPJ_UINT32 pNbComp,
|
||||
// tells if the data is signed
|
||||
OPJ_UINT32 isSigned)
|
||||
{
|
||||
OPJ_FLOAT32 * lMct;
|
||||
OPJ_UINT32 i;
|
||||
OPJ_UINT32 j;
|
||||
OPJ_UINT32 k;
|
||||
|
||||
OPJ_FLOAT32 * lCurrentData = 00;
|
||||
OPJ_FLOAT32 * lCurrentResult = 00;
|
||||
OPJ_FLOAT32 ** lData = (OPJ_FLOAT32 **) pData;
|
||||
|
||||
lCurrentData = (OPJ_FLOAT32 *) opj_malloc (2 * pNbComp * sizeof(OPJ_FLOAT32));
|
||||
if
|
||||
(! lCurrentData)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
lCurrentResult = lCurrentData + pNbComp;
|
||||
|
||||
for
|
||||
(i = 0; i < n; ++i)
|
||||
{
|
||||
lMct = (OPJ_FLOAT32 *) pDecodingData;
|
||||
for
|
||||
(j=0;j<pNbComp;++j)
|
||||
{
|
||||
lCurrentData[j] = (OPJ_FLOAT32) (*(lData[j]));
|
||||
}
|
||||
for
|
||||
(j=0;j<pNbComp;++j)
|
||||
{
|
||||
lCurrentResult[j] = 0;
|
||||
for
|
||||
(k=0;k<pNbComp;++k)
|
||||
{
|
||||
lCurrentResult[j] += *(lMct++) * lCurrentData[k];
|
||||
}
|
||||
*(lData[j]++) = (OPJ_FLOAT32) (lCurrentResult[j]);
|
||||
}
|
||||
}
|
||||
opj_free(lCurrentData);
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
|
|
@ -90,6 +90,18 @@ Get norm of the basis function used for the irreversible multi-component transfo
|
|||
@return
|
||||
*/
|
||||
double mct_getnorm_real(int compno);
|
||||
|
||||
opj_bool mct_decode_custom(
|
||||
// MCT data
|
||||
OPJ_BYTE * pDecodingData,
|
||||
// size of components
|
||||
OPJ_UINT32 n,
|
||||
// components
|
||||
OPJ_BYTE ** pData,
|
||||
// nb of components (i.e. size of pData)
|
||||
OPJ_UINT32 pNbComp,
|
||||
// tells if the data is signed
|
||||
OPJ_UINT32 isSigned);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
|
@ -31,6 +31,116 @@
|
|||
#include "opj_config.h"
|
||||
#include "opj_includes.h"
|
||||
|
||||
typedef struct opj_decompression
|
||||
{
|
||||
opj_bool (* opj_read_header) (
|
||||
void *p_codec,
|
||||
opj_image_t **,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_UINT32 * p_tile_width,
|
||||
OPJ_UINT32 * p_tile_height,
|
||||
OPJ_UINT32 * p_nb_tiles_x,
|
||||
OPJ_UINT32 * p_nb_tiles_y,
|
||||
struct opj_stream_private *cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
opj_image_t* (* opj_decode) (void * p_codec, struct opj_stream_private *p_cio, struct opj_event_mgr * p_manager);
|
||||
opj_bool (*opj_read_tile_header)(
|
||||
void * p_codec,
|
||||
OPJ_UINT32 * p_tile_index,
|
||||
OPJ_UINT32* p_data_size,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_INT32 * p_tile_x1,
|
||||
OPJ_INT32 * p_tile_y1,
|
||||
OPJ_UINT32 * p_nb_comps,
|
||||
opj_bool * p_should_go_on,
|
||||
struct opj_stream_private *p_cio,
|
||||
struct opj_event_mgr * p_manager);
|
||||
opj_bool (*opj_decode_tile_data)(void * p_codec,OPJ_UINT32 p_tile_index,OPJ_BYTE * p_data,OPJ_UINT32 p_data_size,struct opj_stream_private *p_cio,struct opj_event_mgr * p_manager);
|
||||
opj_bool (* opj_end_decompress) (void *p_codec,struct opj_stream_private *cio,struct opj_event_mgr * p_manager);
|
||||
void (* opj_destroy) (void * p_codec);
|
||||
void (*opj_setup_decoder) (void * p_codec,opj_dparameters_t * p_param);
|
||||
opj_bool (*opj_set_decode_area) (void * p_codec,OPJ_INT32 p_start_x,OPJ_INT32 p_end_x,OPJ_INT32 p_start_y,OPJ_INT32 p_end_y,struct opj_event_mgr * p_manager);
|
||||
|
||||
|
||||
}opj_decompression_t;
|
||||
|
||||
typedef struct opj_compression
|
||||
{
|
||||
opj_bool (* opj_start_compress) (void *p_codec,struct opj_stream_private *cio,struct opj_image * p_image, struct opj_event_mgr * p_manager);
|
||||
opj_bool (* opj_encode) (void * p_codec, struct opj_stream_private *p_cio, struct opj_event_mgr * p_manager);
|
||||
opj_bool (* opj_write_tile) (void * p_codec,OPJ_UINT32 p_tile_index,OPJ_BYTE * p_data,OPJ_UINT32 p_data_size,struct opj_stream_private * p_cio,struct opj_event_mgr * p_manager);
|
||||
opj_bool (* opj_end_compress) (void * p_codec, struct opj_stream_private *p_cio, struct opj_event_mgr * p_manager);
|
||||
void (* opj_destroy) (void * p_codec);
|
||||
void (*opj_setup_encoder) (void * p_codec,opj_cparameters_t * p_param,struct opj_image * p_image, struct opj_event_mgr * p_manager);
|
||||
|
||||
}opj_compression_t;
|
||||
|
||||
typedef struct opj_codec_private
|
||||
{
|
||||
union
|
||||
{ /* code-blocks informations */
|
||||
opj_decompression_t m_decompression;
|
||||
opj_compression_t m_compression;
|
||||
} m_codec_data;
|
||||
void * m_codec;
|
||||
opj_event_mgr_t* m_event_mgr;
|
||||
unsigned is_decompressor : 1;
|
||||
}
|
||||
opj_codec_private_t;
|
||||
|
||||
/**
|
||||
* Default callback function.
|
||||
* Do nothing.
|
||||
*/
|
||||
void opj_default_callback (const char *msg, void *client_data)
|
||||
{
|
||||
//FIXME V2 -> V1 cf below
|
||||
}
|
||||
|
||||
void set_default_event_handler(opj_event_mgr_t * p_manager)
|
||||
{
|
||||
//FIXME V2 -> V1
|
||||
//p_manager->m_error_data = 00;
|
||||
//p_manager->m_warning_data = 00;
|
||||
//p_manager->m_info_data = 00;
|
||||
p_manager->error_handler = opj_default_callback;
|
||||
p_manager->info_handler = opj_default_callback;
|
||||
p_manager->warning_handler = opj_default_callback;
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_read_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file)
|
||||
{
|
||||
OPJ_UINT32 l_nb_read = fread(p_buffer,1,p_nb_bytes,p_file);
|
||||
return l_nb_read ? l_nb_read : -1;
|
||||
}
|
||||
|
||||
OPJ_UINT32 opj_write_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file)
|
||||
{
|
||||
return fwrite(p_buffer,1,p_nb_bytes,p_file);
|
||||
}
|
||||
|
||||
OPJ_SIZE_T opj_skip_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data)
|
||||
{
|
||||
if
|
||||
(fseek(p_user_data,p_nb_bytes,SEEK_CUR))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return p_nb_bytes;
|
||||
}
|
||||
|
||||
opj_bool opj_seek_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data)
|
||||
{
|
||||
if
|
||||
(fseek(p_user_data,p_nb_bytes,SEEK_SET))
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
#ifdef _WIN32
|
||||
#ifndef OPJ_STATIC
|
||||
|
@ -95,6 +205,120 @@ opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) {
|
|||
return dinfo;
|
||||
}
|
||||
|
||||
opj_codec_t* OPJ_CALLCONV opj_create_decompress_v2(OPJ_CODEC_FORMAT p_format)
|
||||
{
|
||||
opj_codec_private_t *l_info = 00;
|
||||
|
||||
l_info = (opj_codec_private_t*) opj_calloc(1, sizeof(opj_codec_private_t));
|
||||
if (!l_info){
|
||||
return 00;
|
||||
}
|
||||
memset(l_info, 0, sizeof(opj_codec_private_t));
|
||||
|
||||
l_info->is_decompressor = 1;
|
||||
|
||||
switch
|
||||
(p_format)
|
||||
{
|
||||
case CODEC_J2K:
|
||||
l_info->m_codec_data.m_decompression.opj_decode = (opj_image_t* (*) (void *, struct opj_stream_private *, struct opj_event_mgr * ))j2k_decode;
|
||||
l_info->m_codec_data.m_decompression.opj_end_decompress = (opj_bool (*) (void *,struct opj_stream_private *,struct opj_event_mgr *))j2k_end_decompress;
|
||||
l_info->m_codec_data.m_decompression.opj_read_header = (opj_bool (*) (
|
||||
void *,
|
||||
opj_image_t **,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
struct opj_stream_private *,
|
||||
struct opj_event_mgr * )) j2k_read_header;
|
||||
l_info->m_codec_data.m_decompression.opj_destroy = (void (*) (void *))j2k_destroy;
|
||||
l_info->m_codec_data.m_decompression.opj_setup_decoder = (void (*) (void * ,opj_dparameters_t * )) j2k_setup_decoder;
|
||||
l_info->m_codec_data.m_decompression.opj_read_tile_header = (opj_bool (*) (
|
||||
void *,
|
||||
OPJ_UINT32*,
|
||||
OPJ_UINT32*,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
opj_bool *,
|
||||
struct opj_stream_private *,
|
||||
struct opj_event_mgr * )) j2k_read_tile_header;
|
||||
l_info->m_codec_data.m_decompression.opj_decode_tile_data = (opj_bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr * )) j2k_decode_tile;
|
||||
l_info->m_codec_data.m_decompression.opj_set_decode_area = (opj_bool (*) (void *,OPJ_INT32,OPJ_INT32,OPJ_INT32,OPJ_INT32, struct opj_event_mgr * )) j2k_set_decode_area;
|
||||
l_info->m_codec = j2k_create_decompress_v2();
|
||||
if
|
||||
(! l_info->m_codec)
|
||||
{
|
||||
opj_free(l_info);
|
||||
return 00;
|
||||
}
|
||||
break;
|
||||
|
||||
case CODEC_JP2:
|
||||
/* get a JP2 decoder handle */
|
||||
#ifdef TODO_MSD
|
||||
l_info->m_codec_data.m_decompression.opj_decode = (opj_image_t* (*) (void *, struct opj_stream_private *, struct opj_event_mgr * ))opj_jp2_decode;
|
||||
l_info->m_codec_data.m_decompression.opj_end_decompress = (opj_bool (*) (void *,struct opj_stream_private *,struct opj_event_mgr *)) jp2_end_decompress;
|
||||
l_info->m_codec_data.m_decompression.opj_read_header = (opj_bool (*) (
|
||||
void *,
|
||||
opj_image_t **,
|
||||
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
struct opj_stream_private *,
|
||||
struct opj_event_mgr * )) jp2_read_header;
|
||||
|
||||
l_info->m_codec_data.m_decompression.opj_read_tile_header = (
|
||||
opj_bool (*) (
|
||||
void *,
|
||||
OPJ_UINT32*,
|
||||
OPJ_UINT32*,
|
||||
OPJ_INT32*,
|
||||
OPJ_INT32*,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_INT32 * ,
|
||||
OPJ_UINT32 * ,
|
||||
opj_bool *,
|
||||
struct opj_stream_private *,
|
||||
struct opj_event_mgr * )) jp2_read_tile_header;
|
||||
|
||||
l_info->m_codec_data.m_decompression.opj_decode_tile_data = (opj_bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr * )) opj_jp2_decode_tile;
|
||||
|
||||
l_info->m_codec_data.m_decompression.opj_destroy = (void (*) (void *))jp2_destroy;
|
||||
l_info->m_codec_data.m_decompression.opj_setup_decoder = (void (*) (void * ,opj_dparameters_t * )) jp2_setup_decoder;
|
||||
l_info->m_codec_data.m_decompression.opj_set_decode_area = (opj_bool (*) (void *,OPJ_INT32,OPJ_INT32,OPJ_INT32,OPJ_INT32, struct opj_event_mgr * )) jp2_set_decode_area;
|
||||
|
||||
|
||||
l_info->m_codec = jp2_create(OPJ_TRUE);
|
||||
if
|
||||
(! l_info->m_codec)
|
||||
{
|
||||
opj_free(l_info);
|
||||
return 00;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case CODEC_UNKNOWN:
|
||||
case CODEC_JPT:
|
||||
default:
|
||||
opj_free(l_info);
|
||||
return 00;
|
||||
}
|
||||
|
||||
// FIXME set_default_event_handler(&(l_info->m_event_mgr));
|
||||
return (opj_codec_t*) l_info;
|
||||
}
|
||||
|
||||
|
||||
void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) {
|
||||
if(dinfo) {
|
||||
/* destroy the codec */
|
||||
|
@ -152,6 +376,22 @@ void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *param
|
|||
}
|
||||
}
|
||||
|
||||
opj_bool OPJ_CALLCONV opj_setup_decoder_v2(opj_codec_t *p_info, opj_dparameters_t *parameters, opj_event_mgr_t* event_mgr)
|
||||
{
|
||||
if (p_info && parameters) {
|
||||
opj_codec_private_t * l_info = (opj_codec_private_t *) p_info;
|
||||
|
||||
if (! l_info->is_decompressor) {
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
l_info->m_codec_data.m_decompression.opj_setup_decoder(l_info->m_codec,parameters);
|
||||
l_info->m_event_mgr = event_mgr;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) {
|
||||
return opj_decode_with_info(dinfo, cio, NULL);
|
||||
}
|
||||
|
@ -284,6 +524,39 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function.
|
||||
* Sets the stream to be a file stream. The FILE must have been open previously.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_file handler to an already open file.
|
||||
*/
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream (FILE * p_file, opj_bool p_is_read_stream)
|
||||
{
|
||||
return opj_stream_create_file_stream(p_file,J2K_STREAM_CHUNK_SIZE,p_is_read_stream);
|
||||
}
|
||||
|
||||
opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file, OPJ_UINT32 p_size, opj_bool p_is_read_stream)
|
||||
{
|
||||
opj_stream_t* l_stream = 00;
|
||||
if
|
||||
(! p_file)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
l_stream = opj_stream_create(p_size,p_is_read_stream);
|
||||
if
|
||||
(! l_stream)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
opj_stream_set_user_data(l_stream,p_file);
|
||||
opj_stream_set_read_function(l_stream,(opj_stream_read_fn) opj_read_from_file);
|
||||
opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from_file);
|
||||
opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file);
|
||||
opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_file);
|
||||
return l_stream;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image) {
|
||||
if(cinfo && parameters && image) {
|
||||
switch(cinfo->codec_format) {
|
||||
|
@ -340,3 +613,61 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) {
|
|||
opj_free(cstr_info->numdecompos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
opj_bool OPJ_CALLCONV opj_read_header (
|
||||
opj_codec_t *p_codec,
|
||||
opj_image_t ** p_image,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_UINT32 * p_tile_width,
|
||||
OPJ_UINT32 * p_tile_height,
|
||||
OPJ_UINT32 * p_nb_tiles_x,
|
||||
OPJ_UINT32 * p_nb_tiles_y,
|
||||
opj_stream_t *p_cio)
|
||||
{
|
||||
if
|
||||
(p_codec && p_cio)
|
||||
{
|
||||
opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec;
|
||||
opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio;
|
||||
if
|
||||
(! l_info->is_decompressor)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
return l_info->m_codec_data.m_decompression.opj_read_header(
|
||||
l_info->m_codec,
|
||||
p_image,
|
||||
p_tile_x0,
|
||||
p_tile_y0,
|
||||
p_tile_width,
|
||||
p_tile_height,
|
||||
p_nb_tiles_x,
|
||||
p_nb_tiles_y,
|
||||
l_cio,
|
||||
//&(l_info->m_event_mgr));
|
||||
l_info->m_event_mgr);
|
||||
}
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
void OPJ_CALLCONV opj_destroy_codec(opj_codec_t *p_info)
|
||||
{
|
||||
if
|
||||
(p_info)
|
||||
{
|
||||
opj_codec_private_t * l_info = (opj_codec_private_t *) p_info;
|
||||
if
|
||||
(l_info->is_decompressor)
|
||||
{
|
||||
l_info->m_codec_data.m_decompression.opj_destroy(l_info->m_codec);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_info->m_codec_data.m_compression.opj_destroy(l_info->m_codec);
|
||||
}
|
||||
l_info->m_codec = 00;
|
||||
opj_free(l_info);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,19 @@ typedef int opj_bool;
|
|||
#define OPJ_TRUE 1
|
||||
#define OPJ_FALSE 0
|
||||
|
||||
typedef unsigned int OPJ_UINT32;
|
||||
typedef int OPJ_INT32;
|
||||
typedef unsigned short OPJ_UINT16;
|
||||
typedef short OPJ_INT16;
|
||||
typedef char OPJ_CHAR;
|
||||
typedef unsigned char OPJ_BYTE;
|
||||
typedef unsigned int OPJ_SIZE_T;
|
||||
typedef double OPJ_FLOAT64;
|
||||
typedef float OPJ_FLOAT32;
|
||||
|
||||
// Avoid compile-time warning because parameter is not used
|
||||
#define OPJ_ARG_NOT_USED(x) (void)(x)
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
Useful constant definitions
|
||||
|
@ -77,6 +88,12 @@ typedef int opj_bool;
|
|||
#define J2K_MAXRLVLS 33 /**< Number of maximum resolution level authorized */
|
||||
#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /**< Number of maximum sub-band linked to number of resolution level */
|
||||
|
||||
#define J2K_DEFAULT_NB_SEGS 10
|
||||
#define J2K_STREAM_CHUNK_SIZE 0x100000 /** 1 mega by default */
|
||||
#define J2K_DEFAULT_HEADER_SIZE 1000
|
||||
#define J2K_MCC_DEFAULT_NB_RECORDS 10
|
||||
#define J2K_MCT_DEFAULT_NB_RECORDS 10
|
||||
|
||||
/* UniPG>> */
|
||||
#define JPWL_MAX_NO_TILESPECS 16 /**< Maximum number of tile parts expected by JPWL: increase at your will */
|
||||
#define JPWL_MAX_NO_PACKSPECS 16 /**< Maximum number of packet parts expected by JPWL: increase at your will */
|
||||
|
@ -177,6 +194,7 @@ used for
|
|||
</ul>
|
||||
*/
|
||||
typedef struct opj_event_mgr {
|
||||
void* client_data;
|
||||
/** Error message callback if available, NULL otherwise */
|
||||
opj_msg_callback error_handler;
|
||||
/** Warning message callback if available, NULL otherwise */
|
||||
|
@ -448,6 +466,11 @@ typedef struct opj_dinfo {
|
|||
/* other specific fields go here */
|
||||
} opj_dinfo_t;
|
||||
|
||||
/**
|
||||
* J2k codec.
|
||||
*/
|
||||
typedef void * opj_codec_t;
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
I/O stream typedef definitions
|
||||
|
@ -484,6 +507,14 @@ typedef struct opj_cio {
|
|||
unsigned char *bp;
|
||||
} opj_cio_t;
|
||||
|
||||
typedef OPJ_UINT32 (* opj_stream_read_fn) (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_UINT32 (* opj_stream_write_fn) (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) ;
|
||||
typedef OPJ_SIZE_T (* opj_stream_skip_fn) (OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
typedef opj_bool (* opj_stream_seek_fn) (OPJ_SIZE_T p_nb_bytes, void * p_user_data) ;
|
||||
|
||||
|
||||
typedef void * opj_stream_t;
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
image typedef definitions
|
||||
|
@ -525,15 +556,15 @@ Defines image data and characteristics
|
|||
*/
|
||||
typedef struct opj_image {
|
||||
/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the image area */
|
||||
int x0;
|
||||
OPJ_UINT32 x0;
|
||||
/** YOsiz: vertical offset from the origin of the reference grid to the top side of the image area */
|
||||
int y0;
|
||||
OPJ_UINT32 y0;
|
||||
/** Xsiz: width of the reference grid */
|
||||
int x1;
|
||||
OPJ_UINT32 x1;
|
||||
/** Ysiz: height of the reference grid */
|
||||
int y1;
|
||||
OPJ_UINT32 y1;
|
||||
/** number of components in the image */
|
||||
int numcomps;
|
||||
OPJ_UINT16 numcomps;
|
||||
/** color space: sRGB, Greyscale or YUV */
|
||||
OPJ_COLOR_SPACE color_space;
|
||||
/** image components */
|
||||
|
@ -544,6 +575,7 @@ typedef struct opj_image {
|
|||
int icc_profile_len;
|
||||
} opj_image_t;
|
||||
|
||||
|
||||
/**
|
||||
Component parameters structure used by the opj_image_create function
|
||||
*/
|
||||
|
@ -783,6 +815,73 @@ Set position in byte stream
|
|||
*/
|
||||
OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos);
|
||||
|
||||
|
||||
/**
|
||||
* Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream.
|
||||
*
|
||||
* @param l_is_reader if set to true then the stream will be an input stream, an output stream else.
|
||||
*
|
||||
* @return a stream object.
|
||||
*/
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_default_create(opj_bool p_is_input);
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create(OPJ_UINT32 p_size, opj_bool p_is_input);
|
||||
|
||||
/**
|
||||
* Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must
|
||||
* close its own implementation of the stream.
|
||||
*
|
||||
* @param p_stream the stream to destroy.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream);
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a read function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a read function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function);
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a write function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a write function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function);
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a skip function.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a skip function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function);
|
||||
|
||||
/**
|
||||
* Sets the given function to be used as a seek function, the stream is then seekable.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_function the function to use a skip function.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the given data to be used as a user data for the stream.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_data the data to set.
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_stream_set_user_data (opj_stream_t* p_stream, void * p_data);
|
||||
|
||||
|
||||
/**
|
||||
* Helper function.
|
||||
* Sets the stream to be a file stream. The FILE must have been open previously.
|
||||
* @param p_stream the stream to modify
|
||||
* @param p_file handler to an already open file.
|
||||
*/
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream (FILE * p_file, opj_bool p_is_read_stream);
|
||||
OPJ_API opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file, OPJ_UINT32 p_buffer_size, opj_bool p_is_read_stream);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
event manager functions definitions
|
||||
|
@ -796,6 +895,14 @@ OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, op
|
|||
codec functions definitions
|
||||
==========================================================
|
||||
*/
|
||||
/**
|
||||
Creates a J2K/JPT/JP2 decompression structure
|
||||
@param format Decoder to select
|
||||
@return Returns a handle to a decompressor if successful, returns NULL otherwise
|
||||
*/
|
||||
OPJ_API opj_codec_t* OPJ_CALLCONV opj_create_decompress_v2(OPJ_CODEC_FORMAT format);
|
||||
|
||||
|
||||
/**
|
||||
Creates a J2K/JPT/JP2 decompression structure
|
||||
@param format Decoder to select
|
||||
|
@ -819,6 +926,11 @@ Decoding parameters are returned in j2k->cp.
|
|||
@param parameters decompression parameters
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters);
|
||||
|
||||
OPJ_API opj_bool OPJ_CALLCONV opj_setup_decoder_v2( opj_codec_t *p_info,
|
||||
opj_dparameters_t *parameters,
|
||||
opj_event_mgr_t* event_mgr);
|
||||
|
||||
/**
|
||||
Decode an image from a JPEG-2000 codestream
|
||||
@param dinfo decompressor handle
|
||||
|
@ -900,6 +1012,35 @@ Destroy Codestream information after compression or decompression
|
|||
OPJ_API void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info);
|
||||
|
||||
|
||||
/**
|
||||
* Decodes an image header.
|
||||
*
|
||||
* @param p_codec codec to use to decode the image.
|
||||
* @param p_image pointer to a previously created image.
|
||||
* @param p_tile_x0 pointer to a value that will hold the reference point x0 of the tiling grid.
|
||||
* @param p_tile_y0 pointer to a value that will hold the reference point y0 of the tiling grid.
|
||||
* @param p_tile_width pointer to a value that will hold the size in x of a tile in the grid.
|
||||
* @param p_tile_height pointer to a value that will hold the size in y of a tile in the grid.
|
||||
* @param p_nb_tiles_x pointer to a value that will hold the number of tiles in the x direction.
|
||||
* @param p_nb_tiles_y pointer to a value that will hold the number of tiles in the y direction.
|
||||
*/
|
||||
OPJ_API opj_bool OPJ_CALLCONV opj_read_header (
|
||||
opj_codec_t *p_codec,
|
||||
opj_image_t ** p_image,
|
||||
OPJ_INT32 * p_tile_x0,
|
||||
OPJ_INT32 * p_tile_y0,
|
||||
OPJ_UINT32 * p_tile_width,
|
||||
OPJ_UINT32 * p_tile_height,
|
||||
OPJ_UINT32 * p_nb_tiles_x,
|
||||
OPJ_UINT32 * p_nb_tiles_y,
|
||||
opj_stream_t *p_cio);
|
||||
|
||||
/**
|
||||
Destroy a decompressor handle
|
||||
@param dinfo decompressor handle to destroy
|
||||
*/
|
||||
OPJ_API void OPJ_CALLCONV opj_destroy_codec(opj_codec_t * p_codec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
|
@ -136,4 +137,7 @@ static INLINE long lrintf(float f){
|
|||
#endif /* USE_JPWL */
|
||||
/* <<JPWL */
|
||||
|
||||
// V2
|
||||
#include "function_list.h"
|
||||
|
||||
#endif /* OPJ_INCLUDES_H */
|
||||
|
|
612
libopenjpeg/pi.c
612
libopenjpeg/pi.c
|
@ -69,6 +69,62 @@ Get next packet in component-precinct-resolution-layer order.
|
|||
*/
|
||||
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
|
||||
* The precinct widths, heights, dx and dy for each component at each resolution will be stored as well.
|
||||
* the last parameter of the function should be an array of pointers of size nb components, each pointer leading
|
||||
* to an area of size 4 * max_res. The data is stored inside this area with the following pattern :
|
||||
* dx_compi_res0 , dy_compi_res0 , w_compi_res0, h_compi_res0 , dx_compi_res1 , dy_compi_res1 , w_compi_res1, h_compi_res1 , ...
|
||||
*
|
||||
* @param p_image the image being encoded.
|
||||
* @param p_cp the coding parameters.
|
||||
* @param tileno the tile index of the tile being encoded.
|
||||
* @param p_tx0 pointer that will hold the X0 parameter for the tile
|
||||
* @param p_tx1 pointer that will hold the X1 parameter for the tile
|
||||
* @param p_ty0 pointer that will hold the Y0 parameter for the tile
|
||||
* @param p_ty1 pointer that will hold the Y1 parameter for the tile
|
||||
* @param p_max_prec pointer that will hold the the maximum precision for all the bands of the tile
|
||||
* @param p_max_res pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
|
||||
* @param dx_min pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
|
||||
* @param dy_min pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
|
||||
* @param p_resolutions pointer to an area corresponding to the one described above.
|
||||
*/
|
||||
void get_all_encoding_parameters(
|
||||
const opj_image_t *p_image,
|
||||
const opj_cp_v2_t *p_cp,
|
||||
OPJ_UINT32 tileno,
|
||||
OPJ_INT32 * p_tx0,
|
||||
OPJ_INT32 * p_tx1,
|
||||
OPJ_INT32 * p_ty0,
|
||||
OPJ_INT32 * p_ty1,
|
||||
OPJ_UINT32 * p_dx_min,
|
||||
OPJ_UINT32 * p_dy_min,
|
||||
OPJ_UINT32 * p_max_prec,
|
||||
OPJ_UINT32 * p_max_res,
|
||||
OPJ_UINT32 ** p_resolutions
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Allocates memory for a packet iterator. Data and data sizes are set by this operation.
|
||||
* No other data is set. The include section of the packet iterator is not allocated.
|
||||
*
|
||||
* @param p_image the image used to initialize the packet iterator (in fact only the number of components is relevant.
|
||||
* @param p_cp the coding parameters.
|
||||
* @param p_tile_no the index of the tile from which creating the packet iterator.
|
||||
*/
|
||||
opj_pi_iterator_t * pi_create(
|
||||
const opj_image_t *image,
|
||||
const opj_cp_v2_t *cp,
|
||||
OPJ_UINT32 tileno
|
||||
);
|
||||
|
||||
void pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ_UINT32 p_max_precision,OPJ_UINT32 p_max_res);
|
||||
void pi_update_decode_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ_UINT32 p_max_precision,OPJ_UINT32 p_max_res);
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
@ -540,6 +596,210 @@ opj_pi_iterator_t *pi_create_decode(opj_image_t *image, opj_cp_t *cp, int tileno
|
|||
}
|
||||
|
||||
|
||||
opj_pi_iterator_t *pi_create_decode_v2(
|
||||
opj_image_t *p_image,
|
||||
opj_cp_v2_t *p_cp,
|
||||
OPJ_UINT32 p_tile_no
|
||||
)
|
||||
{
|
||||
// loop
|
||||
OPJ_UINT32 pino;
|
||||
OPJ_UINT32 compno, resno;
|
||||
|
||||
// to store w, h, dx and dy fro all components and resolutions
|
||||
OPJ_UINT32 * l_tmp_data;
|
||||
OPJ_UINT32 ** l_tmp_ptr;
|
||||
|
||||
// encoding prameters to set
|
||||
OPJ_UINT32 l_max_res;
|
||||
OPJ_UINT32 l_max_prec;
|
||||
OPJ_INT32 l_tx0,l_tx1,l_ty0,l_ty1;
|
||||
OPJ_UINT32 l_dx_min,l_dy_min;
|
||||
OPJ_UINT32 l_bound;
|
||||
OPJ_UINT32 l_step_p , l_step_c , l_step_r , l_step_l ;
|
||||
OPJ_UINT32 l_data_stride;
|
||||
|
||||
// pointers
|
||||
opj_pi_iterator_t *l_pi = 00;
|
||||
opj_tcp_v2_t *l_tcp = 00;
|
||||
const opj_tccp_t *l_tccp = 00;
|
||||
opj_pi_comp_t *l_current_comp = 00;
|
||||
opj_image_comp_t * l_img_comp = 00;
|
||||
opj_pi_iterator_t * l_current_pi = 00;
|
||||
OPJ_UINT32 * l_encoding_value_ptr = 00;
|
||||
|
||||
// preconditions in debug
|
||||
assert(p_cp != 00);
|
||||
assert(p_image != 00);
|
||||
assert(p_tile_no < p_cp->tw * p_cp->th);
|
||||
|
||||
// initializations
|
||||
l_tcp = &p_cp->tcps[p_tile_no];
|
||||
l_bound = l_tcp->numpocs+1;
|
||||
|
||||
l_data_stride = 4 * J2K_MAXRLVLS;
|
||||
l_tmp_data = (OPJ_UINT32*)opj_malloc(
|
||||
l_data_stride * p_image->numcomps * sizeof(OPJ_UINT32));
|
||||
if
|
||||
(! l_tmp_data)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
l_tmp_ptr = (OPJ_UINT32**)opj_malloc(
|
||||
p_image->numcomps * sizeof(OPJ_UINT32 *));
|
||||
if
|
||||
(! l_tmp_ptr)
|
||||
{
|
||||
opj_free(l_tmp_data);
|
||||
return 00;
|
||||
}
|
||||
|
||||
// memory allocation for pi
|
||||
l_pi = pi_create(p_image,p_cp,p_tile_no);
|
||||
if
|
||||
(!l_pi)
|
||||
{
|
||||
opj_free(l_tmp_data);
|
||||
opj_free(l_tmp_ptr);
|
||||
return 00;
|
||||
}
|
||||
|
||||
l_encoding_value_ptr = l_tmp_data;
|
||||
// update pointer array
|
||||
for
|
||||
(compno = 0; compno < p_image->numcomps; ++compno)
|
||||
{
|
||||
l_tmp_ptr[compno] = l_encoding_value_ptr;
|
||||
l_encoding_value_ptr += l_data_stride;
|
||||
}
|
||||
// get encoding parameters
|
||||
get_all_encoding_parameters(p_image,p_cp,p_tile_no,&l_tx0,&l_tx1,&l_ty0,&l_ty1,&l_dx_min,&l_dy_min,&l_max_prec,&l_max_res,l_tmp_ptr);
|
||||
|
||||
// step calculations
|
||||
l_step_p = 1;
|
||||
l_step_c = l_max_prec * l_step_p;
|
||||
l_step_r = p_image->numcomps * l_step_c;
|
||||
l_step_l = l_max_res * l_step_r;
|
||||
|
||||
// set values for first packet iterator
|
||||
l_current_pi = l_pi;
|
||||
|
||||
// memory allocation for include
|
||||
l_current_pi->include = (OPJ_INT16*) opj_calloc(l_tcp->numlayers * l_step_l, sizeof(OPJ_INT16));
|
||||
if
|
||||
(!l_current_pi->include)
|
||||
{
|
||||
opj_free(l_tmp_data);
|
||||
opj_free(l_tmp_ptr);
|
||||
pi_destroy_v2(l_pi, l_bound);
|
||||
return 00;
|
||||
}
|
||||
memset(l_current_pi->include,0,l_tcp->numlayers * l_step_l* sizeof(OPJ_INT16));
|
||||
|
||||
// special treatment for the first packet iterator
|
||||
l_current_comp = l_current_pi->comps;
|
||||
l_img_comp = p_image->comps;
|
||||
l_tccp = l_tcp->tccps;
|
||||
|
||||
l_current_pi->tx0 = l_tx0;
|
||||
l_current_pi->ty0 = l_ty0;
|
||||
l_current_pi->tx1 = l_tx1;
|
||||
l_current_pi->ty1 = l_ty1;
|
||||
|
||||
//l_current_pi->dx = l_img_comp->dx;
|
||||
//l_current_pi->dy = l_img_comp->dy;
|
||||
|
||||
l_current_pi->step_p = l_step_p;
|
||||
l_current_pi->step_c = l_step_c;
|
||||
l_current_pi->step_r = l_step_r;
|
||||
l_current_pi->step_l = l_step_l;
|
||||
|
||||
/* allocation for components and number of components has already been calculated by pi_create */
|
||||
for
|
||||
(compno = 0; compno < l_current_pi->numcomps; ++compno)
|
||||
{
|
||||
opj_pi_resolution_t *l_res = l_current_comp->resolutions;
|
||||
l_encoding_value_ptr = l_tmp_ptr[compno];
|
||||
|
||||
l_current_comp->dx = l_img_comp->dx;
|
||||
l_current_comp->dy = l_img_comp->dy;
|
||||
/* resolutions have already been initialized */
|
||||
for
|
||||
(resno = 0; resno < l_current_comp->numresolutions; resno++)
|
||||
{
|
||||
l_res->pdx = *(l_encoding_value_ptr++);
|
||||
l_res->pdy = *(l_encoding_value_ptr++);
|
||||
l_res->pw = *(l_encoding_value_ptr++);
|
||||
l_res->ph = *(l_encoding_value_ptr++);
|
||||
++l_res;
|
||||
}
|
||||
++l_current_comp;
|
||||
++l_img_comp;
|
||||
++l_tccp;
|
||||
}
|
||||
++l_current_pi;
|
||||
|
||||
for
|
||||
(pino = 1 ; pino<l_bound ; ++pino )
|
||||
{
|
||||
opj_pi_comp_t *l_current_comp = l_current_pi->comps;
|
||||
opj_image_comp_t * l_img_comp = p_image->comps;
|
||||
l_tccp = l_tcp->tccps;
|
||||
|
||||
l_current_pi->tx0 = l_tx0;
|
||||
l_current_pi->ty0 = l_ty0;
|
||||
l_current_pi->tx1 = l_tx1;
|
||||
l_current_pi->ty1 = l_ty1;
|
||||
//l_current_pi->dx = l_dx_min;
|
||||
//l_current_pi->dy = l_dy_min;
|
||||
l_current_pi->step_p = l_step_p;
|
||||
l_current_pi->step_c = l_step_c;
|
||||
l_current_pi->step_r = l_step_r;
|
||||
l_current_pi->step_l = l_step_l;
|
||||
|
||||
/* allocation for components and number of components has already been calculated by pi_create */
|
||||
for
|
||||
(compno = 0; compno < l_current_pi->numcomps; ++compno)
|
||||
{
|
||||
opj_pi_resolution_t *l_res = l_current_comp->resolutions;
|
||||
l_encoding_value_ptr = l_tmp_ptr[compno];
|
||||
|
||||
l_current_comp->dx = l_img_comp->dx;
|
||||
l_current_comp->dy = l_img_comp->dy;
|
||||
/* resolutions have already been initialized */
|
||||
for
|
||||
(resno = 0; resno < l_current_comp->numresolutions; resno++)
|
||||
{
|
||||
l_res->pdx = *(l_encoding_value_ptr++);
|
||||
l_res->pdy = *(l_encoding_value_ptr++);
|
||||
l_res->pw = *(l_encoding_value_ptr++);
|
||||
l_res->ph = *(l_encoding_value_ptr++);
|
||||
++l_res;
|
||||
}
|
||||
++l_current_comp;
|
||||
++l_img_comp;
|
||||
++l_tccp;
|
||||
}
|
||||
// special treatment
|
||||
l_current_pi->include = (l_current_pi-1)->include;
|
||||
++l_current_pi;
|
||||
}
|
||||
opj_free(l_tmp_data);
|
||||
l_tmp_data = 00;
|
||||
opj_free(l_tmp_ptr);
|
||||
l_tmp_ptr = 00;
|
||||
if
|
||||
(l_tcp->POC)
|
||||
{
|
||||
pi_update_decode_poc (l_pi,l_tcp,l_max_prec,l_max_res);
|
||||
}
|
||||
else
|
||||
{
|
||||
pi_update_decode_not_poc(l_pi,l_tcp,l_max_prec,l_max_res);
|
||||
}
|
||||
return l_pi;
|
||||
}
|
||||
|
||||
opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno, J2K_T2_MODE t2_mode){
|
||||
int p, q, pino;
|
||||
int compno, resno;
|
||||
|
@ -961,3 +1221,355 @@ opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int p
|
|||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
|
||||
* The precinct widths, heights, dx and dy for each component at each resolution will be stored as well.
|
||||
* the last parameter of the function should be an array of pointers of size nb components, each pointer leading
|
||||
* to an area of size 4 * max_res. The data is stored inside this area with the following pattern :
|
||||
* dx_compi_res0 , dy_compi_res0 , w_compi_res0, h_compi_res0 , dx_compi_res1 , dy_compi_res1 , w_compi_res1, h_compi_res1 , ...
|
||||
*
|
||||
* @param p_image the image being encoded.
|
||||
* @param p_cp the coding parameters.
|
||||
* @param tileno the tile index of the tile being encoded.
|
||||
* @param p_tx0 pointer that will hold the X0 parameter for the tile
|
||||
* @param p_tx1 pointer that will hold the X1 parameter for the tile
|
||||
* @param p_ty0 pointer that will hold the Y0 parameter for the tile
|
||||
* @param p_ty1 pointer that will hold the Y1 parameter for the tile
|
||||
* @param p_max_prec pointer that will hold the the maximum precision for all the bands of the tile
|
||||
* @param p_max_res pointer that will hold the the maximum number of resolutions for all the poc inside the tile.
|
||||
* @param dx_min pointer that will hold the the minimum dx of all the components of all the resolutions for the tile.
|
||||
* @param dy_min pointer that will hold the the minimum dy of all the components of all the resolutions for the tile.
|
||||
* @param p_resolutions pointer to an area corresponding to the one described above.
|
||||
*/
|
||||
void get_all_encoding_parameters(
|
||||
const opj_image_t *p_image,
|
||||
const opj_cp_v2_t *p_cp,
|
||||
OPJ_UINT32 tileno,
|
||||
OPJ_INT32 * p_tx0,
|
||||
OPJ_INT32 * p_tx1,
|
||||
OPJ_INT32 * p_ty0,
|
||||
OPJ_INT32 * p_ty1,
|
||||
OPJ_UINT32 * p_dx_min,
|
||||
OPJ_UINT32 * p_dy_min,
|
||||
OPJ_UINT32 * p_max_prec,
|
||||
OPJ_UINT32 * p_max_res,
|
||||
OPJ_UINT32 ** p_resolutions
|
||||
)
|
||||
{
|
||||
// loop
|
||||
OPJ_UINT32 compno, resno;
|
||||
|
||||
// pointers
|
||||
const opj_tcp_v2_t *tcp = 00;
|
||||
const opj_tccp_t * l_tccp = 00;
|
||||
const opj_image_comp_t * l_img_comp = 00;
|
||||
|
||||
// to store l_dx, l_dy, w and h for each resolution and component.
|
||||
OPJ_UINT32 * lResolutionPtr;
|
||||
|
||||
// position in x and y of tile
|
||||
OPJ_UINT32 p, q;
|
||||
|
||||
// preconditions in debug
|
||||
assert(p_cp != 00);
|
||||
assert(p_image != 00);
|
||||
assert(tileno < p_cp->tw * p_cp->th);
|
||||
|
||||
// initializations
|
||||
tcp = &p_cp->tcps [tileno];
|
||||
l_tccp = tcp->tccps;
|
||||
l_img_comp = p_image->comps;
|
||||
|
||||
// position in x and y of tile
|
||||
|
||||
p = tileno % p_cp->tw;
|
||||
q = tileno / p_cp->tw;
|
||||
|
||||
/* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */
|
||||
*p_tx0 = int_max(p_cp->tx0 + p * p_cp->tdx, p_image->x0);
|
||||
*p_tx1 = int_min(p_cp->tx0 + (p + 1) * p_cp->tdx, p_image->x1);
|
||||
*p_ty0 = int_max(p_cp->ty0 + q * p_cp->tdy, p_image->y0);
|
||||
*p_ty1 = int_min(p_cp->ty0 + (q + 1) * p_cp->tdy, p_image->y1);
|
||||
|
||||
// max precision and resolution is 0 (can only grow)
|
||||
*p_max_prec = 0;
|
||||
*p_max_res = 0;
|
||||
|
||||
// take the largest value for dx_min and dy_min
|
||||
*p_dx_min = 0x7fffffff;
|
||||
*p_dy_min = 0x7fffffff;
|
||||
|
||||
for
|
||||
(compno = 0; compno < p_image->numcomps; ++compno)
|
||||
{
|
||||
// aritmetic variables to calculate
|
||||
OPJ_UINT32 l_level_no;
|
||||
OPJ_INT32 l_rx0, l_ry0, l_rx1, l_ry1;
|
||||
OPJ_INT32 l_px0, l_py0, l_px1, py1;
|
||||
OPJ_UINT32 l_product;
|
||||
OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
|
||||
OPJ_UINT32 l_pdx, l_pdy , l_pw , l_ph;
|
||||
|
||||
lResolutionPtr = p_resolutions[compno];
|
||||
|
||||
l_tcx0 = int_ceildiv(*p_tx0, l_img_comp->dx);
|
||||
l_tcy0 = int_ceildiv(*p_ty0, l_img_comp->dy);
|
||||
l_tcx1 = int_ceildiv(*p_tx1, l_img_comp->dx);
|
||||
l_tcy1 = int_ceildiv(*p_ty1, l_img_comp->dy);
|
||||
if
|
||||
(l_tccp->numresolutions > *p_max_res)
|
||||
{
|
||||
*p_max_res = l_tccp->numresolutions;
|
||||
}
|
||||
|
||||
// use custom size for precincts
|
||||
l_level_no = l_tccp->numresolutions - 1;
|
||||
for
|
||||
(resno = 0; resno < l_tccp->numresolutions; ++resno)
|
||||
{
|
||||
OPJ_UINT32 l_dx, l_dy;
|
||||
// precinct width and height
|
||||
l_pdx = l_tccp->prcw[resno];
|
||||
l_pdy = l_tccp->prch[resno];
|
||||
*lResolutionPtr++ = l_pdx;
|
||||
*lResolutionPtr++ = l_pdy;
|
||||
l_dx = l_img_comp->dx * (1 << (l_pdx + l_level_no));
|
||||
l_dy = l_img_comp->dy * (1 << (l_pdy + l_level_no));
|
||||
// take the minimum size for l_dx for each comp and resolution
|
||||
*p_dx_min = int_min(*p_dx_min, l_dx);
|
||||
*p_dy_min = int_min(*p_dy_min, l_dy);
|
||||
// various calculations of extents
|
||||
|
||||
l_rx0 = int_ceildivpow2(l_tcx0, l_level_no);
|
||||
l_ry0 = int_ceildivpow2(l_tcy0, l_level_no);
|
||||
l_rx1 = int_ceildivpow2(l_tcx1, l_level_no);
|
||||
l_ry1 = int_ceildivpow2(l_tcy1, l_level_no);
|
||||
l_px0 = int_floordivpow2(l_rx0, l_pdx) << l_pdx;
|
||||
l_py0 = int_floordivpow2(l_ry0, l_pdy) << l_pdy;
|
||||
l_px1 = int_ceildivpow2(l_rx1, l_pdx) << l_pdx;
|
||||
py1 = int_ceildivpow2(l_ry1, l_pdy) << l_pdy;
|
||||
l_pw = (l_rx0==l_rx1)?0:((l_px1 - l_px0) >> l_pdx);
|
||||
l_ph = (l_ry0==l_ry1)?0:((py1 - l_py0) >> l_pdy);
|
||||
*lResolutionPtr++ = l_pw;
|
||||
*lResolutionPtr++ = l_ph;
|
||||
l_product = l_pw * l_ph;
|
||||
// update precision
|
||||
if
|
||||
(l_product > *p_max_prec)
|
||||
{
|
||||
*p_max_prec = l_product;
|
||||
}
|
||||
--l_level_no;
|
||||
}
|
||||
++l_tccp;
|
||||
++l_img_comp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates memory for a packet iterator. Data and data sizes are set by this operation.
|
||||
* No other data is set. The include section of the packet iterator is not allocated.
|
||||
*
|
||||
* @param p_image the image used to initialize the packet iterator (in fact only the number of components is relevant.
|
||||
* @param p_cp the coding parameters.
|
||||
* @param p_tile_no the index of the tile from which creating the packet iterator.
|
||||
*/
|
||||
opj_pi_iterator_t * pi_create(
|
||||
const opj_image_t *image,
|
||||
const opj_cp_v2_t *cp,
|
||||
OPJ_UINT32 tileno
|
||||
)
|
||||
{
|
||||
// loop
|
||||
OPJ_UINT32 pino, compno;
|
||||
// number of poc in the p_pi
|
||||
OPJ_UINT32 l_poc_bound;
|
||||
|
||||
// pointers to tile coding parameters and components.
|
||||
opj_pi_iterator_t *l_pi = 00;
|
||||
opj_tcp_v2_t *tcp = 00;
|
||||
const opj_tccp_t *tccp = 00;
|
||||
|
||||
// current packet iterator being allocated
|
||||
opj_pi_iterator_t *l_current_pi = 00;
|
||||
|
||||
// preconditions in debug
|
||||
assert(cp != 00);
|
||||
assert(image != 00);
|
||||
assert(tileno < cp->tw * cp->th);
|
||||
|
||||
// initializations
|
||||
tcp = &cp->tcps[tileno];
|
||||
l_poc_bound = tcp->numpocs+1;
|
||||
|
||||
|
||||
// memory allocations
|
||||
l_pi = (opj_pi_iterator_t*) opj_calloc((l_poc_bound), sizeof(opj_pi_iterator_t));
|
||||
|
||||
if
|
||||
(!l_pi)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
memset(l_pi,0,l_poc_bound * sizeof(opj_pi_iterator_t));
|
||||
l_current_pi = l_pi;
|
||||
for
|
||||
(pino = 0; pino < l_poc_bound ; ++pino)
|
||||
{
|
||||
l_current_pi->comps = (opj_pi_comp_t*) opj_calloc(image->numcomps, sizeof(opj_pi_comp_t));
|
||||
if
|
||||
(! l_current_pi->comps)
|
||||
{
|
||||
pi_destroy_v2(l_pi, l_poc_bound);
|
||||
return 00;
|
||||
}
|
||||
l_current_pi->numcomps = image->numcomps;
|
||||
memset(l_current_pi->comps,0,image->numcomps * sizeof(opj_pi_comp_t));
|
||||
for
|
||||
(compno = 0; compno < image->numcomps; ++compno)
|
||||
{
|
||||
opj_pi_comp_t *comp = &l_current_pi->comps[compno];
|
||||
tccp = &tcp->tccps[compno];
|
||||
comp->resolutions = (opj_pi_resolution_t*) opj_malloc(tccp->numresolutions * sizeof(opj_pi_resolution_t));
|
||||
if
|
||||
(!comp->resolutions)
|
||||
{
|
||||
pi_destroy_v2(l_pi, l_poc_bound);
|
||||
return 00;
|
||||
}
|
||||
comp->numresolutions = tccp->numresolutions;
|
||||
memset(comp->resolutions,0,tccp->numresolutions * sizeof(opj_pi_resolution_t));
|
||||
}
|
||||
++l_current_pi;
|
||||
}
|
||||
return l_pi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Destroys a packet iterator array.
|
||||
*
|
||||
* @param p_pi the packet iterator array to destroy.
|
||||
* @param p_nb_elements the number of elements in the array.
|
||||
*/
|
||||
void pi_destroy_v2(
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_UINT32 p_nb_elements)
|
||||
{
|
||||
OPJ_UINT32 compno, pino;
|
||||
opj_pi_iterator_t *l_current_pi = p_pi;
|
||||
if
|
||||
(p_pi)
|
||||
{
|
||||
if
|
||||
(p_pi->include)
|
||||
{
|
||||
opj_free(p_pi->include);
|
||||
p_pi->include = 00;
|
||||
}
|
||||
// TODO
|
||||
for
|
||||
(pino = 0; pino < p_nb_elements; ++pino)
|
||||
{
|
||||
if
|
||||
(l_current_pi->comps)
|
||||
{
|
||||
opj_pi_comp_t *l_current_component = l_current_pi->comps;
|
||||
for
|
||||
(compno = 0; compno < l_current_pi->numcomps; compno++)
|
||||
{
|
||||
if
|
||||
(l_current_component->resolutions)
|
||||
{
|
||||
opj_free(l_current_component->resolutions);
|
||||
l_current_component->resolutions = 00;
|
||||
}
|
||||
++l_current_component;
|
||||
}
|
||||
opj_free(l_current_pi->comps);
|
||||
l_current_pi->comps = 0;
|
||||
}
|
||||
++l_current_pi;
|
||||
}
|
||||
opj_free(p_pi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pi_update_decode_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ_UINT32 p_max_precision,OPJ_UINT32 p_max_res)
|
||||
{
|
||||
// loop
|
||||
OPJ_UINT32 pino;
|
||||
|
||||
// encoding prameters to set
|
||||
OPJ_UINT32 l_bound;
|
||||
|
||||
opj_pi_iterator_t * l_current_pi = 00;
|
||||
opj_poc_t* l_current_poc = 0;
|
||||
|
||||
// preconditions in debug
|
||||
assert(p_pi != 00);
|
||||
assert(p_tcp != 00);
|
||||
|
||||
// initializations
|
||||
l_bound = p_tcp->numpocs+1;
|
||||
l_current_pi = p_pi;
|
||||
l_current_poc = p_tcp->pocs;
|
||||
|
||||
for
|
||||
(pino = 0;pino<l_bound;++pino)
|
||||
{
|
||||
l_current_pi->poc.prg = l_current_poc->prg;
|
||||
l_current_pi->first = 1;
|
||||
|
||||
l_current_pi->poc.resno0 = l_current_poc->resno0;
|
||||
l_current_pi->poc.compno0 = l_current_poc->compno0;
|
||||
l_current_pi->poc.layno0 = 0;
|
||||
l_current_pi->poc.precno0 = 0;
|
||||
l_current_pi->poc.resno1 = l_current_poc->resno1;
|
||||
l_current_pi->poc.compno1 = l_current_poc->compno1;
|
||||
l_current_pi->poc.layno1 = l_current_poc->layno1;
|
||||
l_current_pi->poc.precno1 = p_max_precision;
|
||||
++l_current_pi;
|
||||
++l_current_poc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ_UINT32 p_max_precision,OPJ_UINT32 p_max_res)
|
||||
{
|
||||
// loop
|
||||
OPJ_UINT32 pino;
|
||||
|
||||
// encoding prameters to set
|
||||
OPJ_UINT32 l_bound;
|
||||
|
||||
opj_pi_iterator_t * l_current_pi = 00;
|
||||
// preconditions in debug
|
||||
assert(p_tcp != 00);
|
||||
assert(p_pi != 00);
|
||||
|
||||
// initializations
|
||||
l_bound = p_tcp->numpocs+1;
|
||||
l_current_pi = p_pi;
|
||||
|
||||
for
|
||||
(pino = 0;pino<l_bound;++pino)
|
||||
{
|
||||
l_current_pi->poc.prg = p_tcp->prg;
|
||||
l_current_pi->first = 1;
|
||||
l_current_pi->poc.resno0 = 0;
|
||||
l_current_pi->poc.compno0 = 0;
|
||||
l_current_pi->poc.layno0 = 0;
|
||||
l_current_pi->poc.precno0 = 0;
|
||||
l_current_pi->poc.resno1 = p_max_res;
|
||||
l_current_pi->poc.compno1 = l_current_pi->numcomps;
|
||||
l_current_pi->poc.layno1 = p_tcp->numlayers;
|
||||
l_current_pi->poc.precno1 = p_max_precision;
|
||||
++l_current_pi;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -133,6 +133,18 @@ Create a packet iterator for Decoder
|
|||
*/
|
||||
opj_pi_iterator_t *pi_create_decode(opj_image_t * image, opj_cp_t * cp, int tileno);
|
||||
|
||||
|
||||
/**
|
||||
Create a packet iterator for Decoder
|
||||
@param image Raw image for which the packets will be listed
|
||||
@param cp Coding parameters
|
||||
@param tileno Number that identifies the tile for which to list the packets
|
||||
@return Returns a packet iterator that points to the first packet of the tile
|
||||
@see pi_destroy
|
||||
*/
|
||||
opj_pi_iterator_t *pi_create_decode_v2(struct opj_image * image, struct opj_cp_v2 * cp, OPJ_UINT32 tileno);
|
||||
|
||||
|
||||
/**
|
||||
Destroy a packet iterator
|
||||
@param pi Previously created packet iterator
|
||||
|
@ -142,6 +154,17 @@ Destroy a packet iterator
|
|||
*/
|
||||
void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno);
|
||||
|
||||
|
||||
/**
|
||||
* Destroys a packet iterator array.
|
||||
*
|
||||
* @param p_pi the packet iterator array to destroy.
|
||||
* @param p_nb_elements the number of elements in the array.
|
||||
*/
|
||||
void pi_destroy_v2(
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_UINT32 p_nb_elements);
|
||||
|
||||
/**
|
||||
Modify the packet iterator to point to the next packet
|
||||
@param pi Packet iterator to modify
|
||||
|
|
|
@ -1582,3 +1582,74 @@ void t1_decode_cblks(
|
|||
} /* resno */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/**
|
||||
* Creates a new Tier 1 handle
|
||||
* and initializes the look-up tables of the Tier-1 coder/decoder
|
||||
* @return a new T1 handle if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_t1_t* t1_create_v2()
|
||||
{
|
||||
opj_t1_t *l_t1 = 00;
|
||||
|
||||
l_t1 = (opj_t1_t*) opj_malloc(sizeof(opj_t1_t));
|
||||
if
|
||||
(!l_t1)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
memset(l_t1,0,sizeof(opj_t1_t));
|
||||
|
||||
/* create MQC and RAW handles */
|
||||
l_t1->mqc = mqc_create();
|
||||
if
|
||||
(! l_t1->mqc)
|
||||
{
|
||||
t1_destroy(l_t1);
|
||||
return 00;
|
||||
}
|
||||
l_t1->raw = raw_create();
|
||||
if
|
||||
(! l_t1->raw)
|
||||
{
|
||||
t1_destroy(l_t1);
|
||||
return 00;
|
||||
}
|
||||
return l_t1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroys a previously created T1 handle
|
||||
*
|
||||
* @param p_t1 Tier 1 handle to destroy
|
||||
*/
|
||||
void t1_destroy_v2(opj_t1_t *p_t1)
|
||||
{
|
||||
if
|
||||
(! p_t1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* destroy MQC and RAW handles */
|
||||
mqc_destroy(p_t1->mqc);
|
||||
p_t1->mqc = 00;
|
||||
raw_destroy(p_t1->raw);
|
||||
p_t1->raw = 00;
|
||||
if
|
||||
(p_t1->data)
|
||||
{
|
||||
opj_aligned_free(p_t1->data);
|
||||
p_t1->data = 00;
|
||||
}
|
||||
if
|
||||
(p_t1->flags)
|
||||
{
|
||||
opj_aligned_free(p_t1->flags);
|
||||
p_t1->flags = 00;
|
||||
}
|
||||
opj_free(p_t1);
|
||||
}
|
||||
|
|
|
@ -139,6 +139,22 @@ Decode the code-blocks of a tile
|
|||
@param tccp Tile coding parameters
|
||||
*/
|
||||
void t1_decode_cblks(opj_t1_t* t1, opj_tcd_tilecomp_t* tilec, opj_tccp_t* tccp);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new Tier 1 handle
|
||||
* and initializes the look-up tables of the Tier-1 coder/decoder
|
||||
* @return a new T1 handle if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_t1_t* t1_create_v2();
|
||||
|
||||
/**
|
||||
* Destroys a previously created T1 handle
|
||||
*
|
||||
* @param p_t1 Tier 1 handle to destroy
|
||||
*/
|
||||
void t1_destroy_v2(opj_t1_t *p_t1);
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
823
libopenjpeg/t2.c
823
libopenjpeg/t2.c
|
@ -79,6 +79,72 @@ Decode a packet of a tile from a source buffer
|
|||
static int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile,
|
||||
opj_tcp_t *tcp, opj_pi_iterator_t *pi, opj_packet_info_t *pack_info);
|
||||
|
||||
|
||||
/**
|
||||
Decode a packet of a tile from a source buffer
|
||||
@param t2 T2 handle
|
||||
@param src Source buffer
|
||||
@param len Length of the source buffer
|
||||
@param tile Tile for which to write the packets
|
||||
@param tcp Tile coding parameters
|
||||
@param pi Packet identity
|
||||
@return
|
||||
*/
|
||||
static opj_bool t2_decode_packet_v2(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info);
|
||||
|
||||
static opj_bool t2_skip_packet(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info);
|
||||
|
||||
static opj_bool t2_read_packet_header(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
opj_bool * p_is_data_present,
|
||||
OPJ_BYTE *p_src_data,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info);
|
||||
|
||||
static opj_bool t2_read_packet_data(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src_data,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *pack_info);
|
||||
|
||||
static opj_bool t2_skip_packet_data(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *pack_info);
|
||||
|
||||
/**
|
||||
@param seg
|
||||
@param cblksty
|
||||
@param first
|
||||
*/
|
||||
static opj_bool t2_init_seg_v2(opj_tcd_cblk_dec_t* cblk, OPJ_UINT32 index, OPJ_UINT32 cblksty, OPJ_UINT32 first);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*@}*/
|
||||
|
@ -768,6 +834,116 @@ int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj
|
|||
return (c - src);
|
||||
}
|
||||
|
||||
opj_bool t2_decode_packets_v2(
|
||||
opj_t2_v2_t *p_t2,
|
||||
OPJ_UINT32 p_tile_no,
|
||||
struct opj_tcd_tile *p_tile,
|
||||
OPJ_BYTE *p_src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_len,
|
||||
struct opj_codestream_info *p_cstr_info)
|
||||
{
|
||||
OPJ_BYTE *l_current_data = p_src;
|
||||
opj_pi_iterator_t *l_pi = 00;
|
||||
OPJ_UINT32 pino;
|
||||
opj_image_t *l_image = p_t2->image;
|
||||
opj_cp_v2_t *l_cp = p_t2->cp;
|
||||
opj_cp_v2_t *cp = p_t2->cp;
|
||||
opj_tcp_v2_t *l_tcp = &(p_t2->cp->tcps[p_tile_no]);
|
||||
OPJ_UINT32 l_nb_bytes_read;
|
||||
OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
|
||||
opj_pi_iterator_t *l_current_pi = 00;
|
||||
OPJ_UINT32 curtp = 0;
|
||||
OPJ_UINT32 tp_start_packno;
|
||||
opj_packet_info_t *l_pack_info = 00;
|
||||
opj_image_comp_t* l_img_comp = 00;
|
||||
|
||||
|
||||
if
|
||||
(p_cstr_info)
|
||||
{
|
||||
l_pack_info = p_cstr_info->tile[p_tile_no].packet;
|
||||
}
|
||||
|
||||
/* create a packet iterator */
|
||||
l_pi = pi_create_decode_v2(l_image, l_cp, p_tile_no);
|
||||
if
|
||||
(!l_pi)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
tp_start_packno = 0;
|
||||
l_current_pi = l_pi;
|
||||
|
||||
for
|
||||
(pino = 0; pino <= l_tcp->numpocs; ++pino)
|
||||
{
|
||||
while
|
||||
(pi_next(l_current_pi))
|
||||
{
|
||||
|
||||
if
|
||||
(l_tcp->num_layers_to_decode > l_current_pi->layno && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions)
|
||||
{
|
||||
l_nb_bytes_read = 0;
|
||||
if
|
||||
(! t2_decode_packet_v2(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info))
|
||||
{
|
||||
pi_destroy_v2(l_pi,l_nb_pocs);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
l_img_comp = &(l_image->comps[l_current_pi->compno]);
|
||||
l_img_comp->resno_decoded = uint_max(l_current_pi->resno, l_img_comp->resno_decoded);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_nb_bytes_read = 0;
|
||||
if
|
||||
(! t2_skip_packet(p_t2,p_tile,l_tcp,l_current_pi,l_current_data,&l_nb_bytes_read,p_max_len,l_pack_info))
|
||||
{
|
||||
pi_destroy_v2(l_pi,l_nb_pocs);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
l_current_data += l_nb_bytes_read;
|
||||
p_max_len -= l_nb_bytes_read;
|
||||
|
||||
/* INDEX >> */
|
||||
if(p_cstr_info) {
|
||||
opj_tile_info_t *info_TL = &p_cstr_info->tile[p_tile_no];
|
||||
opj_packet_info_t *info_PK = &info_TL->packet[p_cstr_info->packno];
|
||||
if (!p_cstr_info->packno) {
|
||||
info_PK->start_pos = info_TL->end_header + 1;
|
||||
} else if (info_TL->packet[p_cstr_info->packno-1].end_pos >= (OPJ_INT32)p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_pos){ // New tile part
|
||||
info_TL->tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; // Number of packets in previous tile-part
|
||||
tp_start_packno = p_cstr_info->packno;
|
||||
curtp++;
|
||||
info_PK->start_pos = p_cstr_info->tile[p_tile_no].tp[curtp].tp_end_header+1;
|
||||
} else {
|
||||
info_PK->start_pos = (cp->m_specific_param.m_enc.m_tp_on && info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[p_cstr_info->packno - 1].end_pos + 1;
|
||||
}
|
||||
info_PK->end_pos = info_PK->start_pos + l_nb_bytes_read - 1;
|
||||
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
|
||||
++p_cstr_info->packno;
|
||||
}
|
||||
/* << INDEX */
|
||||
}
|
||||
++l_current_pi;
|
||||
}
|
||||
/* INDEX >> */
|
||||
if
|
||||
(p_cstr_info) {
|
||||
p_cstr_info->tile[p_tile_no].tp[curtp].tp_numpacks = p_cstr_info->packno - tp_start_packno; // Number of packets in last tile-part
|
||||
}
|
||||
/* << INDEX */
|
||||
|
||||
/* don't forget to release pi */
|
||||
pi_destroy_v2(l_pi,l_nb_pocs);
|
||||
*p_data_read = l_current_data - p_src;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) {
|
||||
|
@ -781,13 +957,660 @@ opj_t2_t* t2_create(opj_common_ptr cinfo, opj_image_t *image, opj_cp_t *cp) {
|
|||
return t2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Tier 2 handle
|
||||
*
|
||||
* @param p_image Source or destination image
|
||||
* @param p_cp Image coding parameters.
|
||||
* @return a new T2 handle if successful, NULL otherwise.
|
||||
*/
|
||||
opj_t2_v2_t* t2_create_v2(
|
||||
opj_image_t *p_image,
|
||||
opj_cp_v2_t *p_cp)
|
||||
{
|
||||
/* create the tcd structure */
|
||||
opj_t2_v2_t *l_t2 = (opj_t2_v2_t*)opj_malloc(sizeof(opj_t2_v2_t));
|
||||
if
|
||||
(!l_t2)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
memset(l_t2,0,sizeof(opj_t2_t));
|
||||
l_t2->image = p_image;
|
||||
l_t2->cp = p_cp;
|
||||
return l_t2;
|
||||
}
|
||||
|
||||
void t2_destroy(opj_t2_t *t2) {
|
||||
if(t2) {
|
||||
opj_free(t2);
|
||||
}
|
||||
}
|
||||
|
||||
void t2_destroy_v2(opj_t2_v2_t *t2) {
|
||||
if(t2) {
|
||||
opj_free(t2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static opj_bool t2_decode_packet_v2(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info)
|
||||
{
|
||||
opj_bool l_read_data;
|
||||
OPJ_UINT32 l_nb_bytes_read = 0;
|
||||
OPJ_UINT32 l_nb_total_bytes_read = 0;
|
||||
|
||||
*p_data_read = 0;
|
||||
|
||||
if
|
||||
(! t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info))
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
p_src += l_nb_bytes_read;
|
||||
l_nb_total_bytes_read += l_nb_bytes_read;
|
||||
p_max_length -= l_nb_bytes_read;
|
||||
/* we should read data for the packet */
|
||||
if
|
||||
(l_read_data)
|
||||
{
|
||||
l_nb_bytes_read = 0;
|
||||
if
|
||||
(! t2_read_packet_data(p_t2,p_tile,p_pi,p_src,&l_nb_bytes_read,p_max_length,p_pack_info))
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
l_nb_total_bytes_read += l_nb_bytes_read;
|
||||
}
|
||||
*p_data_read = l_nb_total_bytes_read;
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
static opj_bool t2_skip_packet(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info)
|
||||
{
|
||||
opj_bool l_read_data;
|
||||
OPJ_UINT32 l_nb_bytes_read = 0;
|
||||
OPJ_UINT32 l_nb_total_bytes_read = 0;
|
||||
|
||||
*p_data_read = 0;
|
||||
|
||||
if
|
||||
(! t2_read_packet_header(p_t2,p_tile,p_tcp,p_pi,&l_read_data,p_src,&l_nb_bytes_read,p_max_length,p_pack_info))
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
p_src += l_nb_bytes_read;
|
||||
l_nb_total_bytes_read += l_nb_bytes_read;
|
||||
p_max_length -= l_nb_bytes_read;
|
||||
/* we should read data for the packet */
|
||||
if
|
||||
(l_read_data)
|
||||
{
|
||||
l_nb_bytes_read = 0;
|
||||
if
|
||||
(! t2_skip_packet_data(p_t2,p_tile,p_pi,&l_nb_bytes_read,p_max_length,p_pack_info))
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
l_nb_total_bytes_read += l_nb_bytes_read;
|
||||
}
|
||||
*p_data_read = l_nb_total_bytes_read;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static opj_bool t2_read_packet_header(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_tcp_v2_t *p_tcp,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
opj_bool * p_is_data_present,
|
||||
OPJ_BYTE *p_src_data,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *p_pack_info)
|
||||
{
|
||||
/* loop */
|
||||
OPJ_UINT32 bandno, cblkno;
|
||||
OPJ_UINT32 l_nb_code_blocks;
|
||||
OPJ_UINT32 l_remaining_length;
|
||||
OPJ_UINT32 l_header_length;
|
||||
OPJ_UINT32 * l_modified_length_ptr = 00;
|
||||
OPJ_BYTE *l_current_data = p_src_data;
|
||||
opj_cp_v2_t *l_cp = p_t2->cp;
|
||||
opj_bio_t *l_bio = 00; /* BIO component */
|
||||
opj_tcd_band_t *l_band = 00;
|
||||
opj_tcd_cblk_dec_t* l_cblk = 00;
|
||||
opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
|
||||
|
||||
OPJ_BYTE *l_header_data = 00;
|
||||
OPJ_BYTE **l_header_data_start = 00;
|
||||
|
||||
OPJ_UINT32 l_present;
|
||||
|
||||
if
|
||||
(p_pi->layno == 0)
|
||||
{
|
||||
l_band = l_res->bands;
|
||||
/* reset tagtrees */
|
||||
for
|
||||
(bandno = 0; bandno < l_res->numbands; ++bandno)
|
||||
{
|
||||
opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
|
||||
|
||||
if (
|
||||
! ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0)))
|
||||
{
|
||||
tgt_reset(l_prc->incltree);
|
||||
tgt_reset(l_prc->imsbtree);
|
||||
l_cblk = l_prc->cblks.dec;
|
||||
l_nb_code_blocks = l_prc->cw * l_prc->ch;
|
||||
for
|
||||
(cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)
|
||||
{
|
||||
l_cblk->numsegs = 0;
|
||||
l_cblk->real_num_segs = 0;
|
||||
++l_cblk;
|
||||
}
|
||||
}
|
||||
++l_band;
|
||||
}
|
||||
}
|
||||
|
||||
/* SOP markers */
|
||||
|
||||
if (p_tcp->csty & J2K_CP_CSTY_SOP) {
|
||||
if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) {
|
||||
// TODO opj_event_msg(t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n");
|
||||
} else {
|
||||
l_current_data += 6;
|
||||
}
|
||||
|
||||
/** TODO : check the Nsop value */
|
||||
}
|
||||
|
||||
/*
|
||||
When the marker PPT/PPM is used the packet header are store in PPT/PPM marker
|
||||
This part deal with this caracteristic
|
||||
step 1: Read packet header in the saved structure
|
||||
step 2: Return to codestream for decoding
|
||||
*/
|
||||
|
||||
l_bio = bio_create();
|
||||
if
|
||||
(! l_bio)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
if
|
||||
(l_cp->ppm == 1)
|
||||
{ /* PPM */
|
||||
l_header_data_start = &l_cp->ppm_data;
|
||||
l_header_data = *l_header_data_start;
|
||||
l_modified_length_ptr = &(l_cp->ppm_len);
|
||||
|
||||
}
|
||||
else if
|
||||
(p_tcp->ppt == 1)
|
||||
{ /* PPT */
|
||||
l_header_data_start = &(p_tcp->ppt_data);
|
||||
l_header_data = *l_header_data_start;
|
||||
l_modified_length_ptr = &(p_tcp->ppt_len);
|
||||
}
|
||||
else
|
||||
{ /* Normal Case */
|
||||
l_header_data_start = &(l_current_data);
|
||||
l_header_data = *l_header_data_start;
|
||||
l_remaining_length = p_src_data+p_max_length-l_header_data;
|
||||
l_modified_length_ptr = &(l_remaining_length);
|
||||
}
|
||||
bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr);
|
||||
l_present = bio_read(l_bio, 1);
|
||||
if
|
||||
(!l_present)
|
||||
{
|
||||
bio_inalign(l_bio);
|
||||
l_header_data += bio_numbytes(l_bio);
|
||||
bio_destroy(l_bio);
|
||||
/* EPH markers */
|
||||
if (p_tcp->csty & J2K_CP_CSTY_EPH) {
|
||||
if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
|
||||
printf("Error : expected EPH marker\n");
|
||||
} else {
|
||||
l_header_data += 2;
|
||||
}
|
||||
}
|
||||
l_header_length = (l_header_data - *l_header_data_start);
|
||||
*l_modified_length_ptr -= l_header_length;
|
||||
*l_header_data_start += l_header_length;
|
||||
/* << INDEX */
|
||||
// End of packet header position. Currently only represents the distance to start of packet
|
||||
// Will be updated later by incrementing with packet start value
|
||||
if
|
||||
(p_pack_info)
|
||||
{
|
||||
p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
|
||||
}
|
||||
/* INDEX >> */
|
||||
* p_is_data_present = OPJ_FALSE;
|
||||
*p_data_read = l_current_data - p_src_data;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
l_band = l_res->bands;
|
||||
for
|
||||
(bandno = 0; bandno < l_res->numbands; ++bandno)
|
||||
{
|
||||
opj_tcd_precinct_t *l_prc = &(l_band->precincts[p_pi->precno]);
|
||||
|
||||
if ((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0))
|
||||
{
|
||||
++l_band;
|
||||
continue;
|
||||
}
|
||||
l_nb_code_blocks = l_prc->cw * l_prc->ch;
|
||||
l_cblk = l_prc->cblks.dec;
|
||||
for
|
||||
(cblkno = 0; cblkno < l_nb_code_blocks; cblkno++)
|
||||
{
|
||||
OPJ_UINT32 l_included,l_increment, l_segno;
|
||||
OPJ_INT32 n;
|
||||
/* if cblk not yet included before --> inclusion tagtree */
|
||||
if
|
||||
(!l_cblk->numsegs)
|
||||
{
|
||||
l_included = tgt_decode(l_bio, l_prc->incltree, cblkno, p_pi->layno + 1);
|
||||
/* else one bit */
|
||||
}
|
||||
else
|
||||
{
|
||||
l_included = bio_read(l_bio, 1);
|
||||
}
|
||||
/* if cblk not included */
|
||||
if
|
||||
(!l_included)
|
||||
{
|
||||
l_cblk->numnewpasses = 0;
|
||||
++l_cblk;
|
||||
continue;
|
||||
}
|
||||
/* if cblk not yet included --> zero-bitplane tagtree */
|
||||
if
|
||||
(!l_cblk->numsegs)
|
||||
{
|
||||
OPJ_UINT32 i = 0;
|
||||
while
|
||||
(!tgt_decode(l_bio, l_prc->imsbtree, cblkno, i))
|
||||
{
|
||||
++i;
|
||||
}
|
||||
l_cblk->numbps = l_band->numbps + 1 - i;
|
||||
l_cblk->numlenbits = 3;
|
||||
}
|
||||
/* number of coding passes */
|
||||
l_cblk->numnewpasses = t2_getnumpasses(l_bio);
|
||||
l_increment = t2_getcommacode(l_bio);
|
||||
/* length indicator increment */
|
||||
l_cblk->numlenbits += l_increment;
|
||||
l_segno = 0;
|
||||
if
|
||||
(!l_cblk->numsegs)
|
||||
{
|
||||
if
|
||||
(! t2_init_seg_v2(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 1))
|
||||
{
|
||||
bio_destroy(l_bio);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
l_segno = l_cblk->numsegs - 1;
|
||||
if
|
||||
(l_cblk->segs[l_segno].numpasses == l_cblk->segs[l_segno].maxpasses)
|
||||
{
|
||||
++l_segno;
|
||||
if
|
||||
(! t2_init_seg_v2(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0))
|
||||
{
|
||||
bio_destroy(l_bio);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
n = l_cblk->numnewpasses;
|
||||
|
||||
do {
|
||||
l_cblk->segs[l_segno].numnewpasses = int_min(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses, n);
|
||||
l_cblk->segs[l_segno].newlen = bio_read(l_bio, l_cblk->numlenbits + uint_floorlog2(l_cblk->segs[l_segno].numnewpasses));
|
||||
n -= l_cblk->segs[l_segno].numnewpasses;
|
||||
if
|
||||
(n > 0)
|
||||
{
|
||||
++l_segno;
|
||||
if
|
||||
(! t2_init_seg_v2(l_cblk, l_segno, p_tcp->tccps[p_pi->compno].cblksty, 0))
|
||||
{
|
||||
bio_destroy(l_bio);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (n > 0);
|
||||
++l_cblk;
|
||||
}
|
||||
++l_band;
|
||||
}
|
||||
|
||||
if
|
||||
(bio_inalign(l_bio))
|
||||
{
|
||||
bio_destroy(l_bio);
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
l_header_data += bio_numbytes(l_bio);
|
||||
bio_destroy(l_bio);
|
||||
|
||||
/* EPH markers */
|
||||
if (p_tcp->csty & J2K_CP_CSTY_EPH) {
|
||||
if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) {
|
||||
// TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n");
|
||||
} else {
|
||||
l_header_data += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
l_header_length = (l_header_data - *l_header_data_start);
|
||||
*l_modified_length_ptr -= l_header_length;
|
||||
*l_header_data_start += l_header_length;
|
||||
/* << INDEX */
|
||||
// End of packet header position. Currently only represents the distance to start of packet
|
||||
// Will be updated later by incrementing with packet start value
|
||||
if
|
||||
(p_pack_info)
|
||||
{
|
||||
p_pack_info->end_ph_pos = (OPJ_INT32)(l_current_data - p_src_data);
|
||||
}
|
||||
/* INDEX >> */
|
||||
* p_is_data_present = OPJ_TRUE;
|
||||
*p_data_read = l_current_data - p_src_data;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static opj_bool t2_read_packet_data(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_BYTE *p_src_data,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *pack_info)
|
||||
{
|
||||
OPJ_UINT32 bandno, cblkno;
|
||||
OPJ_UINT32 l_nb_code_blocks;
|
||||
OPJ_BYTE *l_current_data = p_src_data;
|
||||
opj_tcd_band_t *l_band = 00;
|
||||
opj_tcd_cblk_dec_t* l_cblk = 00;
|
||||
opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
|
||||
|
||||
l_band = l_res->bands;
|
||||
for
|
||||
(bandno = 0; bandno < l_res->numbands; ++bandno)
|
||||
{
|
||||
opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
|
||||
|
||||
if
|
||||
((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0))
|
||||
{
|
||||
++l_band;
|
||||
continue;
|
||||
}
|
||||
l_nb_code_blocks = l_prc->cw * l_prc->ch;
|
||||
l_cblk = l_prc->cblks.dec;
|
||||
for
|
||||
(cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)
|
||||
{
|
||||
opj_tcd_seg_t *l_seg = 00;
|
||||
if
|
||||
(!l_cblk->numnewpasses)
|
||||
{
|
||||
/* nothing to do */
|
||||
++l_cblk;
|
||||
continue;
|
||||
}
|
||||
if
|
||||
(!l_cblk->numsegs)
|
||||
{
|
||||
l_seg = l_cblk->segs;
|
||||
++l_cblk->numsegs;
|
||||
l_cblk->len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
||||
if
|
||||
(l_seg->numpasses == l_seg->maxpasses)
|
||||
{
|
||||
++l_seg;
|
||||
++l_cblk->numsegs;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if
|
||||
(l_current_data + l_seg->newlen > p_src_data + p_max_length)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
#ifdef USE_JPWL
|
||||
/* we need here a j2k handle to verify if making a check to
|
||||
the validity of cblocks parameters is selected from user (-W) */
|
||||
|
||||
/* let's check that we are not exceeding */
|
||||
if ((cblk->len + seg->newlen) > 8192) {
|
||||
opj_event_msg(t2->cinfo, EVT_WARNING,
|
||||
"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
|
||||
seg->newlen, cblkno, precno, bandno, resno, compno);
|
||||
if (!JPWL_ASSUME) {
|
||||
opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
|
||||
return -999;
|
||||
}
|
||||
seg->newlen = 8192 - cblk->len;
|
||||
opj_event_msg(t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", seg->newlen);
|
||||
break;
|
||||
};
|
||||
|
||||
#endif /* USE_JPWL */
|
||||
|
||||
memcpy(l_cblk->data + l_cblk->len, l_current_data, l_seg->newlen);
|
||||
if
|
||||
(l_seg->numpasses == 0)
|
||||
{
|
||||
l_seg->data = &l_cblk->data;
|
||||
l_seg->dataindex = l_cblk->len;
|
||||
}
|
||||
l_current_data += l_seg->newlen;
|
||||
l_seg->numpasses += l_seg->numnewpasses;
|
||||
l_cblk->numnewpasses -= l_seg->numnewpasses;
|
||||
|
||||
l_seg->real_num_passes = l_seg->numpasses;
|
||||
l_cblk->len += l_seg->newlen;
|
||||
l_seg->len += l_seg->newlen;
|
||||
if
|
||||
(l_cblk->numnewpasses > 0)
|
||||
{
|
||||
++l_seg;
|
||||
++l_cblk->numsegs;
|
||||
}
|
||||
}
|
||||
while (l_cblk->numnewpasses > 0);
|
||||
l_cblk->real_num_segs = l_cblk->numsegs;
|
||||
++l_cblk;
|
||||
}
|
||||
++l_band;
|
||||
}
|
||||
*(p_data_read) = l_current_data - p_src_data;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static opj_bool t2_skip_packet_data(
|
||||
opj_t2_v2_t* p_t2,
|
||||
opj_tcd_tile_t *p_tile,
|
||||
opj_pi_iterator_t *p_pi,
|
||||
OPJ_UINT32 * p_data_read,
|
||||
OPJ_UINT32 p_max_length,
|
||||
opj_packet_info_t *pack_info)
|
||||
{
|
||||
OPJ_UINT32 bandno, cblkno;
|
||||
OPJ_UINT32 l_nb_code_blocks;
|
||||
opj_tcd_band_t *l_band = 00;
|
||||
opj_tcd_cblk_dec_t* l_cblk = 00;
|
||||
|
||||
opj_tcd_resolution_t* l_res = &p_tile->comps[p_pi->compno].resolutions[p_pi->resno];
|
||||
|
||||
*p_data_read = 0;
|
||||
l_band = l_res->bands;
|
||||
for
|
||||
(bandno = 0; bandno < l_res->numbands; ++bandno)
|
||||
{
|
||||
opj_tcd_precinct_t *l_prc = &l_band->precincts[p_pi->precno];
|
||||
|
||||
if
|
||||
((l_band->x1-l_band->x0 == 0)||(l_band->y1-l_band->y0 == 0))
|
||||
{
|
||||
++l_band;
|
||||
continue;
|
||||
}
|
||||
l_nb_code_blocks = l_prc->cw * l_prc->ch;
|
||||
l_cblk = l_prc->cblks.dec;
|
||||
for
|
||||
(cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno)
|
||||
{
|
||||
opj_tcd_seg_t *l_seg = 00;
|
||||
if
|
||||
(!l_cblk->numnewpasses)
|
||||
{
|
||||
/* nothing to do */
|
||||
++l_cblk;
|
||||
continue;
|
||||
}
|
||||
if
|
||||
(!l_cblk->numsegs)
|
||||
{
|
||||
l_seg = l_cblk->segs;
|
||||
++l_cblk->numsegs;
|
||||
l_cblk->len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_seg = &l_cblk->segs[l_cblk->numsegs - 1];
|
||||
if
|
||||
(l_seg->numpasses == l_seg->maxpasses)
|
||||
{
|
||||
++l_seg;
|
||||
++l_cblk->numsegs;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if
|
||||
(* p_data_read + l_seg->newlen > p_max_length)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
|
||||
#ifdef USE_JPWL
|
||||
/* we need here a j2k handle to verify if making a check to
|
||||
the validity of cblocks parameters is selected from user (-W) */
|
||||
|
||||
/* let's check that we are not exceeding */
|
||||
if ((cblk->len + seg->newlen) > 8192) {
|
||||
opj_event_msg(t2->cinfo, EVT_WARNING,
|
||||
"JPWL: segment too long (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
|
||||
seg->newlen, cblkno, precno, bandno, resno, compno);
|
||||
if (!JPWL_ASSUME) {
|
||||
opj_event_msg(t2->cinfo, EVT_ERROR, "JPWL: giving up\n");
|
||||
return -999;
|
||||
}
|
||||
seg->newlen = 8192 - cblk->len;
|
||||
opj_event_msg(t2->cinfo, EVT_WARNING, " - truncating segment to %d\n", seg->newlen);
|
||||
break;
|
||||
};
|
||||
|
||||
#endif /* USE_JPWL */
|
||||
*(p_data_read) += l_seg->newlen;
|
||||
l_seg->numpasses += l_seg->numnewpasses;
|
||||
l_cblk->numnewpasses -= l_seg->numnewpasses;
|
||||
if
|
||||
(l_cblk->numnewpasses > 0)
|
||||
{
|
||||
++l_seg;
|
||||
++l_cblk->numsegs;
|
||||
}
|
||||
}
|
||||
while (l_cblk->numnewpasses > 0);
|
||||
++l_cblk;
|
||||
}
|
||||
++l_band;
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static opj_bool t2_init_seg_v2(opj_tcd_cblk_dec_t* cblk, OPJ_UINT32 index, OPJ_UINT32 cblksty, OPJ_UINT32 first)
|
||||
{
|
||||
opj_tcd_seg_t* seg = 00;
|
||||
OPJ_UINT32 l_nb_segs = index + 1;
|
||||
|
||||
if
|
||||
(l_nb_segs > cblk->m_current_max_segs)
|
||||
{
|
||||
cblk->m_current_max_segs += J2K_DEFAULT_NB_SEGS;
|
||||
cblk->segs = (opj_tcd_seg_t*) opj_realloc(cblk->segs, cblk->m_current_max_segs * sizeof(opj_tcd_seg_t));
|
||||
if
|
||||
(! cblk->segs)
|
||||
{
|
||||
return OPJ_FALSE;
|
||||
}
|
||||
}
|
||||
seg = &cblk->segs[index];
|
||||
memset(seg,0,sizeof(opj_tcd_seg_t));
|
||||
|
||||
if (cblksty & J2K_CCP_CBLKSTY_TERMALL) {
|
||||
seg->maxpasses = 1;
|
||||
}
|
||||
else if (cblksty & J2K_CCP_CBLKSTY_LAZY) {
|
||||
if (first) {
|
||||
seg->maxpasses = 10;
|
||||
} else {
|
||||
seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1;
|
||||
}
|
||||
} else {
|
||||
seg->maxpasses = 109;
|
||||
}
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,19 @@ typedef struct opj_t2 {
|
|||
opj_cp_t *cp;
|
||||
} opj_t2_t;
|
||||
|
||||
/**
|
||||
Tier-2 coding
|
||||
*/
|
||||
typedef struct opj_t2_v2 {
|
||||
/** codec context */
|
||||
opj_common_ptr cinfo;
|
||||
|
||||
/** Encoding: pointer to the src image. Decoding: pointer to the dst image. */
|
||||
opj_image_t *image;
|
||||
/** pointer to the image coding parameters */
|
||||
opj_cp_v2_t *cp;
|
||||
} opj_t2_v2_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -83,6 +96,25 @@ Decode the packets of a tile from a source buffer
|
|||
*/
|
||||
int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile, opj_codestream_info_t *cstr_info);
|
||||
|
||||
/**
|
||||
Decode the packets of a tile from a source buffer
|
||||
@param t2 T2 handle
|
||||
@param src the source buffer
|
||||
@param len length of the source buffer
|
||||
@param tileno number that identifies the tile for which to decode the packets
|
||||
@param tile tile for which to decode the packets
|
||||
*/
|
||||
opj_bool t2_decode_packets_v2(opj_t2_v2_t *t2, OPJ_UINT32 tileno,struct opj_tcd_tile *tile, OPJ_BYTE *src, OPJ_UINT32 * p_data_read, OPJ_UINT32 len, struct opj_codestream_info *cstr_info);
|
||||
|
||||
/**
|
||||
* Creates a Tier 2 handle
|
||||
*
|
||||
* @param p_image Source or destination image
|
||||
* @param p_cp Image coding parameters.
|
||||
* @return a new T2 handle if successful, NULL otherwise.
|
||||
*/
|
||||
opj_t2_v2_t* t2_create_v2(struct opj_image *p_image, opj_cp_v2_t *p_cp);
|
||||
|
||||
/**
|
||||
Create a T2 handle
|
||||
@param cinfo Codec context info
|
||||
|
@ -97,6 +129,12 @@ Destroy a T2 handle
|
|||
*/
|
||||
void t2_destroy(opj_t2_t *t2);
|
||||
|
||||
/**
|
||||
Destroy a T2 handle
|
||||
@param t2 T2 handle to destroy
|
||||
*/
|
||||
void t2_destroy_v2(opj_t2_v2_t *t2);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
1178
libopenjpeg/tcd.c
1178
libopenjpeg/tcd.c
File diff suppressed because it is too large
Load Diff
|
@ -41,17 +41,31 @@ each other. The functions in TCD.C are used by some function in J2K.C.
|
|||
/** @defgroup TCD TCD - Implementation of a tile coder/decoder */
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
//typedef struct opj_tcd_seg {
|
||||
// unsigned char** data;
|
||||
// int dataindex;
|
||||
// int numpasses;
|
||||
// int len;
|
||||
// int maxpasses;
|
||||
// int numnewpasses;
|
||||
// int newlen;
|
||||
//} opj_tcd_seg_t;
|
||||
|
||||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
typedef struct opj_tcd_seg {
|
||||
unsigned char** data;
|
||||
int dataindex;
|
||||
int numpasses;
|
||||
int len;
|
||||
int maxpasses;
|
||||
int numnewpasses;
|
||||
int newlen;
|
||||
OPJ_BYTE ** data;
|
||||
OPJ_UINT32 dataindex;
|
||||
OPJ_UINT32 numpasses;
|
||||
OPJ_UINT32 real_num_passes;
|
||||
OPJ_UINT32 len;
|
||||
OPJ_UINT32 maxpasses;
|
||||
OPJ_UINT32 numnewpasses;
|
||||
OPJ_UINT32 newlen;
|
||||
} opj_tcd_seg_t;
|
||||
|
||||
/**
|
||||
|
@ -88,40 +102,75 @@ typedef struct opj_tcd_cblk_enc {
|
|||
int totalpasses; /* total number of passes */
|
||||
} opj_tcd_cblk_enc_t;
|
||||
|
||||
//typedef struct opj_tcd_cblk_dec {
|
||||
// unsigned char* data; /* Data */
|
||||
// opj_tcd_seg_t* segs; /* segments informations */
|
||||
// int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
// int numbps;
|
||||
// int numlenbits;
|
||||
// int len; /* length */
|
||||
// int numnewpasses; /* number of pass added to the code-blocks */
|
||||
// int numsegs; /* number of segments */
|
||||
//} opj_tcd_cblk_dec_t;
|
||||
|
||||
typedef struct opj_tcd_cblk_dec {
|
||||
unsigned char* data; /* Data */
|
||||
OPJ_BYTE * data; /* Data */
|
||||
opj_tcd_seg_t* segs; /* segments informations */
|
||||
int x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
int numbps;
|
||||
int numlenbits;
|
||||
int len; /* length */
|
||||
int numnewpasses; /* number of pass added to the code-blocks */
|
||||
int numsegs; /* number of segments */
|
||||
OPJ_INT32 x0, y0, x1, y1; /* dimension of the code-blocks : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_UINT32 numbps;
|
||||
OPJ_UINT32 numlenbits;
|
||||
OPJ_UINT32 len; /* length */
|
||||
OPJ_UINT32 numnewpasses; /* number of pass added to the code-blocks */
|
||||
OPJ_UINT32 numsegs; /* number of segments */
|
||||
OPJ_UINT32 real_num_segs;
|
||||
OPJ_UINT32 m_current_max_segs;
|
||||
} opj_tcd_cblk_dec_t;
|
||||
|
||||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
//typedef struct opj_tcd_precinct {
|
||||
// int x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
// int cw, ch; /* number of precinct in width and heigth */
|
||||
// union{ /* code-blocks informations */
|
||||
// opj_tcd_cblk_enc_t* enc;
|
||||
// opj_tcd_cblk_dec_t* dec;
|
||||
// } cblks;
|
||||
// opj_tgt_tree_t *incltree; /* inclusion tree */
|
||||
// opj_tgt_tree_t *imsbtree; /* IMSB tree */
|
||||
//} opj_tcd_precinct_t;
|
||||
|
||||
|
||||
typedef struct opj_tcd_precinct {
|
||||
int x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
int cw, ch; /* number of precinct in width and heigth */
|
||||
OPJ_INT32 x0, y0, x1, y1; /* dimension of the precinct : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_UINT32 cw, ch; /* number of precinct in width and heigth */
|
||||
union{ /* code-blocks informations */
|
||||
opj_tcd_cblk_enc_t* enc;
|
||||
opj_tcd_cblk_dec_t* dec;
|
||||
} cblks;
|
||||
opj_tgt_tree_t *incltree; /* inclusion tree */
|
||||
opj_tgt_tree_t *imsbtree; /* IMSB tree */
|
||||
OPJ_UINT32 block_size; /* size taken by cblks (in bytes) */
|
||||
struct opj_tgt_tree *incltree; /* inclusion tree */
|
||||
struct opj_tgt_tree *imsbtree; /* IMSB tree */
|
||||
} opj_tcd_precinct_t;
|
||||
|
||||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
//typedef struct opj_tcd_band {
|
||||
// int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
// int bandno;
|
||||
// opj_tcd_precinct_t *precincts; /* precinct information */
|
||||
// int numbps;
|
||||
// float stepsize;
|
||||
//} opj_tcd_band_t;
|
||||
|
||||
typedef struct opj_tcd_band {
|
||||
int x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
int bandno;
|
||||
OPJ_INT32 x0, y0, x1, y1; /* dimension of the subband : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_UINT32 bandno;
|
||||
opj_tcd_precinct_t *precincts; /* precinct information */
|
||||
int numbps;
|
||||
float stepsize;
|
||||
OPJ_UINT32 precincts_data_size; /* size of data taken by precincts */
|
||||
OPJ_INT32 numbps;
|
||||
OPJ_FLOAT32 stepsize;
|
||||
} opj_tcd_band_t;
|
||||
|
||||
/**
|
||||
|
@ -137,14 +186,27 @@ typedef struct opj_tcd_resolution {
|
|||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
typedef struct opj_tcd_tilecomp {
|
||||
int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
int numresolutions; /* number of resolutions level */
|
||||
//typedef struct opj_tcd_tilecomp {
|
||||
// int x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
// int numresolutions; /* number of resolutions level */
|
||||
// opj_tcd_resolution_t *resolutions; /* resolutions information */
|
||||
// int *data; /* data of the component */
|
||||
// int numpix; /* add fixed_quality */
|
||||
//} opj_tcd_tilecomp_t;
|
||||
|
||||
typedef struct opj_tcd_tilecomp
|
||||
{
|
||||
OPJ_INT32 x0, y0, x1, y1; /* dimension of component : left upper corner (x0, y0) right low corner (x1,y1) */
|
||||
OPJ_UINT32 numresolutions; /* number of resolutions level */
|
||||
OPJ_UINT32 minimum_num_resolutions; /* number of resolutions level to decode (at max)*/
|
||||
opj_tcd_resolution_t *resolutions; /* resolutions information */
|
||||
int *data; /* data of the component */
|
||||
int numpix; /* add fixed_quality */
|
||||
OPJ_UINT32 resolutions_size; /* size of data for resolutions (in bytes) */
|
||||
OPJ_INT32 *data; /* data of the component */
|
||||
OPJ_UINT32 data_size; /* size of the data of the component */
|
||||
OPJ_INT32 numpix; /* add fixed_quality */
|
||||
} opj_tcd_tilecomp_t;
|
||||
|
||||
|
||||
/**
|
||||
FIXME: documentation
|
||||
*/
|
||||
|
@ -200,6 +262,39 @@ typedef struct opj_tcd {
|
|||
double encoding_time;
|
||||
} opj_tcd_t;
|
||||
|
||||
|
||||
struct opj_image;
|
||||
struct opj_cp_v2;
|
||||
struct opj_tcp_v2;
|
||||
/**
|
||||
Tile coder/decoder
|
||||
*/
|
||||
typedef struct opj_tcd_v2
|
||||
{
|
||||
/** Position of the tilepart flag in Progression order*/
|
||||
OPJ_INT32 tp_pos;
|
||||
/** Tile part number*/
|
||||
OPJ_UINT32 tp_num;
|
||||
/** Current tile part number*/
|
||||
OPJ_UINT32 cur_tp_num;
|
||||
/** Total number of tileparts of the current tile*/
|
||||
OPJ_UINT32 cur_totnum_tp;
|
||||
/** Current Packet iterator number */
|
||||
OPJ_UINT32 cur_pino;
|
||||
/** info on each image tile */
|
||||
opj_tcd_image_t *tcd_image;
|
||||
/** image */
|
||||
struct opj_image *image;
|
||||
/** coding parameters */
|
||||
struct opj_cp_v2 *cp;
|
||||
/** coding/decoding parameters common to all tiles */
|
||||
struct opj_tcp_v2 *tcp;
|
||||
/** current encoded/decoded tile */
|
||||
OPJ_UINT32 tcd_tileno;
|
||||
/** tell if the tcd is a decoder. */
|
||||
OPJ_UINT32 m_is_decoder : 1;
|
||||
} opj_tcd_v2_t;
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -214,6 +309,54 @@ Create a new TCD handle
|
|||
@return Returns a new TCD handle if successful returns NULL otherwise
|
||||
*/
|
||||
opj_tcd_t* tcd_create(opj_common_ptr cinfo);
|
||||
|
||||
/**
|
||||
Create a new TCD handle
|
||||
@param FIXME
|
||||
@return Returns a new TCD handle if successful returns NULL otherwise
|
||||
*/
|
||||
opj_tcd_v2_t* tcd_create_v2(opj_bool p_is_decoder);
|
||||
|
||||
/**
|
||||
Destroy a previously created TCD handle
|
||||
@param tcd TCD handle to destroy
|
||||
*/
|
||||
void tcd_destroy_v2(opj_tcd_v2_t *tcd);
|
||||
|
||||
/**
|
||||
* Initialize the tile coder and may reuse some meory.
|
||||
* @param p_tcd TCD handle.
|
||||
* @param p_image raw image.
|
||||
* @param p_cp coding parameters.
|
||||
* @param p_tile_no current tile index to encode.
|
||||
*
|
||||
* @return true if the encoding values could be set (false otherwise).
|
||||
*/
|
||||
opj_bool tcd_init_v2(
|
||||
opj_tcd_v2_t *p_tcd,
|
||||
//struct opj_image * p_image,
|
||||
opj_image_t * p_image,
|
||||
//struct opj_cp * p_cp
|
||||
opj_cp_v2_t * p_cp
|
||||
);
|
||||
|
||||
/**
|
||||
* Allocates memory for decoding a specific tile.
|
||||
*
|
||||
* @param p_tcd the tile decoder.
|
||||
* @param p_image the image to decode.
|
||||
* @param p_cp the decoding parameters.
|
||||
* @param p_tile_no the index of the tile received in sequence. This not necesseraly lead to the
|
||||
* tile at index p_tile_no.
|
||||
* @param p_cstr_info codestream info (if any).
|
||||
*
|
||||
* @return true if the remaining data is sufficient.s
|
||||
*/
|
||||
opj_bool tcd_init_decode_tile(
|
||||
opj_tcd_v2_t *p_tcd,
|
||||
OPJ_UINT32 p_tile_no
|
||||
);
|
||||
|
||||
/**
|
||||
Destroy a previously created TCD handle
|
||||
@param tcd TCD handle to destroy
|
||||
|
@ -278,6 +421,33 @@ Free the memory allocated for decoding
|
|||
void tcd_free_decode(opj_tcd_t *tcd);
|
||||
void tcd_free_decode_tile(opj_tcd_t *tcd, int tileno);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the maximum tile size that will be taken by the tile once decoded.
|
||||
*/
|
||||
OPJ_UINT32 tcd_get_decoded_tile_size (
|
||||
opj_tcd_v2_t *p_tcd
|
||||
);
|
||||
|
||||
/**
|
||||
Decode a tile from a buffer into a raw image
|
||||
@param tcd TCD handle
|
||||
@param src Source buffer
|
||||
@param len Length of source buffer
|
||||
@param tileno Number that identifies one of the tiles to be decoded
|
||||
*/
|
||||
opj_bool tcd_decode_tile_v2(opj_tcd_v2_t *tcd, OPJ_BYTE *src, OPJ_UINT32 len, OPJ_UINT32 tileno, struct opj_codestream_info *cstr_info);
|
||||
|
||||
|
||||
/**
|
||||
* Copies tile data from the system onto the given memory block.
|
||||
*/
|
||||
opj_bool tcd_update_tile_data (
|
||||
opj_tcd_v2_t *p_tcd,
|
||||
OPJ_BYTE * p_dest,
|
||||
OPJ_UINT32 p_dest_length
|
||||
);
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/*@}*/
|
||||
|
||||
|
|
|
@ -108,6 +108,114 @@ opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv) {
|
|||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialises a tag-tree from an exixting one.
|
||||
*
|
||||
* @param p_tree the tree to reinitialize.
|
||||
* @param p_num_leafs_h the width of the array of leafs of the tree
|
||||
* @param p_num_leafs_v the height of the array of leafs of the tree
|
||||
* @return a new tag-tree if successful, NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v)
|
||||
{
|
||||
OPJ_INT32 l_nplh[32];
|
||||
OPJ_INT32 l_nplv[32];
|
||||
opj_tgt_node_t *l_node = 00;
|
||||
opj_tgt_node_t *l_parent_node = 00;
|
||||
opj_tgt_node_t *l_parent_node0 = 00;
|
||||
OPJ_UINT32 i;
|
||||
OPJ_INT32 j,k;
|
||||
OPJ_UINT32 l_num_levels;
|
||||
OPJ_UINT32 n;
|
||||
OPJ_UINT32 l_node_size;
|
||||
|
||||
if
|
||||
(! p_tree)
|
||||
{
|
||||
return 00;
|
||||
}
|
||||
if
|
||||
((p_tree->numleafsh != p_num_leafs_h) || (p_tree->numleafsv != p_num_leafs_v))
|
||||
{
|
||||
p_tree->numleafsh = p_num_leafs_h;
|
||||
p_tree->numleafsv = p_num_leafs_v;
|
||||
|
||||
l_num_levels = 0;
|
||||
l_nplh[0] = p_num_leafs_h;
|
||||
l_nplv[0] = p_num_leafs_v;
|
||||
p_tree->numnodes = 0;
|
||||
do
|
||||
{
|
||||
n = l_nplh[l_num_levels] * l_nplv[l_num_levels];
|
||||
l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2;
|
||||
l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2;
|
||||
p_tree->numnodes += n;
|
||||
++l_num_levels;
|
||||
}
|
||||
while (n > 1);
|
||||
|
||||
/* ADD */
|
||||
if
|
||||
(p_tree->numnodes == 0)
|
||||
{
|
||||
tgt_destroy(p_tree);
|
||||
return 00;
|
||||
}
|
||||
l_node_size = p_tree->numnodes * sizeof(opj_tgt_node_t);
|
||||
if
|
||||
(l_node_size > p_tree->nodes_size)
|
||||
{
|
||||
p_tree->nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size);
|
||||
if
|
||||
(! p_tree->nodes)
|
||||
{
|
||||
tgt_destroy(p_tree);
|
||||
return 00;
|
||||
}
|
||||
memset(((char *) p_tree->nodes) + p_tree->nodes_size, 0 , l_node_size - p_tree->nodes_size);
|
||||
p_tree->nodes_size = l_node_size;
|
||||
}
|
||||
l_node = p_tree->nodes;
|
||||
l_parent_node = &p_tree->nodes[p_tree->numleafsh * p_tree->numleafsv];
|
||||
l_parent_node0 = l_parent_node;
|
||||
|
||||
for
|
||||
(i = 0; i < l_num_levels - 1; ++i)
|
||||
{
|
||||
for
|
||||
(j = 0; j < l_nplv[i]; ++j)
|
||||
{
|
||||
k = l_nplh[i];
|
||||
while
|
||||
(--k >= 0)
|
||||
{
|
||||
l_node->parent = l_parent_node;
|
||||
++l_node;
|
||||
if (--k >= 0)
|
||||
{
|
||||
l_node->parent = l_parent_node;
|
||||
++l_node;
|
||||
}
|
||||
++l_parent_node;
|
||||
}
|
||||
if ((j & 1) || j == l_nplv[i] - 1)
|
||||
{
|
||||
l_parent_node0 = l_parent_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_parent_node = l_parent_node0;
|
||||
l_parent_node0 += l_nplh[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
l_node->parent = 0;
|
||||
}
|
||||
tgt_reset(p_tree);
|
||||
|
||||
return p_tree;
|
||||
}
|
||||
|
||||
void tgt_destroy(opj_tgt_tree_t *tree) {
|
||||
opj_free(tree->nodes);
|
||||
opj_free(tree);
|
||||
|
|
|
@ -52,16 +52,29 @@ typedef struct opj_tgt_node {
|
|||
int known;
|
||||
} opj_tgt_node_t;
|
||||
|
||||
///** OPJ_V1
|
||||
//Tag tree
|
||||
//*/
|
||||
//typedef struct opj_tgt_tree {
|
||||
// int numleafsh;
|
||||
// int numleafsv;
|
||||
// int numnodes;
|
||||
// opj_tgt_node_t *nodes;
|
||||
//} opj_tgt_tree_t;
|
||||
|
||||
/**
|
||||
Tag tree
|
||||
*/
|
||||
typedef struct opj_tgt_tree {
|
||||
int numleafsh;
|
||||
int numleafsv;
|
||||
int numnodes;
|
||||
opj_tgt_node_t *nodes;
|
||||
typedef struct opj_tgt_tree
|
||||
{
|
||||
OPJ_UINT32 numleafsh;
|
||||
OPJ_UINT32 numleafsv;
|
||||
OPJ_UINT32 numnodes;
|
||||
opj_tgt_node_t *nodes;
|
||||
OPJ_UINT32 nodes_size; /* maximum size taken by nodes */
|
||||
} opj_tgt_tree_t;
|
||||
|
||||
|
||||
/** @name Exported functions */
|
||||
/*@{*/
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -72,6 +85,18 @@ Create a tag-tree
|
|||
@return Returns a new tag-tree if successful, returns NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv);
|
||||
|
||||
/**
|
||||
* Reinitialises a tag-tree from an exixting one.
|
||||
*
|
||||
* @param p_tree the tree to reinitialize.
|
||||
* @param p_num_leafs_h the width of the array of leafs of the tree
|
||||
* @param p_num_leafs_v the height of the array of leafs of the tree
|
||||
* @return a new tag-tree if successful, NULL otherwise
|
||||
*/
|
||||
opj_tgt_tree_t *tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, OPJ_UINT32 p_num_leafs_v);
|
||||
|
||||
|
||||
/**
|
||||
Destroy a tag-tree, liberating memory
|
||||
@param tree Tag-tree to destroy
|
||||
|
|
|
@ -20,3 +20,9 @@
|
|||
#cmakedefine HAVE_LCMS1_H @HAVE_LCMS1_H@
|
||||
#cmakedefine HAVE_LCMS2_H @HAVE_LCMS2_H@
|
||||
|
||||
#cmakedefine CMAKE_WORDS_BIGENDIAN
|
||||
#ifdef CMAKE_WORDS_BIGENDIAN
|
||||
#define OPJ_BIG_ENDIAN
|
||||
#else
|
||||
#define OPJ_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue