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

📄 region_decompressor.cpp

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  render_dims.pos = min;  render_dims.size = lim - min;  kdu_coords tmp_sampling = ref_comp->sampling;  tmp_sampling.x<<=1; tmp_sampling.y<<=1; // Measure offsets in half pels  kdu_coords ref_offset;  codestream.get_registration(ref_comp->comp_idx,tmp_sampling,ref_offset);  ref_offset.x -= 1-(ref_comp->sampling.x&1); // Even sub-sampling factors yield  ref_offset.y -= 1-(ref_comp->sampling.y&1); // sample positions effectively                               // displaced to the right (or down) by half a pel  for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++)    {      kdr_component *comp = components + c;      tmp_sampling = comp->sampling;      tmp_sampling.x<<=1; tmp_sampling.y<<=1; // Measure offsets in half pels      kdu_coords offset;      codestream.get_registration(comp->comp_idx,tmp_sampling,offset);      offset -= ref_offset; // Measure offsets relative to reference component      comp->interp.x = comp->dims.pos.x * comp->sampling.x - render_dims.pos.x        + 1 + ((comp->sampling.x+offset.x)>>1);      comp->interp.y = comp->dims.pos.y * comp->sampling.y - render_dims.pos.y        + 1 + ((comp->sampling.y+offset.y)>>1);      if ((c < 3) && use_ycc &&          ((comp->interp != components[0].interp) ||           (comp->sampling != components[0].sampling)))        { kdu_error e; e << "The code-stream incorrectly identifies the use "          "of a colour transform when the components have different "          "sub-sampling or alignment properties."; }    }  // Pre-create channel line buffers.  for (c=0; c < num_channels; c++)    channels[c].line.pre_create(&allocator,render_dims.size.x,false,true);  // Perform final resource allocation  allocator.finalize();  for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++)    components[c].line.create();  for (c=0; c < num_channels; c++)    channels[c].line.create();}/******************************************************************************//*                    kdr_region_decompressor::close_tile                     *//******************************************************************************/void  kdr_region_decompressor::close_tile(){  int c;  assert(tile_open);  tile_open = false;  current_tile.close();  for (c=0; c < 6; c++)    {      kdr_component *comp = components + c;      if (comp->engine.exists())        comp->engine.destroy();      comp->line.destroy(); // Works even if it was never pre-created    }  for (c=0; c < num_channels; c++)    channels[c].line.destroy();  allocator.restart(); // Get ready to use the allocator again in the next tile}/******************************************************************************//*                       kdr_region_decompressor::finish                      *//******************************************************************************/bool  kdr_region_decompressor::finish(){  bool success;  int c;  success = !codestream_failure;  if (success && tile_open)    {      try {        current_tile.close();        }      catch (int) // `kdu_error' can throw this exception from deep inside core        {          success = false;        }    }  tile_open = false;  codestream_failure = false;  // Cleanup any left over resources.  for (c=0; c < 6; c++)    {      kdr_component *comp = components + c;      if (comp->engine.exists())        comp->engine.destroy();      comp->line.destroy();    }  for (c=0; c < num_channels; c++)    {      channels[c].line.destroy();      channels[c].lut = NULL;    }  codestream = kdu_codestream(); // Invalidate the internal pointer for safety  allocator.restart(); // Get ready to use the allocation object again.  return success;}/******************************************************************************//*                       kdr_region_decompressor::process                     *//******************************************************************************/bool  kdr_region_decompressor::process(kdu_byte *buffer, int buffer_row_gap,                                   kdu_dims buffer_region,                                   kdu_dims &incomplete_region,                                   int suggested_increment,                                   kdu_dims &new_region){  new_region.size = kdu_coords(0,0); // In case we decompress nothing  if (codestream_failure || !incomplete_region)    return false;  assert(incomplete_region == (incomplete_region & buffer_region));  try { // Protect, in case a fatal error is generated by the decompressor      if (!tile_open)        open_tile();      kdu_dims incomplete_tile_region = render_dims & incomplete_region;      if (!incomplete_tile_region)        { // No intersection between tile and incomplete region.          if (next_tile_idx.x == valid_tiles.pos.x)            { // This is the last tile on the current row of tiles.              int y = render_dims.pos.y + render_dims.size.y;              if (y > incomplete_region.pos.y)                { // Incomplete region must have shrunk in the meantime.                  y -= incomplete_region.pos.y;                  if (y > incomplete_region.size.y)                    y = incomplete_region.size.y;                  incomplete_region.pos.y += y;                  incomplete_region.size.y -= y;                }            }          close_tile();          return true; // Let the caller get back to us for more tile processing        }      bool last_tile_in_row = // Advance incomplete region only when this true        ((incomplete_tile_region.pos.x+incomplete_tile_region.size.x) ==         (incomplete_region.pos.x+incomplete_region.size.x));      // Determine an appropriate number of lines to process before returning.      // Note that some or all of these lines might not intersect with the      // incomplete region.      assert(suggested_increment > 0);      suggested_increment *= channels[0].source->sampling.x;      suggested_increment *= channels[0].source->sampling.y;      int new_lines = ceil_ratio(suggested_increment,render_dims.size.x);      int y_lim = incomplete_tile_region.pos.y + incomplete_tile_region.size.y;      if ((new_lines+render_dims.pos.y) > y_lim)        new_lines = y_lim - render_dims.pos.y;      assert(new_lines > 0);      // Determine and process new region.      new_region = incomplete_tile_region;      new_region.size.y = 0;      buffer +=         ((incomplete_tile_region.pos.y-buffer_region.pos.y)*buffer_row_gap +         (incomplete_tile_region.pos.x-buffer_region.pos.x))*3;      for (; new_lines > 0; new_lines--,           render_dims.pos.y++, render_dims.size.y--)        {          int c;          // Decompress new image component lines as necessary.          for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++)            {              kdr_component *comp = components + c;              if (comp->dims.size.y <= 0)                { // No more lines available.                  if (!comp->line_buf_valid)    // Tile has no lines of this                    reset_line_buf(comp->line); // component at all.  Set to 0's                  continue;                }              do {                  if (comp->interp.y <= 0)                    {                      comp->interp.y += comp->sampling.y;                      comp->line_buf_valid = false;                    }                  if (!comp->line_buf_valid)                    {                      comp->engine.pull(comp->line,true);                      comp->dims.size.y--;                      comp->dims.pos.y++;                    }                } while ((comp->interp.y <= 0) && (comp->dims.size.y > 0));            }          // Finish processing of component lines which have been invalidated          if (use_ycc && !components[0].line_buf_valid)            {              assert((!components[1].line_buf_valid) &&                     (!components[2].line_buf_valid));              kdu_convert_ycc_to_rgb(components[0].line,components[1].line,                                     components[2].line);            }          for (c=0; (c < 6) && (components[c].comp_idx >= 0); c++)            {              kdr_component *comp = components + c;              if (!comp->line_buf_valid)                {                  comp->line_buf_valid = true;                  if (comp->palette_bits > 0)                    convert_samples_to_palette_indices(comp->line,                         comp->bit_depth,comp->is_signed,comp->palette_bits);                }              comp->interp.y--; // Decrement interpolation counter.            }          // Now process a new set of channel lines, as required          if (render_dims.pos.y == incomplete_tile_region.pos.y)            { // This line has non-empty intersection with the incomplete region              int skip_cols = incomplete_tile_region.pos.x-render_dims.pos.x;              int num_cols = incomplete_tile_region.size.x;              for (c=0; c < num_channels; c++)                {                  kdr_channel *channel = channels + c;                  kdr_component *comp = channel->source;                  if (channel->lut != NULL)                    interpolate_and_map(comp->line,comp->interp.x,                                    comp->sampling.x,channel->lut,                                    channel->line,skip_cols,num_cols);                  else                    interpolate_and_convert(comp->line,comp->interp.x,                                    comp->sampling.x,comp->bit_depth,                                    channel->line,skip_cols,num_cols);                }              if (space == JP2_sYCC_SPACE)                kdu_convert_ycc_to_rgb(channels[0].line,channels[1].line,                                       channels[2].line,num_cols);              else if (space == JP2_iccLUM_SPACE)                colour.convert_icc_to_slum(channels[0].line,num_cols);              else if (space == JP2_iccRGB_SPACE)                colour.convert_icc_to_srgb(channels[0].line,channels[1].line,                                           channels[2].line,num_cols);              for (c=0; c < num_channels; c++)                transfer_fixed_point(channels[c].line,buffer+2-c,num_cols);              if (num_channels == 1)                { // Above code only transferred the red channel.                  kdu_byte *bp = buffer;                  for (c=num_cols; c > 0; c--, bp+=3)                    bp[0] = bp[1] = bp[2];                }              buffer += buffer_row_gap*3;              incomplete_tile_region.pos.y++;              incomplete_tile_region.size.y--;              new_region.size.y++; // Transferred data region grows by one row.              if (last_tile_in_row)                {                  assert(render_dims.pos.y == incomplete_region.pos.y);                  incomplete_region.pos.y++;                  incomplete_region.size.y--;                }            }        }      if (!incomplete_tile_region)        { // Done all the processing we need for this tile.          close_tile();          return true;        }    }  catch (int)    {      codestream_failure = true;      return false;    }  return true;}

⌨️ 快捷键说明

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