📄 hpbit_stream_out.c
字号:
pre_marker_to_mic(hpbit_stream_out_ref self, hpbit_markers_ptr markers,
hpbit_pre_marker_ptr pm)
{
std_byte *bp, *buf, index;
hpbit_marker_elt_ptr elt,cmc_nullme,wmc_nullme;
long int length;
int valid, nseg=-1, i, cmc_copied, wmc_copied;
std_ushort sh;
std_uint *nmcs,*nmcn,*mmcs,*mmcn,*tmcx,*tmco,*cmc,*wmc,*ilptr,*olptr,j;
/* std_uint **cmc_nullme,**wmc_nullme; */
/* for the moment, the MCC is required in the main header. This eliminates
a difficulty that will occur in reading the marker from a tile-part
header. Also, this routine will not properly construct the MCC
marker if its index (instance) is non-zero and it appears in a tile-part
header. FOr a tile-part MCC, instance will be zero since there can
only be one. Index is always supplied.*/
if (markers != &(self->global_markers))
return;
valid = 1;
for(elt=pm->elements;(elt!=NULL)&&valid;elt=elt->next)
switch((char)(elt->element_id)){
case ELTID_MIC_IX:
valid = (elt->size==1);
index = (std_byte) elt->buf[0];
break;
case ELTID_MIC_NMCS:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
nmcs = elt->buf;
break;
case ELTID_MIC_NMCN:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
nmcn = elt->buf;
break;
case ELTID_MIC_MMCS:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
mmcs = elt->buf;
break;
case ELTID_MIC_MMCN:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
mmcn = elt->buf;
break;
case ELTID_MIC_TMCX:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
tmcx = elt->buf;
break;
case ELTID_MIC_TMCO:
nseg = (nseg<0)?elt->size:nseg;
valid = (elt->size==nseg);
tmco = elt->buf;
break;
case ELTID_MIC_CMC:
cmc = elt->buf;
cmc_nullme = elt;
cmc_copied = elt->copied_on_set;
break;
case ELTID_MIC_WMC:
wmc = elt->buf;
wmc_nullme = elt;
wmc_copied = elt->copied_on_set;
break;
default:
valid = 0;
}
if (!valid)
return;
length = 5 + 5 * nseg;
for( i=0; i<nseg; i++ ) {
length += ( nmcn[i] * (nmcs[i] + 1) );
length += ( mmcn[i] * (mmcs[i] + 1) );
}
bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,length+2);
sh = MARKER_MIC;
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
copy_to_big_endian(&length,bp,1,4); bp += 1*4;
*(bp++) = index;
for( i=0, ilptr=cmc, olptr=wmc; i<nseg; i++ ) {
sh = ((std_ushort) *(nmcs+i) &0x0003 << 14) |
((std_ushort) *(nmcn+i) & 0x3FFF);
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
for( j=0; j<*(nmcn+i); j++ )
if ( *(nmcs+i) == 0 )
*(bp++) = (std_byte) *(ilptr++);
else {
sh = (std_ushort) *(ilptr++);
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
}
sh = ((std_ushort) *(mmcs+i) &0x0003 << 14) |
((std_ushort) *(mmcn+i) & 0x3FFF);
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
for( j=0; j<*(mmcn+i); j++ )
if ( *(mmcs+i) == 0 )
*(bp++) = (std_byte) *(olptr++);
else {
sh = (std_ushort) *(olptr++);
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
}
*(bp++) = (((std_byte) *(tmco+i) & 0x0F) << 4) |
((std_byte) *(tmcx+i) & 0x0F);
}
assert(bp == (buf+length+2));
add_codestream_marker(markers,buf,length+2,pm->instance,1);
if(cmc_copied==1){
local_free(cmc);
cmc_nullme->buf = NULL;
}
if(wmc_copied==1){
local_free(wmc);
wmc_nullme->buf = NULL;
}
/* if (SPmct->copied_on_set) {
local_free(SPmct->buf);
SPmct->buf = NULL;
}*/
pm->translated = 1;
}
/*****************************************************************************/
/* STATIC pre_marker_to_cbd */
/*****************************************************************************/
static void
pre_marker_to_cbd(hpbit_stream_out_ref self, hpbit_markers_ptr markers,
hpbit_pre_marker_ptr pm)
{
std_byte *bp, *buf, byth, bytl;
hpbit_marker_elt_ptr elt,bd_nullme;
std_ushort length, num;
int valid, i, bd_copied, *bd, first_bd, allsame, num_in_marker;
std_ushort sh;
/* The CBD may only appear in the main header. */
/* Assumes that the bitdepths array pre-marker element was assigned
indirectly */
if (markers != &(self->global_markers))
return;
valid = 1;
for (elt=pm->elements; (elt != NULL) && valid; elt=elt->next)
switch ((char)(elt->element_id)) {
case ELTID_CBD_N:
valid = (elt->size == 1); num = (std_ushort) elt->buf[0]; break;
case ELTID_CBD_BD:
bd = (int *) elt->buf;
bd_nullme = elt;
bd_copied = elt->copied_on_set;
break;
default: valid = 0;
}
if (!valid)
return;
/* Determine # bds that will go into marker */
first_bd = bd[0];
allsame = 1;
i = 1;
while( (allsame) && (i < num) )
allsame = ( bd[i++] == first_bd );
num_in_marker = (allsame)?1:num;
/* fprintf(stderr,"allsame=%d num_in=%d, num=%d\n bd[2]=%d",allsame,num_in_marker,num,bd[2]); */
length = 4 + num_in_marker;
bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,length+2);
sh = MARKER_CBD;
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
copy_to_big_endian(&length,bp,1,2); bp += 1*2;
sh = ( ((std_ushort)allsame) << 15 ) | ( (num-1) & 0x7FFF );
copy_to_big_endian(&sh,bp,1,2); bp += 1*2;
for( i=0; i<num_in_marker; i++ ) {
byth = (std_byte) ((bd[i] < 0)?1:0);
bytl = (std_byte) ((bd[i] < 0)?(-1-bd[i]):bd[i]-1);
*(bp++) = (byth << 7) | (bytl & 0x3F);
}
assert(bp == (buf+length+2));
add_codestream_marker(markers,buf,length+2,pm->instance,1);
if(bd_copied==1){
local_free(bd);
bd_nullme->buf = NULL;
}
pm->translated = 1;
}
/* End Aerospace MCT mods */
/* SAIC/Sharp/Fuji Xmask begin */
/*****************************************************************************/
/* STATIC pre_marker_to_vms */
/*****************************************************************************/
static void
pre_marker_to_vms(hpbit_stream_out_ref self, hpbit_markers_ptr markers,
hpbit_pre_marker_ptr pm)
{
vms_marker vms;
std_byte *bp, *buf;
hpbit_marker_elt_ptr elt, Svms, Wvms, Rvms, Avms, Bvms;
int length, valid;
memset(&vms,0,sizeof(vms_marker));
Svms = Wvms = Rvms = Avms = Bvms = NULL;
valid = 1;
for (elt=pm->elements; (elt != NULL) && valid; elt=elt->next)
switch ((char)(elt->element_id)) {
case ELTID_VMS_S:
Svms = elt; break;
case ELTID_VMS_W:
Wvms = elt; break;
case ELTID_VMS_R:
Rvms = elt; break;
case ELTID_VMS_A:
Avms = elt; break;
case ELTID_VMS_B:
Bvms = elt; break;
default: valid = 0;
}
if (!valid)
return;
length = 9;
vms.VMS = MARKER_VMS;
vms.Lvms = length-2;
bp = buf = (std_byte *) local_malloc(HPBIT_MEM_KEY,length);
copy_to_big_endian(&(vms.VMS),bp,2,2); bp += 2*2;
if ((Svms == NULL) || (Wvms == NULL) ||
(Rvms == NULL) || (Avms == NULL) || (Bvms == NULL)) {
*(bp++) = (std_byte) 0;
*(bp++) = (std_byte) 0;
*(bp++) = (std_byte) 0;
*(bp++) = (std_byte) 0;
*(bp++) = (std_byte) 0;
}
else {
*(bp++) = (std_byte) Svms->buf[0];
*(bp++) = (std_byte) Wvms->buf[0];
*(bp++) = (std_byte) Rvms->buf[0];
*(bp++) = (std_byte) Avms->buf[0];
*(bp++) = (std_byte) Bvms->buf[0];
}
add_codestream_marker(markers,buf,length,pm->instance,0);
pm->translated = 1;
}
/* SAIC/Sharp/Fuji Xmask end */
/*****************************************************************************/
/* STATIC process_markers */
/*****************************************************************************/
static void
process_markers(hpbit_stream_out_ref self, hpbit_tile_ptr tile)
/* This function first verifies each of the elements in the pre-markers,
to make sure that all declared quantities have actually been set. It
then augments the pre-markers in individual tiles with any elements
which appeared in the global header, but not in the tile version.
It then constructs codestream markers from the pre-markers, updating
the `total_codestream_bytes' field and setting the `processed' field.
`tile' is NULL if the global header markers are being processed;
otherwise, it points to the tile whose markers are to be processed. */
{
hpbit_markers_ptr markers;
hpbit_pre_marker_ptr pm, gpm;
hpbit_marker_elt_ptr elt, gelt;
int n, tnum, c;
if (tile == NULL)
markers = &(self->global_markers);
else
markers = &(tile->markers);
if (markers->processed)
return;
/* First, check for incomplete elements. */
for (pm=markers->pre_markers; pm != NULL; pm = pm->next)
{
for (elt=pm->elements; elt != NULL; elt = elt->next)
{ /* Check marker element values correctly set. */
for (n=0; n < elt->size; n++)
if (elt->set_buf[n] == 0)
local_error("One or more declared marker element values not "
"set. Problem encountered in a marker element "
"with description, \"%s\"!",elt->description);
else if (elt->set_buf[n] > 1)
local_error("One or more declared marker element values set "
"multiple times. Problem encountered in a marker "
"element with description, \"%s\"!",
elt->description);
}
}
/* Link connected pre-markers. */
link_connected_pre_markers(markers);
/* Inherit pre-markers and elements from corresponding global pre-markers
as necessary */
if (tile != NULL)
{
/* Inherit entire pre-markers necessary. */
for (pm=markers->pre_markers; pm != NULL; pm = pm->next)
{
hpbit_pre_marker_ptr scan;
if ((pm->link_next == NULL) || (pm->link_prev != NULL))
continue;
/* Found the head of a connected list of pre-markers. Look for
a corresponding group in the global header. */
for (gpm=self->global_markers.pre_markers;
gpm != NULL; gpm = gpm->next)
if ((gpm->id == pm->id) &&
(gpm->instance == pm->instance))
break;
if (gpm == NULL)
continue;
while (gpm->link_prev != NULL)
gpm = gpm->link_prev;
/* Inherit any pre-marker from the global header's version of
this group which does not currently belong to the group in
the tile header. */
for (; gpm != NULL; gpm=gpm->link_next)
{
for (scan=pm; scan != NULL; scan=scan->link_next)
if ((scan->id == gpm->id) && (scan->instance == gpm->instance))
break;
if (scan == NULL)
{
scan = (hpbit_pre_marker_ptr)
local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_pre_marker));
scan->next = markers->pre_markers;
markers->pre_markers = scan;
scan->prev = NULL;
scan->next->prev = scan;
scan->id = gpm->id;
scan->instance = gpm->instance;
scan->link_next = pm;
pm->link_prev = scan;
}
}
}
/* Now inherit individual elements as necessary. */
for (pm=markers->pre_markers; pm != NULL; pm = pm->next)
{
for (gpm=self->global_markers.pre_markers;
gpm != NULL; gpm = gpm->next)
if ((gpm->id == pm->id) &&
(gpm->instance == pm->instance))
break;
if (gpm == NULL)
continue;
for (gelt=gpm->elements; gel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -