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

📄 blocks.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************//*                         kd_block::read_body_bytes                         *//*****************************************************************************/void  kd_block::read_body_bytes(kd_input *source, kd_buf_server *buf_server){  int body_bytes = this->temp_length; this->temp_length = 0;  int xfer_bytes;  if (body_bytes == 0)    return;  if (num_passes == 255)    { // Read and discard the code-bytes.      assert(first_buf == NULL);      kd_code_buffer *tmp_buf = buf_server->get();      while ((body_bytes > 0) && !source->failed())        {          xfer_bytes = KD_CODE_BUFFER_LEN;          xfer_bytes = (body_bytes < xfer_bytes)?body_bytes:xfer_bytes;          source->read(tmp_buf->buf,xfer_bytes);          body_bytes -= xfer_bytes;        }      buf_server->release(tmp_buf);      return;    }  while (body_bytes > 0)    {      xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos;      if (xfer_bytes == 0)        {          current_buf = current_buf->next = buf_server->get();          buf_pos = 0;          xfer_bytes = KD_CODE_BUFFER_LEN;        }      xfer_bytes = (body_bytes < xfer_bytes)?body_bytes:xfer_bytes;      xfer_bytes = source->read(current_buf->buf+buf_pos,xfer_bytes);      if (xfer_bytes == 0)        break;      body_bytes -= xfer_bytes;      buf_pos += xfer_bytes;      this->num_bytes += xfer_bytes;    }}/*****************************************************************************//*                          kd_block::retrieve_data                          *//*****************************************************************************/void  kd_block::retrieve_data(kdu_block *block, int max_layers){  assert(num_passes < 255); // 255 has the special meaning: "discard block"  block->num_passes = 0; // We will increment this as we read them in.  block->missing_msbs = msbs_w;  if (beta == 0)    return;  if ((num_bytes+2) > block->max_bytes)    block->set_max_bytes(((int) num_bytes)+4096,false); // A generous allocation  if (num_passes > block->max_passes)    block->set_max_passes(((int) num_passes)+32,false); // A generous allocation  int remaining_bytes = num_bytes;  kdu_byte *bp = block->byte_buffer;  current_buf = first_buf;  buf_pos = 0;  for (pass_idx=0; pass_idx < num_passes; )    {      // Get the layer index for the next contribution.      int layer_idx = get_byte();      layer_idx = (layer_idx<<8) + get_byte();      if (layer_idx >= max_layers)        break;      int new_passes, new_bytes;      kdu_byte idx = pass_idx;      bool more_headers=true;      assert(block->num_passes == (int) pass_idx);      while (more_headers)        {          new_bytes = get_byte();          new_bytes = (new_bytes << 8) + get_byte();          new_passes = get_byte();          more_headers = false;          if (new_bytes & (1<<15))            {              more_headers = true;              new_bytes &= ~(1<<15);            }          for (; new_passes > 0; new_passes--, new_bytes=0, idx++)            {              block->pass_lengths[idx] = new_bytes;              block->pass_slopes[idx] = 0;            }          assert(idx <= num_passes);        }      assert(idx > 0);      block->pass_slopes[idx-1] = ((1<<16)-1) - layer_idx;      for (; pass_idx < idx; pass_idx++)        {          new_bytes = block->pass_lengths[pass_idx];          if (new_bytes > remaining_bytes)            return;          block->num_passes = pass_idx+1;          remaining_bytes -= new_bytes;          while (new_bytes > 0)            {              int xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos;              if (xfer_bytes == 0)                {                  current_buf = current_buf->next;                  buf_pos = 0;                  assert(current_buf != NULL);                  xfer_bytes = KD_CODE_BUFFER_LEN;                }              xfer_bytes = (xfer_bytes < new_bytes)?xfer_bytes:new_bytes;              new_bytes -= xfer_bytes;              while (xfer_bytes--)                *(bp++) = current_buf->buf[buf_pos++];            }        }    }}/*****************************************************************************//*                           kd_block::store_data                            *//*****************************************************************************/void  kd_block::store_data(kdu_block *block, kd_buf_server *buf_server){  assert(block->modes == (int) modes);  assert(block->missing_msbs < 255);  assert(block->num_passes <= 255);  assert(first_buf == NULL);  // Now copy the coding pass summary information.  int n, val, total_bytes;  msbs_w = (kdu_byte) block->missing_msbs;  start_buffering(buf_server);  num_passes = (kdu_byte) block->num_passes;  total_bytes = 0;  for (n=0; n < block->num_passes; n++)    {      val = block->pass_slopes[n];      assert(val >= 0);      put_byte((kdu_byte)(val>>8),buf_server);      put_byte((kdu_byte) val,buf_server);      val = block->pass_lengths[n];      assert((val >= 0) && (val < (1<<16)));      total_bytes += val;      put_byte((kdu_byte)(val>>8),buf_server);      put_byte((kdu_byte) val,buf_server);    }  assert(total_bytes <= block->max_bytes);  // Finally, copy the code-bytes.  kdu_byte *bp = block->byte_buffer;  while (total_bytes > 0)    {      int xfer_bytes = KD_CODE_BUFFER_LEN - buf_pos;      if (xfer_bytes == 0)        {          current_buf = current_buf->next = buf_server->get();          buf_pos = 0;          xfer_bytes = KD_CODE_BUFFER_LEN;        }      xfer_bytes = (xfer_bytes < total_bytes)?xfer_bytes:total_bytes;      total_bytes -= xfer_bytes;      while (xfer_bytes--)        current_buf->buf[buf_pos++] = *(bp++);    }  current_buf = first_buf;  buf_pos = 0;}/*****************************************************************************//*                           kd_block::trim_data                             *//*****************************************************************************/bool  kd_block::trim_data(kdu_uint16 slope_threshold, kd_buf_server *buf_server){  if (num_passes == 0)    return false;  // Find the number of passes we can keep.  int n;  int potential_body_bytes = 0;  int max_body_bytes = 0;  int max_passes = 0;  kd_code_buffer *save_current_buf = current_buf;  kdu_byte save_buf_pos = buf_pos;  current_buf = first_buf;  buf_pos = 0;  for (n=0; n < num_passes; n++)    {      kdu_uint16 slope = get_byte();      slope = (slope<<8) + get_byte();      if ((slope != 0) && (slope <= slope_threshold))        break; // Need to discard this one.      kdu_uint16 length = get_byte();      length = (length<<8) + get_byte();      potential_body_bytes += length;      if (slope != 0)        {          max_body_bytes = potential_body_bytes;          max_passes = n+1;        }    }  // Restore the counters.  current_buf = save_current_buf;  buf_pos = save_buf_pos;  // Now go back through the data setting additional pass slopes to 0.     /* Notice that we do not change `num_passes' for that would prevent        us from later locating the body bytes. */  if (n == num_passes)    return false;  kd_code_buffer *buf_ptr = first_buf;  int pos = max_passes << 2;  while (pos > KD_CODE_BUFFER_LEN)    { buf_ptr = buf_ptr->next; pos -= KD_CODE_BUFFER_LEN; }  n = (num_passes-max_passes)<<2; // Number of bytes to set to 0  while (n--)    {      if (pos == KD_CODE_BUFFER_LEN)        { buf_ptr = buf_ptr->next; pos = 0; }      buf_ptr->buf[pos++] = 0;    }  // Now remove the unwanted body bytes.  buf_ptr = first_buf;  pos = (num_passes<<2) + max_body_bytes;  while (pos > KD_CODE_BUFFER_LEN)    { buf_ptr = buf_ptr->next; pos -= KD_CODE_BUFFER_LEN; }  kd_code_buffer *tmp;  while ((tmp=buf_ptr->next) != NULL)    {      buf_ptr->next = tmp->next;      buf_server->release(tmp);    }  return true;}/*****************************************************************************//*                          kd_block::start_packet                           *//*****************************************************************************/int  kd_block::start_packet(int layer_idx, kdu_uint16 slope_threshold){  if (layer_idx == 0)    {      pass_idx = 0;      current_buf = first_buf;      buf_pos = 0;      layer_w = 0xFFFF;      if (num_passes == 0)        msbs_w = 0xFF; /* We will never include this block.  Make sure its                          `msbs_w' value does not damage the efficiency with                          with the neighbouring blocks are represented. */      // Reflect `msbs_w' value into higher nodes in the tag tree.      for (kd_block *scan=this->up_down; scan != NULL; scan=scan->up_down)        if (scan->msbs_w > msbs_w)          scan->msbs_w = msbs_w;        else          break; // No point in going further up the tree.    }  // Find number of new passes.  pending_new_passes = 0;  temp_length = 0;  if (pass_idx == num_passes)    {      layer_w = 0xFFFF; // `save_beta' may have been reset by `save_output_tree      return 0;    }  kd_code_buffer *save_current_buf = current_buf;  kdu_byte save_buf_pos = buf_pos;  int test_length = 0;  int test_passes = 0;  for (int n=(num_passes-pass_idx); n > 0; n--)    {      kdu_uint16 slope = get_byte();      slope = (slope<<8) + get_byte();      if ((slope != 0) && (slope <= slope_threshold))        break;      kdu_uint16 length = get_byte();      length = (length<<8) + get_byte();      test_passes++;      test_length += length;      if (slope != 0)        {          pending_new_passes = test_passes;          assert(test_length < (1<<16));          temp_length = (kdu_uint16) test_length;        }    }  current_buf = save_current_buf;  buf_pos = save_buf_pos;  // See if we need to update tag tree nodes.  if (pass_idx == 0)    {      if (pending_new_passes)        {          layer_w  = (kdu_uint16) layer_idx;          for (kd_block *scan=up_down; scan != NULL; scan=scan->up_down)            if (scan->layer_w > layer_w)              scan->layer_w = layer_w;            else              break; // No point in going further up the tree.        }      else        layer_w = 0xFFFF;    }  return temp_length;}/*****************************************************************************//*                       kd_block::write_packet_header                       *//*****************************************************************************/void  kd_block::write_packet_header(kd_header_out &head, int layer_idx,                                 bool simulate){  // Process inclusion information first  bool included = (pending_new_passes > 0);  if (pass_idx == 0)    { // First time inclusion.      assert((included && (layer_w < 0xFFFF)) ||             ((!included) && (layer_w == 0xFFFF)));      kdu_byte save_new_passes=pending_new_passes; // Shares layer_wbar storage      layer_wbar = (kdu_uint16) layer_idx;      kd_block *scan, *prev, *next;      // Walk up to the root node in the tree.      scan=this; prev=NULL;      while ((next=scan->up_down) != NULL)        { scan->up_down=prev; prev=scan; scan=next; }      scan->up_down = prev;      // Walk back down the tree, performing the encoding steps.      kdu_uint16 wbar_min = 0;      kdu_uint16 threshold = layer_wbar+1;      prev = NULL;      while (scan != NULL)        {          if (scan->layer_wbar < wbar_min)            scan->layer_wbar = wbar_min;          while ((scan->layer_w >= scan->layer_wbar) &&                 (scan->layer_wbar < threshold))            {              scan->layer_wbar++;              head.put_bit((scan->layer_w >= scan->layer_wbar)?0:1);            }          wbar_min =            (scan->layer_w<scan->layer_wbar)?scan->layer_w:scan->layer_wbar;          next=scan->up_down; scan->up_down=prev; prev=scan; scan=next;        }      pending_new_passes = save_new_passes; // Finished using layer_wbar now    }  else

⌨️ 快捷键说明

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