📄 hpbit_stream_in.c
字号:
length = read_non_data_bytes(self,entry->buf+4,length-4); entry->num_bytes = length + 4; markers->total_codestream_bytes += entry->num_bytes; } while (1);}/*****************************************************************************//* STATIC add_elt *//*****************************************************************************/static hpbit_marker_elt_ptr add_elt(hpbit_pre_marker_ptr pm, const char *elt_id, int size) /* Adds a new element to the list managed by `pm' and returns a pointer to this new element. The new element has `size' entries. */{ hpbit_marker_elt_ptr elt; int marker_id, element_id; marker_id = elt_id[0]; element_id = elt_id[1]; assert(marker_id == pm->id); assert(size > 0); for (elt=pm->elements; elt != NULL; elt=elt->next) assert(elt->element_id != element_id); elt = (hpbit_marker_elt_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_marker_elt)); elt->next = pm->elements; pm->elements = elt; elt->marker_id = marker_id; elt->element_id = element_id; elt->description = elt_id + 2; elt->size = size; elt->buf = (std_uint *) local_malloc(HPBIT_MEM_KEY,size*sizeof(std_uint)); return(elt);}/*****************************************************************************//* STATIC get_tile_component_bands *//*****************************************************************************/static int get_tile_component_bands(hpbit_stream_in_ref self, int tnum, int comp_idx, int num_levels) /* This function computes the total number of bands for the relevant tile-component based on the number of decomposition levels and any special decomposition structure. */{ int length, hp_descent, num_bands, n; length = (int) self->base.size_marker_elt(&(self->base),tnum,MARKER_COC_DECOMP,comp_idx); if (length == 0) return(3*num_levels+1); /* Mallat decomposition. */ num_bands = 1; hp_descent = 0; for (n=0; n < num_levels; n++) { if (n < length) hp_descent = (int) self->base.get_marker_val(&(self->base),tnum,MARKER_COC_DECOMP, comp_idx,n); if (hp_descent == 1) num_bands += 3; else if (hp_descent == 2) num_bands += 12; else if (hp_descent == 3) num_bands += 48; else num_bands += 3; /* Error; use Mallat as default. */ } return(num_bands);}/*****************************************************************************//* STATIC process_ppt_markers *//*****************************************************************************/static void process_ppt_markers(hpbit_markers_ptr markers, hpbit_tilepart_ptr tp){ std_byte z; hpbit_codestream_marker_ptr cp, prev; hpbit_packed_head_ptr ph, last_ph; int length; assert(tp->packed_heads == NULL); z = 0; last_ph = NULL; do { for (prev=NULL, cp=markers->codestream_markers; cp != NULL; prev=cp, cp=cp->next) if ((cp->buf[1] == (MARKER_PPT & 0x00FF)) && (cp->num_bytes > 5) && (cp->buf[4] == z)) { assert(!cp->accesses); if (prev == NULL) markers->codestream_markers = cp->next; else prev->next = cp->next; ph = (hpbit_packed_head_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_packed_head)); if (last_ph == NULL) tp->packed_heads = ph; else last_ph->next = ph; last_ph = ph; ph->data_handle = cp->buf; ph->data = cp->buf + 5; length = (int) cp->buf[2]; length <<= 8; length |= (int) cp->buf[3]; ph->bytes_left = length - 3; local_free(cp); break; } z++; } while (cp != NULL);}/*****************************************************************************//* STATIC process_ppm_markers *//*****************************************************************************/static void process_ppm_markers(hpbit_markers_ptr markers, hpbit_stream_in_ref self){ std_byte z; hpbit_codestream_marker_ptr cp, prev; hpbit_stored_heads_ptr sh, last_sh; hpbit_packed_head_ptr ph; std_byte *buf; int length, tp_bytes; assert(self->stored_heads == NULL); z = 0; last_sh = NULL; do { for (prev=NULL, cp=markers->codestream_markers; cp != NULL; prev=cp, cp=cp->next) if ((cp->buf[1] == (MARKER_PPM & 0x00FF)) && (cp->num_bytes > 5) && (cp->buf[4] == z)) { assert(!cp->accesses); if (prev == NULL) markers->codestream_markers = cp->next; else prev->next = cp->next; length = (int) cp->buf[2]; length <<= 8; length |= (int) cp->buf[3]; length -= 3; buf = cp->buf + 5; do { sh = (hpbit_stored_heads_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_stored_heads)); if (last_sh == NULL) self->stored_heads = sh; else last_sh->next = sh; last_sh = sh; tp_bytes = 0; if (length >= 2) { tp_bytes = (int) *(buf++); length--; tp_bytes <<= 8; tp_bytes |= (int) *(buf++); length--; } if (tp_bytes > length) tp_bytes = length; sh->packed_heads = ph = (hpbit_packed_head_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_packed_head)); ph->next = NULL; ph->bytes_left = tp_bytes; ph->data = buf; ph->data_handle = NULL; length -= tp_bytes; buf += tp_bytes; if (length <= 2) ph->data_handle = cp->buf; } while (length > 2); local_free(cp); break; } z++; } while (cp != NULL);}/*****************************************************************************//* STATIC translate_cod_coc_markers *//*****************************************************************************/static int translate_cod_coc_markers(hpbit_stream_in_ref self, hpbit_markers_ptr markers) /* Looks for COD and COC markers in the `markers->codestream_markers' list and uses these to construct the COD and COC pre-markers, putting them on the `markers->pre_markers' list. If no COD marker can be found, the function returns 0. Otherwise, the function returns 1. The function should not raise asserts or terminate the program abnormally. If marker translation fails, `self->failed_marker_translations' should be incremented instead. Note: only the `num_components' field of `markers->params' is valid on entry; the function should not itself attempt to set any fields in the `markers->params' structure, since these are set later. You should be able to extract any other coding parameters you need from the COD/COC markers themselves. */{ /* RSV mjg & gkw */ hpbit_codestream_marker_ptr cp; int failure; cod_marker cod; coc_marker coc; int comp; hpbit_pre_marker_ptr pm; hpbit_marker_elt_ptr elt; std_byte *bp; memset(&cod,0,sizeof(cod)); memset(&coc,0,sizeof(coc)); failure = 0; for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if (cp->buf[1] == (MARKER_COD & 0x00FF)) { hpbit_pre_marker_ptr pm; hpbit_marker_elt_ptr elt; std_byte *bp; int comps, c; assert(cp->accesses == 0); bp = cp->buf; copy_from_big_endian(bp,&(cod.COD),2,2); bp += 2*2; cod.Scod = *(bp++); cod.level = *(bp++); cod.prog = *(bp++); copy_from_big_endian(bp,&(cod.layers),1,2); bp += 1*2; cod.xcb = *(bp++); cod.ycb = *(bp++); cod.mod = *(bp++); cod.rev = *(bp++); if (cod.Scod == 1) { cod.ppx = *(bp++); cod.ppy = *(bp++); } pm = (hpbit_pre_marker_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_pre_marker)); pm->next = markers->pre_markers; markers->pre_markers = pm; pm->id = MARKER_COD & 0x00FF; pm->instance = 0; elt = add_elt(pm,MARKER_COD_PROG,1); elt->buf[0] = cod.prog; elt = add_elt(pm,MARKER_COD_LAYERS,1); elt->buf[0] = cod.layers; cp->accesses = 1; break; } self->failed_marker_translations += failure; if (cp==NULL) /* No COD found */ return(0); if (failure) return(0); /* Now for each component either read a COC, or if none create a COC from the COD, and add the pre-marker */ failure = 0; for (comp=0; comp < markers->params.num_components; comp++) { for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if (cp->buf[1] == (MARKER_COC & 0x00FF)) { if ((markers->params.num_components < 256) && (cp->buf[4] != comp)) continue; if ((markers->params.num_components >=256) && ((cp->buf[4] << 8) + cp->buf[5] != comp)) continue; assert(cp->accesses == 0); bp = cp->buf; copy_from_big_endian(bp,&(coc.COC),2,2); bp += 2*2; coc.Ccoc = *(bp++); assert(coc.COC == MARKER_COC); coc.Scoc = *(bp++); coc.level = *(bp++); coc.xcb = *(bp++); coc.ycb = *(bp++); coc.mod = *(bp++); coc.rev = *(bp++); if (coc.Scoc == 1) { coc.ppx = *(bp++); coc.ppy = *(bp++); } cp->accesses = 1; break; } self->failed_marker_translations += failure; if (cp == NULL) /* Didn't find marker */ { /* Note: this code doesn't work if COD is a marker, but */ /* COC is premarker, but only the VM writes pre-markers and */ /* it either writes both COD and COC as markers or as premarkers */ /* copy from cod */ coc.Ccoc = comp; coc.Scoc = cod.Scod; coc.level = cod.level; coc.xcb = cod.xcb; coc.ycb = cod.ycb; coc.mod = cod.mod; coc.rev = cod.rev; coc.ppx = cod.ppx; coc.ppy = coc.ppy; } pm = (hpbit_pre_marker_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_pre_marker)); pm->next = markers->pre_markers; markers->pre_markers = pm; pm->id = MARKER_COC & 0x00FF; pm->instance = coc.Ccoc; elt = add_elt(pm,MARKER_COC_LEVELS,1); elt->buf[0] = coc.level; elt = add_elt(pm,MARKER_COC_REV,1); elt->buf[0] = coc.rev; elt = add_elt(pm,MARKER_COC_XCB,1); elt->buf[0] = coc.xcb; elt = add_elt(pm,MARKER_COC_YCB,1); elt->buf[0] = coc.ycb; if (coc.Scoc == 1) { elt = add_elt(pm,MARKER_COC_PPX,1); elt->buf[0] = coc.ppx; elt = add_elt(pm,MARKER_COC_PPY,1); elt->buf[0] = coc.ppy; } elt = add_elt(pm,MARKER_COC_MOD,1); elt->buf[0] = coc.mod; } return(1);}/*****************************************************************************//* STATIC translate_qcd_qcc_markers *//*****************************************************************************/static int translate_qcd_qcc_markers(hpbit_stream_in_ref self, hpbit_markers_ptr markers) /* Looks for QCD and QCC markers in the `markers->codestream_markers' list and uses these to construct the COD and COC pre-markers, putting them on the `markers->pre_markers' list. If no QCD marker can be found, the function returns 0. Otherwise, the function returns 1. The function should not raise asserts or terminate the program abnormally. If marker translation fails, `self->failed_marker_translations' should be incremented instead. Note: all coding parameters collected in `markers->params' are accurate and available for error checking and codestream marker formation. There should be no need to store further coding parameters. */{ qcc_marker qcd,qcc; hpbit_pre_marker_ptr pm; hpbit_codestream_marker_ptr cp; hpbit_marker_elt_ptr elt; std_byte *bp; int comp; int data_size; int failure = 0; memset(&qcd,0,sizeof(qcd)); memset(&qcc,0,sizeof(qcc)); /* First find a QCD and pass the WHICH up */ for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if (cp->buf[1] == (MARKER_QCD & 0x00FF)) { assert(cp->accesses == 0); bp = cp->buf; copy_from_big_endian(bp,&(qcd.QCC),2,2); bp += 2*2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -