+ /* Channel Definition box */
+ /* FIXME not provided by parameters */
+ /* We try to do what we can... */
+ alpha_count = 0U;
+ for (i = 0; i < image->numcomps; i++) {
+ if (image->comps[i].alpha != 0) {
+ alpha_count++;
+ alpha_channel = i;
+ }
+ }
+ if (alpha_count == 1U) { /* no way to deal with more than 1 alpha channel */
+ switch (jp2->enumcs) {
+ case 16:
+ case 18:
+ color_channels = 3;
+ break;
+ case 17:
+ color_channels = 1;
+ break;
+ default:
+ alpha_count = 0U;
+ break;
+ }
+ if (alpha_count == 0U) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but unknown enumcs. No cdef box will be created.\n");
+ } else if (image->numcomps < (color_channels+1)) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel specified but not enough image components for an automatic cdef box creation.\n");
+ alpha_count = 0U;
+ } else if ((OPJ_UINT32)alpha_channel < color_channels) {
+ opj_event_msg(p_manager, EVT_WARNING, "Alpha channel position conflicts with color channel. No cdef box will be created.\n");
+ alpha_count = 0U;
+ }
+ } else if (alpha_count > 1) {
+ opj_event_msg(p_manager, EVT_WARNING, "Multiple alpha channels specified. No cdef box will be created.\n");
+ }
+ if (alpha_count == 1U) { /* if here, we know what we can do */
+ jp2->color.jp2_cdef = (opj_jp2_cdef_t*)opj_malloc(sizeof(opj_jp2_cdef_t));
+ if(!jp2->color.jp2_cdef) {
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
+ return OPJ_FALSE;
+ }
+ /* no memset needed, all values will be overwritten except if jp2->color.jp2_cdef->info allocation fails, */
+ /* in which case jp2->color.jp2_cdef->info will be NULL => valid for destruction */
+ jp2->color.jp2_cdef->info = (opj_jp2_cdef_info_t*) opj_malloc(image->numcomps * sizeof(opj_jp2_cdef_info_t));
+ if (!jp2->color.jp2_cdef->info) {
+ /* memory will be freed by opj_jp2_destroy */
+ opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to setup the JP2 encoder\n");
+ return OPJ_FALSE;
+ }
+ jp2->color.jp2_cdef->n = (OPJ_UINT16) image->numcomps; /* cast is valid : image->numcomps [1,16384] */
+ for (i = 0U; i < color_channels; i++) {
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 0U;
+ jp2->color.jp2_cdef->info[i].asoc = (OPJ_UINT16)(i+1U); /* No overflow + cast is valid : image->numcomps [1,16384] */
+ }
+ for (; i < image->numcomps; i++) {
+ if (image->comps[i].alpha != 0) { /* we'll be here exactly once */
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 1U; /* Opacity channel */
+ jp2->color.jp2_cdef->info[i].asoc = 0U; /* Apply alpha channel to the whole image */
+ } else {
+ /* Unknown channel */
+ jp2->color.jp2_cdef->info[i].cn = (OPJ_UINT16)i; /* cast is valid : image->numcomps [1,16384] */
+ jp2->color.jp2_cdef->info[i].typ = 65535U;
+ jp2->color.jp2_cdef->info[i].asoc = 65535U;
+ }
+ }
+ }