[trunk] modify image_to_j2k and the lib to support functionalities given by the v2 alpha branch

This commit is contained in:
Mickael Savinaud 2012-03-15 10:23:20 +00:00
parent d9940f416b
commit 3a78e8010d
20 changed files with 7050 additions and 263 deletions

View File

@ -6,6 +6,7 @@
* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
* Copyright (c) 2005, Herve Drolon, FreeImage Team
* Copyright (c) 2006-2007, Parvatha Elangovan
* Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -211,6 +212,8 @@ void encode_help_display(void) {
fprintf(stdout," -F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n");
fprintf(stdout," Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n");
fprintf(stdout,"\n");
fprintf(stdout,"-m : use array-based MCT, values are coma separated, line by line\n");
fprintf(stdout," no specific separators between lines, no space allowed between values\n");
fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n");
fprintf(stdout," NOTICE: currently supports only RPCL order\n");
fprintf(stdout,"\n");
@ -1054,6 +1057,73 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
}
break;
/* ------------------------------------------------------ */
case 'm': /* mct input file */
{
char *lFilename = opj_optarg;
char *lMatrix;
char *lCurrentPtr ;
float *lCurrentDoublePtr;
float *lSpace;
int *l_int_ptr;
int lNbComp = 0, lTotalComp, lMctComp, i, lStrLen;
/* Open file */
FILE * lFile = fopen(lFilename,"r");
if (lFile == NULL) {
return 1;
}
/* Set size of file and read its content*/
fseek(lFile,0,SEEK_END);
lStrLen = ftell(lFile);
fseek(lFile,0,SEEK_SET);
lMatrix = (char *) malloc(lStrLen + 1);
fread(lMatrix, lStrLen, 1, lFile);
fclose(lFile);
lMatrix[lStrLen] = 0;
lCurrentPtr = lMatrix;
/* replace ',' by 0 */
while (*lCurrentPtr != 0 ) {
if (*lCurrentPtr == ' ') {
*lCurrentPtr = 0;
++lNbComp;
}
++lCurrentPtr;
}
++lNbComp;
lCurrentPtr = lMatrix;
lNbComp = (int) (sqrt(4*lNbComp + 1)/2. - 0.5);
lMctComp = lNbComp * lNbComp;
lTotalComp = lMctComp + lNbComp;
lSpace = (float *) malloc(lTotalComp * sizeof(float));
lCurrentDoublePtr = lSpace;
for (i=0;i<lMctComp;++i) {
lStrLen = strlen(lCurrentPtr) + 1;
*lCurrentDoublePtr++ = (float) atof(lCurrentPtr);
lCurrentPtr += lStrLen;
}
l_int_ptr = (int*) lCurrentDoublePtr;
for (i=0;i<lNbComp;++i) {
lStrLen = strlen(lCurrentPtr) + 1;
*l_int_ptr++ = atoi(lCurrentPtr);
lCurrentPtr += lStrLen;
}
/* TODO should not be here ! */
opj_set_MCT(parameters, lSpace, (int *)(lSpace + lMctComp), lNbComp);
/* Free memory*/
free(lSpace);
free(lMatrix);
}
break;
/* ------------------------------------------------------ */
/* UniPG>> */
@ -1486,20 +1556,30 @@ void info_callback(const char *msg, void *client_data) {
}
/* -------------------------------------------------------------------------- */
/**
* IMAGE_TO_J2K MAIN
*/
/* -------------------------------------------------------------------------- */
int main(int argc, char **argv) {
opj_bool bSuccess;
FILE *f = NULL;
opj_cparameters_t parameters; /* compression parameters */
img_fol_t img_fol;
opj_event_mgr_t event_mgr; /* event manager */
opj_stream_t *cio = 00;
opj_codec_t* cinfo = 00;
opj_image_t *image = NULL;
int i,num_images;
int imageno;
dircnt_t *dirptr = NULL;
raw_cparameters_t raw_cp;
opj_codestream_info_t cstr_info; /* Codestream information structure */
char indexfilename[OPJ_PATH_LEN]; /* index file name */
int i, num_images, imageno;
img_fol_t img_fol;
dircnt_t *dirptr = NULL;
opj_bool bSuccess;
/*
configure the event callbacks (not required)
setting of each callback is optionnal
@ -1580,6 +1660,7 @@ int main(int argc, char **argv) {
continue;
}
}
switch(parameters.decod_format) {
case PGX_DFMT:
break;
@ -1600,213 +1681,151 @@ int main(int argc, char **argv) {
continue;
}
/* decode the source image */
/* ----------------------- */
/* decode the source image */
/* ----------------------- */
switch (parameters.decod_format) {
case PGX_DFMT:
image = pgxtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pgx file\n");
return 1;
}
break;
switch (parameters.decod_format) {
case PGX_DFMT:
image = pgxtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pgx file\n");
return 1;
}
break;
case PXM_DFMT:
image = pnmtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pnm file\n");
return 1;
}
break;
case PXM_DFMT:
image = pnmtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load pnm file\n");
return 1;
}
break;
case BMP_DFMT:
image = bmptoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load bmp file\n");
return 1;
}
break;
case BMP_DFMT:
image = bmptoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load bmp file\n");
return 1;
}
break;
#ifdef HAVE_LIBTIFF
case TIF_DFMT:
image = tiftoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tiff file\n");
return 1;
}
break;
case TIF_DFMT:
image = tiftoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tiff file\n");
return 1;
}
break;
#endif /* HAVE_LIBTIFF */
case RAW_DFMT:
image = rawtoimage(parameters.infile, &parameters, &raw_cp);
if (!image) {
fprintf(stderr, "Unable to load raw file\n");
return 1;
}
break;
case TGA_DFMT:
image = tgatoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tga file\n");
return 1;
}
break;
case RAW_DFMT:
image = rawtoimage(parameters.infile, &parameters, &raw_cp);
if (!image) {
fprintf(stderr, "Unable to load raw file\n");
return 1;
}
break;
case TGA_DFMT:
image = tgatoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load tga file\n");
return 1;
}
break;
#ifdef HAVE_LIBPNG
case PNG_DFMT:
image = pngtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load png file\n");
return 1;
}
break;
case PNG_DFMT:
image = pngtoimage(parameters.infile, &parameters);
if (!image) {
fprintf(stderr, "Unable to load png file\n");
return 1;
}
break;
#endif /* HAVE_LIBPNG */
}
/* Can happen if input file is TIFF or PNG
* and HAVE_LIBTIF or HAVE_LIBPNG is undefined
*/
if( !image)
{
if( !image) {
fprintf(stderr, "Unable to load file: got no image\n");
return 1;
}
/* Decide if MCT should be used */
parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
}
if(parameters.cp_cinema){
cinema_setup_encoder(&parameters,image,&img_fol);
/* Decide if MCT should be used */
parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
if(parameters.cp_cinema){
cinema_setup_encoder(&parameters,image,&img_fol);
}
/* encode the destination image */
/* ---------------------------- */
switch(parameters.decod_format) {
case J2K_CFMT: /* JPEG-2000 codestream */
{
/* Get a decoder handle */
cinfo = opj_create_compress_v2(CODEC_J2K);
break;
}
/* encode the destination image */
/* ---------------------------- */
if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
int codestream_length;
size_t res;
opj_cio_t *cio = NULL;
FILE *f = NULL;
/* get a J2K compressor handle */
opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
/* setup the encoder parameters using the current image and user parameters */
opj_setup_encoder(cinfo, &parameters, image);
/* open a byte stream for writing */
/* allocate memory for all tiles */
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
/* encode the image */
if (*indexfilename) /* If need to extract codestream information*/
bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
else
bSuccess = opj_encode(cinfo, cio, image, NULL);
if (!bSuccess) {
opj_cio_close(cio);
fprintf(stderr, "failed to encode image\n");
return 1;
}
codestream_length = cio_tell(cio);
/* write the buffer to disk */
f = fopen(parameters.outfile, "wb");
if (!f) {
fprintf(stderr, "failed to open %s for writing\n", parameters.outfile);
return 1;
}
res = fwrite(cio->buffer, 1, codestream_length, f);
if( res < (size_t)codestream_length ) { /* FIXME */
fprintf(stderr, "failed to write %d (%s)\n", codestream_length, parameters.outfile);
return 1;
}
fclose(f);
fprintf(stderr,"Generated outfile %s\n",parameters.outfile);
/* close and free the byte stream */
opj_cio_close(cio);
/* Write the index to disk */
if (*indexfilename) {
bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) {
fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
}
}
/* free remaining compression structures */
opj_destroy_compress(cinfo);
if (*indexfilename)
opj_destroy_cstr_info(&cstr_info);
} else { /* JP2 format output */
int codestream_length;
size_t res;
opj_cio_t *cio = NULL;
FILE *f = NULL;
opj_cinfo_t *cinfo = NULL;
/* get a JP2 compressor handle */
cinfo = opj_create_compress(CODEC_JP2);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
/* setup the encoder parameters using the current image and using user parameters */
opj_setup_encoder(cinfo, &parameters, image);
/* open a byte stream for writing */
/* allocate memory for all tiles */
cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
/* encode the image */
if (*indexfilename || parameters.jpip_on) /* If need to extract codestream information*/
bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
else
bSuccess = opj_encode(cinfo, cio, image, NULL);
if (!bSuccess) {
opj_cio_close(cio);
fprintf(stderr, "failed to encode image\n");
return 1;
}
codestream_length = cio_tell(cio);
/* write the buffer to disk */
f = fopen(parameters.outfile, "wb");
if (!f) {
fprintf(stderr, "failed to open %s for writing\n", parameters.outfile);
return 1;
}
res = fwrite(cio->buffer, 1, codestream_length, f);
if( res < (size_t)codestream_length ) { /* FIXME */
fprintf(stderr, "failed to write %d (%s)\n", codestream_length, parameters.outfile);
return 1;
}
fclose(f);
fprintf(stderr,"Generated outfile %s\n",parameters.outfile);
/* close and free the byte stream */
opj_cio_close(cio);
/* Write the index to disk */
if (*indexfilename) {
bSuccess = write_index_file(&cstr_info, indexfilename);
if (bSuccess) {
fprintf(stderr, "Failed to output index file\n");
}
}
/* free remaining compression structures */
opj_destroy_compress(cinfo);
if (*indexfilename)
opj_destroy_cstr_info(&cstr_info);
case JP2_CFMT: /* JPEG 2000 compressed image data */
{
/* Get a decoder handle */
cinfo = opj_create_compress_v2(CODEC_JP2);
break;
}
default:
fprintf(stderr, "skipping file..\n");
opj_stream_destroy(cio);
continue;
}
opj_setup_encoder_v2(cinfo, &parameters, image);
/* Open the output file*/
f = fopen(parameters.outfile, "wb");
if (! f) {
fprintf(stderr, "Not enable to create output file!\n");
opj_stream_destroy(cio);
return 1;
}
/* open a byte stream for writing and allocate memory for all tiles */
cio = opj_stream_create_default_file_stream(f,OPJ_FALSE);
if (! cio){
return 1;
}
/* encode the image */
bSuccess = opj_start_compress(cinfo,image,cio);
bSuccess = bSuccess && opj_encode_v2(cinfo, cio);
bSuccess = bSuccess && opj_end_compress(cinfo, cio);
if (!bSuccess) {
opj_stream_destroy(cio);
fclose(f);
fprintf(stderr, "failed to encode image\n");
return 1;
}
fprintf(stderr,"Generated outfile %s\n",parameters.outfile);
/* close and free the byte stream */
opj_stream_destroy(cio);
fclose(f);
/* free remaining compression structures */
opj_destroy_codec(cinfo);
/* free image data */
opj_image_destroy(image);
/* free image data */
opj_image_destroy(image);
}
/* free user parameters structure */
if(parameters.cp_comment) free(parameters.cp_comment);
if(parameters.cp_comment) free(parameters.cp_comment);
if(parameters.cp_matrice) free(parameters.cp_matrice);
return 0;

View File

@ -128,6 +128,12 @@ Inverse wavelet transform in 2-D.
*/
static opj_bool dwt_decode_tile_v2(opj_tcd_tilecomp_v2_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
static opj_bool dwt_encode_procedure( opj_tcd_tilecomp_v2_t * tilec,
void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) );
static OPJ_UINT32 dwt_max_resolution_v2(opj_tcd_resolution_v2_t* restrict r, OPJ_UINT32 i);
/*@}*/
/*@}*/
@ -383,6 +389,95 @@ void dwt_encode(opj_tcd_tilecomp_t * tilec) {
}
}
/* <summary> */
/* Forward 5-3 wavelet transform in 2-D. */
/* </summary> */
INLINE opj_bool dwt_encode_procedure(opj_tcd_tilecomp_v2_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) )
{
OPJ_INT32 i, j, k;
OPJ_INT32 *a = 00;
OPJ_INT32 *aj = 00;
OPJ_INT32 *bj = 00;
OPJ_INT32 w, l;
OPJ_INT32 rw; /* width of the resolution level computed */
OPJ_INT32 rh; /* height of the resolution level computed */
OPJ_INT32 l_data_size;
opj_tcd_resolution_v2_t * l_cur_res = 0;
opj_tcd_resolution_v2_t * l_last_res = 0;
w = tilec->x1-tilec->x0;
l = tilec->numresolutions-1;
a = tilec->data;
l_cur_res = tilec->resolutions + l;
l_last_res = l_cur_res - 1;
rw = l_cur_res->x1 - l_cur_res->x0;
rh = l_cur_res->y1 - l_cur_res->y0;
l_data_size = dwt_max_resolution_v2( tilec->resolutions,tilec->numresolutions) * sizeof(OPJ_INT32);
bj = (OPJ_INT32*)opj_malloc(l_data_size);
if (! bj) {
return OPJ_FALSE;
}
i = l;
while (i--) {
OPJ_INT32 rw1; /* width of the resolution level once lower than computed one */
OPJ_INT32 rh1; /* height of the resolution level once lower than computed one */
OPJ_INT32 cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
OPJ_INT32 cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
OPJ_INT32 dn, sn;
rw = l_cur_res->x1 - l_cur_res->x0;
rh = l_cur_res->y1 - l_cur_res->y0;
rw1 = l_last_res->x1 - l_last_res->x0;
rh1 = l_last_res->y1 - l_last_res->y0;
cas_row = l_cur_res->x0 & 1;
cas_col = l_cur_res->y0 & 1;
sn = rh1;
dn = rh - rh1;
for (j = 0; j < rw; ++j) {
aj = a + j;
for (k = 0; k < rh; ++k) {
bj[k] = aj[k*w];
}
(*p_function) (bj, dn, sn, cas_col);
dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
}
sn = rw1;
dn = rw - rw1;
for (j = 0; j < rh; j++) {
aj = a + j * w;
for (k = 0; k < rw; k++) bj[k] = aj[k];
(*p_function) (bj, dn, sn, cas_row);
dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
}
l_cur_res = l_last_res;
--l_last_res;
}
opj_free(bj);
return OPJ_TRUE;
}
/* Forward 5-3 wavelet transform in 2-D. */
/* </summary> */
opj_bool dwt_encode_v2(opj_tcd_tilecomp_v2_t * tilec)
{
return dwt_encode_procedure(tilec,dwt_encode_1);
}
#ifdef OPJ_V1
/* <summary> */
/* Inverse 5-3 wavelet transform in 2-D. */
@ -492,6 +587,13 @@ void dwt_encode_real(opj_tcd_tilecomp_t * tilec) {
}
}
/* <summary> */
/* Forward 9-7 wavelet transform in 2-D. */
/* </summary> */
opj_bool dwt_encode_real_v2(opj_tcd_tilecomp_v2_t * tilec)
{
return dwt_encode_procedure(tilec,dwt_encode_1_real);
}
/* <summary> */
/* Get gain of 9-7 wavelet transform. */

View File

@ -52,6 +52,13 @@ Forward 5-3 wavelet tranform in 2-D.
Apply a reversible DWT transform to a component of an image.
@param tilec Tile component information (current tile)
*/
opj_bool dwt_encode_v2(struct opj_tcd_tilecomp_v2 * tilec);
/**
Forward 5-3 wavelet tranform in 2-D.
Apply a reversible DWT transform to a component of an image.
@param tilec Tile component information (current tile)
*/
void dwt_encode(opj_tcd_tilecomp_t * tilec);
/**
Inverse 5-3 wavelet tranform in 2-D.
@ -87,6 +94,7 @@ Apply an irreversible DWT transform to a component of an image.
@param tilec Tile component information (current tile)
*/
void dwt_encode_real(opj_tcd_tilecomp_t * tilec);
opj_bool dwt_encode_real_v2(opj_tcd_tilecomp_v2_t * tilec);
/**
KEEP TRUNK VERSION + return type of v2 because rev557
Inverse 9-7 wavelet transform in 2-D.

View File

@ -104,6 +104,15 @@ Divide an integer and round upwards
static INLINE int int_ceildiv(int a, int b) {
return (a + b - 1) / b;
}
/**
Divide an integer and round upwards
@return Returns a divided by b
*/
static INLINE OPJ_UINT32 uint_ceildiv(OPJ_UINT32 a, OPJ_UINT32 b) {
return (a + b - 1) / b;
}
/**
Divide an integer by a power of 2 and round upwards
@return Returns a divided by 2^b

File diff suppressed because it is too large Load Diff

View File

@ -107,6 +107,7 @@ The functions in J2K.C have for goal to read/write the several parts of the code
* These values may be combined with a | operator.
* */
typedef enum J2K_STATUS {
J2K_STATE_NONE = 0x0000, /**< a SOC marker is expected */
J2K_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */
J2K_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */
J2K_STATE_MH = 0x0004, /**< the decoding process is in the main header */
@ -1024,4 +1025,47 @@ opj_bool j2k_get_tile( opj_j2k_v2_t *p_j2k,
opj_bool j2k_set_decoded_resolution_factor(opj_j2k_v2_t *p_j2k, OPJ_UINT32 res_factor, opj_event_mgr_t * p_manager);
/**
* Writes a tile.
* @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_write_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 );
/**
* Encodes an image into a JPEG-2000 codestream
*/
opj_bool j2k_encode_v2( opj_j2k_v2_t * p_j2k,
opj_stream_private_t *cio,
struct opj_event_mgr * p_manager );
/**
* Starts a compression scheme, i.e. validates the codec parameters, writes the header.
*
* @param p_j2k the jpeg2000 codec.
* @param cio the stream object.
* @param p_manager the user event manager.
*
* @return true if the codec is valid.
*/
opj_bool j2k_start_compress(opj_j2k_v2_t *p_j2k,
struct opj_stream_private *cio,
struct opj_image * p_image,
struct opj_event_mgr * p_manager );
/**
* Ends the compression procedures and possibiliy add data to be read after the
* codestream.
*/
opj_bool j2k_end_compress( opj_j2k_v2_t *p_j2k,
opj_stream_private_t *cio,
struct opj_event_mgr * p_manager);
#endif /* __J2K_H */

View File

@ -132,6 +132,19 @@ static opj_bool jp2_read_ftyp_v2(
struct opj_event_mgr * p_manager
);
/**
* Skips the Jpeg2000 Codestream Header box - JP2C Header box.
*
* @param cio the stream to write data to.
* @param jp2 the jpeg2000 file codec.
* @param p_manager user event manager.
*
* @return true if writting was successful.
*/
opj_bool jp2_skip_jp2c( opj_jp2_v2_t *jp2,
struct opj_stream_private *cio,
struct opj_event_mgr * p_manager );
/**
* Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
*
@ -286,6 +299,13 @@ static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int le
/*@}*/
/**
* Sets up the procedures to do on writting header after the codestream.
* Developpers wanting to extend the library can add their own writting procedures.
*/
static void jp2_setup_end_header_writting (opj_jp2_v2_t *jp2);
/**
* Sets up the procedures to do on reading header after the codestream.
* Developpers wanting to extend the library can add their own writting procedures.
@ -350,6 +370,31 @@ static opj_bool jp2_read_boxhdr_v2(
*/
static const opj_jp2_header_handler_t * jp2_find_handler (int p_id );
/**
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
*/
static void jp2_setup_encoding_validation (opj_jp2_v2_t *jp2);
/**
* Sets up the procedures to do on writting header. Developpers wanting to extend the library can add their own writting procedures.
*/
static void jp2_setup_header_writting (opj_jp2_v2_t *jp2);
/**
* The default validation procedure without any extension.
*
* @param jp2 the jpeg2000 codec to validate.
* @param cio the input stream to validate.
* @param p_manager the user event manager.
*
* @return true if the parameters are correct.
*/
opj_bool jp2_default_validation ( opj_jp2_v2_t * jp2,
struct opj_stream_private *cio,
struct opj_event_mgr * p_manager );
/**
* Finds the image execution function related to the given box id.
*
@ -1980,9 +2025,47 @@ opj_bool jp2_end_decompress(opj_jp2_v2_t *jp2, opj_stream_private_t *cio, opj_ev
return j2k_end_decompress(jp2->j2k, cio, p_manager);
}
/**
* Ends the compression procedures and possibility add data to be read after the
* codestream.
*/
opj_bool jp2_end_compress( opj_jp2_v2_t *jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager)
{
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);
assert(p_manager != 00);
/* customization of the end encoding */
jp2_setup_end_header_writting(jp2);
if (! j2k_end_compress(jp2->j2k,cio,p_manager)) {
return OPJ_FALSE;
}
/* write header */
return jp2_exec(jp2,jp2->m_procedure_list,cio,p_manager);
}
/**
* Sets up the procedures to do on writing header after the codestream.
* Developers wanting to extend the library can add their own writing procedures.
*/
void jp2_setup_end_header_writting (opj_jp2_v2_t *jp2)
{
/* preconditions */
assert(jp2 != 00);
opj_procedure_list_add_procedure(jp2->m_procedure_list,(void*)jp2_write_jp2c );
/* DEVELOPER CORNER, add your custom procedures */
}
/**
* Sets up the procedures to do on reading header after the codestream.
* Developpers wanting to extend the library can add their own writting procedures.
* Developers wanting to extend the library can add their own writing procedures.
*/
void jp2_setup_end_header_reading (opj_jp2_v2_t *jp2)
{
@ -1992,6 +2075,68 @@ void jp2_setup_end_header_reading (opj_jp2_v2_t *jp2)
/* DEVELOPER CORNER, add your custom procedures */
}
/**
* The default validation procedure without any extension.
*
* @param jp2 the jpeg2000 codec to validate.
* @param cio the input stream to validate.
* @param p_manager the user event manager.
*
* @return true if the parameters are correct.
*/
opj_bool jp2_default_validation ( opj_jp2_v2_t * jp2,
opj_stream_private_t *cio,
opj_event_mgr_t * p_manager )
{
opj_bool l_is_valid = OPJ_TRUE;
unsigned int i;
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);
assert(p_manager != 00);
/* JPEG2000 codec validation */
/*TODO*/
/* STATE checking */
/* make sure the state is at 0 */
l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);
/* make sure not reading a jp2h ???? WEIRD */
l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);
/* POINTER validation */
/* make sure a j2k codec is present */
l_is_valid &= (jp2->j2k != 00);
/* make sure a procedure list is present */
l_is_valid &= (jp2->m_procedure_list != 00);
/* make sure a validation list is present */
l_is_valid &= (jp2->m_validation_list != 00);
/* PARAMETER VALIDATION */
/* number of components */
l_is_valid &= (jp2->numcl > 0);
/* width */
l_is_valid &= (jp2->h > 0);
/* height */
l_is_valid &= (jp2->w > 0);
/* precision */
for (i = 0; i < jp2->numcomps; ++i) {
l_is_valid &= (jp2->comps[i].bpcc > 0);
}
/* METH */
l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));
/* stream validation */
/* back and forth is needed */
l_is_valid &= opj_stream_has_seek(cio);
return l_is_valid;
}
/**
* Reads a jpeg2000 file header structure.
@ -2126,6 +2271,42 @@ opj_bool jp2_exec (
return l_result;
}
/**
* Starts a compression scheme, i.e. validates the codec parameters, writes the header.
*
* @param jp2 the jpeg2000 file codec.
* @param cio the stream object.
*
* @return true if the codec is valid.
*/
opj_bool jp2_start_compress(opj_jp2_v2_t *jp2,
struct opj_stream_private *cio,
opj_image_t * p_image,
struct opj_event_mgr * p_manager)
{
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);
assert(p_manager != 00);
/* customization of the validation */
jp2_setup_encoding_validation (jp2);
/* validation of the parameters codec */
if (! jp2_exec(jp2,jp2->m_validation_list,cio,p_manager)) {
return OPJ_FALSE;
}
/* customization of the encoding */
jp2_setup_header_writting(jp2);
/* write header */
if (! jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) {
return OPJ_FALSE;
}
return j2k_start_compress(jp2->j2k,cio,p_image,p_manager);
}
/**
* Finds the execution function related to the given box id.
@ -2288,6 +2469,32 @@ opj_bool jp2_read_ftyp_v2(
return OPJ_TRUE;
}
/**
* Skips the Jpeg2000 Codestream Header box - JP2C Header box.
*
* @param cio the stream to write data to.
* @param jp2 the jpeg2000 file codec.
* @param p_manager user event manager.
*
* @return true if writting was successful.
*/
opj_bool jp2_skip_jp2c( opj_jp2_v2_t *jp2,
struct opj_stream_private *cio,
struct opj_event_mgr * p_manager )
{
/* preconditions */
assert(jp2 != 00);
assert(cio != 00);
assert(p_manager != 00);
jp2->j2k_codestream_offset = opj_stream_tell(cio);
if (opj_stream_skip(cio,8,p_manager) != 8) {
return OPJ_FALSE;
}
return OPJ_TRUE;
}
/**
* Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box).
@ -2479,6 +2686,19 @@ opj_bool jp2_read_header( struct opj_stream_private *p_stream,
p_manager);
}
/**
* Sets up the validation ,i.e. adds the procedures to launch to make sure the codec parameters
* are valid. Developers wanting to extend the library can add their own validation procedures.
*/
void jp2_setup_encoding_validation (opj_jp2_v2_t *jp2)
{
/* preconditions */
assert(jp2 != 00);
opj_procedure_list_add_procedure(jp2->m_validation_list, (void*)jp2_default_validation);
/* DEVELOPER CORNER, add your custom validation procedure */
}
/**
* Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters
* are valid. Developpers wanting to extend the library can add their own validation procedures.
@ -2490,6 +2710,24 @@ void jp2_setup_decoding_validation (opj_jp2_v2_t *jp2)
/* DEVELOPER CORNER, add your custom validation procedure */
}
/**
* Sets up the procedures to do on writting header.
* Developers wanting to extend the library can add their own writing procedures.
*/
void jp2_setup_header_writting (opj_jp2_v2_t *jp2)
{
/* preconditions */
assert(jp2 != 00);
opj_procedure_list_add_procedure(jp2->m_procedure_list,(void*)jp2_write_jp );
opj_procedure_list_add_procedure(jp2->m_procedure_list,(void*)jp2_write_ftyp );
opj_procedure_list_add_procedure(jp2->m_procedure_list,(void*)jp2_write_jp2h );
opj_procedure_list_add_procedure(jp2->m_procedure_list,(void*)jp2_skip_jp2c );
/* DEVELOPER CORNER, insert your custom procedures */
}
/**
* Sets up the procedures to do on reading header.
* Developpers wanting to extend the library can add their own writting procedures.
@ -2531,6 +2769,22 @@ opj_bool jp2_read_tile_header( opj_jp2_v2_t * p_jp2,
p_manager);
}
/**
* Writes a tile.
* @param p_j2k the jpeg2000 codec.
* @param p_stream the stream to write data to.
* @param p_manager the user event manager.
*/
opj_bool jp2_write_tile ( opj_jp2_v2_t *p_jp2,
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 )
{
return j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager);
}
/**
* Decode tile data.
* @param p_j2k the jpeg2000 codec.

View File

@ -330,6 +330,28 @@ Encode an image into a JPEG-2000 file stream
opj_bool opj_jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info);
/**
* Starts a compression scheme, i.e. validates the codec parameters, writes the header.
*
* @param jp2 the jpeg2000 file codec.
* @param cio the stream object.
*
* @return true if the codec is valid.
*/
opj_bool jp2_start_compress(opj_jp2_v2_t *jp2,
struct opj_stream_private *cio,
struct opj_image * p_image,
struct opj_event_mgr * p_manager);
/**
* Ends the compression procedures and possibiliy add data to be read after the
* codestream.
*/
opj_bool jp2_end_compress( opj_jp2_v2_t *jp2,
struct opj_stream_private *cio,
struct opj_event_mgr * p_manager);
/* ----------------------------------------------------------------------- */
/**
@ -373,6 +395,21 @@ opj_bool jp2_read_tile_header (
struct opj_event_mgr * p_manager
);
/**
* Writes a tile.
* @param p_j2k the jpeg2000 codec.
* @param p_stream the stream to write data to.
* @param p_manager the user event manager.
*/
opj_bool jp2_write_tile ( opj_jp2_v2_t *p_jp2,
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 );
/**
* Decode tile data.
* @param p_j2k the jpeg2000 codec.

View File

@ -45,6 +45,16 @@ static const double mct_norms[3] = { 1.732, .8292, .8292 };
/* </summary> */
static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 };
const OPJ_FLOAT64 * get_mct_norms ()
{
return mct_norms;
}
const OPJ_FLOAT64 * get_mct_norms_real ()
{
return mct_norms_real;
}
/* <summary> */
/* Foward reversible MCT. */
/* </summary> */
@ -190,6 +200,62 @@ double mct_getnorm_real(int compno) {
}
opj_bool mct_encode_custom(
// MCT data
OPJ_BYTE * pCodingdata,
// 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_FLOAT32 *) pCodingdata;
OPJ_UINT32 i;
OPJ_UINT32 j;
OPJ_UINT32 k;
OPJ_UINT32 lNbMatCoeff = pNbComp * pNbComp;
OPJ_INT32 * lCurrentData = 00;
OPJ_INT32 * lCurrentMatrix = 00;
OPJ_INT32 ** lData = (OPJ_INT32 **) pData;
OPJ_UINT32 lMultiplicator = 1 << 13;
OPJ_INT32 * lMctPtr;
lCurrentData = (OPJ_INT32 *) opj_malloc((pNbComp + lNbMatCoeff) * sizeof(OPJ_INT32));
if (! lCurrentData) {
return OPJ_FALSE;
}
lCurrentMatrix = lCurrentData + pNbComp;
for (i =0;i<lNbMatCoeff;++i) {
lCurrentMatrix[i] = (OPJ_INT32) (*(lMct++) * lMultiplicator);
}
for (i = 0; i < n; ++i) {
lMctPtr = lCurrentMatrix;
for (j=0;j<pNbComp;++j) {
lCurrentData[j] = (*(lData[j]));
}
for (j=0;j<pNbComp;++j) {
*(lData[j]) = 0;
for (k=0;k<pNbComp;++k) {
*(lData[j]) += fix_mul(*lMctPtr, lCurrentData[k]);
++lMctPtr;
}
++lData[j];
}
}
opj_free(lCurrentData);
return OPJ_TRUE;
}
opj_bool mct_decode_custom(
/* MCT data */
OPJ_BYTE * pDecodingData,

View File

@ -91,6 +91,19 @@ Get norm of the basis function used for the irreversible multi-component transfo
*/
double mct_getnorm_real(int compno);
opj_bool mct_encode_custom(
// MCT data
OPJ_BYTE * p_coding_data,
// size of components
OPJ_UINT32 n,
// components
OPJ_BYTE ** p_data,
// nb of components (i.e. size of p_data)
OPJ_UINT32 p_nb_comp,
// tells if the data is signed
OPJ_UINT32 is_signed);
opj_bool mct_decode_custom(
/* MCT data */
OPJ_BYTE * pDecodingData,
@ -102,6 +115,9 @@ opj_bool mct_decode_custom(
OPJ_UINT32 pNbComp,
/* tells if the data is signed */
OPJ_UINT32 isSigned);
const OPJ_FLOAT64 * get_mct_norms ();
const OPJ_FLOAT64 * get_mct_norms_real ();
/* ----------------------------------------------------------------------- */
/*@}*/

View File

@ -96,12 +96,32 @@ typedef struct opj_decompression
*/
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);
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);
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;
@ -529,6 +549,105 @@ opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) {
return cinfo;
}
opj_codec_t* OPJ_CALLCONV opj_create_compress_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 = 0;
switch(p_format) {
case CODEC_J2K:
l_info->m_codec_data.m_compression.opj_encode = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_event_mgr * )) j2k_encode_v2;
l_info->m_codec_data.m_compression.opj_end_compress = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_event_mgr *)) j2k_end_compress;
l_info->m_codec_data.m_compression.opj_start_compress = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_image * ,
struct opj_event_mgr *)) j2k_start_compress;
l_info->m_codec_data.m_compression.opj_write_tile = (opj_bool (*) ( void *,
OPJ_UINT32,
OPJ_BYTE*,
OPJ_UINT32,
struct opj_stream_private *,
struct opj_event_mgr *) ) j2k_write_tile;
l_info->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) j2k_destroy;
l_info->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) j2k_setup_encoder;
l_info->m_codec = j2k_create_compress_v2();
if (! l_info->m_codec) {
opj_free(l_info);
return 00;
}
break;
case CODEC_JP2:
/* get a JP2 decoder handle */
l_info->m_codec_data.m_compression.opj_encode = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_event_mgr * )) opj_jp2_encode;
l_info->m_codec_data.m_compression.opj_end_compress = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_event_mgr *)) jp2_end_compress;
l_info->m_codec_data.m_compression.opj_start_compress = (opj_bool (*) ( void *,
struct opj_stream_private *,
struct opj_image * ,
struct opj_event_mgr *)) jp2_start_compress;
l_info->m_codec_data.m_compression.opj_write_tile = (opj_bool (*) ( void *,
OPJ_UINT32,
OPJ_BYTE*,
OPJ_UINT32,
struct opj_stream_private *,
struct opj_event_mgr *)) jp2_write_tile;
l_info->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) jp2_destroy;
l_info->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) jp2_setup_encoder;
l_info->m_codec = jp2_create(OPJ_FALSE);
if (! l_info->m_codec) {
opj_free(l_info);
return 00;
}
break;
case CODEC_UNKNOWN:
case CODEC_JPT:
default:
opj_free(l_info);
return 00;
}
/*set_default_event_handler(&(l_info->m_event_mgr));*/
return (opj_codec_t*) l_info;
}
void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) {
if(cinfo) {
/* destroy the codec */
@ -658,6 +777,66 @@ void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *param
}
}
opj_bool OPJ_CALLCONV opj_setup_encoder_v2(opj_codec_t *p_info, opj_cparameters_t *parameters, opj_image_t *image)
{
if (p_info && parameters && image) {
opj_codec_private_t * l_codec = ((opj_codec_private_t *) p_info);
if (! l_codec->is_decompressor) {
l_codec->m_codec_data.m_compression.opj_setup_encoder(l_codec->m_codec,parameters,image,l_codec->m_event_mgr);
return OPJ_TRUE;
}
}
return OPJ_FALSE;
}
opj_bool OPJ_CALLCONV opj_start_compress ( opj_codec_t *p_codec,
opj_image_t * p_image,
opj_stream_t *p_cio)
{
if (p_codec && p_cio) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio;
if (! l_codec->is_decompressor) {
return l_codec->m_codec_data.m_compression.opj_start_compress(l_codec->m_codec,l_cio,p_image,l_codec->m_event_mgr);
}
}
return OPJ_FALSE;
}
opj_bool OPJ_CALLCONV opj_encode_v2(opj_codec_t *p_info, opj_stream_t *cio)
{
if (p_info && cio) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_info;
opj_stream_private_t * l_cio = (opj_stream_private_t *) cio;
if (! l_codec->is_decompressor) {
l_codec->m_codec_data.m_compression.opj_encode(l_codec->m_codec,l_cio,l_codec->m_event_mgr);
return OPJ_TRUE;
}
}
return OPJ_FALSE;
}
opj_bool OPJ_CALLCONV opj_end_compress (opj_codec_t *p_codec,opj_stream_t *p_cio)
{
if (p_codec && p_cio) {
opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec;
opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio;
if (! l_codec->is_decompressor) {
return l_codec->m_codec_data.m_compression.opj_end_compress(l_codec->m_codec,l_cio,l_codec->m_event_mgr);
}
}
return OPJ_FALSE;
}
opj_bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) {
if (index != NULL)
opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n"
@ -1034,3 +1213,31 @@ opj_bool OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_codec, OP
return OPJ_TRUE;
}
opj_bool OPJ_CALLCONV opj_set_MCT(opj_cparameters_t *parameters,OPJ_FLOAT32 * pEncodingMatrix,OPJ_INT32 * p_dc_shift,OPJ_UINT32 pNbComp)
{
OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * sizeof(OPJ_FLOAT32);
OPJ_UINT32 l_dc_shift_size = pNbComp * sizeof(OPJ_INT32);
OPJ_UINT32 l_mct_total_size = l_matrix_size + l_dc_shift_size;
/* add MCT capability */
int rsiz = (int)parameters->cp_rsiz | (int)MCT;
parameters->cp_rsiz = (OPJ_RSIZ_CAPABILITIES)rsiz;
parameters->irreversible = 1;
/* use array based MCT */
parameters->tcp_mct = 2;
parameters->mct_data = opj_malloc(l_mct_total_size);
if (! parameters->mct_data) {
return OPJ_FALSE;
}
memcpy(parameters->mct_data,pEncodingMatrix,l_matrix_size);
memcpy(((OPJ_BYTE *) parameters->mct_data) + l_matrix_size,p_dc_shift,l_dc_shift_size);
return OPJ_TRUE;
}

