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

📄 ebcot_encoder.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
          significant = (master->block_mag >> master->bit_idx) & 1;
          if (significant)
            { /* Significant for the first time. */
              master->first_bit_idx = master->bit_idx;
              mark_termination_points(info->passes,info->insignificant_msbs,
                                      info->max_passes,
                                      master->terminate_each_pass,
                                      master->full_effort_msbs);
            }
        }
      if (!significant)
        info->insignificant_msbs++;
      for (n=0; n < PASSES_PER_BITPLANE; n++, pass_idx++)
        {
          block_coding_pass_func pass_function;

          if (pass_idx == info->max_passes)
            { bitplane_idx = last_bitplane; break; }

          if (pass_idx == first_lossless_pass)
            { /* Switch to MSE LUT's which correctly estimate distortion
                 reduction when processing the LSB of a lossless sample
                 value representation. */
              master->initial_mse_lut = ebcot_lossless_initial_mse_lut;
              master->refinement_mse_lut = ebcot_lossless_refinement_mse_lut;
            }
          if (significant)
            {
              pass_function = band->pass_funcs[n];
              if (master->reset)
                dst_arith_coder__model_init(&(master->coder_state),
                                            initial_mq_contexts);
              /* Begin David T Cvis mod */
              for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap)
                for (i=cells_wide; i--; cell++)
                  cell->delta_mse = 0;
              pass_function(master);
              for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap)
                for (i=cells_wide; i--; cell++)
                  {
                    double wmse_inc;

                    wmse_inc = (double)(cell->delta_mse);

                    wmse_inc *= scale_wmse;
                    if (n == 0)
                      wmse_inc *= 4.0;
                    wmse_inc *= cell->visibility_factor;
                    delta_wmse += wmse_inc;
                  }
              /* End David T Cvis mod */
              if (master->segmark && (n==0))
                insert_segment_marker(master);
              master->saved_states[pass_idx] = master->coder_state;
              if (info->passes[pass_idx].terminated)
                info->passes[pass_idx].cumulative_bytes =
                  dst_arith_coder__deactivate(&(master->coder_state),
                                              master->easy_termination);
            }
          else
            info->passes[pass_idx].cumulative_bytes = 0;
          master->cumulative_wmse[pass_idx] = delta_wmse;
        }
    }
  dst_arith_coder__flush(&(master->coder_state));
#ifdef DST_LOG_SYMBOLS
  fclose(master->coder_state.symbol_log);
  master->coder_state.symbol_log = NULL;
