JPEG-LS extensions标准之熵编码部分

本文简要介绍了JPEG-LS扩展标准中的算术编码的流程及实现细节。更为详细的描述可以参考ITU-T T.870扩展标准。

算术编码流程

1.初始化

初始化主要包括Creg,Areg,Buf[2],Av[31],Th[30],对于MLcnt,LPScnt,MPSvalue的初始化在此不再重复。

其中Creg=0,Areg=0xff*0xff,unsigned char buf[2]为无符号数组,初始化为0.

Av,Th标准规定为固定值,如下:

int Av[31] = {
        0x7ab6, 0x7068, 0x6678, 0x5ce2, 0x53a6, 0x4ac0, 0x4230, 0x39f4,
        0x33fc, 0x301a, 0x2c4c, 0x2892, 0x24ea, 0x2156, 0x1dd6, 0x1a66,
        0x170a, 0x13c0, 0x1086, 0x0d60, 0x0b0e, 0x0986, 0x0804, 0x0686,
        0x050a, 0x0394, 0x027e, 0x01c6, 0x013e, 0x0100, 0x0000
    };
    int    Th[30] = {
        0x7800, 0x7000, 0x6800, 0x6000, 0x5800, 0x5000, 0x4800, 0x4000,
        0x3c00, 0x3800, 0x3400, 0x3000, 0x2c00, 0x2800, 0x2400, 0x2000,
        0x1c00, 0x1800, 0x1400, 0x1000, 0x0e00, 0x0c00, 0x0a00,0x0800,
        0x0600, 0x0400, 0x0300, 0x0200, 0x0180, 0x0001
    };

从第二步开始,相当于在实现AritmeticEncode(Bin,S)函数。

2.确定合适的Av值

不解释,直接上代码

//Search of suitable Av
        Prob = (LPScnt[S]<<16)/MLcnt[S];
        for(Aindex=0;Aindex<30;++Aindex)
            if(Prob>Th[Aindex]) break;
        for(wct=0;Areg<(0x8000>>wct);++wct)
            ;
        if( (MLcnt[S]==MAXcnt)&&(LPScnt[S]==1))
            Avd = 0x0002;
        else
            Avd = Av[Aindex]>>wct;
        Hd = 0x8000 >> wct;

3.更新Creg和Areg变量

不解释,直接上代码,这里变量Bin指的是输入算术编码器的待编码的字符,S也是通过从外部输入到算术编码的。

//Update of Creg and Areg
        Avd = Areg - Avd;
        if(Avd < Hd)
            Avd = (Avd+Hd)/2;

        if(Bin == MPSvalue[S])
            Areg = Avd;
        else{
            Creg = Creg + Avd;
            Areg = Areg - Avd;
        }

4.更新计数器

//Update of counters
        if(MLcnt[S] == MAXcnt){
            if(Bin != MPSvalue[S]){
                MLcnt[S] = (MLcnt[S]+1)/2+1;
                LPScnt[S] = (LPScnt[S]+1)/2+1;
            }
            else
                if(LPScnt[S]!=1){
                    MLcnt[S] = (MLcnt[S]+1)/2+1;
                    LPScnt[S] = (LPScnt[S]+1)/2;
                }
        }
        else{
            MLcnt[S]++;
            if(Bin!=MPSvalue[S])
                LPScnt[S]++;
        }
        if(MLcnt[S]<LPScnt[S]*2){
            LPScnt[S] = MLcnt[S]-LPScnt[S];
            MPSvalue[S]=1-MPSvalue[S];
        }

5.归一化Areg和Creg,并输出编码结果

//Renormalization of Areg and Creg and output data bit stream
        if(Areg<0x100){
            if(Creg>=0xff * 0xff){
                Creg -=0xff * 0xff;
                Buf[0]++;
                if(Buf[0]==0xff){
                    Buf[0]=0;
                    Buf[1]++;
                }
            }
            AppendToBitStream(Buf[1],8);

            Buf[1] = Buf[0];
            Buf[0] = ((Creg>>8)+Creg+1)>>8;
            Creg+=Buf[0];
            Creg=((Creg&0xff)<<8)-(Creg&0xff);
            Areg=(Areg<<8)-Areg;
        }

