- opj_jp2_box_t box;
- OPJ_UINT32 l_nb_bytes_read;
- const opj_jp2_header_handler_t * l_current_handler;
- const opj_jp2_header_handler_t * l_current_handler_misplaced;
- OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
- OPJ_UINT32 l_current_data_size;
- OPJ_BYTE * l_current_data = 00;
-
- /* preconditions */
- assert(stream != 00);
- assert(jp2 != 00);
- assert(p_manager != 00);
-
- l_current_data = (OPJ_BYTE*)opj_calloc(1,l_last_data_size);
-
- if (l_current_data == 00) {
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n");
- return OPJ_FALSE;
- }
-
- while (opj_jp2_read_boxhdr(&box,&l_nb_bytes_read,stream,p_manager)) {
- /* is it the codestream box ? */
- if (box.type == JP2_JP2C) {
- if (jp2->jp2_state & JP2_STATE_HEADER) {
- jp2->jp2_state |= JP2_STATE_CODESTREAM;
- opj_free(l_current_data);
- return OPJ_TRUE;
- }
- else {
- opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
- opj_free(l_current_data);
- return OPJ_FALSE;
- }
- }
- else if (box.length == 0) {
- opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
- opj_free(l_current_data);
- return OPJ_FALSE;
- }
- /* testcase 1851.pdf.SIGSEGV.ce9.948 */
- else if (box.length < l_nb_bytes_read) {
- opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type);
- opj_free(l_current_data);
- return OPJ_FALSE;
- }
-
- l_current_handler = opj_jp2_find_handler(box.type);
- l_current_handler_misplaced = opj_jp2_img_find_handler(box.type);
- l_current_data_size = box.length - l_nb_bytes_read;
-
- if ((l_current_handler != 00) || (l_current_handler_misplaced != 00)) {
- if (l_current_handler == 00) {
- opj_event_msg(p_manager, EVT_WARNING, "Found a misplaced '%c%c%c%c' box outside jp2h box\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
- if (jp2->jp2_state & JP2_STATE_HEADER) {
- /* read anyway, we already have jp2h */
- l_current_handler = l_current_handler_misplaced;
- } else {
- opj_event_msg(p_manager, EVT_WARNING, "JPEG2000 Header box not read yet, '%c%c%c%c' box will be ignored\n", (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0));
- jp2->jp2_state |= JP2_STATE_UNKNOWN;
- if (opj_stream_skip(stream,l_current_data_size,p_manager) != l_current_data_size) {
- opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n");
- opj_free(l_current_data);
- return OPJ_FALSE;
- }
- continue;
- }
- }
- if ((OPJ_OFF_T)l_current_data_size > opj_stream_get_number_byte_left(stream)) {
- /* do not even try to malloc if we can't read */
- opj_event_msg(p_manager, EVT_ERROR, "Invalid box size %d for box '%c%c%c%c'. Need %d bytes, %d bytes remaining \n", box.length, (OPJ_BYTE)(box.type>>24), (OPJ_BYTE)(box.type>>16), (OPJ_BYTE)(box.type>>8), (OPJ_BYTE)(box.type>>0), l_current_data_size, (OPJ_UINT32)opj_stream_get_number_byte_left(stream));
- opj_free(l_current_data);
- return OPJ_FALSE;
- }
- if (l_current_data_size > l_last_data_size) {
- OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size);
- if (!new_current_data) {
- opj_free(l_current_data);
- opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n");
- return OPJ_FALSE;
- }
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(cio != 00);
+ assert(p_manager != 00);
+
+ /* customization of the end encoding */
+ if (! opj_jp2_setup_end_header_reading(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ /* write header */
+ if (! opj_jp2_exec(jp2, jp2->m_procedure_list, cio, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ return opj_j2k_end_decompress(jp2->j2k, cio, p_manager);
+}
+
+OPJ_BOOL opj_jp2_end_compress(opj_jp2_t *jp2,
+ opj_stream_private_t *cio,
+ opj_event_mgr_t * p_manager
+ )
+{
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(cio != 00);
+ assert(p_manager != 00);
+
+ /* customization of the end encoding */
+ if (! opj_jp2_setup_end_header_writing(jp2, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ if (! opj_j2k_end_compress(jp2->j2k, cio, p_manager)) {
+ return OPJ_FALSE;
+ }
+
+ /* write header */
+ return opj_jp2_exec(jp2, jp2->m_procedure_list, cio, p_manager);
+}
+
+static OPJ_BOOL opj_jp2_setup_end_header_writing(opj_jp2_t *jp2,
+ opj_event_mgr_t * p_manager)
+{
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(p_manager != 00);
+
+#ifdef USE_JPIP
+ if (jp2->jpip_on) {
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,
+ (opj_procedure)opj_jpip_write_iptr, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
+#endif
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,
+ (opj_procedure)opj_jp2_write_jp2c, p_manager)) {
+ return OPJ_FALSE;
+ }
+ /* DEVELOPER CORNER, add your custom procedures */
+#ifdef USE_JPIP
+ if (jp2->jpip_on) {
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,
+ (opj_procedure)opj_jpip_write_cidx, p_manager)) {
+ return OPJ_FALSE;
+ }
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,
+ (opj_procedure)opj_jpip_write_fidx, p_manager)) {
+ return OPJ_FALSE;
+ }
+ }
+#endif
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_jp2_setup_end_header_reading(opj_jp2_t *jp2,
+ opj_event_mgr_t * p_manager)
+{
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(p_manager != 00);
+
+ if (! opj_procedure_list_add_procedure(jp2->m_procedure_list,
+ (opj_procedure)opj_jp2_read_header_procedure, p_manager)) {
+ return OPJ_FALSE;
+ }
+ /* DEVELOPER CORNER, add your custom procedures */
+
+ return OPJ_TRUE;
+}
+
+static OPJ_BOOL opj_jp2_default_validation(opj_jp2_t * jp2,
+ opj_stream_private_t *cio,
+ opj_event_mgr_t * p_manager
+ )
+{
+ OPJ_BOOL l_is_valid = OPJ_TRUE;
+ OPJ_UINT32 i;
+
+ /* preconditions */
+ assert(jp2 != 00);
+ assert(cio != 00);
+ assert(p_manager != 00);
+
+ OPJ_UNUSED(p_manager);
+
+ /* JPEG2000 codec validation */
+
+ /* STATE checking */
+ /* make sure the state is at 0 */
+ l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE);
+
+ /* make sure not reading a jp2h ???? WEIRD */
+ l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE);
+
+ /* POINTER validation */
+ /* make sure a j2k codec is present */
+ l_is_valid &= (jp2->j2k != 00);
+
+ /* make sure a procedure list is present */
+ l_is_valid &= (jp2->m_procedure_list != 00);
+
+ /* make sure a validation list is present */
+ l_is_valid &= (jp2->m_validation_list != 00);
+
+ /* PARAMETER VALIDATION */
+ /* number of components */
+ l_is_valid &= (jp2->numcl > 0);
+ /* width */
+ l_is_valid &= (jp2->h > 0);
+ /* height */
+ l_is_valid &= (jp2->w > 0);
+ /* precision */
+ for (i = 0; i < jp2->numcomps; ++i) {
+ l_is_valid &= ((jp2->comps[i].bpcc & 0x7FU) <
+ 38U); /* 0 is valid, ignore sign for check */
+ }
+
+ /* METH */
+ l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3));
+
+ /* stream validation */
+ /* back and forth is needed */
+ l_is_valid &= opj_stream_has_seek(cio);
+
+ return l_is_valid;
+}
+
+static OPJ_BOOL opj_jp2_read_header_procedure(opj_jp2_t *jp2,
+ opj_stream_private_t *stream,
+ opj_event_mgr_t * p_manager
+ )
+{
+ opj_jp2_box_t box;
+ OPJ_UINT32 l_nb_bytes_read;
+ const opj_jp2_header_handler_t * l_current_handler;
+ const opj_jp2_header_handler_t * l_current_handler_misplaced;
+ OPJ_UINT32 l_last_data_size = OPJ_BOX_SIZE;
+ OPJ_UINT32 l_current_data_size;
+ OPJ_BYTE * l_current_data = 00;
+
+ /* preconditions */
+ assert(stream != 00);
+ assert(jp2 != 00);
+ assert(p_manager != 00);
+
+ l_current_data = (OPJ_BYTE*)opj_calloc(1, l_last_data_size);
+
+ if (l_current_data == 00) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Not enough memory to handle jpeg2000 file header\n");
+ return OPJ_FALSE;
+ }
+
+ while (opj_jp2_read_boxhdr(&box, &l_nb_bytes_read, stream, p_manager)) {
+ /* is it the codestream box ? */
+ if (box.type == JP2_JP2C) {
+ if (jp2->jp2_state & JP2_STATE_HEADER) {
+ jp2->jp2_state |= JP2_STATE_CODESTREAM;
+ opj_free(l_current_data);
+ return OPJ_TRUE;
+ } else {
+ opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ } else if (box.length == 0) {
+ opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ /* testcase 1851.pdf.SIGSEGV.ce9.948 */
+ else if (box.length < l_nb_bytes_read) {
+ opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length,
+ box.type);
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+
+ l_current_handler = opj_jp2_find_handler(box.type);
+ l_current_handler_misplaced = opj_jp2_img_find_handler(box.type);
+ l_current_data_size = box.length - l_nb_bytes_read;
+
+ if ((l_current_handler != 00) || (l_current_handler_misplaced != 00)) {
+ if (l_current_handler == 00) {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "Found a misplaced '%c%c%c%c' box outside jp2h box\n",
+ (OPJ_BYTE)(box.type >> 24), (OPJ_BYTE)(box.type >> 16),
+ (OPJ_BYTE)(box.type >> 8), (OPJ_BYTE)(box.type >> 0));
+ if (jp2->jp2_state & JP2_STATE_HEADER) {
+ /* read anyway, we already have jp2h */
+ l_current_handler = l_current_handler_misplaced;
+ } else {
+ opj_event_msg(p_manager, EVT_WARNING,
+ "JPEG2000 Header box not read yet, '%c%c%c%c' box will be ignored\n",
+ (OPJ_BYTE)(box.type >> 24), (OPJ_BYTE)(box.type >> 16),
+ (OPJ_BYTE)(box.type >> 8), (OPJ_BYTE)(box.type >> 0));
+ jp2->jp2_state |= JP2_STATE_UNKNOWN;
+ if (opj_stream_skip(stream, l_current_data_size,
+ p_manager) != l_current_data_size) {
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Problem with skipping JPEG2000 box, stream error\n");
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ continue;
+ }
+ }
+ if ((OPJ_OFF_T)l_current_data_size > opj_stream_get_number_byte_left(stream)) {
+ /* do not even try to malloc if we can't read */
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Invalid box size %d for box '%c%c%c%c'. Need %d bytes, %d bytes remaining \n",
+ box.length, (OPJ_BYTE)(box.type >> 24), (OPJ_BYTE)(box.type >> 16),
+ (OPJ_BYTE)(box.type >> 8), (OPJ_BYTE)(box.type >> 0), l_current_data_size,
+ (OPJ_UINT32)opj_stream_get_number_byte_left(stream));
+ opj_free(l_current_data);
+ return OPJ_FALSE;
+ }
+ if (l_current_data_size > l_last_data_size) {
+ OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,
+ l_current_data_size);
+ if (!new_current_data) {
+ opj_free(l_current_data);
+ opj_event_msg(p_manager, EVT_ERROR,
+ "Not enough memory to handle jpeg2000 box\n");
+ return OPJ_FALSE;
+ }