#endif /* DST_LOG_SYMBOLS */

  /* Update state information in `info' and `band' to reflect operations. */
  
  info->first_unit = heap;
  info->first_pos = heap_pos;
  last_bytes = 0;
  last_terminated_bytes = 0;
  for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++)
    if (info->passes[n].terminated)
      break;
  if (n < pass_idx)
    next_terminated_bytes = info->passes[n].cumulative_bytes;
  for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++)
    {
      if (!info->passes[n].terminated)
        {
          info->passes[n].cumulative_bytes =
            dst_arith_coder__get_minimum_bytes(master->saved_states+n,
                                               heap,heap_pos,
                                               last_terminated_bytes,
                                               next_terminated_bytes);
        }
      else
        {
          int m;

          assert(next_terminated_bytes ==
                 (int) info->passes[n].cumulative_bytes);
          last_terminated_bytes = next_terminated_bytes;
          for (m=n+1; m < pass_idx; m++)
            if (info->passes[m].terminated)
              {
                next_terminated_bytes = info->passes[m].cumulative_bytes;
                break;
              }
        }
      assert(last_bytes <= info->passes[n].cumulative_bytes);
      last_bytes = info->passes[n].cumulative_bytes;
    }
  assert(last_bytes <= (master->coder_state.saved_words<<2));
  compute_rd_slopes(pass_idx,master->cumulative_wmse,
                    info->passes,self->rd_slope_rates);

  /* SAIC TCQ begin */  /* Force last three bit-planes to be included at same time */
  if (master->include_all_passes && (pass_idx > 2) && significant) {
    info->passes[pass_idx-2].rd_slope = -1;
    info->passes[pass_idx-3].rd_slope = -1;
  }
  /* SAIC TCQ begin */

  /* SAIC TCQ begin mods */
  if (band->quant_to_zero) {
    for (n=0; n<pass_idx; n++) {
      info->passes[n].rd_slope = -1;
    }
  }
  else if ((band->lossless || master->include_all_passes) && (pass_idx > 0) &&
      (info->passes[pass_idx-1].rd_slope <= 0) &&
      significant)        /* Force inclusion of all bitplane passes */
    { /* Must include all significant coding passes in lossless mode to
         comply with the JPEG2000 standard, even if the last pass is
         not required to achieve 0 distortion under the assumption that the
         dequantizer will round to the midpoint of the quantization
         thresholds.  This requirement is introduced to avoid dependence on
         the dequantizer's rounding strategy. */
      info->passes[pass_idx-1].rd_slope = 1; /* Least desirable legal slope. */
      /* Now make sure we have not violated the requirement that slopes
         for points on the convex hull be strictly decreasing and have
         strictly increasing lengths. */
      for (n=pass_idx-2; n >= 0; n--)
        if (info->passes[n].rd_slope > 0)
          { /* Otherwise not on the convex hull. */
            if ((info->passes[n].rd_slope == 1) ||
                (info->passes[n].cumulative_bytes ==
                 info->passes[pass_idx-1].cumulative_bytes))
              {
                info->passes[pass_idx-1].rd_slope = info->passes[n].rd_slope;
                info->passes[n].rd_slope = 0;
              }
            break;
          }
    }
  /* SAIC TCQ end mods */

  for (; pass_idx < info->max_passes; pass_idx++)
    {
      info->passes[pass_idx].cumulative_bytes = last_bytes;
      info->passes[pass_idx].rd_slope = -1;
    }
  band->heap_tail = master->coder_state.heap;
  band->next_heap_pos = master->coder_state.next_heap_pos;

  /* CRIL Technology/SAIC Scan Buffer begin */
  info->next_unit = master->coder_state.heap;
  info->next_unit_used = master->coder_state.next_heap_pos;
  /* CRIL Technology/SAIC Scan Buffer end */

  /* End of timed section. */

  if (self->cpu_time >= 0)
    self->cpu_time += (std_int)(clock()-cpu_time);

  /* See if code word byte order needs to be reversed. */

  msb_first = 1; *((std_byte *)(&msb_first)) = 0;
  if (!msb_first)
    { /* Least significant byte appears first in each code word.  Need to
         reverse this to allow the word buffers to be written out as byte
         buffers later when we generate the bit-stream. */
      std_int word, *wp;
      int heap_remnant;

      wp = heap->words + heap_pos;
      heap_remnant = DST_HEAP_WORDS - heap_pos;
      assert(heap_remnant > 0);
      for (n=master->coder_state.saved_words; n > 0; n--)
        {
          word = *wp;
          word = ((word >> 24) & 0x000000FF) | ((word >>  8) & 0x0000FF00) |
                 ((word <<  8) & 0x00FF0000) | ((word << 24) & 0xFF000000);
          *(wp++) = word;
          if ((--heap_remnant) == 0)
            { heap_remnant = DST_HEAP_WORDS; heap=heap->next; wp=heap->words; }
        }
    }
}


/* ========================================================================= */
/* ---------------------- Layer Construction Functions --------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                      get_layer_specs                               */
/*****************************************************************************/

static void
  get_layer_specs(ebcot_encoder_ref self, cmdl_ref cmdl,
                  int max_bytes, int rows, int cols)

 /* This function determines the total number of bit-stream layers, based
    on information supplied via the `-Clayers' argument, if any, and uses
    this information to construct an initial `layer_info' array for the
    object referenced by `self'.  The contents of this array may change
    and the number of layers may be reduced when the
    `complete_quality_layers' function is called.
    For the moment, the `max_cumulative_bytes' field of each
    `ebcot_layer_info' record will be set to the total number of bytes
    for the entire code-stream which should be devoted to the relevant layer,
    plus all previous layers and the global header itself.  During the call
    to `complete_quality_layers', the global header size
    will be subtracted from the `max_cumulative_bytes' field of each
    `ebcot_layer_info' record. */

