summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/openjp2/j2k.c88
-rw-r--r--src/lib/openjp2/openjpeg.h7
-rw-r--r--src/lib/openjp2/tcd.c46
3 files changed, 107 insertions, 34 deletions
diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c
index 8e4b3966..641932a9 100644
--- a/src/lib/openjp2/j2k.c
+++ b/src/lib/openjp2/j2k.c
@@ -6832,25 +6832,84 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
parameters->tcp_rates[0] = 0;
}
+ if (parameters->cp_disto_alloc) {
+ /* Emit warnings if tcp_rates are not decreasing */
+ for (i = 1; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) {
+ OPJ_FLOAT32 rate_i_corr = parameters->tcp_rates[i];
+ OPJ_FLOAT32 rate_i_m_1_corr = parameters->tcp_rates[i - 1];
+ if (rate_i_corr <= 1.0) {
+ rate_i_corr = 1.0;
+ }
+ if (rate_i_m_1_corr <= 1.0) {
+ rate_i_m_1_corr = 1.0;
+ }
+ if (rate_i_corr >= rate_i_m_1_corr) {
+ if (rate_i_corr != parameters->tcp_rates[i] &&
+ rate_i_m_1_corr != parameters->tcp_rates[i - 1]) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "tcp_rates[%d]=%f (corrected as %f) should be strictly lesser "
+ "than tcp_rates[%d]=%f (corrected as %f)\n",
+ i, parameters->tcp_rates[i], rate_i_corr,
+ i - 1, parameters->tcp_rates[i - 1], rate_i_m_1_corr);
+ } else if (rate_i_corr != parameters->tcp_rates[i]) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "tcp_rates[%d]=%f (corrected as %f) should be strictly lesser "
+ "than tcp_rates[%d]=%f\n",
+ i, parameters->tcp_rates[i], rate_i_corr,
+ i - 1, parameters->tcp_rates[i - 1]);
+ } else if (rate_i_m_1_corr != parameters->tcp_rates[i - 1]) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "tcp_rates[%d]=%f should be strictly lesser "
+ "than tcp_rates[%d]=%f (corrected as %f)\n",
+ i, parameters->tcp_rates[i],
+ i - 1, parameters->tcp_rates[i - 1], rate_i_m_1_corr);
+ } else {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "tcp_rates[%d]=%f should be strictly lesser "
+ "than tcp_rates[%d]=%f\n",
+ i, parameters->tcp_rates[i],
+ i - 1, parameters->tcp_rates[i - 1]);
+ }
+ }
+ }
+ } else if (parameters->cp_fixed_quality) {
+ /* Emit warnings if tcp_distoratio are not increasing */
+ for (i = 1; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) {
+ if (parameters->tcp_distoratio[i] < parameters->tcp_distoratio[i - 1] &&
+ !(i == (OPJ_UINT32)parameters->tcp_numlayers - 1 &&
+ parameters->tcp_distoratio[i] == 0)) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "tcp_distoratio[%d]=%f should be strictly greater "
+ "than tcp_distoratio[%d]=%f\n",
+ i, parameters->tcp_distoratio[i], i - 1,
+ parameters->tcp_distoratio[i - 1]);
+ }
+ }
+ }
+
/* see if max_codestream_size does limit input rate */
if (parameters->max_cs_size <= 0) {
if (parameters->tcp_rates[parameters->tcp_numlayers - 1] > 0) {
OPJ_FLOAT32 temp_size;
- temp_size = (OPJ_FLOAT32)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec) /
- (parameters->tcp_rates[parameters->tcp_numlayers - 1] * 8 *
- (OPJ_FLOAT32)image->comps[0].dx * (OPJ_FLOAT32)image->comps[0].dy);
- parameters->max_cs_size = (int) floor(temp_size);
+ temp_size = (OPJ_FLOAT32)(((double)image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
+ ((double)parameters->tcp_rates[parameters->tcp_numlayers - 1] * 8 *
+ image->comps[0].dx * image->comps[0].dy));
+ if (temp_size > INT_MAX) {
+ parameters->max_cs_size = INT_MAX;
+ } else {
+ parameters->max_cs_size = (int) floor(temp_size);
+ }
} else {
parameters->max_cs_size = 0;
}
} else {
OPJ_FLOAT32 temp_rate;
OPJ_BOOL cap = OPJ_FALSE;
- temp_rate = (OPJ_FLOAT32)(image->numcomps * image->comps[0].w *
- image->comps[0].h * image->comps[0].prec) /
- (OPJ_FLOAT32)(((OPJ_UINT32)parameters->max_cs_size) * 8 * image->comps[0].dx *
- image->comps[0].dy);
+ temp_rate = (OPJ_FLOAT32)(((double)image->numcomps * image->comps[0].w *
+ image->comps[0].h * image->comps[0].prec) /
+ (((double)parameters->max_cs_size) * 8 * image->comps[0].dx *
+ image->comps[0].dy));
for (i = 0; i < (OPJ_UINT32) parameters->tcp_numlayers; i++) {
if (parameters->tcp_rates[i] < temp_rate) {
parameters->tcp_rates[i] = temp_rate;
@@ -7084,6 +7143,10 @@ OPJ_BOOL opj_j2k_setup_encoder(opj_j2k_t *p_j2k,
tcp->rates[j] = parameters->tcp_rates[j];
}
}
+ if (!cp->m_specific_param.m_enc.m_fixed_quality &&
+ tcp->rates[j] <= 1.0) {
+ tcp->rates[j] = 0.0; /* force lossless */
+ }
}
tcp->csty = (OPJ_UINT32)parameters->csty;
@@ -9591,9 +9654,10 @@ static OPJ_BOOL opj_j2k_read_SPCod_SPCoc(opj_j2k_t *p_j2k,
/* If user wants to remove more resolutions than the codestream contains, return error */
if (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) {
opj_event_msg(p_manager, EVT_ERROR,
- "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
- "of resolutions of this component\nModify the cp_reduce parameter.\n\n",
- compno);
+ "Error decoding component %d.\nThe number of resolutions "
+ "to remove (%d) is greater or equal than the number "
+ "of resolutions of this component (%d)\nModify the cp_reduce parameter.\n\n",
+ compno, l_cp->m_specific_param.m_dec.m_reduce, l_tccp->numresolutions);
p_j2k->m_specific_param.m_decoder.m_state |=
0x8000;/* FIXME J2K_DEC_STATE_ERR;*/
return OPJ_FALSE;
diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h
index 7020d37d..79e0bb4f 100644
--- a/src/lib/openjp2/openjpeg.h
+++ b/src/lib/openjp2/openjpeg.h
@@ -381,9 +381,12 @@ typedef struct opj_cparameters {
OPJ_UINT32 numpocs;
/** number of layers */
int tcp_numlayers;
- /** rates of layers - might be subsequently limited by the max_cs_size field */
+ /** rates of layers - might be subsequently limited by the max_cs_size field.
+ * Should be decreasing. 1 can be
+ * used as last value to indicate the last layer is lossless. */
float tcp_rates[100];
- /** different psnr for successive layers */
+ /** different psnr for successive layers. Should be increasing. 0 can be
+ * used as last value to indicate the last layer is lossless. */
float tcp_distoratio[100];
/** number of resolutions */
int numresolution;
diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c
index c652f8ba..d577f024 100644
--- a/src/lib/openjp2/tcd.c
+++ b/src/lib/openjp2/tcd.c
@@ -273,28 +273,33 @@ void opj_tcd_makelayer(opj_tcd_t *tcd,
n = cblk->numpassesinlayers;
- for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
- OPJ_UINT32 dr;
- OPJ_FLOAT64 dd;
- opj_tcd_pass_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 (thresh < 0) {
+ /* Special value to indicate to use all passes */
+ n = cblk->totalpasses;
+ } else {
+ for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {
+ OPJ_UINT32 dr;
+ OPJ_FLOAT64 dd;
+ opj_tcd_pass_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) {
+ if (!dr) {
+ if (dd != 0) {
+ n = passno + 1;
+ }
+ continue;
+ }
+ if (thresh - (dd / dr) <
+ DBL_EPSILON) { /* do not rely on float equality, check with DBL_EPSILON margin */
n = passno + 1;
}
- continue;
- }
- if (thresh - (dd / dr) <
- DBL_EPSILON) { /* do not rely on float equality, check with DBL_EPSILON margin */
- n = passno + 1;
}
}
@@ -617,7 +622,8 @@ OPJ_BOOL opj_tcd_rateallocate(opj_tcd_t *tcd,
opj_t2_destroy(t2);
} else {
- goodthresh = min;
+ /* Special value to indicate to use all passes */
+ goodthresh = -1;
}
if (cstr_info) { /* Threshold for Marcela Index */