AppendToBitStream(i,j)函数使用j bit将无符号整数i写入到输出码流中。这里由于j固定为8,故相当于直接向输出码流中写入1字节。

6.结束编码

当编码完所有像素后,编码器最后向输出码流写入4字节,分别为Buf[1],Buf[0],和Creg。

这里有一个疑问,Buf[1],Buf[0]都是一个字节没有什么可说的,但是Creg是int类型,理论上应该有32位,但是标准却规定Creg在最后的输出中只占有2个字节,那么一旦最终的Creg>65536怎么办?在实际的测试中,我确实发现按照标准的这种结尾的处理方式,会导致解码在最后几个bit出现错误(恢复数据不正确),但是无论怎么调整编码结束时对结尾的处理,都无法到达理想的效果,所以这里留下一个疑问,有待高人解答。是标准有什么隐含地方没说明,还是标准有问题?

上面就是整个算术编码的流程,至于其中的原理,标准没有说明,所以不用过多关心,我们只是用用就好。

下面简要介绍一下对应的解码流程。

解码流程跟编码流程有相同的部分,相同的部分代码不再贴出。

1.初始化,这里的初始化与编码初始化相同,唯一不同的是Creg的初始化值,在读入的已经编码的比特流中,前两个字节始终是0x00,可以舍去,第3个字节乘以0xFF再加上第4个字节得到的值作为Creg的初始化值。其他变量的初始化值与编码时相同。

2.确定合适的Av值,此段代码与编码完全一致。

3.恢复Bin

//detemination of Bin
        Avd = Areg - Avd;
        if(Avd < Hd)
            Avd = (Avd+Hd)/2;
        if(Creg < Avd){
            Areg = Avd;
            Bin = MPSvalue[S];
        }
        else{
            Creg = Creg - Avd;
            Areg = Areg - Avd;
            Bin = 1 - MPSvalue[S];
        }

经过此步,便恢复出一比特的Bin值。

4.更新计数器,此段代码与编码完全一致。

5.归一化Areg和Creg

if(Areg<0x100){
            Creg = (Creg<<8)-Creg+GetByte();
            Areg = (Areg<<8)-Areg;
        }

GetByte()函数表示从输入码流中读取一字节数据。

如上五步就是整个的算术解码过程。

时间: 2024-11-08 19:23:45

JPEG-LS extensions标准之熵编码部分的相关文章

JPEG图片解码

简介 JPEG是一种广泛适用的压缩图像标准方式.JPEG就是「联合图像专家组」(JointPhotographicExpertsGroup)的首字母缩写.采用这种压缩格式的文件一般就称为JPEG:此类文件的一般扩展名有:.jpeg..jfif..jpg或.jpe,其中在主流平台最常见的是.jpg. JPEG/JFIF是互联网上最常见的图像存储和传送格式.但此格式不适合用来绘制线条.文字或图标,因为它的压缩方式对这几种图片损坏严重.PNG和GIF文件更适合以上几种图片.不过GIF每像素只支持8bi

twain图像处理和扫描控件ImagXpress

ImagXpress是一款功能强大的twain图像处理控件,具有TWAIN扫描.压缩,浏览,注释,打印,图像处理,文档清洁,文件格式转换,使用该TWAIN扫描控件可以添加世界上最强大的图像处理功能到您的应用程序中,控件提供了.NET 和ActiveX版本,可用于32位和64位操作系统. 具体功能: 压缩以及文件格式: 支持1,4,8,16,24,32位图像 支持2到16位灰度图像 支持超过8位,灰度有损的JPEG 支持文本.文件中的Unicode(双字节)字符 支持转换为PDF或扫描为PDF,如