View File

@ -173,7 +173,8 @@ typedef OPJ_INT64 OPJ_OFF_T;
typedef enum RSIZ_CAPABILITIES {
STD_RSIZ = 0, /** Standard JPEG2000 profile*/
CINEMA2K = 3, /** Profile name for a 2K image*/
CINEMA4K = 4 /** Profile name for a 4K image*/
CINEMA4K = 4, /** Profile name for a 4K image*/
MCT = 0x8100
} OPJ_RSIZ_CAPABILITIES;
/**
@ -425,6 +426,9 @@ typedef struct opj_cparameters {
char tcp_mct;
/** Enable JPIP indexing*/
opj_bool jpip_on;
/** Naive implementation of MCT restricted to a single reversible array based encoding without offset concerning all the components. */
void * mct_data;
} opj_cparameters_t;
#define OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG 0x0001
@ -1399,6 +1403,15 @@ Creates a J2K/JP2 compression structure
@return Returns a handle to a compressor if successful, returns NULL otherwise
*/
OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format);
/**
Creates a J2K/JP2 compression structure
@param format Coder to select
@return Returns a handle to a compressor if successful, returns NULL otherwise
*/
OPJ_API opj_codec_t* OPJ_CALLCONV opj_create_compress_v2(OPJ_CODEC_FORMAT format);
/**
Destroy a compressor handle
@param cinfo compressor handle to destroy
@ -1433,6 +1446,32 @@ Setup the encoder parameters using the current image and using user parameters.
@param image Input filled image
*/
OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image);
/**
Setup the encoder parameters using the current image and using user parameters.
@param cinfo Compressor handle
@param parameters Compression parameters
@param image Input filled image
*/
OPJ_API opj_bool OPJ_CALLCONV opj_setup_encoder_v2(opj_codec_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image);
opj_bool OPJ_CALLCONV opj_start_compress ( opj_codec_t *p_codec,
opj_image_t * p_image,
opj_stream_t *p_cio);
opj_bool OPJ_CALLCONV opj_end_compress (opj_codec_t *p_codec,opj_stream_t *p_cio);
/**
Encode an image into a JPEG-2000 codestream
@param cinfo compressor handle
@param cio Output buffer stream
@param image Image to encode
@param index Depreacted -> Set to NULL. To extract index, used opj_encode_wci()
@return Returns true if successful, returns false otherwise
*/
OPJ_API opj_bool OPJ_CALLCONV opj_encode_v2(opj_codec_t *cinfo, opj_stream_t * cio);
/**
Encode an image into a JPEG-2000 codestream
3@param cinfo compressor handle
@ -1537,6 +1576,26 @@ OPJ_API opj_jp2_metadata_t* OPJ_CALLCONV opj_get_jp2_metadata(opj_codec_t *p_cod
OPJ_API opj_jp2_index_t* OPJ_CALLCONV opj_get_jp2_index(opj_codec_t *p_codec);
/*
==========================================================
new functions
==========================================================
*/
/**
* Sets the MCT matrix to use.
*
* @param parameters the parameters to change.
* @param pEncodingMatrix the encoding matrix.
* @param p_dc_shift the dc shift coefficients to use.
* @param pNbComp the number of components of the image.
*
* @return true if the parameters could be set.
*/
OPJ_API opj_bool OPJ_CALLCONV opj_set_MCT( opj_cparameters_t *parameters,
OPJ_FLOAT32 * pEncodingMatrix,
OPJ_INT32 * p_dc_shift,
OPJ_UINT32 pNbComp);

View File

