📄 hpbit_stream_in.c
字号:
elt->description = "<unknown>"; single_flag = (elt->element_id & 0x40)?1:0; size_flag = (elt->element_id & 0x80)?1:0; elt->element_id &= 0x3F; if (single_flag) { prec = 1; elt->size = 1; } else { if (total_bytes < (2+size_flag)) { destroy_pre_marker(pm); return(0); } prec = *(bp++); total_bytes--; if ((prec != 1) && (prec != 2) && (prec != 4)) local_error("CME marker used to pack regular marker segments " "seems to be corrupt!"); elt->size = *(bp++); total_bytes--; if (size_flag) { elt->size <<= 8; elt->size += *(bp++); total_bytes--; } } nvals = elt->size; nbytes = nvals * prec; if ((total_bytes < nbytes) || (nvals == 0)) { destroy_pre_marker(pm); return(0); } elt->buf = (std_uint *) local_malloc(HPBIT_MEM_KEY,nvals*sizeof(std_uint)); dp = elt->buf; switch (prec) { case 1: { for (n=nvals; n > 0; n--, dp++) *dp = (std_uint) *(bp++); } break; case 2: { for (n=nvals; n > 0; n--, dp++) { *dp = (std_uint) *(bp++); *dp <<= 8; *dp |= (std_uint) *(bp++); } } break; case 4: { for (n=nvals; n > 0; n--, dp++) { *dp = (std_uint) *(bp++); *dp <<= 8; *dp |= (std_uint) *(bp++); *dp <<= 8; *dp |= (std_uint) *(bp++); *dp <<= 8; *dp |= (std_uint) *(bp++); } } break; default: assert(0); } total_bytes -= nbytes; } /* If we get here, translation was successful. Add to the list. */ pm->next = markers->pre_markers; markers->pre_markers = pm; self->num_non_compliant_markers++; return(1);}/*****************************************************************************//* STATIC process_markers *//*****************************************************************************/static void process_markers(hpbit_stream_in_ref self, hpbit_tilepart_ptr tp) /* Constructs pre-markers from the codestream markers associated with the global header (if `tile' is NULL) or the supplied tile-part. */{ hpbit_markers_ptr markers; hpbit_codestream_marker_ptr cp; int failure, tnum, c; if (tp == NULL) markers = &(self->global_markers); else markers = &(tp->markers); /* Begin by processing and removing any PPM/PPT markers. */ if (tp == NULL) process_ppm_markers(markers,self); else { hpbit_stored_heads_ptr sh; if ((sh = self->stored_heads) != NULL) { tp->packed_heads = sh->packed_heads; self->stored_heads = sh->next; local_free(sh); } else process_ppt_markers(markers,tp); } /* Next, process those markers which are required to determine the contents of `markers->params' which will be required to correctly parse the other codestream markers. */ failure = 0; for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if (cp->buf[1] == (MARKER_SIZ & 0x00FF)) { failure = !siz_to_pre_marker(self,markers,cp); break; } self->failed_marker_translations += failure; if (failure || (cp == NULL)) /* Need to get SIZ from generic markers. */ { failure = 0; for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if ((cp->accesses == 0) && (cp->buf[1] == (MARKER_CME & 0x00FF)) && (cp->buf[4] == 0x00FF) && (cp->buf[5] == (MARKER_SIZ & 0x00FF))) { failure = !cme_to_pre_marker(self,markers,cp); self->failed_marker_translations += failure; } } tnum = (tp == NULL)?-1:(tp->tnum); markers->params.num_components = (int) self->base.get_marker_val(&(self->base),tnum,MARKER_SIZ_C,0,0); if (!translate_cod_coc_markers(self,markers)) { for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) if ((cp->accesses == 0) && (cp->buf[1] == (MARKER_CME & 0x00FF)) && (cp->buf[4] == 0x00FF) && ((cp->buf[5] == (MARKER_COD & 0x00FF)) || (cp->buf[5] == (MARKER_COC & 0x00FF)))) { failure = !cme_to_pre_marker(self,markers,cp); self->failed_marker_translations += failure; } } markers->params.components = (hpbit_component_params_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_component_params)* markers->params.num_components); for (c=0; c < markers->params.num_components; c++) { markers->params.components[c].num_levels = (int) self->base.get_marker_val(&(self->base),tnum,MARKER_COC_LEVELS,c,0); markers->params.components[c].num_bands = get_tile_component_bands(self,tnum,c, markers->params.components[c].num_levels); } /* Now parse the dependent markers. */ translate_qcd_qcc_markers(self,markers); for (cp=markers->codestream_markers; cp != NULL; cp=cp->next) { if (cp->accesses != 0) continue; failure = 0; if (cp->buf[1] == (MARKER_SIZ & 0x00FF)) failure = !siz_to_pre_marker(self,markers,cp); /* To catch failures */ else if (cp->buf[1] == (MARKER_ERS & 0x00FF)) failure = !ers_to_pre_marker(self,markers,cp); else if (cp->buf[1] == (MARKER_RGN & 0x00FF)) failure = !rgn_to_pre_marker(self,markers,cp); else if (cp->buf[1] == (MARKER_POC & 0x00FF)) failure = !poc_to_pre_marker(self,markers,cp); else if ((cp->buf[1] == (MARKER_CME & 0x00FF)) && (cp->buf[4] == 0x00FF)) failure = !cme_to_pre_marker(self,markers,cp); if (failure) self->failed_marker_translations++; }}/*****************************************************************************//* STATIC read_new_tilepart_header *//*****************************************************************************/static int read_new_tilepart_header(hpbit_stream_in_ref self) /* This function appends a record to the end of the `tileparts' list managed by `self', reads the tile-part's header, processes all markers and updates the `non_data_bytes_left' field in `self' to reflect the number of file bytes which may be read beyond the end of this new tile-part's data portion. If the last tile-part in the list has not yet been fully read (as determined by its `data_bytes_left' field), the function reads and buffers its contents first. Note that the function has no effect on the state of the `current_tilepart' pointer in `self'. If successful, the function returns 1. If no new tile-parts may be recovered from the codestream, the function returns 0. If a corrupted tile-part header is encountered (i.e. one whose SOT marker is corrupt or contains an out-of-order tile-part number or one which contains no terminating SOS marker), the function returns -1. */{ std_ushort delimiter; hpbit_tilepart_ptr tp, last_tp, scan; sot_marker sot; int byte_val, old_style_sot; for (last_tp=NULL, tp=self->tileparts; tp != NULL; tp=tp->next) last_tp = tp; if ((last_tp != NULL) && (last_tp->data_bytes_left > 0)) buffer_remaining_tilepart_bytes(self,last_tp); tp = (hpbit_tilepart_ptr) local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_tilepart)); byte_val = 0; if (!self->have_sot) { /* Make non-data accesses until the SOT marker is recovered. */ do { while (byte_val != 0x00FF) { byte_val = fetch_non_data_byte(self); if (byte_val == EOF) { destroy_tilepart(tp); return(0); } } if ((byte_val = fetch_non_data_byte(self)) == EOF) { destroy_tilepart(tp); return(0); } } while (byte_val != (MARKER_SOT & 0x00FF)); } self->have_sot = 0; /* We have consumed the marker code. */ /* Read the rest of the SOT marker. */ sot.SOT = MARKER_SOT; byte_val = fetch_non_data_byte(self); sot.Lsot = (std_ushort) byte_val; byte_val = fetch_non_data_byte(self); sot.Lsot = (sot.Lsot << 8) | ((std_ushort) byte_val); byte_val = fetch_non_data_byte(self); sot.Isot = (std_ushort) byte_val; byte_val = fetch_non_data_byte(self); sot.Isot = (sot.Isot << 8) | ((std_ushort) byte_val); byte_val = fetch_non_data_byte(self); sot.Psot = (std_uint) byte_val; byte_val = fetch_non_data_byte(self); sot.Psot = (sot.Psot << 8) | ((std_uint) byte_val); byte_val = fetch_non_data_byte(self); sot.Psot = (sot.Psot << 8) | ((std_uint) byte_val); byte_val = fetch_non_data_byte(self); sot.Psot = (sot.Psot << 8) | ((std_uint) byte_val); byte_val = fetch_non_data_byte(self); sot.TPsot = (std_byte) byte_val; old_style_sot = (sot.Lsot == 9)?1:0; if (!old_style_sot) { byte_val = fetch_non_data_byte(self); sot.NTPsot = (std_byte) byte_val; } if (byte_val == EOF) { destroy_tilepart(tp); return(0); } if (sot.Lsot != (10-old_style_sot)) { destroy_tilepart(tp); return(-1); } tp->tnum = (int)(sot.Isot); tp->tpart = (int) sot.TPsot; if (old_style_sot) tp->num_tileparts = INT_MAX; else tp->num_tileparts = (int) sot.NTPsot; /* Look for another tile-part from the same tile. */ for (last_tp=NULL, scan=self->tileparts; scan != NULL; scan=scan->next) if (scan->tnum == tp->tnum) last_tp = scan; if (last_tp != NULL) tp->num_tileparts = last_tp->num_tileparts; if (((last_tp == NULL) && (tp->tpart != 0)) || ((last_tp != NULL) && (tp->tpart != (last_tp->tpart+1))) || (tp->num_tileparts <= tp->tpart)) { destroy_tilepart(tp); return(-1); } tp->markers.total_codestream_bytes = 12; tp->last_part = last_tp; /* Read the remaining marker codes. */ delimiter = read_markers(self,tp); if (delimiter != MARKER_SOS) { destroy_tilepart(tp); if ((delimiter == 0) || (delimiter == MARKER_EOI)) return(0); return(-1); } tp->markers.total_codestream_bytes += 2; /* Include size of SOS marker. */ /* Append new tile-part to the list. We commit to returning 1 now. */ last_tp = self->tileparts; if (last_tp == NULL) self->tileparts = tp; else { while (last_tp->next != NULL) last_tp = last_tp->next; last_tp->next = tp; } /* Complete processing of new tile-part record. */ process_markers(self,tp); if (sot.Psot == 0) { tp->data_bytes = tp->data_bytes_left = INT_MAX; tp->actual_length_unknown = 1; } else tp->data_bytes = tp->data_bytes_left = (int)(sot.Psot) - tp->markers.total_codestream_bytes; if (self->byte_limit_set && (tp->data_bytes_left > self->non_data_bytes_left)) { if (self->non_data_bytes_left < 0) self->non_data_bytes_left = 0; tp->data_bytes_left = self->non_data_bytes_left; } self->non_data_bytes_left -= tp->data_bytes_left; /* Determine whether or not resync/EPH markers should be used. */ { /* Note: can't use the interface functions here since they access only tile-specific markers, not tile-part-specific markers. */ hpbit_pre_marker_ptr pm; hpbit_marker_elt_ptr elt; tp->resync = self->global_resync; tp->eph = self->global_eph; if (tp->last_part != NULL) tp->resync = tp->last_part->resync; for (pm=tp->markers.pre_markers; pm != NULL; pm=pm->next) if (pm->id == (MARKER_ERS & 0x00FF)) break; elt = NULL; if (pm != NULL) { for (elt=pm->elements; elt != NULL; elt=elt->next) if (elt->element_id == ELTID_ERS_SOP) break; if (elt != NULL) { assert(elt->size == 1); tp->resync = (int) elt->buf[0]; } for (elt=pm->elements; elt != NULL; elt=elt->next) if (elt->element_id == ELTID_ERS_EPH) break; if (elt != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -