opj_sparse_array_int32_t* opj_sparse_array_int32_create(OPJ_UINT32 width, OPJ_UINT32 height, OPJ_UINT32 block_width, OPJ_UINT32 block_height) { opj_sparse_array_int32_t* sa; if (width == 0 || height == 0 || block_width == 0 || block_height == 0) { return NULL; } if (block_width > ((OPJ_UINT32)~0U) / block_height / sizeof(OPJ_INT32)) { return NULL; } sa = opj_calloc(1, sizeof(opj_sparse_array_int32_t)); sa->width = width; sa->height = height; sa->block_width = block_width; sa->block_height = block_height; sa->block_count_hor = opj_uint_ceildiv(width, block_width); sa->block_count_ver = opj_uint_ceildiv(height, block_height); if (sa->block_count_hor > ((OPJ_UINT32)~0U) / sa->block_count_ver) { opj_free(sa); return NULL; } sa->data_blocks = opj_calloc(sizeof(OPJ_INT32*), sa->block_count_hor * sa->block_count_ver); if (sa->data_blocks == NULL) { opj_free(sa); return NULL; } return sa; }
/* Create region manager. Note: because this method uses a tcd struct, and we can't forward declare the struct in region_mgr.h header file, this method's declaration can be found in the tcd.h header file. */ bool opj_tile_buf_create_component(opj_tcd_tilecomp_t* tilec, bool irreversible, uint32_t cblkw, uint32_t cblkh, opj_image_t* output_image, uint32_t dx, uint32_t dy) { int32_t resno = 0; opj_rect_t component_output_rect; opj_tile_buf_component_t* comp = NULL; if (!tilec) return false; /* create region component struct*/ comp = new opj_tile_buf_component_t(); if (!comp) { return false; } comp->data = NULL; opj_rect_init(&comp->tile_dim, tilec->x0, tilec->y0, tilec->x1, tilec->y1); if (output_image) { opj_rect_init(&comp->dim, opj_uint_ceildiv(output_image->x0,dx), opj_uint_ceildiv(output_image->y0,dy), opj_uint_ceildiv(output_image->x1,dx), opj_uint_ceildiv(output_image->y1,dy)); /* clip output image to tile */ opj_rect_clip(&comp->tile_dim, &comp->dim, &comp->dim); } else { comp->dim = comp->tile_dim; } /* for encode, we don't need to allocate resolutions */ if (!output_image) { opj_tile_buf_destroy_component(tilec->buf); tilec->buf = comp; return true; } component_output_rect = comp->dim; /* fill resolutions vector */ for (resno = (int32_t)(tilec->numresolutions-1); resno >= 0; --resno) { uint32_t bandno; opj_tcd_resolution_t* tcd_res = tilec->resolutions + resno; opj_tile_buf_resolution_t* res = (opj_tile_buf_resolution_t*)opj_calloc(1, sizeof(opj_tile_buf_resolution_t)); if (!res) { opj_tile_buf_destroy_component(comp); return false; } res->bounds.x = tcd_res->x1 - tcd_res->x0; res->bounds.y = tcd_res->y1 - tcd_res->y0; res->origin.x = tcd_res->x0; res->origin.y = tcd_res->y0; for (bandno = 0; bandno < tcd_res->numbands; ++bandno) { opj_tcd_band_t* band = tcd_res->bands + bandno; opj_rect_t band_rect; opj_rect_init(&band_rect, band->x0, band->y0, band->x1, band->y1 ); res->band_region[bandno].dim = component_output_rect; if (resno > 0) { /*For next level down, E' = ceil((E-b)/2) where b in {0,1} identifies band */ opj_pt_t shift; shift.x = band->bandno & 1; shift.y = band->bandno & 2; opj_rect_pan(&res->band_region[bandno].dim, &shift); opj_rect_ceildivpow2(&res->band_region[bandno].dim, 1); /* boundary padding */ opj_rect_grow(&res->band_region[bandno].dim, irreversible ? 3 : 2); } /* add code block padding around region */ (res->band_region + bandno)->data_dim = (res->band_region + bandno)->dim; opj_rect_grow2(&(res->band_region + bandno)->data_dim, cblkw, cblkh); } component_output_rect = res->band_region[0].dim; res->num_bands = tcd_res->numbands; comp->resolutions.push_back(res); } opj_tile_buf_destroy_component(tilec->buf); tilec->buf = comp; return true; }