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;
                }
                l_current_data = new_current_data;
                l_last_data_size = l_current_data_size;
            }

            l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(stream, l_current_data,
                              l_current_data_size, p_manager);
            if (l_nb_bytes_read != l_current_data_size) {
                opj_event_msg(p_manager, EVT_ERROR,
                              "Problem with reading JPEG2000 box, stream error\n");
                opj_free(l_current_data);
                return OPJ_FALSE;
            }

            if (! l_current_handler->handler(jp2, l_current_data, l_current_data_size,
                                             p_manager)) {
                opj_free(l_current_data);
                return OPJ_FALSE;
            }
        } else {
            if (!(jp2->jp2_state & JP2_STATE_SIGNATURE)) {
                opj_event_msg(p_manager, EVT_ERROR,
                              "Malformed JP2 file format: first box must be JPEG 2000 signature box\n");
                opj_free(l_current_data);
                return OPJ_FALSE;
            }
            if (!(jp2->jp2_state & JP2_STATE_FILE_TYPE)) {
                opj_event_msg(p_manager, EVT_ERROR,
                              "Malformed JP2 file format: second box must be file type box\n");
                opj_free(l_current_data);
                return OPJ_FALSE;
            }
            jp2->jp2_state |= JP2_STATE_UNKNOWN;
            if (opj_stream_skip(stream, l_current_data_size,
                                p_manager) != l_current_data_size) {
                if (jp2->jp2_state & JP2_STATE_CODESTREAM) {
                    /* If we already read the codestream, do not error out */
                    /* Needed for data/input/nonregression/issue254.jp2 */
                    opj_event_msg(p_manager, EVT_WARNING,
                                  "Problem with skipping JPEG2000 box, stream error\n");
                    opj_free(l_current_data);
                    return OPJ_TRUE;
                } else {
                    opj_event_msg(p_manager, EVT_ERROR,
                                  "Problem with skipping JPEG2000 box, stream error\n");
                    opj_free(l_current_data);
                    return OPJ_FALSE;
                }
            }
        }
    }

    opj_free(l_current_data);

    return OPJ_TRUE;
}