📄 hpbit_stream_out.c
字号:
/*****************************************************************************/static void translate_cod_coc_markers(hpbit_stream_out_ref self, hpbit_markers_ptr markers) /* Converts COD/COD markers onto the `markers->pre_markers' list into codestream markers, which it adds to the `markers->codestream_markers' list. Attempts to form a minimal number of COC codestream markers by creating a COD marker whose parameters are common to as many components as possible. If translation is successful, the function sets the `translated' flag in the relevant `hpbit_pre_marker' structure. Otherwise, the function returns without creating the codestream markers and an appropriate non-standard generic marker will be created 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. Note also that redundancies between the global and tile headers should already have been removed. In fact, you will find that the COD and COC pre-markers are all connected via the `link_next' and `link_prev' fields, although not in any particular order. */{ /* MJG - need to find all COD/COC premarkers and handle jointly*/ /* if we can't write a COC we should not write the COD because the decoder isn't designed to get some info from a COD and some from a premarker */ hpbit_pre_marker_ptr pm; hpbit_marker_elt_ptr elt; cod_marker cod; coc_marker coc; std_byte *bp, *buf; int length, comps, c; int valid; /* first check */ for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; if (pm->id == (MARKER_COD & 0x00FF)) { valid = 1; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_COD_PROG: case ELTID_COD_LAYERS: valid = (elt->size == 1); break; default: valid = 0; local_printf(5,72,"Got COD %d will use premarker",elt->element_id); } if (!valid) return; } else if (pm->id == (MARKER_COC & 0x00FF)) { valid = 1; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_COC_LEVELS: case ELTID_COC_XCB: case ELTID_COC_YCB: case ELTID_COC_MOD: case ELTID_COC_REV: case ELTID_COC_PPX: case ELTID_COC_PPY: valid = (elt->size == 1); break; default: valid = 0; local_printf(5,72,"Got COC %d will use premarker",elt->element_id); } if (!valid) return; } } /* Now Encode */ /* Grab cod only info */ for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; if (pm->id == (MARKER_COD & 0x00FF)) { memset(&cod,0,sizeof(cod_marker)); valid = 1; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_COD_PROG: valid = (elt->size == 1); cod.prog = (std_byte)(elt->buf[0]); break; case ELTID_COD_LAYERS: valid = (elt->size == 1); cod.layers = (std_ushort)(elt->buf[0]); break; default: valid = 0; local_printf(5,72,"Got COD %d don't understand it",elt->element_id); } if (!valid) return; pm->translated = 1; /* not yet, but it will be */ } } /* Now write a COD with component 0 parameters */ for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; else if (pm->id == (MARKER_COC & 0x00FF)) { if (pm->instance != 0) continue; valid = 1; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_COC_LEVELS: valid = (elt->size == 1); cod.level = (std_byte)(elt->buf[0]); break; case ELTID_COC_XCB: valid = (elt->size == 1); cod.xcb = (std_byte)(elt->buf[0]); break; case ELTID_COC_YCB: valid = (elt->size == 1); cod.ycb = (std_byte)(elt->buf[0]); break; case ELTID_COC_MOD: valid = (elt->size == 1); cod.mod = (std_byte)(elt->buf[0]); break; case ELTID_COC_REV: valid = (elt->size == 1); cod.rev = (std_byte)(elt->buf[0]); break; case ELTID_COC_PPX: cod.Scod |= 1; valid = (elt->size == 1); cod.ppx = (std_byte)(elt->buf[0]); break; case ELTID_COC_PPY: cod.Scod |= 1; valid = (elt->size == 1); cod.ppy = (std_byte)(elt->buf[0]); break; default: valid = 0; local_printf(5,72,"Got COC %d don't understand it",elt->element_id); } length = 15; if (cod.Scod == 1) length += 2; cod.COD = MARKER_COD; cod.Lcod = length -2; bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,length); copy_to_big_endian(&(cod.COD),bp,2,2); bp += 2*2; *(bp++) = cod.Scod; *(bp++) = cod.level; *(bp++) = cod.prog; copy_to_big_endian(&(cod.layers),bp,1,2); bp += 1*2; *(bp++) = cod.xcb; *(bp++) = cod.ycb; *(bp++) = cod.mod; *(bp++) = cod.rev; if (cod.Scod == 1) { *(bp++) = cod.ppx; *(bp++) = cod.ppy; } add_codestream_marker(markers,buf,length,pm->instance,0); pm->translated = 1; } } /* Now encode each component COC that is different*/ for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; else if (pm->id == (MARKER_COC & 0x00FF)) { memset(&coc,0,sizeof(coc_marker)); valid = 1; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_COC_LEVELS: valid = (elt->size == 1); coc.level = (std_byte)(elt->buf[0]); break; case ELTID_COC_XCB: valid = (elt->size == 1); coc.xcb = (std_byte)(elt->buf[0]); break; case ELTID_COC_YCB: valid = (elt->size == 1); coc.ycb = (std_byte)(elt->buf[0]); break; case ELTID_COC_MOD: valid = (elt->size == 1); coc.mod = (std_byte)(elt->buf[0]); break; case ELTID_COC_REV: valid = (elt->size == 1); coc.rev = (std_byte)(elt->buf[0]); break; case ELTID_COC_PPX: coc.Scoc |= 1; valid = (elt->size == 1); coc.ppx = (std_byte)(elt->buf[0]); break; case ELTID_COC_PPY: coc.Scoc |= 1; valid = (elt->size == 1); coc.ppy = (std_byte)(elt->buf[0]); break; default: valid = 0; local_printf(5,72,"Got COC %d don't understand it",elt->element_id); } if (!valid) return; if ( (coc.level != cod.level) || (coc.xcb != cod.xcb) || (coc.ycb != cod.ycb) || (coc.mod != cod.mod) || (coc.rev != cod.rev) || (coc.Scoc != cod.Scod) || (coc.ppx != cod.ppx) || (coc.ppy != cod.ppy) ) { length = 11; if ((coc.Scoc & 1 ) == 1) /* packet partition */ length += 2; if (markers->params.num_components > 255) length++; coc.COC = MARKER_COC; coc.Lcoc = length -2; coc.Ccoc = pm->instance; bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,length); copy_to_big_endian(&(coc.COC),bp,2,2); bp += 2*2; if (markers->params.num_components > 255) { *(bp++) = (std_byte) coc.Ccoc >> 8; } *(bp++) = (std_byte) coc.Ccoc & 0xff; *(bp++) = coc.Scoc; *(bp++) = coc.level; *(bp++) = coc.xcb; *(bp++) = coc.ycb; *(bp++) = coc.mod; *(bp++) = coc.rev; if ((coc.Scoc & 1) == 1) { *(bp++) = coc.ppx; *(bp++) = coc.ppy; } add_codestream_marker(markers,buf,length,pm->instance,0); } /* mark translated even if we didn't write because it matches COD */ pm->translated = 1; } }}/*****************************************************************************//* STATIC translate_qcd_qcc_markers *//*****************************************************************************/static void translate_qcd_qcc_markers(hpbit_stream_out_ref self, hpbit_markers_ptr markers) /* Converts QCD/QCC markers onto the `markers->pre_markers' list into codestream markers, which it adds to the `markers->codestream_markers' list. Attempts to form a minimal number of QCCC codestream markers by creating a QCD marker whose parameters are common to as many components as possible. If translation is successful, the function sets the `translated' flag in the relevant `hpbit_pre_marker' structure. Otherwise, the function returns without creating the codestream markers and an appropriate non-standard generic marker will be created 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. Note also that redundancies between the global and tile headers should already have been removed. In fact, you will find that the QCD and QCC pre-markers are all connected via the `link_next' and `link_prev' fields, although not in any particular order. */{ hpbit_pre_marker_ptr pm; qcc_marker qcc; /* RSV mjg - Make sure QCD/QCC data is part I */ int valid = 1; for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; else if (pm->id == (MARKER_QCD & 0x00FF)) { hpbit_marker_elt_ptr elt; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_QCD_WHICH: valid = (elt->size == 1) && (elt->buf[0] == 0); break; default: valid = 0; local_printf(5,72,"Got QCD %d don't understand it",elt->element_id); } if (!valid) return; } else if (pm->id == (MARKER_QCC & 0x00FF)) { hpbit_marker_elt_ptr elt; std_byte *bp, *buf; for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_QCC_REV: case ELTID_QCC_STEP: case ELTID_QCC_GUARD: break; default: valid = 0; local_printf(5,72,"Got QCC %d don't understand it",elt->element_id); } } if (!valid) return; } /* Now write a QCD and components - 1 QCCs */ /* make component 0 the QCD and write others as QCC for now */ /* TODO: eliminate duplicates */ for (pm=markers->pre_markers; pm != NULL; pm = pm->next) { if (pm->translated) continue; else if (pm->id == (MARKER_QCD & 0x00FF)) { pm->translated = 1; } else if (pm->id == (MARKER_QCC & 0x00FF)) { hpbit_marker_elt_ptr elt; int length = 0; std_byte *buf, *bp; int component= pm->instance; int qcc_data_size; int qcc_data_type; int *qcc_data; memset(&qcc,0,sizeof(qcc)); for (elt=pm->elements; elt != NULL && valid; elt=elt->next) switch ((char)(elt->element_id)) { case ELTID_QCC_REV: qcc_data_size = elt->size; qcc_data = elt->buf; qcc_data_type = 1; qcc.Sqcc |= 0; /* a noop */ break; case ELTID_QCC_STEP: qcc_data_size = elt->size; qcc_data = elt->buf; qcc_data_type = 2; if (elt->size == 1) qcc.Sqcc |= 1; else qcc.Sqcc |= 2; break; case ELTID_QCC_GUARD: qcc.Sqcc |= (elt->buf[0] << 5); break; default: valid = 0; local_printf(5,72,"Got QCC %d don't understand it",elt->element_id); } /* write it out */ qcc.QCC = MARKER_QCC; qcc.Lqcc = 4+ qcc_data_size * qcc_data_type; if (component == 0) { qcc.Lqcc--; /* no component # */ qcc.QCC = MARKER_QCD; bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,qcc.Lqcc+2); copy_to_big_endian(&(qcc.QCC),bp,2,2); bp += 2*2; /* no component # */ } else { bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,qcc.Lqcc+2); copy_to_big_endian(&(qcc.QCC),bp,2,2); bp += 2*2; *(bp++) = component; } *(bp++) = qcc.Sqcc; if (qcc_data_type == 1) { /* REV data */ int i; for(i=0; i<qcc_data_size; i++) *(bp++) = (std_byte) qcc_data[i]; } else { /* STEP data */ int i; for(i=0; i<qcc_data_size; i++) { *(bp++) = (std_byte) (qcc_data[i] >> 8); *(bp++) = (std_byte) (qcc_data[i] & 0xff); } } add_codestream_marker(markers,buf,qcc.Lqcc+2,pm->instance,0); pm->translated = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -