⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 component_demix.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
          (((float) *comp_ptr[l])*xform_mat[k][l]);
      interm_ptr[k]++;
    }
    for(l=0;l<n_in;l++)
      comp_ptr[l]++;
      }
    }
    else if(seg.off_vector>0){
      /* Inverse decorrel matrix is identity */
      for(j=0;j<width;j++){
    for(k=0;k<n_out;k++)
      *(interm_ptr[k]++) = 
        ((float) *(comp_ptr[k]++))+offset_vec[k];
      }
    }
    else{ /* Decorrel offset is null */
      for(j=0;j<width;j++){
    for(k=0;k<n_out;k++)
      *(interm_ptr[k]++) = ((float) *(comp_ptr[k]++));
      }
    }
  }
  
  /* then do all of the dependency transforms putting the result back
     into the line buffers*/
  for(i=0;i<seg_collection->n_intermed_segments;i++){
    seg = seg_collection->intermed_segment[i];
    n_in = seg.n_input_components;
    for(j=0;j<n_in;j++)
      interm_ptr[j] = interm_components+seg.input_components[j]*width;
    n_out = seg.n_output_components;
    for(j=0;j<n_out;j++)
      comp_ptr[j] = buffers[seg.output_components[j]];
    xform_mat = transforms->depend_xfms[seg.xfm_matrix].matrix_values;
    offset_vec = transforms->depend_offs[seg.off_vector].vector_values;
    
    /* It is probably most efficient to deal with null transform matrices
       here by using 4 different pieces of code for the 4 possible cases,
       otherwise much time will be spent allocating and deallocating
       memory */
    
    if ((seg.xfm_matrix>0)&&(seg.off_vector>0)){
      for(j=0;j<width;j++){
    for(k=0;k<n_out;k++)
      *interm_ptr[k] += offset_vec[k];
    for(l=0;l<n_out;l++)
      for(k=l+1;k<n_out;k++)
        *interm_ptr[k] += (*interm_ptr[l]*xform_mat[k][l]);
    for(k=0;k<n_out;k++)
      *(comp_ptr[k]++) = (ifc_int)(*(interm_ptr[k]++)+0.5);
      }
    }
    else if((seg.xfm_matrix>0)&&(seg.off_vector==0)){
      for(j=0;j<width;j++){
    for(l=0;l<n_out;l++)
      for(k=l+1;k<n_out;k++)
        *interm_ptr[k] += (*interm_ptr[l]*xform_mat[k][l]);
    for(k=0;k<n_out;k++)
      *(comp_ptr[k]++) = (ifc_int)(*(interm_ptr[k]++)+0.5);
      }
    }
    else if (seg.off_vector > 0){
      /* Inverse dependency transform is null */
      for(j=0;j<width;j++) 
    for(k=0;k<n_out;k++)
      *(comp_ptr[k]++) =
        (ifc_int) (*(interm_ptr[k]++)+offset_vec[k]+0.5);
    }
    else{ /* Dependency offset is null also */
      for(j=0;j<width;j++)
    for(k=0;k<n_out;k++)
      *(comp_ptr[k]++) = (ifc_int) (*(interm_ptr[k]++)+0.5);
    }
  }
  
  /* free up the allocated space */
  local_free(comp_ptr);
  local_free(interm_ptr);
  local_free(interm_components);
}

/*****************************************************************************/
/* STATIC                        destroy_transfoms                           */
/*****************************************************************************/
static void destroy_transforms(the_component_demix_ref self)
{
  int i;
  
  /* Assumes that all matrix data values are obtained indirectly from the
     get_marker_val_indirect routine. Therefore, freeing the memory location
     here causes it to be lost for good. (so don't) */
  if(self->transforms == NULL)
    return;
  
  if (self->transforms->decorrel_xfms != NULL) {
    for(i=1;i<=self->transforms->n_decorrel_xfm;i++)
      local_free(self->transforms->decorrel_xfms[i].matrix_values);
    local_free(self->transforms->decorrel_xfms);
  }
  
  if (self->transforms->depend_xfms != NULL) {
    for(i=1;i<=self->transforms->n_depend_xfm;i++)
      local_free(self->transforms->depend_xfms[i].matrix_values);
    local_free(self->transforms->depend_xfms);
  }
  
  if (self->transforms->decorrel_offs != NULL)
    local_free(self->transforms->decorrel_offs);
  
  if (self->transforms->depend_offs != NULL)
    local_free(self->transforms->depend_offs);
  
  local_free(self->transforms);
  self->transforms = NULL;
}

/*****************************************************************************/
/* STATIC                       destroy_collections                          */
/*****************************************************************************/
static void destroy_collections(the_component_demix_ref self)
{
  collection_ref cptr;
  
  /* Assumes that the component indices are obtained indirectly through
     get_marker_val_indirect. Therefore, freeing the memory here would lose
     the component lists for good. (so don't) */
  
  cptr = self->tile_collection;
  if (cptr == NULL)
    return;
  
  if (cptr->comp_segment != NULL)
    local_free(cptr->comp_segment);
  
  if (cptr->intermed_segment != NULL)
    local_free(cptr->intermed_segment);
  
  local_free(cptr);
  
  self->tile_collection = NULL;
}

