+ tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
+ if (! tcp->m_mct_decoding_matrix) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Not enough memory to allocate encoder MCT decoding matrix \n");
+ return OPJ_FALSE;
+ }
+ if (opj_matrix_inversion_f(lTmpBuf, (tcp->m_mct_decoding_matrix),
+ image->numcomps) == OPJ_FALSE) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Failed to inverse encoder MCT decoding matrix \n");
+ return OPJ_FALSE;
+ }
+
+ tcp->mct_norms = (OPJ_FLOAT64*)
+ opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
+ if (! tcp->mct_norms) {
+ opj_free(lTmpBuf);
+ lTmpBuf = NULL;
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Not enough memory to allocate encoder MCT norms \n");
+ return OPJ_FALSE;
+ }
+ opj_calculate_norms(tcp->mct_norms, image->numcomps,
+ tcp->m_mct_decoding_matrix);
+ opj_free(lTmpBuf);
+
+ for (i = 0; i < image->numcomps; i++) {
+ opj_tccp_t *tccp = &tcp->tccps[i];
+ tccp->m_dc_level_shift = l_dc_shift[i];
+ }
+
+ if (opj_j2k_setup_mct_encoding(tcp, image) == OPJ_FALSE) {
+ /* free will be handled by opj_j2k_destroy */
+ opj_event_msg(p_manager, EVT_ERROR, "Failed to setup j2k mct encoding\n");
+ return OPJ_FALSE;
+ }
+ } else {
+ if (tcp->mct == 1 && image->numcomps >= 3) { /* RGB->YCC MCT is enabled */
+ if ((image->comps[0].dx != image->comps[1].dx) ||
+ (image->comps[0].dx != image->comps[2].dx) ||
+ (image->comps[0].dy != image->comps[1].dy) ||
+ (image->comps[0].dy != image->comps[2].dy)) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Cannot perform MCT on components with different sizes. Disabling MCT.\n");
+ tcp->mct = 0;
+ }
+ }
+ for (i = 0; i < image->numcomps; i++) {
+ opj_tccp_t *tccp = &tcp->tccps[i];
+ opj_image_comp_t * l_comp = &(image->comps[i]);
+
+ if (! l_comp->sgnd) {
+ tccp->m_dc_level_shift = 1 << (l_comp->prec - 1);
+ }
+ }
+ }
+
+ for (i = 0; i < image->numcomps; i++) {
+ opj_tccp_t *tccp = &tcp->tccps[i];
+
+ tccp->csty = parameters->csty &
+ 0x01; /* 0 => one precinct || 1 => custom precinct */
+ tccp->numresolutions = (OPJ_UINT32)parameters->numresolution;
+ tccp->cblkw = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockw_init);
+ tccp->cblkh = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockh_init);
+ tccp->cblksty = (OPJ_UINT32)parameters->mode;
+ tccp->qmfbid = parameters->irreversible ? 0 : 1;
+ tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT :
+ J2K_CCP_QNTSTY_NOQNT;
+ tccp->numgbits = 2;
+
+ if ((OPJ_INT32)i == parameters->roi_compno) {
+ tccp->roishift = parameters->roi_shift;
+ } else {
+ tccp->roishift = 0;
+ }
+
+ if (parameters->csty & J2K_CCP_CSTY_PRT) {
+ OPJ_INT32 p = 0, it_res;
+ assert(tccp->numresolutions > 0);
+ for (it_res = (OPJ_INT32)tccp->numresolutions - 1; it_res >= 0; it_res--) {
+ if (p < parameters->res_spec) {
+
+ if (parameters->prcw_init[p] < 1) {
+ tccp->prcw[it_res] = 1;
+ } else {
+ tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prcw_init[p]);
+ }
+
+ if (parameters->prch_init[p] < 1) {
+ tccp->prch[it_res] = 1;
+ } else {
+ tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prch_init[p]);
+ }
+
+ } else {
+ OPJ_INT32 res_spec = parameters->res_spec;
+ OPJ_INT32 size_prcw = 0;
+ OPJ_INT32 size_prch = 0;
+
+ assert(res_spec > 0); /* issue 189 */
+ size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1));
+ size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1));
+
+
+ if (size_prcw < 1) {
+ tccp->prcw[it_res] = 1;
+ } else {
+ tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prcw);
+ }
+
+ if (size_prch < 1) {
+ tccp->prch[it_res] = 1;
+ } else {
+ tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prch);
+ }
+ }
+ p++;
+ /*printf("\nsize precinct for level %d : %d,%d\n", it_res,tccp->prcw[it_res], tccp->prch[it_res]); */
+ } /*end for*/
+ } else {
+ for (j = 0; j < tccp->numresolutions; j++) {
+ tccp->prcw[j] = 15;
+ tccp->prch[j] = 15;
+ }
+ }
+
+ opj_dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec);
+ }
+ }
+
+ if (parameters->mct_data) {
+ opj_free(parameters->mct_data);
+ parameters->mct_data = 00;
+ }
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index,
+ OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
+{
+ assert(cstr_index != 00);
+
+ /* expand the list? */
+ if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) {
+ opj_marker_info_t *new_marker;
+ cstr_index->maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32)
+ cstr_index->maxmarknum);
+ new_marker = (opj_marker_info_t *) opj_realloc(cstr_index->marker,
+ cstr_index->maxmarknum * sizeof(opj_marker_info_t));
+ if (! new_marker) {
+ opj_free(cstr_index->marker);
+ cstr_index->marker = NULL;
+ cstr_index->maxmarknum = 0;
+ cstr_index->marknum = 0;
+ /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add mh marker\n"); */
+ return OPJ_FALSE;
+ }
+ cstr_index->marker = new_marker;
+ }
+
+ /* add the marker */
+ cstr_index->marker[cstr_index->marknum].type = (OPJ_UINT16)type;
+ cstr_index->marker[cstr_index->marknum].pos = (OPJ_INT32)pos;
+ cstr_index->marker[cstr_index->marknum].len = (OPJ_INT32)len;
+ cstr_index->marknum++;
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno,
+ opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos,
+ OPJ_UINT32 len)
+{
+ assert(cstr_index != 00);
+ assert(cstr_index->tile_index != 00);
+
+ /* expand the list? */
+ if ((cstr_index->tile_index[tileno].marknum + 1) >
+ cstr_index->tile_index[tileno].maxmarknum) {
+ opj_marker_info_t *new_marker;
+ cstr_index->tile_index[tileno].maxmarknum = (OPJ_UINT32)(100 +
+ (OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum);
+ new_marker = (opj_marker_info_t *) opj_realloc(
+ cstr_index->tile_index[tileno].marker,
+ cstr_index->tile_index[tileno].maxmarknum * sizeof(opj_marker_info_t));
+ if (! new_marker) {
+ opj_free(cstr_index->tile_index[tileno].marker);
+ cstr_index->tile_index[tileno].marker = NULL;
+ cstr_index->tile_index[tileno].maxmarknum = 0;
+ cstr_index->tile_index[tileno].marknum = 0;
+ /* opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to add tl marker\n"); */
+ return OPJ_FALSE;
+ }
+ cstr_index->tile_index[tileno].marker = new_marker;
+ }
+
+ /* add the marker */
+ cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].type
+ = (OPJ_UINT16)type;
+ cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].pos
+ = (OPJ_INT32)pos;
+ cstr_index->tile_index[tileno].marker[cstr_index->tile_index[tileno].marknum].len
+ = (OPJ_INT32)len;
+ cstr_index->tile_index[tileno].marknum++;
+
+ if (type == J2K_MS_SOT) {
+ OPJ_UINT32 l_current_tile_part = cstr_index->tile_index[tileno].current_tpsno;
+
+ if (cstr_index->tile_index[tileno].tp_index) {
+ cstr_index->tile_index[tileno].tp_index[l_current_tile_part].start_pos = pos;
+ }
+
+ }
+ return OPJ_TRUE;
+}