📄 ebcot_decoder.c
字号:
if (tile->components[c].num_levels >= max_tile_levels) max_tile_levels = tile->components[c].num_levels+1; tile->packet_sequence = seq = (ebcot_sequence_ptr) local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_sequence)*tile->total_packets); total_packets = 0; order = tile->progression_changes; style = tile->progression; do { if (order != NULL) { max_layers = order->max_layers; max_levels = order->max_levels; max_components = order->max_components; } else max_layers = max_levels = max_components = INT_MAX; if (max_layers > tile->num_layers) max_layers = tile->num_layers; if (max_levels > max_tile_levels) max_levels = max_tile_levels; if (max_components > tile->num_components) max_components = tile->num_components; switch (style) { case LAYER_PROGRESSIVE: num_packets = construct_layer_progression(tile,seq, max_layers,max_levels,max_components); break; case RESOLUTION_LAYER_PROGRESSIVE: num_packets = construct_resolution_layer_progression(tile,seq, max_layers,max_levels,max_components); break; case RESOLUTION_POSITION_PROGRESSIVE: num_packets = construct_resolution_position_progression(tile,seq, max_layers,max_levels,max_components); break; case POSITION_COMPONENT_PROGRESSIVE: num_packets = construct_position_component_progression(tile,seq, max_layers,max_levels,max_components); break; case COMPONENT_POSITION_PROGRESSIVE: num_packets = construct_component_position_progression(tile,seq, max_layers,max_levels,max_components); break; default: assert(0); } seq += num_packets; total_packets += num_packets; if (order == NULL) style = -1; else { style = order->new_progression; order = order->next; } } while (style >= 0); assert(total_packets == tile->total_packets);}/*****************************************************************************//* STATIC build_partitions *//*****************************************************************************/static int build_partitions(ebcot_component_info_ptr comp_info) /* This function constructs the code-block partition and the packet partition for all resolution levels and subbands in the tile-component referenced by `comp_info'. The function returns the total number of packets in the component. */{ ebcot_level_info_ptr lev; ebcot_band_info_ptr band; ebcot_packet_info_ptr packet; ebcot_packet_band_info_ptr pband; ebcot_block_info_ptr block; int x, y, xdim, ydim, xsiz, ysiz, xfact, yfact; int total_packets, amount_missing; int first_packet_rows, first_packet_cols, packet_rows, packet_cols; int first_block_rows, first_block_cols, block_rows, block_cols; int blocks_across, blocks_down, first_blocks_across, first_blocks_down; int n, b, r, c, p; total_packets = 0; for (n=0; n <= comp_info->num_levels; n++) { lev = comp_info->levels + n; if ((lev->dims.cols == 0) || (lev->dims.rows == 0)) { /* Don't need to do anything, since there will be an entirely empty packet partition, but somebody might ask for the block dimensions in each band and expect a non-zero response. */ for (b=lev->min_band; b <= lev->max_band; b++) { band = lev->bands + b; band->block_rows = band->block_cols = 4; } } /* First build packet structure. */ if (lev->ppx < 0) { packet_cols = 1<<30; first_packet_cols = lev->dims.cols; lev->packets_wide = 1; } else { packet_cols = 1<<lev->ppx; first_packet_cols = packet_cols - ((lev->dims.left_col-lev->frame.dims.left_col) & (packet_cols-1)); lev->packets_wide = 1 + ((lev->dims.cols-first_packet_cols+packet_cols-1) / packet_cols); } if (lev->ppy < 0) { packet_rows = 1<<30; first_packet_rows = lev->dims.rows; lev->packets_high = 1; } else { packet_rows = 1<<lev->ppy; first_packet_rows = packet_rows - ((lev->dims.top_row-lev->frame.dims.top_row) & (packet_rows-1)); lev->packets_high = 1 + ((lev->dims.rows-first_packet_rows+packet_rows-1) / packet_rows); } lev->total_packets = lev->packets_wide * lev->packets_high; total_packets += lev->total_packets; lev->packets = (ebcot_packet_info_ptr) local_malloc(EBCOT_MEM_KEY, sizeof(ebcot_packet_info)*lev->total_packets); yfact = comp_info->vert_subsampling << (comp_info->num_levels - n); xfact = comp_info->hor_subsampling << (comp_info->num_levels - n); ysiz = lev->dims.top_row + lev->dims.rows; xsiz = lev->dims.left_col + lev->dims.cols; for (y=lev->dims.top_row, ydim=first_packet_rows, p=0, r=lev->packets_high; r > 0; r--, y += ydim, ydim = packet_rows) for (x=lev->dims.left_col, xdim=first_packet_cols, c=lev->packets_wide; c > 0; c--, x += xdim, xdim = packet_cols, p++) { packet = lev->packets + p; packet->xref = x * xfact; packet->yref = y * yfact; packet->tnum = lev->tnum; packet->component_idx = lev->component_idx; packet->level_idx = lev->level_idx; packet->packet_idx = p; packet->min_band = lev->min_band; packet->max_band = lev->max_band; packet->bands = (ebcot_packet_band_info_ptr) local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_packet_band_info) * (packet->max_band+1)); } /* Determine code-block dimensions. */ block_rows = comp_info->master.max_height; block_cols = comp_info->master.max_width; if (block_rows > (packet_rows >> lev->hp_descent)) block_rows = packet_rows >> lev->hp_descent; if (block_cols > (packet_cols >> lev->hp_descent)) block_cols = packet_cols >> lev->hp_descent; if ((block_rows == 0) || (block_cols == 0)) local_error("Packet partition dimensions too small for given " "decomposition; packet size must be sufficiently large " "that the partition occupies at least one full sample " "in each subband!"); if (comp_info->respect_frames) { band = lev->bands + lev->min_band; /* Any band will do. */ if (block_rows > band->frame.dims.rows) block_rows = band->frame.dims.rows; if (block_cols > band->frame.dims.cols) block_cols = band->frame.dims.cols; } /* Determine the number of blocks across and down a nominal packet. */ blocks_across = (packet_rows >> lev->hp_descent) / block_cols; blocks_down = (packet_cols >> lev->hp_descent) / block_rows; for (b=lev->min_band; b <= lev->max_band; b++) { band = lev->bands + b; /* Initialize code-block structure for the band. */ band->block_rows = block_rows; band->block_cols = block_cols; first_block_rows = block_rows - ((band->dims.top_row-band->frame.dims.top_row) & (block_rows-1)); first_block_cols = block_cols - ((band->dims.left_col-band->frame.dims.left_col) & (block_cols-1)); if (first_block_rows > band->dims.rows) first_block_rows = band->dims.rows; if (first_block_cols > band->dims.cols) first_block_cols = band->dims.cols; band->blocks_high = 1 + ((band->dims.rows-first_block_rows+block_rows-1) / block_rows); band->blocks_wide = 1 + ((band->dims.cols-first_block_cols+block_cols-1) / block_cols); band->total_blocks = band->blocks_wide * band->blocks_high; band->blocks = block = (ebcot_block_info_ptr) local_malloc(EBCOT_MEM_KEY, sizeof(ebcot_block_info)*band->total_blocks); ysiz = band->dims.rows; xsiz = band->dims.cols; for (y=0, ydim=first_block_rows, r=0; r < band->blocks_high; r++, y += ydim, ydim = block_rows) for (x=0, xdim=first_block_cols, c=0; c < band->blocks_wide; c++, x += xdim, xdim = block_cols, block++) { xdim = ((x+xdim)>xsiz)?(xsiz-x):xdim; ydim = ((y+ydim)>ysiz)?(ysiz-y):ydim; block->top_row = y; block->rows = ydim; block->left_col = x; block->cols = xdim; } /* Initialize the packet-band structure for the band. */ first_blocks_across = blocks_across; amount_missing = convert_dimension_from_level_to_band(packet_cols-first_packet_cols, 0,lev->hp_descent,b); first_blocks_across -= amount_missing / block_cols; first_blocks_down = blocks_down; amount_missing = convert_dimension_from_level_to_band(packet_rows-first_packet_rows, 1,lev->hp_descent,b); first_blocks_down -= amount_missing / block_rows; if (lev->ppx < 0) first_blocks_across = band->blocks_wide; if (lev->ppy < 0) first_blocks_down = band->blocks_high; ysiz = band->blocks_high; xsiz = band->blocks_wide; for (y=0, ydim=first_blocks_down, p=0, r=0; r < lev->packets_high; r++, y += ydim, ydim = blocks_down) for (x=0, xdim=first_blocks_across, c=0; c < lev->packets_wide; c++, x += xdim, xdim = blocks_across, p++) { packet = lev->packets + p; pband = packet->bands + b; xdim = ((x+xdim)>xsiz)?(xsiz-x):xdim; ydim = ((y+ydim)>ysiz)?(ysiz-y):ydim; pband->blocks_high = ydim; pband->blocks_wide = xdim; pband->total_blocks = xdim*ydim; pband->block_row_gap = band->blocks_wide; pband->blocks = band->blocks + (y*xsiz + x); pband->band = band; } } } return(total_packets);}/*****************************************************************************//* STATIC construct_tile *//*****************************************************************************/static void construct_tile(ebcot_decoder_ref self, ebcot_tile_ptr tile) /* This function constructs all the contents of a tile which depend upon non-global information, i.e. most of it. It is invoked at the latest possible moment, i.e. when the `decoder__next_tile' function moves us to this tile or when a packet from the relevant tile appears in the codestream. It may be invoked earlier if the `decoder__parse_to_rate' interface function is called since it is not possible to simulate parsing of the codestream without first loading the contents from every tile. The function accesses marker codes from the `stream_in' object and it also accesses tile configuration parameters from the `reverse_info' object; it expects that this object's tile walker has been advanced to the relevant tile position before this function is called. */{ int tnum = tile->tnum; stream_in_ref stream = self->stream; reverse_info_ref info = self->info; ebcot_component_info_ptr comp_info; ebcot_level_info_ptr lev; ebcot_band_info_ptr band; ebcot_packet_info_ptr packet; ebcot_packet_band_info_ptr pband; int c, n, b, p; /* First, build the level and subband structures. */ assert(!tile->constructed); for(c=0; c < tile->num_components; c++) { int num_levels; comp_info = tile->components + c; comp_info->num_levels = num_levels = info->get_var_tile_info(info,c,NULL,NULL); comp_info->max_levels = num_levels - self->discard_levels; if (comp_info->max_levels < 0) local_error("The current codestream does not support sufficient " "resolution scalability for the requested reduction " "in resolution. At most %d resolution levels may " "be discarded!",num_levels); comp_info->levels = (ebcot_level_info_ptr) local_malloc(EBCOT_MEM_KEY, sizeof(ebcot_level_info)*(num_levels+1)); for (n=0; n <= num_levels; n++) { lev = comp_info->levels + n; lev->tnum = tnum; lev->component_idx = c; lev->level_idx = n; info->get_level_info(info,c,n,&(lev->dims),&(lev->hp_descent), &(lev->frame)); if (n == 0) lev->min_band = lev->max_band = LL_BAND; else { if (lev->hp_descent == 0) { lev->min_band = 0; lev->max_band = -1; continue; } else { lev->min_band = 1 << (lev->hp_descent+lev->hp_descent-2); lev->max_band = (1<<(lev->hp_descent+lev->hp_descent))-1; } } lev->bands = (ebcot_band_info_ptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -