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

📄 hpbit_stream_out.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}

/*****************************************************************************/
/* STATIC                 get_tile_component_bands                           */
/*****************************************************************************/

static int
  get_tile_component_bands(hpbit_stream_out_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                 translate_cod_coc_markers                          */
/*****************************************************************************/

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_ppx, cod_ppy, coc_ppx, coc_ppy;
  cod_marker cod;
  coc_marker coc;
  std_byte *buf, *bp, ppxy;
  int length, i;
  int valid;
  cod_ppx = NULL;
  cod_ppy = NULL; 
  coc_ppx = NULL;
  coc_ppy = NULL; 
  /* 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;
          case ELTID_COD_SOP:
            valid = (elt->size <= 1); break;
          case ELTID_COD_EPH:
            valid = (elt->size <= 1); break;
          case ELTID_COD_CXFORM:
            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:
            valid = (elt->size == 1); break;
          case ELTID_COC_XCB:
            valid = (elt->size == 1); break;
          case ELTID_COC_YCB:
            valid = (elt->size == 1); break;
          case ELTID_COC_MOD:
            valid = (elt->size == 1); break;
          case ELTID_COC_REV:
            valid = (elt->size == 1); break;
          case ELTID_COC_PPX:
            valid = 1; break;
          case ELTID_COC_PPY:
            valid = 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;
          case ELTID_COD_SOP:
            if (elt->size && elt->buf[0])
              cod.Scod |= 2;
            else
              cod.Scod &= ~2;
            break;
          case ELTID_COD_EPH:
            if (elt->size && elt->buf[0])
              cod.Scod |= 4;
            else
              cod.Scod &= ~4;
            break;
          case ELTID_COD_CXFORM:
            if (elt->size) {
              cod.cxform = (std_byte)(elt->buf[0]);
              if(cod.cxform == 2) cod.cxform = 1;
            }
            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)) {
        memset(&coc,0,sizeof(coc_marker));
        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 == cod.level + 1); 
            cod_ppx = elt; break;
          case ELTID_COC_PPY:
            cod.Scod |= 1;
            valid = (elt->size == cod.level + 1); 
            cod_ppy = elt; break;
          default: valid = 0;
            local_printf(5,72,"Got COC %d don't understand it",elt->element_id);
          }

        length = 14;
        if (cod.Scod & 1)
          length += (cod.level + 1);
        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.prog;
        copy_to_big_endian(&(cod.layers),bp,1,2); bp += 1*2;
        *(bp++) = cod.cxform;
        *(bp++) = cod.level;
        *(bp++) = cod.xcb;
        *(bp++) = cod.ycb;
        *(bp++) = cod.mod;
        *(bp++) = cod.rev;
        if (cod.Scod & 1) {
           for(i=0;i<cod.level + 1;i++){
              ppxy = (std_byte) (cod_ppy->buf[i] << 4);  
              ppxy |= (std_byte) (cod_ppx->buf[i] & 0x0f);  
              *(bp++) = (std_byte) ppxy;  
            }
        }
        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 == coc.level + 1); 
            coc_ppx = elt; break;
          case ELTID_COC_PPY:
            coc.Scoc |= 1;
            valid = (elt->size == coc.level + 1); 
            coc_ppy = elt; 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_ppx != NULL) && (coc_ppx != cod_ppx)) || /* Ricoh PPX bug fix */
             ((coc_ppy != NULL) && (coc_ppy != cod_ppy)) || /* Ricoh PPY bug fix */
             ((coc.Scoc&1) != (cod.Scod&1)) ) 
          {
            length = 11;
            if (coc.Scoc & 1 )   /* packet partition */
              length += coc.level + 1; /* Ricoh PPX/PPY bug fix */
            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);  /* J. Kasner fix w/ () */
              }
            *(bp++) = (std_byte) (coc.Ccoc & 0xff);  /* J. Kasner fix w/ () */

            *(bp++) = coc.Scoc;
            *(bp++) = coc.level;
            *(bp++) = coc.xcb;
            *(bp++) = coc.ycb;
            *(bp++) = coc.mod;
            *(bp++) = coc.rev;

            if (coc.Scoc & 1) {
                for(i=0;i<coc.level+1;i++){ /* Ricoh PPX/PPY bug fix */
                    ppxy = (std_byte) (coc_ppy->buf[i] << 4);  
                    ppxy |= (std_byte) (coc_ppx->buf[i] & 0x0f);  
                    *(bp++) = (std_byte) ppxy;  
                }
            }

            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;

  /* J. Kasner fix #components > 256 fix */
  int short_components;
  short_components = (markers->params.num_components >= 256)? 1:0;

  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;

⌨️ 快捷键说明

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