@ -69,7 +69,83 @@ Get next packet in component-precinct-resolution-layer order.
*/
static opj_bool pi_next_cprl(opj_pi_iterator_t * pi);
/**
* Updates the coding parameters if the encoding is used with Progression order changes and final (or cinema parameters are used).
*
* @param p_cp the coding parameters to modify
* @param p_tileno the tile index being concerned.
* @param p_tx0 X0 parameter for the tile
* @param p_tx1 X1 parameter for the tile
* @param p_ty0 Y0 parameter for the tile
* @param p_ty1 Y1 parameter for the tile
* @param p_max_prec the maximum precision for all the bands of the tile
* @param p_max_res the maximum number of resolutions for all the poc inside the tile.
* @param dx_min the minimum dx of all the components of all the resolutions for the tile.
* @param dy_min the minimum dy of all the components of all the resolutions for the tile.
*/
void pi_update_encode_poc_and_final (opj_cp_v2_t *p_cp,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
OPJ_UINT32 p_dy_min);
/**
* Updates the coding parameters if the encoding is not used with Progression order changes and final (and cinema parameters are used).
*
* @param p_cp the coding parameters to modify
* @param p_tileno the tile index being concerned.
* @param p_tx0 X0 parameter for the tile
* @param p_tx1 X1 parameter for the tile
* @param p_ty0 Y0 parameter for the tile
* @param p_ty1 Y1 parameter for the tile
* @param p_max_prec the maximum precision for all the bands of the tile
* @param p_max_res the maximum number of resolutions for all the poc inside the tile.
* @param dx_min the minimum dx of all the components of all the resolutions for the tile.
* @param dy_min the minimum dy of all the components of all the resolutions for the tile.
*/
void pi_update_encode_not_poc ( opj_cp_v2_t *p_cp,
OPJ_UINT32 p_num_comps,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
OPJ_UINT32 p_dy_min);
/**
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
*
* @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.
*/
void get_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 );
/**
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
@ -123,6 +199,12 @@ void pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ
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);
OPJ_INT32 pi_check_next_level( OPJ_INT32 pos,
opj_cp_v2_t *cp,
OPJ_UINT32 tileno,
OPJ_UINT32 pino,
const OPJ_CHAR *prog);
/*@}*/
/*@}*/
@ -938,6 +1020,202 @@ opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int ti
return pi;
}
/**
* Creates a packet iterator for encoding.
*
* @param p_image the image being encoded.
* @param p_cp the coding parameters.
* @param p_tile_no index of the tile being encoded.
* @param p_t2_mode the type of pass for generating the packet iterator
* @return a list of packet iterator that points to the first packet of the tile (not true).
*/
opj_pi_iterator_t *pi_initialise_encode_v2(
const opj_image_t *p_image,
opj_cp_v2_t *p_cp,
OPJ_UINT32 p_tile_no,
J2K_T2_MODE p_t2_mode
)
{
// 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_pi->tp_on = p_cp->m_specific_param.m_enc.m_tp_on;
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_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;
}
++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 && ( p_cp->m_specific_param.m_enc.m_cinema || p_t2_mode == FINAL_PASS)) {
pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
}
else {
pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
}
return l_pi;
}
void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
@ -1216,7 +1494,172 @@ opj_bool pi_create_encode( opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int p
return OPJ_FALSE;
}
/**
* Updates the encoding parameters of the codec.
*
* @param p_image the image being encoded.
* @param p_cp the coding parameters.
* @param p_tile_no index of the tile being encoded.
*/
void pi_update_encoding_parameters( const opj_image_t *p_image,
opj_cp_v2_t *p_cp,
OPJ_UINT32 p_tile_no )
{
/* encoding parameters 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;
/* pointers */
opj_tcp_v2_t *l_tcp = 00;
/* preconditions */
assert(p_cp != 00);
assert(p_image != 00);
assert(p_tile_no < p_cp->tw * p_cp->th);
l_tcp = &(p_cp->tcps[p_tile_no]);
/* get encoding parameters */
get_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);
if (l_tcp->POC) {
pi_update_encode_poc_and_final(p_cp,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
}
else {
pi_update_encode_not_poc(p_cp,p_image->numcomps,p_tile_no,l_tx0,l_tx1,l_ty0,l_ty1,l_max_prec,l_max_res,l_dx_min,l_dy_min);
}
}
/**
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
*
* @param p_image the image being encoded.
* @param p_cp the coding parameters.
* @param p_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.
*/
void get_encoding_parameters( const opj_image_t *p_image,
const opj_cp_v2_t *p_cp,
OPJ_UINT32 p_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 )
{
/* loop */
OPJ_UINT32 compno, resno;
/* pointers */
const opj_tcp_v2_t *l_tcp = 00;
const opj_tccp_t * l_tccp = 00;
const opj_image_comp_t * l_img_comp = 00;
/* position in x and y of tile */
OPJ_UINT32 p, q;
/* preconditions */
assert(p_cp != 00);
assert(p_image != 00);
assert(p_tileno < p_cp->tw * p_cp->th);
/* initializations */
l_tcp = &p_cp->tcps [p_tileno];
l_img_comp = p_image->comps;
l_tccp = l_tcp->tccps;
/* here calculation of tx0, tx1, ty0, ty1, maxprec, dx and dy */
p = p_tileno % p_cp->tw;
q = p_tileno / p_cp->tw;
/* find extent of tile */
*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 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) {
/* arithmetic 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_pdx, l_pdy;
OPJ_UINT32 l_pw, l_ph;
OPJ_UINT32 l_product;
OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1;
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 */
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];
l_dx = l_img_comp->dx * (1 << (l_pdx + l_tccp->numresolutions - 1 - resno));
l_dy = l_img_comp->dy * (1 << (l_pdy + l_tccp->numresolutions - 1 - resno));
/* take the minimum size for dx for each comp and resolution */
*p_dx_min = uint_min(*p_dx_min, l_dx);
*p_dy_min = uint_min(*p_dy_min, l_dy);
/* various calculations of extents */
l_level_no = l_tccp->numresolutions - 1 - resno;
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);
l_product = l_pw * l_ph;
/* update precision */
if (l_product > *p_max_prec) {
*p_max_prec = l_product;
}
}
++l_img_comp;
++l_tccp;
}
}
/**
* Gets the encoding parameters needed to update the coding parameters and all the pocs.
@ -1435,7 +1878,164 @@ opj_pi_iterator_t * pi_create( const opj_image_t *image,
return l_pi;
}
/**
* Updates the coding parameters if the encoding is used with Progression order changes and final (or cinema parameters are used).
*
* @param p_cp the coding parameters to modify
* @param p_tileno the tile index being concerned.
* @param p_tx0 X0 parameter for the tile
* @param p_tx1 X1 parameter for the tile
* @param p_ty0 Y0 parameter for the tile
* @param p_ty1 Y1 parameter for the tile
* @param p_max_prec the maximum precision for all the bands of the tile
* @param p_max_res the maximum number of resolutions for all the poc inside the tile.
* @param dx_min the minimum dx of all the components of all the resolutions for the tile.
* @param dy_min the minimum dy of all the components of all the resolutions for the tile.
*/
void pi_update_encode_poc_and_final (opj_cp_v2_t *p_cp,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
OPJ_UINT32 p_dy_min)
{
// loop
OPJ_UINT32 pino;
// tile coding parameter
opj_tcp_v2_t *l_tcp = 00;
// current poc being updated
opj_poc_t * l_current_poc = 00;
// number of pocs
OPJ_UINT32 l_poc_bound;
// preconditions in debug
assert(p_cp != 00);
assert(p_tileno < p_cp->tw * p_cp->th);
// initializations
l_tcp = &p_cp->tcps [p_tileno];
/* number of iterations in the loop */
l_poc_bound = l_tcp->numpocs+1;
// start at first element, and to make sure the compiler will not make a calculation each time in the loop
// store a pointer to the current element to modify rather than l_tcp->pocs[i]
l_current_poc = l_tcp->pocs;
l_current_poc->compS = l_current_poc->compno0;
l_current_poc->compE = l_current_poc->compno1;
l_current_poc->resS = l_current_poc->resno0;
l_current_poc->resE = l_current_poc->resno1;
l_current_poc->layE = l_current_poc->layno1;
// special treatment for the first element
l_current_poc->layS = 0;
l_current_poc->prg = l_current_poc->prg1;
l_current_poc->prcS = 0;
l_current_poc->prcE = p_max_prec;
l_current_poc->txS = p_tx0;
l_current_poc->txE = p_tx1;
l_current_poc->tyS = p_ty0;
l_current_poc->tyE = p_ty1;
l_current_poc->dx = p_dx_min;
l_current_poc->dy = p_dy_min;
++ l_current_poc;
for (pino = 1;pino < l_poc_bound ; ++pino) {
l_current_poc->compS = l_current_poc->compno0;
l_current_poc->compE= l_current_poc->compno1;
l_current_poc->resS = l_current_poc->resno0;
l_current_poc->resE = l_current_poc->resno1;
l_current_poc->layE = l_current_poc->layno1;
l_current_poc->prg = l_current_poc->prg1;
l_current_poc->prcS = 0;
// special treatment here different from the first element
l_current_poc->layS = (l_current_poc->layE > (l_current_poc-1)->layE) ? l_current_poc->layE : 0;
l_current_poc->prcE = p_max_prec;
l_current_poc->txS = p_tx0;
l_current_poc->txE = p_tx1;
l_current_poc->tyS = p_ty0;
l_current_poc->tyE = p_ty1;
l_current_poc->dx = p_dx_min;
l_current_poc->dy = p_dy_min;
++ l_current_poc;
}
}
/**
* Updates the coding parameters if the encoding is not used with Progression order changes and final (and cinema parameters are used).
*
* @param p_cp the coding parameters to modify
* @param p_tileno the tile index being concerned.
* @param p_tx0 X0 parameter for the tile
* @param p_tx1 X1 parameter for the tile
* @param p_ty0 Y0 parameter for the tile
* @param p_ty1 Y1 parameter for the tile
* @param p_max_prec the maximum precision for all the bands of the tile
* @param p_max_res the maximum number of resolutions for all the poc inside the tile.
* @param dx_min the minimum dx of all the components of all the resolutions for the tile.
* @param dy_min the minimum dy of all the components of all the resolutions for the tile.
*/
void pi_update_encode_not_poc ( opj_cp_v2_t *p_cp,
OPJ_UINT32 p_num_comps,
OPJ_UINT32 p_tileno,
OPJ_INT32 p_tx0,
OPJ_INT32 p_tx1,
OPJ_INT32 p_ty0,
OPJ_INT32 p_ty1,
OPJ_UINT32 p_max_prec,
OPJ_UINT32 p_max_res,
OPJ_UINT32 p_dx_min,
OPJ_UINT32 p_dy_min)
{
// loop
OPJ_UINT32 pino;
// tile coding parameter
opj_tcp_v2_t *l_tcp = 00;
// current poc being updated
opj_poc_t * l_current_poc = 00;
// number of pocs
OPJ_UINT32 l_poc_bound;
// preconditions in debug
assert(p_cp != 00);
assert(p_tileno < p_cp->tw * p_cp->th);
// initializations
l_tcp = &p_cp->tcps [p_tileno];
/* number of iterations in the loop */
l_poc_bound = l_tcp->numpocs+1;
// start at first element, and to make sure the compiler will not make a calculation each time in the loop
// store a pointer to the current element to modify rather than l_tcp->pocs[i]
l_current_poc = l_tcp->pocs;
for (pino = 0; pino < l_poc_bound ; ++pino) {
l_current_poc->compS = 0;
l_current_poc->compE = p_num_comps;/*p_image->numcomps;*/
l_current_poc->resS = 0;
l_current_poc->resE = p_max_res;
l_current_poc->layS = 0;
l_current_poc->layE = l_tcp->numlayers;
l_current_poc->prg = l_tcp->prg;
l_current_poc->prcS = 0;
l_current_poc->prcE = p_max_prec;
l_current_poc->txS = p_tx0;
l_current_poc->txE = p_tx1;
l_current_poc->tyS = p_ty0;
l_current_poc->tyE = p_ty1;
l_current_poc->dx = p_dx_min;
l_current_poc->dy = p_dy_min;
++ l_current_poc;
}
}
/**
* Destroys a packet iterator array.
@ -1561,3 +2161,354 @@ void pi_update_decode_not_poc (opj_pi_iterator_t * p_pi,opj_tcp_v2_t * p_tcp,OPJ
++l_current_pi;
}
}
void pi_create_encode_v2( opj_pi_iterator_t *pi,
opj_cp_v2_t *cp,
OPJ_UINT32 tileno,
OPJ_UINT32 pino,
OPJ_UINT32 tpnum,
OPJ_INT32 tppos,
J2K_T2_MODE t2_mode)
{
const OPJ_CHAR *prog;
OPJ_INT32 i,l;
OPJ_UINT32 incr_top=1,resetX=0;
opj_tcp_v2_t *tcps =&cp->tcps[tileno];
opj_poc_t *tcp= &tcps->pocs[pino];
prog = j2k_convert_progression_order(tcp->prg);
pi[pino].first = 1;
pi[pino].poc.prg = tcp->prg;
if(!(cp->m_specific_param.m_enc.m_tp_on&& ((!cp->m_specific_param.m_enc.m_cinema && (t2_mode == FINAL_PASS)) || cp->m_specific_param.m_enc.m_cinema))){
pi[pino].poc.resno0 = tcp->resS;
pi[pino].poc.resno1 = tcp->resE;
pi[pino].poc.compno0 = tcp->compS;
pi[pino].poc.compno1 = tcp->compE;
pi[pino].poc.layno0 = tcp->layS;
pi[pino].poc.layno1 = tcp->layE;
pi[pino].poc.precno0 = tcp->prcS;
pi[pino].poc.precno1 = tcp->prcE;
pi[pino].poc.tx0 = tcp->txS;
pi[pino].poc.ty0 = tcp->tyS;
pi[pino].poc.tx1 = tcp->txE;
pi[pino].poc.ty1 = tcp->tyE;
}else {
for(i=tppos+1;i<4;i++){
switch(prog[i]){
case 'R':
pi[pino].poc.resno0 = tcp->resS;
pi[pino].poc.resno1 = tcp->resE;
break;
case 'C':
pi[pino].poc.compno0 = tcp->compS;
pi[pino].poc.compno1 = tcp->compE;
break;
case 'L':
pi[pino].poc.layno0 = tcp->layS;
pi[pino].poc.layno1 = tcp->layE;
break;
case 'P':
switch(tcp->prg){
case LRCP:
case RLCP:
pi[pino].poc.precno0 = tcp->prcS;
pi[pino].poc.precno1 = tcp->prcE;
break;
default:
pi[pino].poc.tx0 = tcp->txS;
pi[pino].poc.ty0 = tcp->tyS;
pi[pino].poc.tx1 = tcp->txE;
pi[pino].poc.ty1 = tcp->tyE;
break;
}
break;
}
}
if(tpnum==0){
for(i=tppos;i>=0;i--){
switch(prog[i]){
case 'C':
tcp->comp_t = tcp->compS;
pi[pino].poc.compno0 = tcp->comp_t;
pi[pino].poc.compno1 = tcp->comp_t+1;
tcp->comp_t+=1;
break;
case 'R':
tcp->res_t = tcp->resS;
pi[pino].poc.resno0 = tcp->res_t;
pi[pino].poc.resno1 = tcp->res_t+1;
tcp->res_t+=1;
break;
case 'L':
tcp->lay_t = tcp->layS;
pi[pino].poc.layno0 = tcp->lay_t;
pi[pino].poc.layno1 = tcp->lay_t+1;
tcp->lay_t+=1;
break;
case 'P':
switch(tcp->prg){
case LRCP:
case RLCP:
tcp->prc_t = tcp->prcS;
pi[pino].poc.precno0 = tcp->prc_t;
pi[pino].poc.precno1 = tcp->prc_t+1;
tcp->prc_t+=1;
break;
default:
tcp->tx0_t = tcp->txS;
tcp->ty0_t = tcp->tyS;
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx);
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->tx0_t = pi[pino].poc.tx1;
tcp->ty0_t = pi[pino].poc.ty1;
break;
}
break;
}
}
incr_top=1;
}else{
for(i=tppos;i>=0;i--){
switch(prog[i]){
case 'C':
pi[pino].poc.compno0 = tcp->comp_t-1;
pi[pino].poc.compno1 = tcp->comp_t;
break;
case 'R':
pi[pino].poc.resno0 = tcp->res_t-1;
pi[pino].poc.resno1 = tcp->res_t;
break;
case 'L':
pi[pino].poc.layno0 = tcp->lay_t-1;
pi[pino].poc.layno1 = tcp->lay_t;
break;
case 'P':
switch(tcp->prg){
case LRCP:
case RLCP:
pi[pino].poc.precno0 = tcp->prc_t-1;
pi[pino].poc.precno1 = tcp->prc_t;
break;
default:
pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx);
pi[pino].poc.tx1 = tcp->tx0_t ;
pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy);
pi[pino].poc.ty1 = tcp->ty0_t ;
break;
}
break;
}
if(incr_top==1){
switch(prog[i]){
case 'R':
if(tcp->res_t==tcp->resE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
tcp->res_t = tcp->resS;
pi[pino].poc.resno0 = tcp->res_t;
pi[pino].poc.resno1 = tcp->res_t+1;
tcp->res_t+=1;
incr_top=1;
}else{
incr_top=0;
}
}else{
pi[pino].poc.resno0 = tcp->res_t;
pi[pino].poc.resno1 = tcp->res_t+1;
tcp->res_t+=1;
incr_top=0;
}
break;
case 'C':
if(tcp->comp_t ==tcp->compE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
tcp->comp_t = tcp->compS;
pi[pino].poc.compno0 = tcp->comp_t;
pi[pino].poc.compno1 = tcp->comp_t+1;
tcp->comp_t+=1;
incr_top=1;
}else{
incr_top=0;
}
}else{
pi[pino].poc.compno0 = tcp->comp_t;
pi[pino].poc.compno1 = tcp->comp_t+1;
tcp->comp_t+=1;
incr_top=0;
}
break;
case 'L':
if(tcp->lay_t == tcp->layE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
tcp->lay_t = tcp->layS;
pi[pino].poc.layno0 = tcp->lay_t;
pi[pino].poc.layno1 = tcp->lay_t+1;
tcp->lay_t+=1;
incr_top=1;
}else{
incr_top=0;
}
}else{
pi[pino].poc.layno0 = tcp->lay_t;
pi[pino].poc.layno1 = tcp->lay_t+1;
tcp->lay_t+=1;
incr_top=0;
}
break;
case 'P':
switch(tcp->prg){
case LRCP:
case RLCP:
if(tcp->prc_t == tcp->prcE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
tcp->prc_t = tcp->prcS;
pi[pino].poc.precno0 = tcp->prc_t;
pi[pino].poc.precno1 = tcp->prc_t+1;
tcp->prc_t+=1;
incr_top=1;
}else{
incr_top=0;
}
}else{
pi[pino].poc.precno0 = tcp->prc_t;
pi[pino].poc.precno1 = tcp->prc_t+1;
tcp->prc_t+=1;
incr_top=0;
}
break;
default:
if(tcp->tx0_t >= tcp->txE){
if(tcp->ty0_t >= tcp->tyE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
tcp->ty0_t = tcp->tyS;
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->ty0_t = pi[pino].poc.ty1;
incr_top=1;resetX=1;
}else{
incr_top=0;resetX=0;
}
}else{
pi[pino].poc.ty0 = tcp->ty0_t;
pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy);
tcp->ty0_t = pi[pino].poc.ty1;
incr_top=0;resetX=1;
}
if(resetX==1){
tcp->tx0_t = tcp->txS;
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx);
tcp->tx0_t = pi[pino].poc.tx1;
}
}else{
pi[pino].poc.tx0 = tcp->tx0_t;
pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx);
tcp->tx0_t = pi[pino].poc.tx1;
incr_top=0;
}
break;
}
break;
}
}
}
}
}
}
OPJ_INT32 pi_check_next_level( OPJ_INT32 pos,
opj_cp_v2_t *cp,
OPJ_UINT32 tileno,
OPJ_UINT32 pino,
const OPJ_CHAR *prog)
{
OPJ_INT32 i,l;
opj_tcp_v2_t *tcps =&cp->tcps[tileno];
opj_poc_t *tcp = &tcps->pocs[pino];
if(pos>=0){
for(i=pos;pos>=0;i--){
switch(prog[i]){
case 'R':
if(tcp->res_t==tcp->resE){
l=pi_check_next_level(pos-1,cp,tileno,pino,prog);
if(l==1){
return 1;
}else{
return 0;
}
}else{
return 1;
}
break;
case 'C':
if(tcp->comp_t==tcp->compE){
l=pi_check_next_level(pos-1,cp,tileno,pino,prog);
if(l==1){
return 1;
}else{
return 0;
}
}else{
return 1;
}
break;
case 'L':
if(tcp->lay_t==tcp->layE){
l=pi_check_next_level(pos-1,cp,tileno,pino,prog);
if(l==1){
return 1;
}else{
return 0;
}
}else{
return 1;
}
break;
case 'P':
switch(tcp->prg){
case LRCP||RLCP:
if(tcp->prc_t == tcp->prcE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
return 1;
}else{
return 0;
}
}else{
return 1;
}
break;
default:
if(tcp->tx0_t == tcp->txE){
//TY
if(tcp->ty0_t == tcp->tyE){
l=pi_check_next_level(i-1,cp,tileno,pino,prog);
if(l==1){
return 1;
}else{
return 0;
}
}else{
return 1;
}//TY
}else{
return 1;
}
break;
}//end case P
}//end switch
}//end for
}//end if
return 0;
}

View File

@ -110,6 +110,33 @@ Create a packet iterator for Encoder
@see pi_destroy
*/
opj_pi_iterator_t *pi_initialise_encode(opj_image_t *image, opj_cp_t *cp, int tileno,J2K_T2_MODE t2_mode);
/**
* Creates a packet iterator for encoding.
*
* @param p_image the image being encoded.
* @param p_cp the coding parameters.
* @param p_tile_no index of the tile being encoded.
* @param p_t2_mode the type of pass for generating the packet iterator
* @return a list of packet iterator that points to the first packet of the tile (not true).
*/
opj_pi_iterator_t *pi_initialise_encode_v2( const struct opj_image *image,
struct opj_cp_v2 *cp,
OPJ_UINT32 tileno,
J2K_T2_MODE t2_mode);
/**
* Updates the encoding parameters of the codec.
*
* @param p_image the image being encoded.
* @param p_cp the coding parameters.
* @param p_tile_no index of the tile being encoded.
*/
void pi_update_encoding_parameters( const struct opj_image *p_image,
struct opj_cp_v2 *p_cp,
OPJ_UINT32 p_tile_no );
/**
Modify the packet iterator for enabling tile part generation
@param pi Handle to the packet iterator generated in pi_initialise_encode
@ -123,6 +150,19 @@ Modify the packet iterator for enabling tile part generation
@return Returns true if an error is detected
*/
opj_bool pi_create_encode(opj_pi_iterator_t *pi, opj_cp_t *cp,int tileno, int pino,int tpnum, int tppos, J2K_T2_MODE t2_mode,int cur_totnum_tp);
/**
Modify the packet iterator for enabling tile part generation
@param pi Handle to the packet iterator generated in pi_initialise_encode
@param cp Coding parameters
@param tileno Number that identifies the tile for which to list the packets
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
*/
void pi_create_encode_v2( opj_pi_iterator_t *pi, struct opj_cp_v2 *cp,OPJ_UINT32 tileno, OPJ_UINT32 pino,OPJ_UINT32 tpnum, OPJ_INT32 tppos, J2K_T2_MODE t2_mode);
/**
Create a packet iterator for Decoder
@param image Raw image for which the packets will be listed

View File

@ -274,6 +274,17 @@ static double t1_getwmsedec(
double stepsize,
int numcomps,
int mct);
static OPJ_FLOAT64 t1_getwmsedec_v2(
OPJ_INT32 nmsedec,
OPJ_UINT32 compno,
OPJ_UINT32 level,
OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
const OPJ_FLOAT64 * mct_norms);
/**
Encode 1 code-block
@param t1 T1 handle
@ -300,6 +311,20 @@ static void t1_encode_cblk(
int numcomps,
int mct,
opj_tcd_tile_t * tile);
static void t1_encode_cblk_v2(
opj_t1_t *t1,
opj_tcd_cblk_enc_v2_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 compno,
OPJ_UINT32 level,
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_v2_t * tile,
const OPJ_FLOAT64 * mct_norms);
/**
Decode 1 code-block
@param t1 T1 handle
@ -1165,6 +1190,36 @@ static double t1_getwmsedec(
return wmsedec;
}
/** mod fixed_quality */
static OPJ_FLOAT64 t1_getwmsedec_v2(
OPJ_INT32 nmsedec,
OPJ_UINT32 compno,
OPJ_UINT32 level,
OPJ_UINT32 orient,
OPJ_INT32 bpno,
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 numcomps,
const OPJ_FLOAT64 * mct_norms)
{
OPJ_FLOAT64 w1 = 1, w2, wmsedec;
if (mct_norms) {
w1 = mct_norms[compno];
}
if (qmfbid == 1) {
w2 = dwt_getnorm(level, orient);
} else { /* if (qmfbid == 0) */
w2 = dwt_getnorm_real(level, orient);
}
wmsedec = w1 * w2 * stepsize * (1 << bpno);
wmsedec *= wmsedec * nmsedec / 8192.0;
return wmsedec;
}
static opj_bool allocate_buffers(
opj_t1_t *t1,
int w,
@ -1655,28 +1710,24 @@ 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)
{
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)
{
if (! l_t1->mqc) {
t1_destroy(l_t1);
return 00;
}
l_t1->raw = raw_create();
if
(! l_t1->raw)
{
if (! l_t1->raw) {
t1_destroy(l_t1);
return 00;
}
return l_t1;
}
@ -1873,6 +1924,241 @@ static void t1_decode_cblk_v2(
}
}
opj_bool t1_encode_cblks_v2(
opj_t1_t *t1,
opj_tcd_tile_v2_t *tile,
opj_tcp_v2_t *tcp,
const OPJ_FLOAT64 * mct_norms)
{
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
tile->distotile = 0; /* fixed_quality */
for (compno = 0; compno < tile->numcomps; ++compno) {
opj_tcd_tilecomp_v2_t* tilec = &tile->comps[compno];
opj_tccp_t* tccp = &tcp->tccps[compno];
OPJ_UINT32 tile_w = tilec->x1 - tilec->x0;
for (resno = 0; resno < tilec->numresolutions; ++resno) {
opj_tcd_resolution_v2_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_band_v2_t* restrict band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; ++precno) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
for (cblkno = 0; cblkno < prc->cw * prc->ch; ++cblkno) {
opj_tcd_cblk_enc_v2_t* cblk = &prc->cblks.enc[cblkno];
OPJ_INT32 * restrict datap;
OPJ_INT32* restrict tiledp;
OPJ_UINT32 cblk_w;
OPJ_UINT32 cblk_h;
OPJ_UINT32 i, j;
OPJ_INT32 x = cblk->x0 - band->x0;
OPJ_INT32 y = cblk->y0 - band->y0;
if (band->bandno & 1) {
opj_tcd_resolution_v2_t *pres = &tilec->resolutions[resno - 1];
x += pres->x1 - pres->x0;
}
if (band->bandno & 2) {
opj_tcd_resolution_v2_t *pres = &tilec->resolutions[resno - 1];
y += pres->y1 - pres->y0;
}
if(!allocate_buffers(
t1,
cblk->x1 - cblk->x0,
cblk->y1 - cblk->y0))
{
return OPJ_FALSE;
}
datap=t1->data;
cblk_w = t1->w;
cblk_h = t1->h;
tiledp=&tilec->data[(y * tile_w) + x];
if (tccp->qmfbid == 1) {
for (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) {
OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
datap[(j * cblk_w) + i] = tmp << T1_NMSEDEC_FRACBITS;
}
}
} else { /* if (tccp->qmfbid == 0) */
for (j = 0; j < cblk_h; ++j) {
for (i = 0; i < cblk_w; ++i) {
OPJ_INT32 tmp = tiledp[(j * tile_w) + i];
datap[(j * cblk_w) + i] =
fix_mul(
tmp,
8192 * 8192 / ((OPJ_INT32) floor(band->stepsize * 8192))) >> (11 - T1_NMSEDEC_FRACBITS);
}
}
}
t1_encode_cblk_v2(
t1,
cblk,
band->bandno,
compno,
tilec->numresolutions - 1 - resno,
tccp->qmfbid,
band->stepsize,
tccp->cblksty,
tile->numcomps,
tile,
mct_norms);
} /* cblkno */
} /* precno */
} /* bandno */
} /* resno */
} /* compno */
return OPJ_TRUE;
}
/** mod fixed_quality */
static void t1_encode_cblk_v2(
opj_t1_t *t1,
opj_tcd_cblk_enc_v2_t* cblk,
OPJ_UINT32 orient,
OPJ_UINT32 compno,
OPJ_UINT32 level,
OPJ_UINT32 qmfbid,
OPJ_FLOAT64 stepsize,
OPJ_UINT32 cblksty,
OPJ_UINT32 numcomps,
opj_tcd_tile_v2_t * tile,
const OPJ_FLOAT64 * mct_norms)
{
OPJ_FLOAT64 cumwmsedec = 0.0;
opj_mqc_t *mqc = t1->mqc; /* MQC component */
OPJ_UINT32 passno;
OPJ_INT32 bpno;
OPJ_UINT32 passtype;
OPJ_INT32 nmsedec = 0;
OPJ_INT32 max;
OPJ_UINT32 i;
OPJ_BYTE type = T1_TYPE_MQ;
OPJ_FLOAT64 tempwmsedec;
max = 0;
for (i = 0; i < t1->w * t1->h; ++i) {
OPJ_INT32 tmp = abs(t1->data[i]);
max = int_max(max, tmp);
}
cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0;
bpno = cblk->numbps - 1;
passtype = 2;
mqc_resetstates(mqc);
mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
mqc_init_enc(mqc, cblk->data);
for (passno = 0; bpno >= 0; ++passno) {
opj_tcd_pass_v2_t *pass = &cblk->passes[passno];
OPJ_UINT32 correction = 3;
type = ((bpno < ((OPJ_INT32) (cblk->numbps) - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
switch (passtype) {
case 0:
t1_enc_sigpass(t1, bpno, orient, &nmsedec, type, cblksty);
break;
case 1:
t1_enc_refpass(t1, bpno, &nmsedec, type, cblksty);
break;
case 2:
t1_enc_clnpass(t1, bpno, orient, &nmsedec, cblksty);
/* code switch SEGMARK (i.e. SEGSYM) */
if (cblksty & J2K_CCP_CBLKSTY_SEGSYM)
mqc_segmark_enc(mqc);
break;
}
/* fixed_quality */
tempwmsedec = t1_getwmsedec_v2(nmsedec, compno, level, orient, bpno, qmfbid, stepsize, numcomps,mct_norms) ;
cumwmsedec += tempwmsedec;
tile->distotile += tempwmsedec;
/* Code switch "RESTART" (i.e. TERMALL) */
if ((cblksty & J2K_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) {
if (type == T1_TYPE_RAW) {
mqc_flush(mqc);
correction = 1;
/* correction = mqc_bypass_flush_enc(); */
} else { /* correction = mqc_restart_enc(); */
mqc_flush(mqc);
correction = 1;
}
pass->term = 1;
} else {
if (((bpno < ((OPJ_INT32) (cblk->numbps) - 4) && (passtype > 0))
|| ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) {
if (type == T1_TYPE_RAW) {
mqc_flush(mqc);
correction = 1;
/* correction = mqc_bypass_flush_enc(); */
} else { /* correction = mqc_restart_enc(); */
mqc_flush(mqc);
correction = 1;
}
pass->term = 1;
} else {
pass->term = 0;
}
}
if (++passtype == 3) {
passtype = 0;
bpno--;
}
if (pass->term && bpno > 0) {
type = ((bpno < ((OPJ_INT32) (cblk->numbps) - 4)) && (passtype < 2) && (cblksty & J2K_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ;
if (type == T1_TYPE_RAW)
mqc_bypass_init_enc(mqc);
else
mqc_restart_init_enc(mqc);
}
pass->distortiondec = cumwmsedec;
pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */
/* Code-switch "RESET" */
if (cblksty & J2K_CCP_CBLKSTY_RESET)
mqc_reset_enc(mqc);
}
/* Code switch "ERTERM" (i.e. PTERM) */
if (cblksty & J2K_CCP_CBLKSTY_PTERM)
mqc_erterm_enc(mqc);
else /* Default coding */ if (!(cblksty & J2K_CCP_CBLKSTY_LAZY))
mqc_flush(mqc);
cblk->totalpasses = passno;
for (passno = 0; passno<cblk->totalpasses; passno++) {
opj_tcd_pass_v2_t *pass = &cblk->passes[passno];
if (pass->rate > mqc_numbytes(mqc))
pass->rate = mqc_numbytes(mqc);
/*Preventing generation of FF as last data byte of a pass*/
if((pass->rate>1) && (cblk->data[pass->rate - 1] == 0xFF)){
pass->rate--;
}
pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate);
}
}
static void t1_dec_refpass(
opj_t1_t *t1,
OPJ_INT32 bpno,

View File

@ -132,6 +132,12 @@ Encode the code-blocks of a tile
@param tcp Tile coding parameters
*/
void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp);
opj_bool t1_encode_cblks_v2(opj_t1_t *t1,
struct opj_tcd_tile_v2 *tile,
struct opj_tcp_v2 *tcp,
const OPJ_FLOAT64 * mct_norms);
/**
Decode the code-blocks of a tile
@param t1 T1 handle

View File

@ -58,6 +58,28 @@ Encode a packet of a tile to a destination buffer
@return
*/
static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_codestream_info_t *cstr_info, int tileno);
/**
Encode a packet of a tile to a destination buffer
@param tile Tile for which to write the packets
@param tcp Tile coding parameters
@param pi Packet identity
@param dest Destination buffer
@param len Length of the destination buffer
@param cstr_info Codestream information structure
@param tileno Number of the tile encoded
@return
*/
static opj_bool t2_encode_packet_v2(
OPJ_UINT32 tileno,
opj_tcd_tile_v2_t *tile,
opj_tcp_v2_t *tcp,
opj_pi_iterator_t *pi,
OPJ_BYTE *dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 len,
opj_codestream_info_t *cstr_info);
/**
@param cblk
@param index
@ -754,6 +776,128 @@ int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlaye
return (c - dest);
}
opj_bool t2_encode_packets_v2(
opj_t2_v2_t* p_t2,
OPJ_UINT32 p_tile_no,
opj_tcd_tile_v2_t *p_tile,
OPJ_UINT32 p_maxlayers,
OPJ_BYTE *p_dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_len,
opj_codestream_info_t *cstr_info,
OPJ_UINT32 p_tp_num,
OPJ_INT32 p_tp_pos,
OPJ_UINT32 p_pino,
J2K_T2_MODE p_t2_mode)
{
OPJ_BYTE *l_current_data = p_dest;
OPJ_UINT32 l_nb_bytes = 0;
OPJ_UINT32 compno;
OPJ_UINT32 poc;
opj_pi_iterator_t *l_pi = 00;
opj_pi_iterator_t *l_current_pi = 00;
opj_image_t *l_image = p_t2->image;
opj_cp_v2_t *l_cp = p_t2->cp;
opj_tcp_v2_t *l_tcp = &l_cp->tcps[p_tile_no];
OPJ_UINT32 pocno = l_cp->m_specific_param.m_enc.m_cinema == CINEMA4K_24? 2: 1;
OPJ_UINT32 l_max_comp = l_cp->m_specific_param.m_enc.m_max_comp_size > 0 ? l_image->numcomps : 1;
OPJ_UINT32 l_nb_pocs = l_tcp->numpocs + 1;
l_pi = pi_initialise_encode_v2(l_image, l_cp, p_tile_no, p_t2_mode);
if (!l_pi) {
return OPJ_FALSE;
}
* p_data_written = 0;
if (p_t2_mode == THRESH_CALC ){ /* Calculating threshold */
l_current_pi = l_pi;
for (compno = 0; compno < l_max_comp; ++compno) {
OPJ_UINT32 l_comp_len = 0;
l_current_pi = l_pi;
for (poc = 0; poc < pocno ; ++poc) {
OPJ_UINT32 l_tp_num = compno;
pi_create_encode_v2(l_pi, l_cp,p_tile_no,poc,l_tp_num,p_tp_pos,p_t2_mode);
while (pi_next(l_current_pi)) {
if (l_current_pi->layno < p_maxlayers) {
l_nb_bytes = 0;
if (! t2_encode_packet_v2(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
pi_destroy_v2(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
l_comp_len += l_nb_bytes;
l_current_data += l_nb_bytes;
p_max_len -= l_nb_bytes;
* p_data_written += l_nb_bytes;
}
}
if (l_cp->m_specific_param.m_enc.m_max_comp_size) {
if (l_comp_len > l_cp->m_specific_param.m_enc.m_max_comp_size) {
pi_destroy_v2(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
}
++l_current_pi;
}
}
}
else { /* t2_mode == FINAL_PASS */
pi_create_encode_v2(l_pi, l_cp,p_tile_no,p_pino,p_tp_num,p_tp_pos,p_t2_mode);
l_current_pi = &l_pi[p_pino];
while (pi_next(l_current_pi)) {
if (l_current_pi->layno < p_maxlayers) {
l_nb_bytes=0;
if (! t2_encode_packet_v2(p_tile_no,p_tile, l_tcp, l_current_pi, l_current_data, &l_nb_bytes, p_max_len, cstr_info)) {
pi_destroy_v2(l_pi, l_nb_pocs);
return OPJ_FALSE;
}
l_current_data += l_nb_bytes;
p_max_len -= l_nb_bytes;
* p_data_written += l_nb_bytes;
/* INDEX >> */
if(cstr_info) {
if(cstr_info->index_write) {
opj_tile_info_t *info_TL = &cstr_info->tile[p_tile_no];
opj_packet_info_t *info_PK = &info_TL->packet[cstr_info->packno];
if (!cstr_info->packno) {
info_PK->start_pos = info_TL->end_header + 1;
} else {
info_PK->start_pos = ((l_cp->m_specific_param.m_enc.m_tp_on | l_tcp->POC)&& info_PK->start_pos) ? info_PK->start_pos : info_TL->packet[cstr_info->packno - 1].end_pos + 1;
}
info_PK->end_pos = info_PK->start_pos + l_nb_bytes - 1;
info_PK->end_ph_pos += info_PK->start_pos - 1; // End of packet header which now only represents the distance
// to start of packet is incremented by value of start of packet
}
cstr_info->packno++;
}
/* << INDEX */
++p_tile->packno;
}
}
}
pi_destroy_v2(l_pi, l_nb_pocs);
return OPJ_TRUE;
}
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) {
unsigned char *c = src;
opj_pi_iterator_t *pi;
@ -1052,6 +1196,232 @@ static opj_bool t2_decode_packet_v2(
return OPJ_TRUE;
}
static opj_bool t2_encode_packet_v2(
OPJ_UINT32 tileno,
opj_tcd_tile_v2_t * tile,
opj_tcp_v2_t * tcp,
opj_pi_iterator_t *pi,
OPJ_BYTE *dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 length,
opj_codestream_info_t *cstr_info)
{
OPJ_UINT32 bandno, cblkno;
OPJ_BYTE *c = dest;
OPJ_UINT32 l_nb_bytes;
OPJ_UINT32 compno = pi->compno; /* component value */
OPJ_UINT32 resno = pi->resno; /* resolution level value */
OPJ_UINT32 precno = pi->precno; /* precinct value */
OPJ_UINT32 layno = pi->layno; /* quality layer value */
OPJ_UINT32 l_nb_blocks;
opj_tcd_band_v2_t *band = 00;
opj_tcd_cblk_enc_v2_t* cblk = 00;
opj_tcd_pass_v2_t *pass = 00;
opj_tcd_tilecomp_v2_t *tilec = &tile->comps[compno];
opj_tcd_resolution_v2_t *res = &tilec->resolutions[resno];
opj_bio_t *bio = 00; /* BIO component */
/* <SOP 0xff91> */
if (tcp->csty & J2K_CP_CSTY_SOP) {
c[0] = 255;
c[1] = 145;
c[2] = 0;
c[3] = 4;
c[4] = (tile->packno % 65536) / 256;
c[5] = (tile->packno % 65536) % 256;
c += 6;
length -= 6;
}
/* </SOP> */
if (!layno) {
band = res->bands;
for(bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
tgt_reset(prc->incltree);
tgt_reset(prc->imsbtree);
l_nb_blocks = prc->cw * prc->ch;
for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
opj_tcd_cblk_enc_v2_t* cblk = &prc->cblks.enc[cblkno];
cblk->numpasses = 0;
tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps);
}
++band;
}
}
bio = bio_create();
bio_init_enc(bio, c, length);
bio_write(bio, 1, 1); /* Empty header bit */
/* Writing Packet header */
band = res->bands;
for (bandno = 0; bandno < res->numbands; ++bandno) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
l_nb_blocks = prc->cw * prc->ch;
cblk = prc->cblks.enc;
for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
opj_tcd_layer_t *layer = &cblk->layers[layno];
if (!cblk->numpasses && layer->numpasses) {
tgt_setvalue(prc->incltree, cblkno, layno);
}
++cblk;
}
cblk = prc->cblks.enc;
for (cblkno = 0; cblkno < l_nb_blocks; cblkno++) {
opj_tcd_layer_t *layer = &cblk->layers[layno];
OPJ_UINT32 increment = 0;
OPJ_UINT32 nump = 0;
OPJ_UINT32 len = 0, passno;
OPJ_UINT32 l_nb_passes;
/* cblk inclusion bits */
if (!cblk->numpasses) {
tgt_encode(bio, prc->incltree, cblkno, layno + 1);
} else {
bio_write(bio, layer->numpasses != 0, 1);
}
/* if cblk not included, go to the next cblk */
if (!layer->numpasses) {
++cblk;
continue;
}
/* if first instance of cblk --> zero bit-planes information */
if (!cblk->numpasses) {
cblk->numlenbits = 3;
tgt_encode(bio, prc->imsbtree, cblkno, 999);
}
/* number of coding passes included */
t2_putnumpasses(bio, layer->numpasses);
l_nb_passes = cblk->numpasses + layer->numpasses;
pass = cblk->passes + cblk->numpasses;
/* computation of the increase of the length indicator and insertion in the header */
for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
++nump;
len += pass->len;
if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump)));
len = 0;
nump = 0;
}
++pass;
}
t2_putcommacode(bio, increment);
/* computation of the new Length indicator */
cblk->numlenbits += increment;
pass = cblk->passes + cblk->numpasses;
/* insertion of the codeword segment length */
for (passno = cblk->numpasses; passno < l_nb_passes; ++passno) {
nump++;
len += pass->len;
if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) {
bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump));
len = 0;
nump = 0;
}
++pass;
}
++cblk;
}
++band;
}
if (bio_flush(bio)) {
bio_destroy(bio);
return OPJ_FALSE; /* modified to eliminate longjmp !! */
}
l_nb_bytes = bio_numbytes(bio);
c += l_nb_bytes;
length -= l_nb_bytes;
bio_destroy(bio);
/* <EPH 0xff92> */
if (tcp->csty & J2K_CP_CSTY_EPH) {
c[0] = 255;
c[1] = 146;
c += 2;
length -= 2;
}
/* </EPH> */
/* << 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(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->end_ph_pos = (OPJ_INT32)(c - dest);
}
/* INDEX >> */
/* Writing the packet body */
band = res->bands;
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
l_nb_blocks = prc->cw * prc->ch;
cblk = prc->cblks.enc;
for (cblkno = 0; cblkno < l_nb_blocks; ++cblkno) {
opj_tcd_layer_t *layer = &cblk->layers[layno];
if (!layer->numpasses) {
++cblk;
continue;
}
if (layer->len > length) {
return OPJ_FALSE;
}
memcpy(c, layer->data, layer->len);
cblk->numpasses += layer->numpasses;
c += layer->len;
length -= layer->len;
/* << INDEX */
if(cstr_info && cstr_info->index_write) {
opj_packet_info_t *info_PK = &cstr_info->tile[tileno].packet[cstr_info->packno];
info_PK->disto += layer->disto;
if (cstr_info->D_max < info_PK->disto) {
cstr_info->D_max = info_PK->disto;
}
}
++cblk;
/* INDEX >> */
}
++band;
}
* p_data_written += (c - dest);
return OPJ_TRUE;
}
static opj_bool t2_skip_packet(
opj_t2_v2_t* p_t2,
opj_tcd_tile_v2_t *p_tile,

View File

@ -85,6 +85,33 @@ Encode the packets of a tile to a destination buffer
@param cur_totnum_tp The total number of tile parts in the current tile
*/
int t2_encode_packets(opj_t2_t* t2,int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_codestream_info_t *cstr_info,int tpnum, int tppos,int pino,J2K_T2_MODE t2_mode,int cur_totnum_tp);
/**
Encode the packets of a tile to a destination buffer
@param t2 T2 handle
@param tileno number of the tile encoded
@param tile the tile for which to write the packets
@param maxlayers maximum number of layers
@param dest the destination buffer
@param len the length of the destination buffer
@param cstr_info Codestream information structure
@param tpnum Tile part number of the current tile
@param tppos The position of the tile part flag in the progression order
@param t2_mode If == 0 In Threshold calculation ,If == 1 Final pass
*/
opj_bool t2_encode_packets_v2( opj_t2_v2_t* t2,
OPJ_UINT32 tileno,
struct opj_tcd_tile_v2 *tile,
OPJ_UINT32 maxlayers,
OPJ_BYTE *dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 len,
struct opj_codestream_info *cstr_info,
OPJ_UINT32 tpnum,
OPJ_INT32 tppos,
OPJ_UINT32 pino,
J2K_T2_MODE t2_mode);
/**
Decode the packets of a tile from a source buffer
@param t2 T2 handle

View File

@ -32,6 +32,30 @@
#include "opj_includes.h"
/* ----------------------------------------------------------------------- */
static opj_bool tcd_dc_level_shift_encode ( opj_tcd_v2_t *p_tcd );
static opj_bool tcd_mct_encode ( opj_tcd_v2_t *p_tcd );
static opj_bool tcd_dwt_encode ( opj_tcd_v2_t *p_tcd );
static opj_bool tcd_t1_encode ( opj_tcd_v2_t *p_tcd );
static opj_bool tcd_t2_encode ( opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info );
static opj_bool tcd_rate_allocate_encode( opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info );
/* ----------------------------------------------------------------------- */
void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
int tileno, compno, resno, bandno, precno;/*, cblkno;*/
@ -95,6 +119,12 @@ void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_image_t * img) {
*/
static opj_bool tcd_code_block_dec_allocate (opj_tcd_cblk_dec_v2_t * p_code_block);
/**
* Allocates memory for an encoding code block.
*/
static opj_bool tcd_code_block_enc_allocate (opj_tcd_cblk_enc_v2_t * p_code_block);
/**
Free the memory allocated for encoding
@param tcd TCD handle
@ -992,6 +1022,14 @@ void tcd_rateallocate_fixed(opj_tcd_t *tcd) {
}
}
void tcd_rateallocate_fixed_v2(opj_tcd_v2_t *tcd) {
OPJ_UINT32 layno;
for (layno = 0; layno < tcd->tcp->numlayers; layno++) {
tcd_makelayer_fixed_v2(tcd, layno, 1);
}
}
void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
int compno, resno, bandno, precno, cblkno, passno;
@ -1062,6 +1100,184 @@ void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {
}
}
void tcd_makelayer_v2( opj_tcd_v2_t *tcd,
OPJ_UINT32 layno,
OPJ_FLOAT64 thresh,
OPJ_UINT32 final)
{
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
OPJ_UINT32 passno;
opj_tcd_tile_v2_t *tcd_tile = tcd->tcd_image->tiles;
tcd_tile->distolayer[layno] = 0; /* fixed_quality */
for (compno = 0; compno < tcd_tile->numcomps; compno++) {
opj_tcd_tilecomp_v2_t *tilec = &tcd_tile->comps[compno];
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_v2_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_v2_t *band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; precno++) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
opj_tcd_cblk_enc_v2_t *cblk = &prc->cblks.enc[cblkno];
opj_tcd_layer_t *layer = &cblk->layers[layno];
OPJ_UINT32 n;
if (layno == 0) {
cblk->numpassesinlayers = 0;
}
n = cblk->numpassesinlayers;
for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
OPJ_INT32 dr;
OPJ_FLOAT64 dd;
opj_tcd_pass_v2_t *pass = &cblk->passes[passno];
if (n == 0) {
dr = pass->rate;
dd = pass->distortiondec;
} else {
dr = pass->rate - cblk->passes[n - 1].rate;
dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;
}
if (!dr) {
if (dd != 0)
n = passno + 1;
continue;
}
if (dd / dr >= thresh)
n = passno + 1;
}
layer->numpasses = n - cblk->numpassesinlayers;
if (!layer->numpasses) {
layer->disto = 0;
continue;
}
if (cblk->numpassesinlayers == 0) {
layer->len = cblk->passes[n - 1].rate;
layer->data = cblk->data;
layer->disto = cblk->passes[n - 1].distortiondec;
} else {
layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;
}
tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */
if (final)
cblk->numpassesinlayers = n;
}
}
}
}
}
}
void tcd_makelayer_fixed_v2(opj_tcd_v2_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) {
OPJ_UINT32 compno, resno, bandno, precno, cblkno;
OPJ_INT32 value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolutions][3]; */
OPJ_INT32 matrice[10][10][3];
OPJ_UINT32 i, j, k;
opj_cp_v2_t *cp = tcd->cp;
opj_tcd_tile_v2_t *tcd_tile = tcd->tcd_image->tiles;
opj_tcp_v2_t *tcd_tcp = tcd->tcp;
for (compno = 0; compno < tcd_tile->numcomps; compno++) {
opj_tcd_tilecomp_v2_t *tilec = &tcd_tile->comps[compno];
for (i = 0; i < tcd_tcp->numlayers; i++) {
for (j = 0; j < tilec->numresolutions; j++) {
for (k = 0; k < 3; k++) {
matrice[i][j][k] =
(OPJ_INT32) (cp->m_specific_param.m_enc.m_matrice[i * tilec->numresolutions * 3 + j * 3 + k]
* (OPJ_FLOAT32) (tcd->image->comps[compno].prec / 16.0));
}
}
}
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_v2_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_v2_t *band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; precno++) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
opj_tcd_cblk_enc_v2_t *cblk = &prc->cblks.enc[cblkno];
opj_tcd_layer_t *layer = &cblk->layers[layno];
OPJ_UINT32 n;
OPJ_INT32 imsb = tcd->image->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */
/* Correction of the matrix of coefficient to include the IMSB information */
if (layno == 0) {
value = matrice[layno][resno][bandno];
if (imsb >= value) {
value = 0;
} else {
value -= imsb;
}
} else {
value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];
if (imsb >= matrice[layno - 1][resno][bandno]) {
value -= (imsb - matrice[layno - 1][resno][bandno]);
if (value < 0) {
value = 0;
}
}
}
if (layno == 0) {
cblk->numpassesinlayers = 0;
}
n = cblk->numpassesinlayers;
if (cblk->numpassesinlayers == 0) {
if (value != 0) {
n = 3 * value - 2 + cblk->numpassesinlayers;
} else {
n = cblk->numpassesinlayers;
}
} else {
n = 3 * value + cblk->numpassesinlayers;
}
layer->numpasses = n - cblk->numpassesinlayers;
if (!layer->numpasses)
continue;
if (cblk->numpassesinlayers == 0) {
layer->len = cblk->passes[n - 1].rate;
layer->data = cblk->data;
} else {
layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;
layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;
}
if (final)
cblk->numpassesinlayers = n;
}
}
}
}
}
}
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
int compno, resno, bandno, precno, cblkno, passno, layno;
double min, max;
@ -1229,6 +1445,195 @@ opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_code
return OPJ_TRUE;
}
opj_bool tcd_rateallocate_v2( opj_tcd_v2_t *tcd,
OPJ_BYTE *dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 len,
opj_codestream_info_t *cstr_info)
{
OPJ_UINT32 compno, resno, bandno, precno, cblkno, layno;
OPJ_UINT32 passno;
OPJ_FLOAT64 min, max;
OPJ_FLOAT64 cumdisto[100]; /* fixed_quality */
const OPJ_FLOAT64 K = 1; /* 1.1; fixed_quality */
OPJ_FLOAT64 maxSE = 0;
opj_cp_v2_t *cp = tcd->cp;
opj_tcd_tile_v2_t *tcd_tile = tcd->tcd_image->tiles;
opj_tcp_v2_t *tcd_tcp = tcd->tcp;
min = DBL_MAX;
max = 0;
tcd_tile->numpix = 0; /* fixed_quality */
for (compno = 0; compno < tcd_tile->numcomps; compno++) {
opj_tcd_tilecomp_v2_t *tilec = &tcd_tile->comps[compno];
tilec->numpix = 0;
for (resno = 0; resno < tilec->numresolutions; resno++) {
opj_tcd_resolution_v2_t *res = &tilec->resolutions[resno];
for (bandno = 0; bandno < res->numbands; bandno++) {
opj_tcd_band_v2_t *band = &res->bands[bandno];
for (precno = 0; precno < res->pw * res->ph; precno++) {
opj_tcd_precinct_v2_t *prc = &band->precincts[precno];
for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) {
opj_tcd_cblk_enc_v2_t *cblk = &prc->cblks.enc[cblkno];
for (passno = 0; passno < cblk->totalpasses; passno++) {
opj_tcd_pass_v2_t *pass = &cblk->passes[passno];
OPJ_INT32 dr;
OPJ_FLOAT64 dd, rdslope;
if (passno == 0) {
dr = pass->rate;
dd = pass->distortiondec;
} else {
dr = pass->rate - cblk->passes[passno - 1].rate;
dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;
}
if (dr == 0) {
continue;
}
rdslope = dd / dr;
if (rdslope < min) {
min = rdslope;
}
if (rdslope > max) {
max = rdslope;
}
} /* passno */
/* fixed_quality */
tcd_tile->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
tilec->numpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0));
} /* cbklno */
} /* precno */
} /* bandno */
} /* resno */
maxSE += (((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) - 1.0)
* ((OPJ_FLOAT64)(1 << tcd->image->comps[compno].prec) -1.0))
* ((OPJ_FLOAT64)(tilec->numpix));
} /* compno */
/* index file */
if(cstr_info) {
opj_tile_info_t *tile_info = &cstr_info->tile[tcd->tcd_tileno];
tile_info->numpix = tcd_tile->numpix;
tile_info->distotile = tcd_tile->distotile;
tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(OPJ_FLOAT64));
}
for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
OPJ_FLOAT64 lo = min;
OPJ_FLOAT64 hi = max;
opj_bool success = OPJ_FALSE;
OPJ_UINT32 maxlen = tcd_tcp->rates[layno] ? uint_min(((OPJ_UINT32) ceil(tcd_tcp->rates[layno])), len) : len;
OPJ_FLOAT64 goodthresh = 0;
OPJ_FLOAT64 stable_thresh = 0;
OPJ_UINT32 i;
OPJ_FLOAT64 distotarget; /* fixed_quality */
/* fixed_quality */
distotarget = tcd_tile->distotile - ((K * maxSE) / pow((OPJ_FLOAT32)10, tcd_tcp->distoratio[layno] / 10));
/* Don't try to find an optimal threshold but rather take everything not included yet, if
-r xx,yy,zz,0 (disto_alloc == 1 and rates == 0)
-q xx,yy,zz,0 (fixed_quality == 1 and distoratio == 0)
==> possible to have some lossy layers and the last layer for sure lossless */
if ( ((cp->m_specific_param.m_enc.m_disto_alloc==1) && (tcd_tcp->rates[layno]>0)) || ((cp->m_specific_param.m_enc.m_fixed_quality==1) && (tcd_tcp->distoratio[layno]>0))) {
opj_t2_v2_t*t2 = t2_create_v2(tcd->image, cp);
OPJ_FLOAT64 thresh = 0;
if (t2 == 00) {
return OPJ_FALSE;
}
for (i = 0; i < 128; ++i) {
OPJ_FLOAT64 distoachieved = 0; /* fixed_quality */
thresh = (lo + hi) / 2;
tcd_makelayer_v2(tcd, layno, thresh, 0);
if (cp->m_specific_param.m_enc.m_fixed_quality) { /* fixed_quality */
if(cp->m_specific_param.m_enc.m_cinema){
if (! t2_encode_packets_v2(t2,tcd->tcd_tileno, tcd_tile, layno + 1, dest, p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC)) {
lo = thresh;
continue;
}
else {
distoachieved = layno == 0 ?
tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];
if (distoachieved < distotarget) {
hi=thresh;
stable_thresh = thresh;
continue;
}else{
lo=thresh;
}
}
}else{
distoachieved = (layno == 0) ?
tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
if (distoachieved < distotarget) {
hi = thresh;
stable_thresh = thresh;
continue;
}
lo = thresh;
}
} else {
if (! t2_encode_packets_v2(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest,p_data_written, maxlen, cstr_info,tcd->cur_tp_num,tcd->tp_pos,tcd->cur_pino,THRESH_CALC))
{
/* TODO: what to do with l ??? seek / tell ??? */
/* opj_event_msg(tcd->cinfo, EVT_INFO, "rate alloc: len=%d, max=%d\n", l, maxlen); */
lo = thresh;
continue;
}
hi = thresh;
stable_thresh = thresh;
}
}
success = OPJ_TRUE;
goodthresh = stable_thresh == 0? thresh : stable_thresh;
t2_destroy_v2(t2);
} else {
success = OPJ_TRUE;
goodthresh = min;
}
if (!success) {
return OPJ_FALSE;
}
if(cstr_info) { /* Threshold for Marcela Index */
cstr_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;
}
tcd_makelayer_v2(tcd, layno, goodthresh, 1);
/* fixed_quality */
cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : (cumdisto[layno - 1] + tcd_tile->distolayer[layno]);
}
return OPJ_TRUE;
}
int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_codestream_info_t *cstr_info) {
int compno;
int l, i, numpacks = 0;
@ -1993,11 +2398,74 @@ opj_bool FUNCTION ( opj_tcd_v2_t *p_tcd, \
} \
/* V2 ENCODE MACRO_TCD_ALLOCATE(tcd_init_encode_tile,opj_tcd_cblk_enc_t,1.f,enc,tcd_code_block_enc_allocate) */
MACRO_TCD_ALLOCATE(tcd_init_encode_tile, opj_tcd_cblk_enc_v2_t, 1.f, enc, tcd_code_block_enc_allocate)
MACRO_TCD_ALLOCATE(tcd_init_decode_tile, opj_tcd_cblk_dec_v2_t, 0.5f, dec, tcd_code_block_dec_allocate)
#undef MACRO_TCD_ALLOCATE
/**
* Allocates memory for an encoding code block.
*/
opj_bool tcd_code_block_enc_allocate (opj_tcd_cblk_enc_v2_t * p_code_block)
{
if (! p_code_block->data) {
p_code_block->data = (OPJ_BYTE*) opj_malloc(8192+1);
if(! p_code_block->data) {
return OPJ_FALSE;
}
p_code_block->data+=1;
/* no memset since data */
p_code_block->layers = (opj_tcd_layer_t*) opj_malloc(100 * sizeof(opj_tcd_layer_t));
if (! p_code_block->layers) {
return OPJ_FALSE;
}
p_code_block->passes = (opj_tcd_pass_v2_t*) opj_malloc(100 * sizeof(opj_tcd_pass_v2_t));
if (! p_code_block->passes) {
return OPJ_FALSE;
}
}
memset(p_code_block->layers,0,100 * sizeof(opj_tcd_layer_t));
memset(p_code_block->passes,0,100 * sizeof(opj_tcd_pass_v2_t));
return OPJ_TRUE;
}
/**
* Allocates memory for a decoding code block.
*/
opj_bool tcd_code_block_dec_allocate (opj_tcd_cblk_dec_v2_t * p_code_block)
{
OPJ_UINT32 l_seg_size;
if (! p_code_block->data) {
p_code_block->data = (OPJ_BYTE*) opj_malloc(8192);
if (! p_code_block->data) {
return OPJ_FALSE;
}
/*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/
l_seg_size = J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t);
p_code_block->segs = (opj_tcd_seg_t *) opj_malloc(l_seg_size);
if (! p_code_block->segs) {
return OPJ_FALSE;
}
memset(p_code_block->segs,0,l_seg_size);
/*fprintf(stderr, "Allocate %d elements of code_block->data\n", J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/
p_code_block->m_current_max_segs = J2K_DEFAULT_NB_SEGS;
/*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
}
/* TODO */
/*p_code_block->numsegs = 0; */
return OPJ_TRUE;
}
OPJ_UINT32 tcd_get_decoded_tile_size ( opj_tcd_v2_t *p_tcd )
{
@ -2032,6 +2500,89 @@ OPJ_UINT32 tcd_get_decoded_tile_size ( opj_tcd_v2_t *p_tcd )
return l_data_size;
}
opj_bool tcd_encode_tile_v2(opj_tcd_v2_t *p_tcd,
OPJ_UINT32 p_tile_no,
OPJ_BYTE *p_dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_length,
opj_codestream_info_t *p_cstr_info)
{
if (p_tcd->cur_tp_num == 0) {
p_tcd->tcd_tileno = p_tile_no;
p_tcd->tcp = &p_tcd->cp->tcps[p_tile_no];
/* INDEX >> "Precinct_nb_X et Precinct_nb_Y" */
if(p_cstr_info) {
OPJ_UINT32 l_num_packs = 0;
OPJ_UINT32 i;
opj_tcd_tilecomp_v2_t *l_tilec_idx = &p_tcd->tcd_image->tiles->comps[0]; /* based on component 0 */
opj_tccp_t *l_tccp = p_tcd->tcp->tccps; /* based on component 0 */
for (i = 0; i < l_tilec_idx->numresolutions; i++) {
opj_tcd_resolution_v2_t *l_res_idx = &l_tilec_idx->resolutions[i];
p_cstr_info->tile[p_tile_no].pw[i] = l_res_idx->pw;
p_cstr_info->tile[p_tile_no].ph[i] = l_res_idx->ph;
l_num_packs += l_res_idx->pw * l_res_idx->ph;
p_cstr_info->tile[p_tile_no].pdx[i] = l_tccp->prcw[i];
p_cstr_info->tile[p_tile_no].pdy[i] = l_tccp->prch[i];
}
p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc(p_cstr_info->numcomps * p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t));
}
/* << INDEX */
/* FIXME _ProfStart(PGROUP_DC_SHIFT); */
/*---------------TILE-------------------*/
if (! tcd_dc_level_shift_encode(p_tcd)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_DC_SHIFT); */
/* FIXME _ProfStart(PGROUP_MCT); */
if (! tcd_mct_encode(p_tcd)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_MCT); */
/* FIXME _ProfStart(PGROUP_DWT); */
if (! tcd_dwt_encode(p_tcd)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_DWT); */
/* FIXME _ProfStart(PGROUP_T1); */
if (! tcd_t1_encode(p_tcd)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_T1); */
/* FIXME _ProfStart(PGROUP_RATE); */
if (! tcd_rate_allocate_encode(p_tcd,p_dest,p_max_length,p_cstr_info)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_RATE); */
}
/*--------------TIER2------------------*/
/* INDEX */
if (p_cstr_info) {
p_cstr_info->index_write = 1;
}
/* FIXME _ProfStart(PGROUP_T2); */
if (! tcd_t2_encode(p_tcd,p_dest,p_data_written,p_max_length,p_cstr_info)) {
return OPJ_FALSE;
}
/* FIXME _ProfStop(PGROUP_T2); */
/*---------------CLEAN-------------------*/
return OPJ_TRUE;
}
opj_bool tcd_decode_tile_v2(
opj_tcd_v2_t *p_tcd,
@ -2315,38 +2866,6 @@ void tcd_free_tile(opj_tcd_v2_t *p_tcd)
}
/**
* Allocates memory for a decoding code block.
*/
opj_bool tcd_code_block_dec_allocate (opj_tcd_cblk_dec_v2_t * p_code_block)
{
OPJ_UINT32 l_seg_size;
if (! p_code_block->data) {
p_code_block->data = (OPJ_BYTE*) opj_malloc(8192);
if (! p_code_block->data) {
return OPJ_FALSE;
}
/*fprintf(stderr, "Allocate 8192 elements of code_block->data\n");*/
l_seg_size = J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t);
p_code_block->segs = (opj_tcd_seg_t *) opj_malloc(l_seg_size);
if (! p_code_block->segs) {
return OPJ_FALSE;
}
memset(p_code_block->segs,0,l_seg_size);
/*fprintf(stderr, "Allocate %d elements of code_block->data\n", J2K_DEFAULT_NB_SEGS * sizeof(opj_tcd_seg_t));*/
p_code_block->m_current_max_segs = J2K_DEFAULT_NB_SEGS;
/*fprintf(stderr, "m_current_max_segs of code_block->data = %d\n", p_code_block->m_current_max_segs);*/
}
/* TODO */
/*p_code_block->numsegs = 0; */
return OPJ_TRUE;
}
opj_bool tcd_t2_decode (
opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_src_data,
@ -2623,4 +3142,344 @@ void tcd_code_block_dec_deallocate (opj_tcd_precinct_v2_t * p_precinct)
}
}
OPJ_UINT32 tcd_get_encoded_tile_size ( opj_tcd_v2_t *p_tcd )
{
OPJ_UINT32 i,l_data_size = 0;
opj_image_comp_t * l_img_comp = 00;
opj_tcd_tilecomp_v2_t * l_tilec = 00;
OPJ_UINT32 l_size_comp, l_remaining;
l_tilec = p_tcd->tcd_image->tiles->comps;
l_img_comp = p_tcd->image->comps;
for (i=0;i<p_tcd->image->numcomps;++i) {
l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
l_remaining = l_img_comp->prec & 7; /* (%8) */
if (l_remaining) {
++l_size_comp;
}
if (l_size_comp == 3) {
l_size_comp = 4;
}
l_data_size += l_size_comp * (l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0);
++l_img_comp;
++l_tilec;
}
return l_data_size;
}
opj_bool tcd_dc_level_shift_encode ( opj_tcd_v2_t *p_tcd )
{
OPJ_UINT32 compno;
opj_tcd_tilecomp_v2_t * l_tile_comp = 00;
opj_tccp_t * l_tccp = 00;
opj_image_comp_t * l_img_comp = 00;
opj_tcp_v2_t * l_tcp = 00;
opj_tcd_tile_v2_t * l_tile;
OPJ_UINT32 l_nb_elem,i;
OPJ_INT32 * l_current_ptr;
l_tile = p_tcd->tcd_image->tiles;
l_tile_comp = l_tile->comps;
l_tcp = p_tcd->tcp;
l_tccp = p_tcd->tcp->tccps;
l_img_comp = p_tcd->image->comps;
for (compno = 0; compno < l_tile->numcomps; compno++) {
l_current_ptr = l_tile_comp->data;
l_nb_elem = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0);
if (l_tccp->qmfbid == 1) {
for (i = 0; i < l_nb_elem; ++i) {
*l_current_ptr -= l_tccp->m_dc_level_shift ;
++l_current_ptr;
}
}
else {
for (i = 0; i < l_nb_elem; ++i) {
*l_current_ptr = (*l_current_ptr - l_tccp->m_dc_level_shift) << 11 ;
++l_current_ptr;
}
}
++l_img_comp;
++l_tccp;
++l_tile_comp;
}
return OPJ_TRUE;
}
opj_bool tcd_mct_encode ( opj_tcd_v2_t *p_tcd )
{
opj_tcd_tile_v2_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_v2_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
OPJ_UINT32 samples = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0);
OPJ_UINT32 i;
OPJ_BYTE ** l_data = 00;
opj_tcp_v2_t * l_tcp = p_tcd->tcp;
if(!p_tcd->tcp->mct) {
return OPJ_TRUE;
}
if (p_tcd->tcp->mct == 2) {
if (! p_tcd->tcp->m_mct_coding_matrix) {
return OPJ_TRUE;
}
l_data = (OPJ_BYTE **) opj_malloc(l_tile->numcomps*sizeof(OPJ_BYTE*));
if (! l_data) {
return OPJ_FALSE;
}
for (i=0;i<l_tile->numcomps;++i) {
l_data[i] = (OPJ_BYTE*) l_tile_comp->data;
++l_tile_comp;
}
if (! mct_encode_custom(// MCT data
(OPJ_BYTE*) p_tcd->tcp->m_mct_coding_matrix,
// size of components
samples,
// components
l_data,
// nb of components (i.e. size of pData)
l_tile->numcomps,
// tells if the data is signed
p_tcd->image->comps->sgnd) )
{
opj_free(l_data);
return OPJ_FALSE;
}
opj_free(l_data);
}
else if (l_tcp->tccps->qmfbid == 0) {
mct_encode_real(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
}
else {
mct_encode(l_tile->comps[0].data, l_tile->comps[1].data, l_tile->comps[2].data, samples);
}
return OPJ_TRUE;
}
opj_bool tcd_dwt_encode ( opj_tcd_v2_t *p_tcd )
{
opj_tcd_tile_v2_t * l_tile = p_tcd->tcd_image->tiles;
opj_tcd_tilecomp_v2_t * l_tile_comp = p_tcd->tcd_image->tiles->comps;
opj_tccp_t * l_tccp = p_tcd->tcp->tccps;
OPJ_UINT32 compno;
for (compno = 0; compno < l_tile->numcomps; ++compno) {
if (l_tccp->qmfbid == 1) {
if (! dwt_encode_v2(l_tile_comp)) {
return OPJ_FALSE;
}
}
else if (l_tccp->qmfbid == 0) {
if (! dwt_encode_real_v2(l_tile_comp)) {
return OPJ_FALSE;
}
}
++l_tile_comp;
++l_tccp;
}
return OPJ_TRUE;
}
opj_bool tcd_t1_encode ( opj_tcd_v2_t *p_tcd )
{
opj_t1_t * l_t1;
const OPJ_FLOAT64 * l_mct_norms;
opj_tcp_v2_t * l_tcp = p_tcd->tcp;
l_t1 = t1_create_v2();
if (l_t1 == 00) {
return OPJ_FALSE;
}
if (l_tcp->mct == 1) {
// irreversible encoding
if (l_tcp->tccps->qmfbid == 0) {
l_mct_norms = get_mct_norms_real();
}
else {
l_mct_norms = get_mct_norms();
}
}
else {
l_mct_norms = (const OPJ_FLOAT64 *) (l_tcp->mct_norms);
}
if (! t1_encode_cblks_v2(l_t1, p_tcd->tcd_image->tiles , l_tcp, l_mct_norms)) {
t1_destroy_v2(l_t1);
return OPJ_FALSE;
}
t1_destroy_v2(l_t1);
return OPJ_TRUE;
}
opj_bool tcd_t2_encode (opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info )
{
opj_t2_v2_t * l_t2;
l_t2 = t2_create_v2(p_tcd->image, p_tcd->cp);
if (l_t2 == 00) {
return OPJ_FALSE;
}
if (! t2_encode_packets_v2(
l_t2,
p_tcd->tcd_tileno,
p_tcd->tcd_image->tiles,
p_tcd->tcp->numlayers,
p_dest_data,
p_data_written,
p_max_dest_size,
p_cstr_info,
p_tcd->tp_num,
p_tcd->tp_pos,
p_tcd->cur_pino,
FINAL_PASS))
{
t2_destroy_v2(l_t2);
return OPJ_FALSE;
}
t2_destroy_v2(l_t2);
/*---------------CLEAN-------------------*/
return OPJ_TRUE;
}
opj_bool tcd_rate_allocate_encode( opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_dest_data,
OPJ_UINT32 p_max_dest_size,
opj_codestream_info_t *p_cstr_info )
{
opj_cp_v2_t * l_cp = p_tcd->cp;
OPJ_UINT32 l_nb_written = 0;
if (p_cstr_info) {
p_cstr_info->index_write = 0;
}
if (l_cp->m_specific_param.m_enc.m_disto_alloc|| l_cp->m_specific_param.m_enc.m_fixed_quality) {
/* fixed_quality */
/* Normal Rate/distortion allocation */
if (! tcd_rateallocate_v2(p_tcd, p_dest_data,&l_nb_written, p_max_dest_size, p_cstr_info)) {
return OPJ_FALSE;
}
}
else {
/* Fixed layer allocation */
tcd_rateallocate_fixed_v2(p_tcd);
}
return OPJ_TRUE;
}
opj_bool tcd_copy_tile_data ( opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_src,
OPJ_UINT32 p_src_length )
{
OPJ_UINT32 i,j,l_data_size = 0;
opj_image_comp_t * l_img_comp = 00;
opj_tcd_tilecomp_v2_t * l_tilec = 00;
OPJ_UINT32 l_size_comp, l_remaining;
OPJ_UINT32 l_nb_elem;
l_data_size = tcd_get_encoded_tile_size(p_tcd);
if (l_data_size != p_src_length) {
return OPJ_FALSE;
}
l_tilec = p_tcd->tcd_image->tiles->comps;
l_img_comp = p_tcd->image->comps;
for (i=0;i<p_tcd->image->numcomps;++i) {
l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/
l_remaining = l_img_comp->prec & 7; /* (%8) */
l_nb_elem = (l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0);
if (l_remaining) {
++l_size_comp;
}
if (l_size_comp == 3) {
l_size_comp = 4;
}
switch (l_size_comp) {
case 1:
{
OPJ_CHAR * l_src_ptr = (OPJ_CHAR *) p_src;
OPJ_INT32 * l_dest_ptr = l_tilec->data;
if (l_img_comp->sgnd) {
for (j=0;j<l_nb_elem;++j) {
*(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
}
}
else {
for (j=0;j<l_nb_elem;++j) {
*(l_dest_ptr++) = (*(l_src_ptr++))&0xff;
}
}
p_src = (OPJ_BYTE*) l_src_ptr;
}
break;
case 2:
{
OPJ_INT32 * l_dest_ptr = l_tilec->data;
OPJ_INT16 * l_src_ptr = (OPJ_INT16 *) p_src;
if (l_img_comp->sgnd) {
for (j=0;j<l_nb_elem;++j) {
*(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
}
}
else {
for (j=0;j<l_nb_elem;++j) {
*(l_dest_ptr++) = (*(l_src_ptr++))&0xffff;
}
}
p_src = (OPJ_BYTE*) l_src_ptr;
}
break;
case 4:
{
OPJ_INT32 * l_src_ptr = (OPJ_INT32 *) p_src;
OPJ_INT32 * l_dest_ptr = l_tilec->data;
for (j=0;j<l_nb_elem;++j) {
*(l_dest_ptr++) = (OPJ_INT32) (*(l_src_ptr++));
}
p_src = (OPJ_BYTE*) l_src_ptr;
}
break;
}
++l_img_comp;
++l_tilec;
}
return OPJ_TRUE;
}

View File

@ -431,10 +431,28 @@ Initialize the tile decoder
*/
void tcd_malloc_decode(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp);
void tcd_malloc_decode_tile(opj_tcd_t *tcd, opj_image_t * image, opj_cp_t * cp, int tileno, opj_codestream_info_t *cstr_info);
void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final);
void tcd_makelayer_fixed_v2(opj_tcd_v2_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final);
void tcd_rateallocate_fixed(opj_tcd_t *tcd);
void tcd_rateallocate_fixed_v2(opj_tcd_v2_t *tcd);
void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final);
void tcd_makelayer_v2( opj_tcd_v2_t *tcd,
OPJ_UINT32 layno,
OPJ_FLOAT64 thresh,
OPJ_UINT32 final);
opj_bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_codestream_info_t *cstr_info);
opj_bool tcd_rateallocate_v2( opj_tcd_v2_t *tcd,
OPJ_BYTE *dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 len,
opj_codestream_info_t *cstr_info);
/**
Encode a tile from the raw image into a buffer
@param tcd TCD handle
@ -469,6 +487,24 @@ OPJ_UINT32 tcd_get_decoded_tile_size (
opj_tcd_v2_t *p_tcd
);
/**
* Encodes a tile from the raw image into the given buffer.
* @param p_tcd Tile Coder handle
* @param p_tile_no Index of the tile to encode.
* @param p_dest Destination buffer
* @param p_data_written pointer to an int that is incremented by the number of bytes really written on p_dest
* @param p_len Maximum length of the destination buffer
* @param p_cstr_info Codestream information structure
* @return true if the coding is successfull.
*/
opj_bool tcd_encode_tile_v2(opj_tcd_v2_t *p_tcd,
OPJ_UINT32 p_tile_no,
OPJ_BYTE *p_dest,
OPJ_UINT32 * p_data_written,
OPJ_UINT32 p_len,
struct opj_codestream_info *p_cstr_info);
/**
Decode a tile from a buffer into a raw image
@param tcd TCD handle
@ -486,11 +522,33 @@ opj_bool tcd_decode_tile_v2(opj_tcd_v2_t *tcd,
/**
* 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
);
opj_bool tcd_update_tile_data ( opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_dest,
OPJ_UINT32 p_dest_length );
/**
*
*/
OPJ_UINT32 tcd_get_encoded_tile_size ( opj_tcd_v2_t *p_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_encode_tile ( opj_tcd_v2_t *p_tcd,
OPJ_UINT32 p_tile_no );
/**
* Copies tile data from the given memory block onto the system.
*/
opj_bool tcd_copy_tile_data (opj_tcd_v2_t *p_tcd,
OPJ_BYTE * p_src,
OPJ_UINT32 p_src_length );
/* ----------------------------------------------------------------------- */
/*@}*/