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

📄 codestream.cpp

📁 JPEG2000的C++实现代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  for (int t=0; t < num_tiles.x*num_tiles.y; t++)    {      kd_tile *tile = tile_refs[t];      assert(tile != KD_EXPIRED_TILE);      if (tile == NULL)        continue;      for (int c=0; c < tile->num_components; c++)        {          kd_tile_comp *tc = tile->comps+c;          for (int r=0; r <= tc->dwt_levels; r++)            {              kd_resolution *res = tc->resolutions + r;              for (int p=0; p < res->precinct_indices.area(); p++)                {                  kd_precinct *precinct = res->precinct_refs[p];                  assert(precinct != KD_EXPIRED_PRECINCT);                  if (precinct == NULL)                    continue;                  for (int b=res->min_band; b <= res->max_band; b++)                    {                      kd_precinct_band *pb = precinct->bands + b;                      for (int n=0; n < pb->block_indices.area(); n++)                        {                          kd_block *block = pb->blocks + n;                          block->trim_data(threshold,buf_server);                        }                    }                }            }        }    }}/*****************************************************************************//*                    kd_codestream::get_min_header_cost                     *//*****************************************************************************/void  kd_codestream::get_min_header_cost(int &fixed_cost, int &per_layer_cost){  per_layer_cost = 0;  fixed_cost = 2 + siz->generate_marker_segments(NULL,-1,0);#ifdef KDU_IDENTIFIER  fixed_cost += strlen(KDU_IDENTIFIER)+6;#endif  for (int tnum=0; tnum < num_tiles.x*num_tiles.y; tnum++)    {      kd_tile *tile = tile_refs[tnum];      assert((tile != NULL) && (tile != KD_EXPIRED_TILE));      // Calculate cost of all tile-part headers for this tile.      int new_bytes = 0;      int try_tpart = 0;      do {          new_bytes = siz->generate_marker_segments(NULL,tnum,try_tpart);          if ((new_bytes > 0) || (try_tpart == 0))            {              new_bytes += 12; // Cost of SOT marker segment              new_bytes += 2; // Cost of SOD marker            }          fixed_cost += new_bytes;          try_tpart++;        } while (new_bytes != 0);           // Calculate min packet header cost      per_layer_cost += tile->total_precincts;      if (tile->use_eph)        per_layer_cost += tile->total_precincts*2;      if (tile->use_sop)        per_layer_cost += tile->total_precincts*6;    }}/*****************************************************************************//*                       kd_codestream::simulate_output                      *//*****************************************************************************/int  kd_codestream::simulate_output(int &header_bytes, int layer_idx,                                  kdu_uint16 slope_threshold,                                  bool finalize_layer, bool last_layer,                                  int max_bytes, int *sloppy_bytes){  header_bytes = 0;  if (layer_idx == 0)    {      header_bytes = 2 + siz->generate_marker_segments(NULL,-1,0);#ifdef KDU_IDENTIFIER      header_bytes += strlen(KDU_IDENTIFIER)+6;#endif    }  int total_bytes = header_bytes;  for (int n=0; n < num_tiles.x*num_tiles.y; n++)    {      if (total_bytes > max_bytes)        {          assert(!finalize_layer);          return total_bytes;        }      int tile_header_bytes;      assert((tile_refs[n] != NULL) && (tile_refs[n] != KD_EXPIRED_TILE));      total_bytes +=        tile_refs[n]->simulate_output(tile_header_bytes,layer_idx,                                      slope_threshold,finalize_layer,                                      last_layer,max_bytes-total_bytes,                                      sloppy_bytes);      header_bytes += tile_header_bytes;    }  return total_bytes;}/*****************************************************************************//*                          kd_codestream::pcrd_opt                          *//*****************************************************************************/void  kd_codestream::pcrd_opt(int layer_bytes[], kdu_uint16 slope_thresholds[],                          int num_layers){  int rough_upper_bound = 0;  int fixed_header_cost, per_layer_header_cost;  get_min_header_cost(fixed_header_cost,per_layer_header_cost);  int new_header_bytes, new_layer_bytes;  int last_layer_bytes, last_target_bytes, layer_idx;    if (layer_bytes[num_layers-1] == 0)    { // Find rough upper bound for the purpose of spacing intermediate layers      rough_upper_bound =        simulate_output(new_header_bytes,0,0,false,false);    }  // Now work through the layers.  int threshold;  int min_threshold = 0; // Inclusive lower bound.  int lim_threshold = (1<<16); // Exclusive upper bound.  last_layer_bytes = 0;  last_target_bytes = 0;  for (layer_idx=0; layer_idx < num_layers; layer_idx++)    {      bool last_layer = (layer_idx == (num_layers-1));      bool auto_targeting = (layer_bytes[layer_idx] == 0);      if (auto_targeting)        { // Have to make up a suitable number of target bytes          if (last_layer)            {              layer_bytes[layer_idx] = INT_MAX;              auto_targeting = false;            }          else            {              int next_idx, next_target_bytes;              for (next_idx=layer_idx+1; next_idx < num_layers; next_idx++)                if ((next_target_bytes = layer_bytes[next_idx]) > 0)                  break;              if (next_target_bytes == 0)                { // Can only happen if final layer has no assigned rate target                  next_idx = num_layers-1;                  next_target_bytes = rough_upper_bound;                }              if (layer_idx > 0)                { // Logarithmically interpolate known rate targets, after                  // discounting the minimum header cost.                  int start_bytes = last_target_bytes                    - fixed_header_cost - layer_idx*per_layer_header_cost;                  int end_bytes = next_target_bytes                    - fixed_header_cost - (next_idx+1)*per_layer_header_cost;                  if (start_bytes < 1)                    start_bytes = 1;                  if (end_bytes < start_bytes)                    end_bytes = start_bytes;                  double y_start = log(start_bytes);                  double y_end = log(end_bytes);                  double x_start = layer_idx-1;                  double x_end = next_idx;                  double x = layer_idx;                  double y = y_start +                    (x-x_start)/(x_end-x_start)*(y_end-y_start);                  layer_bytes[layer_idx] = ((int) exp(y))                    + fixed_header_cost + (layer_idx+1)*per_layer_header_cost;                }              else                { // Need to settle on a good starting rate target.                  int end_bytes = next_target_bytes                    - fixed_header_cost - (next_idx+1)*per_layer_header_cost;                  if (end_bytes < 1)                    end_bytes = 1;                  int start_bytes = (int) (end_bytes / sqrt(1<<next_idx));                  layer_bytes[0] = start_bytes                    + fixed_header_cost + per_layer_header_cost;                }            }        }      // First use a simple bisection search for the slope threshold      if (lim_threshold < 1)        lim_threshold = 1;      int target_bytes =        layer_bytes[layer_idx] - last_layer_bytes - 2; // 2 is for an EOC      int best_threshold = lim_threshold-1;      min_threshold = 0;      do {          threshold = (min_threshold+lim_threshold)>>1;          assert(threshold < (1<<16));          new_layer_bytes =            simulate_output(new_header_bytes,layer_idx,(kdu_uint16) threshold,                            false,last_layer,target_bytes);          if (new_layer_bytes > target_bytes)            min_threshold = threshold+1;          else if (new_layer_bytes <= target_bytes)            {              best_threshold = threshold;              if (new_layer_bytes == target_bytes)                break; // Found target exactly              lim_threshold = threshold;            }        } while (lim_threshold > min_threshold);      // Finalize the allocation for this layer      threshold = best_threshold;      new_layer_bytes =  // Don't finalize yet        simulate_output(new_header_bytes,layer_idx,(kdu_uint16) threshold,                        false,last_layer);      int remaining_bytes = target_bytes - new_layer_bytes;      if ((remaining_bytes < 0) && !auto_targeting)        { kdu_warning w; w << "Unable to achieve the rate target "          "for quality layer " << layer_idx << ".  Try requesting a smaller "          "number of quality layers.\n";        }      if (last_layer && (remaining_bytes > 0) && (threshold > 0))        {          threshold--;          new_layer_bytes = // Finalize with sloppy fill in.            simulate_output(new_header_bytes,layer_idx,(kdu_uint16) threshold,                            true,true,target_bytes,&remaining_bytes);        }      else        new_layer_bytes = // Finalize without sloppy fill in.          simulate_output(new_header_bytes,layer_idx,(kdu_uint16) threshold,                          true,last_layer);      slope_thresholds[layer_idx] = (kdu_uint16) threshold;      lim_threshold = threshold+1; // We are allowed to repeat the threshold.      last_layer_bytes += new_layer_bytes;      last_target_bytes = layer_bytes[layer_idx];      layer_bytes[layer_idx] = last_layer_bytes+2; // Put EOC back.    }}/*****************************************************************************//*                  kd_codestream::generate_codestream                       *//*****************************************************************************/void  kd_codestream::generate_codestream(int max_layers,                                     kdu_uint16 slope_thresholds[]){  assert(out != NULL);  // First write the main header.  out->put(KDU_SOC);  siz->generate_marker_segments(out,-1,0);#ifdef KDU_IDENTIFIER  int length = strlen(KDU_IDENTIFIER);  out->put(KDU_COM);  out->put((kdu_uint16)(length+4));  out->put((kdu_uint16) 1); // Latin values for COM body.  out->write((kdu_byte *) KDU_IDENTIFIER,length);#endif  // Now cycle through the tiles, interleaving their tile-parts.  bool done;  do {      done = true;      for (int n=0; n < num_tiles.x*num_tiles.y; n++)        {          assert(tile_refs[n] != KD_EXPIRED_TILE);          if (tile_refs[n] == NULL)            { kdu_error e; e << "You may not currently flush compressed "              "code-stream data without completing the compression of all "              "tiles."; }          int tpart_bytes =            tile_refs[n]->generate_tile_part(max_layers,slope_thresholds);          if (tpart_bytes > 0)            done = false;        }    } while (!done);  // Finish up with the EOC marker.  out->put(KDU_EOC);}/* ========================================================================= *//*                              kdu_codestream                               *//* ========================================================================= *//*****************************************************************************//*                       kdu_codestream::create (input)                      *//*****************************************************************************/void  kdu_codestream::create(kdu_compressed_source *source){  assert(state == NULL);  state = new kd_codestream;  state->in = new kd_compressed_input(source);  state->marker = new kd_marker(state->in);  if ((!state->marker->read()) ||      (state->marker->get_code() != KDU_SOC))    { kdu_error e; e << "Code-stream must start with an SOC marker!"; }  state->siz = new siz_params;  if (!(state->marker->read() &&        state->siz->translate_marker_segment(state->marker->get_code(),                                             state->marker->get_length(),                                             state->marker->get_bytes(),-1,0)))    { kdu_error e; e << "Code-stream must contain a valid SIZ marker segment, "      "immediately after the SOC marker!"; }  state->construct_common();}/*****************************************************************************//*                          kdu_codestream::create (output)                  *//*****************************************************************************/void  kdu_codestream::create(siz_params *siz_in,                         kdu_compressed_target *target){  assert(state == NULL);  state = new kd_codestream;  state->out = new kd_compressed_output(target);  state->siz = new siz_params;  state->siz->copy_from(siz_in,-1,-1);  state->construct_common();}/*****************************************************************************//*                           kdu_codestream::destroy                         *//*****************************************************************************/void  kdu_codestream::destroy(){  assert(state != NULL);  delete state;  state = NULL;}/*****************************************************************************//*                       kdu_codestream::share_buffering                     *//*****************************************************************************/void  kdu_codestream::share_buffering(kdu_codestream existing){  assert(!state->tiles_accessed);  state->buf_server->detach();  delete state->buf_server;  state->buf_server = existing.state->buf_server;  state->buf_server->attach();}/*****************************************************************************//*                       kdu_codestream::set_per

⌨️ 快捷键说明

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