{
  double rate;
  char **params;
  int p, extra_layers, n, last_max_bytes;

  self->num_layers = 1;
  self->layer_info = (ebcot_layer_info_ptr)
    local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_layer_info)*2);
  if ((p = cmdl->extract(cmdl,"-Clayers",-1,&params)) < 0)
    { /* Install only one layer. */
      self->layer_info->max_cumulative_bytes = max_bytes;
      self->layer_info->actual_cumulative_bytes = 0;
      self->layer_info->optimize = 1;
      self->layer_info->rd_threshold = 0;
      return;
    }
  if (p == 0)
    { /* Install default SNR scalable rate specs. */
      self->num_layers = 60;
      self->layer_info = (ebcot_layer_info_ptr)
        local_realloc(self->layer_info,
                      sizeof(ebcot_layer_info)*self->num_layers);
      memset(self->layer_info,0,
             sizeof(ebcot_layer_info)*(size_t)(self->num_layers));
      rate = 0.015;
      self->layer_info[0].max_cumulative_bytes = (int)
        (rate * 0.125 * (double)(rows*cols));
      self->layer_info[0].optimize = 1;
      rate = 2.0;
      self->layer_info[49].max_cumulative_bytes = (int)
        (rate * 0.125 * (double)(rows*cols));
      self->layer_info[49].optimize = 1;
    }
  else
    {
      if ((sscanf(*params,"%lf",&rate) == 0) || (rate <= 0.0))
        local_error("The `-Clayers' argument must have zero or more "
                    "specification blocks, each starting with a valid "
                    "positive bit-rate parameter; found \"%s\" instead!",
                    *params);
      params++; p--;
      last_max_bytes = 0; n = 0;
      do {
        extra_layers = 0;
        if ((p > 0) && ((*params)[0] == '+'))
          {
            if ((sscanf((*params)+1,"%d",&extra_layers)==0) ||
                (extra_layers < 0))
              local_error("The `-Clayers' argument contains an "
                          "incorrectly formatted parameter identifying "
                          "extra bit-stream layers!");
            params++; p--;
          }
        self->num_layers += 1 + extra_layers;
        self->layer_info = (ebcot_layer_info_ptr)
          local_realloc(self->layer_info,
                        sizeof(ebcot_layer_info)*self->num_layers);
        self->layer_info[n].max_cumulative_bytes = (int)
          (rate * 0.125 * (double)(rows*cols));
        if (self->layer_info[n].max_cumulative_bytes <= 0)
          self->layer_info[n].max_cumulative_bytes = 1; /* Keep it legal. */
        if (last_max_bytes >= self->layer_info[n].max_cumulative_bytes)
          local_error("The bit-rates supplied to `-Clayers' must appear "
                      "in increasing order!");
        last_max_bytes = self->layer_info[n].max_cumulative_bytes;
        self->layer_info[n].actual_cumulative_bytes = 0;
        self->layer_info[n].optimize = 1;
        self->layer_info[n].rd_threshold = 0;
        n++;
        for (; extra_layers > 0; extra_layers--, n++)
          {
            self->layer_info[n].max_cumulative_bytes = 0;
              /* Fill in true value in `complete_bit_stream_layers'. */
            self->layer_info[n].actual_cumulative_bytes = 0;
            self->layer_info[n].optimize = 0;
            self->layer_info[n].rd_threshold = 0;
          }
      } while (((p--) > 0) && (sscanf(*(params++),"%lf",&rate) == 1));
    }

  n = self->num_layers - 1;
  self->layer_info[n].max_cumulative_bytes = max_bytes;
  self->layer_info[n].actual_cumulative_bytes = 0;
  self->layer_info[n].optimize = 1;
  self->layer_info[n].rd_threshold = 0;
}

/*****************************************************************************/
/* STATIC                   complete_quality_layers                          */

⌨️ 快捷键说明

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