/*****************************************************************************/
/* STATIC                    fill_collection_and_matrix                      */
/*****************************************************************************/
static void fill_collection_and_matrix(the_component_demix_ref self)
{
    /* This sets up the component collection structure for the tile. Also
       sets up the component transforms structure that is needed given the
       matrices accessed in the tile. Puts the collection directly into the
       tile_collection field of self. It is possible that no changes are
       required to this routine to permit MCT,MIC,or MCCs to appear in tile
       part headers. However, the marker construction and decoding routines
       currently prohibit this. Transform usage by a tile is signalled by
       an invalid field in the COD marker. This must be changed. */

    stream_in_ref stream = self->stream;
    int tix = self->current_tile_idx,tnum,index=0,instance=0,nseg;
    int *iptr,*optr,i,ixnum,maxmat,maxoff,intot,outtot,j,nin,nout;
    collection_ref cptr;
    component_xfms_ref tptr;
    segment sptr;
    matrix_data mptr;
    vector_data vptr;
    float *memptr;

    /* the only way index is non-zero is if this MCC is in a tile-part 
       header and is referencing one in the main. Therefore, if the index is
       non-zero, then reference that instance in the main header. */
    /* The default collection (index = 0) will always have an instance of */
    /* zero. If there are more than one set of component collections in the */
    /* main header, then those that are not the default will have instance */
    /* values other than zero. The reference to these collections that */
    /* must occur in a tile-part header will have a zero instance and the */
    /* index found in the tile-part header version of the marker contains */
    /* the instance of the needed marker segment from the main header. */
    /* Perfectly clear, right? */

    index = stream->get_marker_val(stream,tix,MARKER_MCC_IX,0,0);
    if(index>0){ 
        instance = index;
        tnum = -1;
    }
    else
        tnum = tix;

    /* The following line pulls the number of entries in the array which */
    /* stores the number of decorrelation inputs for each component collection. */
    /* The function mcc_to_pre_marker in hpbit_stream_in.c creates this array */
    /* and there will be one of these parameters for each collection. Thus */
    /* if we know the size of the array, we know how many decorrelation */
    /* component collections there are. */
    nseg = stream->size_marker_elt(stream,tnum,MARKER_MCC_NMCN,instance);

    cptr = (collection_ref) local_malloc(MIXING_MEM_KEY,sizeof(collection));
    cptr->n_comp_segments = nseg;
    cptr->comp_segment = 
        (segment_ref) local_malloc(MIXING_MEM_KEY,nseg*sizeof(segment));
    
    /* Now we get pointers to the input and output decorrelation component */
    /* collection lists. The component lists for all input or output */
    /* collections are stored contiguously in an array. The following */
    /* loop fills out the segment structure information for the */
    /* decorrelation transforms. */
    iptr = (int *) stream->get_marker_val_indirect(stream,tnum,
        MARKER_MCC_CMC,instance);   /* Get pointer to start of input list */
    optr = (int *) stream->get_marker_val_indirect(stream,tnum,
        MARKER_MCC_WMC,instance);   /* Get pointer to start of output list */

    for(i=0,maxoff=-1,maxmat=-1,intot=0,outtot=0;i<nseg;i++){
        sptr.n_input_components=    /* Get number of inputs to collection i */
            stream->get_marker_val(stream,tnum,MARKER_MCC_NMCN,instance,i);
        sptr.n_output_components=   /* Get number of outputs to collection i */
            stream->get_marker_val(stream,tnum,MARKER_MCC_MMCN,instance,i);
        sptr.input_components=iptr+intot;   /* Make pointer into input list */
        sptr.output_components=optr+outtot; /* Make pointer into output list */
        intot+=sptr.n_input_components;     /* Increment pointer offsets for */
        outtot+=sptr.n_output_components;   /* next input & output collections */
        sptr.xfm_matrix = stream->get_marker_val(stream,tnum,
            MARKER_MCC_TMCX,instance,i);    /* Get decorrel xfm matrix index */
        if ( sptr.xfm_matrix > maxmat )
            maxmat = sptr.xfm_matrix;
        sptr.off_vector = stream->get_marker_val(stream,tnum,
            MARKER_MCC_TMCO,instance,i);    /* Get decorrel offset matrix index */
        if ( sptr.off_vector > maxoff )
            maxoff = sptr.off_vector;
        cptr->comp_segment[i] = sptr;       /* Store the segment */
    }

    /* set up the decorrelation matrices now */
    tptr = (component_xfms_ref) local_malloc(MIXING_MEM_KEY,
                       sizeof(component_xfms));
    /* There is an implicit assumption here that the matrix indices */
    /* in the MCC marker are contiguous. This is not necessarily true. */
    /* To be robust, we should check for the number of unique indices. */
    /* This should be corrected in the future. Remember that a matrix */
    /* may be reused between two different collections, so you can't */
    /* rely on the number of component collections either. */
    tptr->n_decorrel_xfm = maxmat;
    tptr->n_decorrel_off = maxoff;
    
    tptr->decorrel_xfms = (matrix_data_ref) local_malloc(MIXING_MEM_KEY,
        sizeof(matrix_data)*(maxmat+1));/* The reason for the +1 is that the */
    for(i=0;i<=maxmat;i++)              /* index 0 is reserved NULL xfms */
        tptr->decorrel_xfms[i].matrix_values = NULL;
    tptr->decorrel_offs = (vector_data_ref) local_malloc(MIXING_MEM_KEY,
        sizeof(vector_data)*(maxoff+1));
    for(i=0;i<=maxoff;i++)
        tptr->decorrel_offs[i].vector_values = NULL;
    for(i=0;i<nseg;i++){    /* Loop over all decorrelation transforms */
        ixnum = cptr->comp_segment[i].xfm_matrix;
        if((ixnum>0)&&(tptr->decorrel_xfms[ixnum].matrix_values==NULL)){
            nin = cptr->comp_segment[i].n_input_components;
            nout = cptr->comp_segment[i].n_output_components;
            /* Remember that the transform matrix data is stored in a */
            /* vector along with the transform data for all xfms. */
            mptr.matrix_values = (float **)local_malloc(MIXING_MEM_KEY,
                nout*sizeof(float *));
            /* Original tile number is used to access matrices, since this
               ensures that if a MCT with proper index is present in the
               tile part header, it will override the one in main. */
            memptr = (float *) stream->get_marker_val_indirect(stream,tix,
                MARKER_MCT_SP,ixnum);
            for(j=0;j<nout;j++) /* Generate row pointers into the data */
                mptr.matrix_values[j]= memptr+nin*j;
            tptr->decorrel_xfms[ixnum]=mptr;
        }
        ixnum = cptr->comp_segment[i].off_vector;   /* Get the offset vector */
        /* A little explanation on the instance/index relationship... */
        /* A given binary matrix index, yyyy, where index is in [0,15], the */
        /* index is related to instance numbers for the various matrix types */
        /* by the following */
        /* */
        /* Decorrelation transform matrix :    xx00 yyyy */
        /* Dependency transform matrix    :    xx01 yyyy */
        /* Decorrelation offset matrix    :    xx10 yyyy */
        /* Dependency offset matrix       :    xx11 yyyy */
        /* */
        /* So below we look for instance ixnum+32, or yyyy + 100000 in binary. */
        /* Thus we are reading in a decorrelation offset matrix with index yyyy */
        if((ixnum>0)&&(tptr->decorrel_offs[ixnum].vector_values==NULL)){
            vptr.vector_values=(float *)stream->get_marker_val_indirect(stream,
                tix,MARKER_MCT_SP,ixnum+32);
            tptr->decorrel_offs[ixnum]=vptr;
        }
    }

    /* the only way index is non-zero is if this MIC is in a tile-part 
       header and is referencing one in the main. Therefore, if the index is
       non-zero, then reference that instance in the main header. */
    index = stream->get_marker_val(stream,tnum,MARKER_MIC_IX,0,0);
    if(index>0){
        instance = index;
        tnum = -1;
    }

    /* Time to work on the MIC marker segment. The pre-markers are read and */
    /* the segment information filled in, in much the same way as the MCC */
    /* marker segment. */
    nseg = stream->size_marker_elt(stream,tnum,MARKER_MIC_NMCN,instance);

    cptr->n_intermed_segments = nseg;
    cptr->intermed_segment = 
        (segment_ref) local_malloc(MIXING_MEM_KEY,nseg*sizeof(segment));

    iptr = (int *) stream->get_marker_val_indirect(stream,tnum,
        MARKER_MIC_CMC,instance);
    optr = (int *) stream->get_marker_val_indirect(stream,tnum,
        MARKER_MIC_WMC,instance);

    for(i=0,maxoff=-1,maxmat=-1,intot=0,outtot=0;i<nseg;i++){
        sptr.n_input_components=
            stream->get_marker_val(stream,tnum,MARKER_MIC_NMCN,instance,i);
        sptr.n_output_components=
            stream->get_marker_val(stream,tnum,MARKER_MIC_MMCN,instance,i);
        sptr.input_components = iptr + intot;
        sptr.output_components = optr + outtot;
        intot += sptr.n_input_components;
        outtot += sptr.n_output_components;
        sptr.xfm_matrix = stream->get_marker_val(stream,tnum,
            MARKER_MIC_TMCX,instance,i);
        if ( sptr.xfm_matrix > maxmat )
            maxmat = sptr.xfm_matrix;
        sptr.off_vector = stream->get_marker_val(stream,tnum,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -