`
omygege
  • 浏览: 1357527 次
文章分类
社区版块
存档分类
最新评论

JPEG2000的Kakadu源代码浅析之三:码流解码(一)

 
阅读更多

  本章内容可能要涉及一些信号和图像处理的知识,我将尽可能用较为正式的表述,具体内容可以参考相关书籍。JPEG2000信号与信息处理的一些基础知识也可以参考我的笔记:http://lincoln.yu.googlepages.com/sgnotes.zip

  码流解码过程从main函数中的kdu_codestream codestream的构造声明处开始。随即完成对输入流的绑定,和codestream的一些基本设置。然后根据codestream的已有信息获得通道(channel)个数并从每个通道中取得分量的图像尺寸(dimension)信息。接着完成输出流的配置。随后的两个while嵌套就是进行解码的关键步骤。

  解码是基于一个单元类型为kde_flow_control,以tile为索引的指针数组进行的。第一层while进行行扫描,由for循环对每个数组单元调用advance_tile过程判断是否完成。而第二层while是对行内每个单元在各分量上进行解码。从而advance_components和process_components是核心的解码步骤。

  首先是kde_flow_control的创建,一个kde_flow_control对应一个tile,其横向索引由构造函数参数x_tnum指定(纵向由advance_tile成员函数遍历)。以下是创建的主要工作流程:
  1 导入最关键的参数,码流封装单元codestream;
  2 然后从codestream中打开指定tile,调用kdu_codestream::open函数:
    调用kdu_codestream::create_tile函数
     创建一个kd_tile对象;
     初始化该对象
      以component, resolution, band为序进行三层遍历设置;
    调用kd_tile::open函数打开该kd_tile对象
     以component为索引遍历初始化
      其它初始化操作;
      设置弃级:<code>tc->apparent_dwt_levels = tc->dwt_levels - codestream->discard_levels;</code>;
      以resolution, band为序进行二层遍历初始化;
  3 以component为索引从codestream中获取参数;
  4 以channel为索引配置参数,完成和component的映射;
  5 为各component创建解码单元
    分配数据处理空间,基准尺寸由comp->reversible确定;
    如果该分量只包含一个分辨率级,则直接创建kdu_decoder,否则创建kdu_synthesis,再由它递归为各较低分辨率级创建相应解码单元;
  6 为各具有色彩映射的channel分配数据处理空间,用对应component的分配器;

  关于resolution和band的结构如下(以3级结构190x240为例):
  res_level 0 1 2 3
  dwt_level 3 3 2 1
  dims(width)24 48 95 190
  style [LL][HL] [HL] [HL]
   [LH][HH] [LH][HH][LH][HH]

  图像二维子带变换作为JPEG2000解码的主要组成部分之一采用提升快速算法实现,并且这是一种递归的方法。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics