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:
msheby 2021-10-27 05:10:50 -07:00 committed by GitHub
parent 9f70bf0ad1
commit 90481203a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 7 deletions

View File

@ -95,7 +95,8 @@ opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters);
int imagetobmp(opj_image_t *image, const char *outfile);
/* 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);
/**
Load a single image component encoded in PGX file format

View File

@ -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
* 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_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);
}
} else if ((target_bitdepth > 0) && (target_bitdepth != tiBps)) {
for (j = 0; j < numcomps; ++j) {
scale_component(&(image->comps[j]), target_bitdepth);
}
}
return image;

View File

@ -186,6 +186,11 @@ static void encode_help_display(void)
fprintf(stdout,
" It corresponds to the number of DWT decompositions +1. \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,
" 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,
OPJ_BOOL* pOutPLT,
OPJ_BOOL* pOutTLM,
int* pOutNumThreads)
int* pOutNumThreads,
unsigned int* pTarget_bitdepth)
{
OPJ_UINT32 i, j;
int totlen, c;
@ -620,10 +626,11 @@ static int parse_cmdline_encoder(int argc, char **argv,
{"PLT", NO_ARG, NULL, 'A'},
{"threads", REQ_ARG, NULL, 'B'},
{"TLM", NO_ARG, NULL, 'D'},
{"TargetBitDepth", REQ_ARG, NULL, 'X'},
};
/* 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
"W:"
#endif /* USE_JPWL */
@ -908,6 +915,17 @@ static int parse_cmdline_encoder(int argc, char **argv,
}
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 */
@ -1908,6 +1926,9 @@ int main(int argc, char **argv)
OPJ_BOOL TLM = OPJ_FALSE;
int num_threads = 0;
/** desired bitdepth from input file */
unsigned int target_bitdepth = 0;
/* set encoding parameters to default values */
opj_set_default_encoder_parameters(&parameters);
@ -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 */
if (parse_cmdline_encoder(argc, argv, &parameters, &img_fol, &raw_cp,
indexfilename, sizeof(indexfilename), &framerate, &PLT, &TLM,
&num_threads) == 1) {
&num_threads, &target_bitdepth) == 1) {
ret = 1;
goto fin;
}
@ -2021,7 +2042,7 @@ int main(int argc, char **argv)
#ifdef OPJ_HAVE_LIBTIFF
case TIF_DFMT:
image = tiftoimage(parameters.infile, &parameters);
image = tiftoimage(parameters.infile, &parameters, target_bitdepth);
if (!image) {
fprintf(stderr, "Unable to load tif(f) file\n");
ret = 1;

View File

@ -260,6 +260,9 @@ static opj_image_t* readImageFromFileTIF(const char* filename,
{
opj_image_t* image_read = NULL;
opj_cparameters_t parameters;
#ifdef OPJ_HAVE_LIBTIFF
const unsigned int target_bitdepth = 0;
#endif
(void)nbFilenamePGX;
(void)separator;
@ -284,7 +287,7 @@ static opj_image_t* readImageFromFileTIF(const char* filename,
/* Read the tif file corresponding to the component */
#ifdef OPJ_HAVE_LIBTIFF
image_read = tiftoimage(filename, &parameters);
image_read = tiftoimage(filename, &parameters, target_bitdepth);
#endif
if (!image_read) {
fprintf(stderr, "Unable to load TIF file\n");