【教程】在UEFI启动方式下,通过GRUB2引导,直接从硬盘ISO文件安装Windows10和Ubuntu双系统

本文为作者原创,允许转载,但必须注明原文地址: https://www.cnblogs.com/byronxie/p/9949789.html 动机 最近在自学MIT6.828 Operating System Engineering, 这门课程的代码是针对Linux系统(Ubuntu)的. 我有一台WIN10平板电脑,基本信息如下: 型号是酷比魔方KNOTE8 处理器是Intel Core m3-7Y30 CPU @1.00GHz 1.61GHz RAM 8.00GB 学习编程,必须要动手练习

HDFS是什么?HDFS适合做什么?我们应该怎样操作HDFS系统?(第3篇)

第四章  HDFS文件系统 Hadoop 附带了一个名为 HDFS(Hadoop分布式文件系统)的分布式文件系统,专门存储超大数据文件,为整个Hadoop生态圈提供了基础的存储服务. 本章内容: 1) HDFS文件系统的特点,以及不适用的场景 2) HDFS文件系统重点知识点:体系架构和数据读写流程 3) 关于操作HDFS文件系统的一些基本用户命令 1. HDFS特点: HDFS专为解决大数据存储问题而产生的,其具备了以下特点: 1) HDFS文件系统可存储超大文件 每个磁盘都有默认的数据块大小

Linux下安装firefox的flash插件

OS:ORACLE-LINUX 5.71.下载"install_flash_player_11_linux.i386.tar.gz" 包2.自己创建个目录,解压[[email protected] flash]# tar -xvf install_flash_player_11_linux.i386.tar.gz3.查找插件目录[[email protected] mozilla]# find / -name mozilla/usr/lib64/mozilla/usr/share/mo

centos 火狐浏览器安装adobe flash player插件

今天想要在linux下上网看个电影.结果打开浏览器,提示没有安装flash player插件,点击自己主动安装,却提示系统不支持最新版本号的插件.我的系统是用的RHEL 5.5.没办法,google一番,下载到一个软件包install_flash_player_11_linux.i386.tar.gz. install_flash_player_11_linux.i386.tar.gz下载地址:http://vdisk.weibo.com/s/yeY-P 安装方法例如以下,做个总结:将软件包解压

乱谈常见图像格式

作者:马健邮箱:[email protected]发布:2013.02.15最后更新:2013.02.19 目录一.BMP二.GIF.PNG三.JPEG(JPG)四.JPEG 2000五.TIFF六.DjVu七.PDF八.小结 CEP.CV.UV中都支持多种图像格式,因此经常有人问我相同的问题:不同的图像格式究竟有什么不同?保存图像的时候究竟应该选择哪种图像格式? 本文希望能够对以上问题给出浅显的回答,当然是否已经浅到能让您理解的程度,就要看造化了. 一.BMP BMP是微软提出的一种图像格式,

R语言数据集的技术

特征值选择技术要点 特征值选择技术要点(特征值分解) 作者:王立敏 文章来源:xiahouzuoxin 一.特征值分解 1.特征值分解 线性代数中,特征分解(Eigendecomposition),又称谱分解(Spectral decomposition)是将矩阵分解为由其特征值和特征向量表示的矩阵之积的方法.需要注意只有对可对角化矩阵才可以施以特征分解. 设A有n个特征值及特征向量,则: 将上面的写到一起成矩阵形式: 若(x1,x2,...,xn)可逆,则左右两边都求逆,则方阵A可直接通过特征

HDFS常用的Shell命令(转载)

原文地址: http://www.cuiweiyou.com/1405.html 0.shell [email protected]:~# hadoop fs Usage: hadoop fs [generic options] [-appendToFile <localsrc> ... <dst>] [-cat [-ignoreCrc] <src> ...] [-checksum <src> ...] [-chgrp [-R] GROUP PATH...]