opj_compress: add a -TargetBitDepth switch for TIFF output (#1384)
Sometimes, given the same (16-bit TIF) input, one wants to generate a variety of J2C outputs (say, 16-, 12-, and 10-bit). This patch allows one to downsample input files, and so makes it easier to automate OpenJPEG in mass generation of J2Cs without having to pipe though an image processing program.
This commit is contained in:
parent
9f70bf0ad1
commit
90481203a2
|
@ -95,7 +95,8 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters);
|
||||||
int imagetobmp(opj_image_t *image, const char *outfile);
|
int imagetobmp(opj_image_t *image, const char *outfile);
|
||||||
|
|
||||||
/* TIFF conversion*/
|
/* TIFF conversion*/
|
||||||
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters);
|
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
|
||||||
|
const unsigned int target_bitdepth);
|
||||||
int imagetotif(opj_image_t *image, const char *outfile);
|
int imagetotif(opj_image_t *image, const char *outfile);
|
||||||
/**
|
/**
|
||||||
Load a single image component encoded in PGX file format
|
Load a single image component encoded in PGX file format
|
||||||
|
|
|
@ -1247,7 +1247,8 @@ static void tif_16uto32s(const OPJ_UINT16* pSrc, OPJ_INT32* pDst,
|
||||||
* libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
|
* libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
|
||||||
* CINEMA : 12 bit precision
|
* CINEMA : 12 bit precision
|
||||||
*/
|
*/
|
||||||
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
|
opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters,
|
||||||
|
const unsigned int target_bitdepth)
|
||||||
{
|
{
|
||||||
int subsampling_dx = parameters->subsampling_dx;
|
int subsampling_dx = parameters->subsampling_dx;
|
||||||
int subsampling_dy = parameters->subsampling_dy;
|
int subsampling_dy = parameters->subsampling_dy;
|
||||||
|
@ -1506,6 +1507,10 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
|
||||||
scale_component(&(image->comps[j]), 12);
|
scale_component(&(image->comps[j]), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if ((target_bitdepth > 0) && (target_bitdepth != tiBps)) {
|
||||||
|
for (j = 0; j < numcomps; ++j) {
|
||||||
|
scale_component(&(image->comps[j]), target_bitdepth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,11 @@ static void encode_help_display(void)
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
" It corresponds to the number of DWT decompositions +1. \n");
|
" It corresponds to the number of DWT decompositions +1. \n");
|
||||||
fprintf(stdout, " Default: 6.\n");
|
fprintf(stdout, " Default: 6.\n");
|
||||||
|
fprintf(stdout, "-TargetBitDepth <target bit depth>\n");
|
||||||
|
fprintf(stdout, " Target bit depth.\n");
|
||||||
|
fprintf(stdout, " Number of bits per component to use from input image\n");
|
||||||
|
fprintf(stdout, " if all bits are unwanted.\n");
|
||||||
|
fprintf(stdout, " (Currently only implemented for TIF.)\n");
|
||||||
fprintf(stdout, "-b <cblk width>,<cblk height>\n");
|
fprintf(stdout, "-b <cblk width>,<cblk height>\n");
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
" Code-block size. The dimension must respect the constraint \n");
|
" Code-block size. The dimension must respect the constraint \n");
|
||||||
|
@ -600,7 +605,8 @@ static int parse_cmdline_encoder(int argc, char **argv,
|
||||||
int* pOutFramerate,
|
int* pOutFramerate,
|
||||||
OPJ_BOOL* pOutPLT,
|
OPJ_BOOL* pOutPLT,
|
||||||
OPJ_BOOL* pOutTLM,
|
OPJ_BOOL* pOutTLM,
|
||||||
int* pOutNumThreads)
|
int* pOutNumThreads,
|
||||||
|
unsigned int* pTarget_bitdepth)
|
||||||
{
|
{
|
||||||
OPJ_UINT32 i, j;
|
OPJ_UINT32 i, j;
|
||||||
int totlen, c;
|
int totlen, c;
|
||||||
|
@ -620,10 +626,11 @@ static int parse_cmdline_encoder(int argc, char **argv,
|
||||||
{"PLT", NO_ARG, NULL, 'A'},
|
{"PLT", NO_ARG, NULL, 'A'},
|
||||||
{"threads", REQ_ARG, NULL, 'B'},
|
{"threads", REQ_ARG, NULL, 'B'},
|
||||||
{"TLM", NO_ARG, NULL, 'D'},
|
{"TLM", NO_ARG, NULL, 'D'},
|
||||||
|
{"TargetBitDepth", REQ_ARG, NULL, 'X'},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* parse the command line */
|
/* parse the command line */
|
||||||
const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:"
|
const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:X:"
|
||||||
#ifdef USE_JPWL
|
#ifdef USE_JPWL
|
||||||
"W:"
|
"W:"
|
||||||
#endif /* USE_JPWL */
|
#endif /* USE_JPWL */
|
||||||
|
@ -908,6 +915,17 @@ static int parse_cmdline_encoder(int argc, char **argv,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* ----------------------------------------------------- */
|
||||||
|
case 'X': { /* target bitdepth */
|
||||||
|
char *s = opj_optarg;
|
||||||
|
sscanf(s, "%u", pTarget_bitdepth);
|
||||||
|
if (*pTarget_bitdepth == 0) {
|
||||||
|
fprintf(stderr, "Target bitdepth must be at least 1 bit.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* ----------------------------------------------------- */
|
/* ----------------------------------------------------- */
|
||||||
|
|
||||||
case 'n': { /* resolution */
|
case 'n': { /* resolution */
|
||||||
|
@ -1908,6 +1926,9 @@ int main(int argc, char **argv)
|
||||||
OPJ_BOOL TLM = OPJ_FALSE;
|
OPJ_BOOL TLM = OPJ_FALSE;
|
||||||
int num_threads = 0;
|
int num_threads = 0;
|
||||||
|
|
||||||
|
/** desired bitdepth from input file */
|
||||||
|
unsigned int target_bitdepth = 0;
|
||||||
|
|
||||||
/* set encoding parameters to default values */
|
/* set encoding parameters to default values */
|
||||||
opj_set_default_encoder_parameters(¶meters);
|
opj_set_default_encoder_parameters(¶meters);
|
||||||
|
|
||||||
|
@ -1928,7 +1949,7 @@ int main(int argc, char **argv)
|
||||||
255; /* This will be set later according to the input image or the provided option */
|
255; /* This will be set later according to the input image or the provided option */
|
||||||
if (parse_cmdline_encoder(argc, argv, ¶meters, &img_fol, &raw_cp,
|
if (parse_cmdline_encoder(argc, argv, ¶meters, &img_fol, &raw_cp,
|
||||||
indexfilename, sizeof(indexfilename), &framerate, &PLT, &TLM,
|
indexfilename, sizeof(indexfilename), &framerate, &PLT, &TLM,
|
||||||
&num_threads) == 1) {
|
&num_threads, &target_bitdepth) == 1) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto fin;
|
goto fin;
|
||||||
}
|
}
|
||||||
|
@ -2021,7 +2042,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
#ifdef OPJ_HAVE_LIBTIFF
|
#ifdef OPJ_HAVE_LIBTIFF
|
||||||
case TIF_DFMT:
|
case TIF_DFMT:
|
||||||
image = tiftoimage(parameters.infile, ¶meters);
|
image = tiftoimage(parameters.infile, ¶meters, target_bitdepth);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
fprintf(stderr, "Unable to load tif(f) file\n");
|
fprintf(stderr, "Unable to load tif(f) file\n");
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
|
@ -260,6 +260,9 @@ static opj_image_t* readImageFromFileTIF(const char* filename,
|
||||||
{
|
{
|
||||||
opj_image_t* image_read = NULL;
|
opj_image_t* image_read = NULL;
|
||||||
opj_cparameters_t parameters;
|
opj_cparameters_t parameters;
|
||||||
|
#ifdef OPJ_HAVE_LIBTIFF
|
||||||
|
const unsigned int target_bitdepth = 0;
|
||||||
|
#endif
|
||||||
(void)nbFilenamePGX;
|
(void)nbFilenamePGX;
|
||||||
(void)separator;
|
(void)separator;
|
||||||
|
|
||||||
|
@ -284,7 +287,7 @@ static opj_image_t* readImageFromFileTIF(const char* filename,
|
||||||
|
|
||||||
/* Read the tif file corresponding to the component */
|
/* Read the tif file corresponding to the component */
|
||||||
#ifdef OPJ_HAVE_LIBTIFF
|
#ifdef OPJ_HAVE_LIBTIFF
|
||||||
image_read = tiftoimage(filename, ¶meters);
|
image_read = tiftoimage(filename, ¶meters, target_bitdepth);
|
||||||
#endif
|
#endif
|
||||||
if (!image_read) {
|
if (!image_read) {
|
||||||
fprintf(stderr, "Unable to load TIF file\n");
|
fprintf(stderr, "Unable to load TIF file\n");
|
||||||
|
|
Loading…
Reference in New Issue