背景技术
手机、数码产品发展迅速,要想在越来越剧烈的竞争中处于不败之地,除了不断推出比市场上更新的产品之外,降低成本也是一种途径,在软件设计中最为令人关注的是内存的使用。数码产品最常见的功能是图片解码浏览,通常解码一副很大的图片需要很大的内存,而最终屏幕显示需要的内存需要的却很小,因此如何减少图像解码过程使用的内存成为软件工程师急需考虑的问题。
图像压缩编码算法模型包括基于序列式离散余弦变换、渐进式离散余弦变换、无损压缩和层次压缩算法等。前两种算法属于有损压缩,压缩比比较大,他们的区别是渐进式离散预先变换首先编码整幅图片的轮廓,再逐步细化各个象素,而序列式离散余弦变换则按照从左到右、从上到下的顺序编码;无损压缩的压缩比比较小;层次压缩算法与渐进式离散余弦变换类似,适用于多种分辨率需要的环境。本文讲述的算法基于序列式离散余弦变换模型,它的解码框图如图1所示。
图像的解码分别经过熵解码(哈夫曼解码)、反量化、反离散余弦变换,最后生成一个个的8x8块,若干个8x8块按照YUV比例组合成一个个的MCU,称为最小编码单元,编码时以它为一个单元进行编码,这些MCU按照原图像从左到右、从上到下的顺序排列顺序,组合成一整幅图片。在已有的应用方案中,实现整幅图片解码是先预留足够大的内存来保存一幅图片所有象素的YUV数据(或者RGB数据),解完之后再进行缩放,最后送到屏幕显示,释放掉原来的解码用的内存,如图2所示。
现有的图像解码加显示方案中间使用了很大的内存,而在使用之后又释放,这对于内存相对紧张的应用或者需要减少内存成本的产品来说,是极大的浪费,甚至在解码分辨率很大的图片的时候,根本不可行。因此急需要一种方法来减少图像解码过程中需要的内存。
发明内容
本发明的目的在于提供一种既不影响原有速度,又能避免使用大内存的要求的图像分段解码方法。
本发明的目的可通过以下的技术措施来实现:一种图像分段解码方法,包括以下步骤:
(1)、在内存里先分配一个MCU行大小的内存,再把要解码图像分成两个以上的MCU行,然后初始化要解码图片的高度和宽度,并获得其缩小因子;
(2)、按顺序取步骤(1)中分成的其中一个MCU行,对应生成一个MCU行的YUV数据;
(3)、利用步骤(1)得出的缩小因子把步骤(2)生成的一个MCU行的YUV数据进行缩小采样,转换成RGB数据,并保存到目的缓冲位置;
(4)重复使用步骤1中分配的同一个内存,依次对图像分成的其余MCU行重复步骤(2)、(3)、直至整幅图像解码完毕;
(5)、把解码完毕的整幅图片,缓冲送到显示屏显示。
本发明所述步骤(1)的缩小因子包括水平和垂直方向的缩小因子,分别为要解码图像的宽度和高度与目的图像的宽度和高度的比值。
本发明所述步骤(3)进行的缩小采样,转换成RGB数据过程为:通过目的图像和所要解码图像YUV缓冲的行号和列号,获得目的图像和所要解码图像的YUV缓冲位置,再取出所要解码图像缓冲的YUV数据,转换为RGB数据,保存到目的图像的缓冲位置。
本发明所述的目的图像和所要解码图像YUV缓冲的行号分别为上一个MCU行解码中获得的目的图像的下一个象素行和要解码图象的第一个象素行。上述一个象素行是图像的分辨率的行数,而一个MCU行通常包含若干个象素行,例如图像分辨率为320x240,则图像共有240个象素行。
本发明结合了图像解码与LCD显示的实际状况,以及在很多嵌入式应用中,可用的内存比较少,避免了使用大内存的要求,既达到相同效果,又不影响原有的速度,可以在内存紧张的情况下,完成超大图片的解码及显示。
具体实施方式
如图3所示,为分段解码缩小图像流程示意图。将图片分成若干个MCU行,按一个MCU行一个模块进行解码:分配一个MCU行大小的内存,当解码完一个MCU行之后,通过定点算法将它转换并缩小到对应的屏幕缓冲里面,接着解下一个MCU行,每次解码只使用同一块内存,直到整幅图片解码完毕。具体步骤如下:
(1)、在内存里先分配一个MCU行大小,再把要解码图象分成两个以上MCU行,具体MCU行数由图像大小及格式决定,然后初始化要解码图片的高度和宽度,并获得其缩小因子。其中计算缩小因子及初始化变量如下:
假设需解码的原图像的宽度和高为ImgWidth、ImgHeight,目的图像宽度和高度为LCDWidth、LCDHeight(即为显示屏幕的宽度和高度),则水平(X)和垂直(Y)方向的缩小因子factorX、factorY分别用需解码的原图像的宽度和高度除以目的图像的宽度和高度。采用16.16定点形式的Newton-Raphson迭代算法计算,定点表示是指用一个整数来表示浮点数,通常高位表示整数部分,低位表示小数部分,例如一个32位的整数,如果采用16.16的定点表示,意思是高16位代表整数,低16位代表小数。注意到图像的宽高均为整数,计算时必须先转换为定点数(左移16位),考虑到算法要求分母在[0.5,1)范围内,因此对分子分母进行等比例缩小(右移),总的结果是左移若干位,左移的位数由下列等式得出:
shiftX=16-log2(LCDWidth)-1;
shiftY=16-log2(LCDHeight)-1;
最终缩小因子由下列等式得出:
factorX=(ImgWidth<<shiftX)/(LCDWidth<<shiftX);
factory=(ImgHeight<<shiftY)/(LCDHeight<<shiftY);
缩小因子在下面缩小采样过程会使用到,作为循环的步长值。
(2)、按顺序取步骤(1)中分成的一个MCU行,对应生成一个MCU行的YUV数据,作为下一阶段缩小的源数据。
(3)、把步骤(2)生成的一个MCU行的YUV数据进行缩小采样,转换成RGB数据,并保存到目的缓冲位置。
由于使用的是定点运算,而最后要转换成图像的整数行号列号,因此每一次分段解码缩小处理之后,会有小数转换到整数的误差,需要获得下一次分段解码的原图像第一个象素行(定点数表示)firstSrcLine、目的图像的下一个象素行(正整数表示)nextDstLine,它们的初始化值为0。
处理流程如下所示,其中i,j分别为目的图象缓冲的行号和列号,tmpSrcLine和tmpSrcColumn分别为需解码的原图像YUV缓冲的行号和列号。具体步骤为:
a)i与tmpSrcLine的初始值为上一次分段解码后得出的nextDstLine,firstSrcLine;
b)如果当前原图像行号tmpSrcLine值如果小于MCU行的高度,执行c),否则执行i);
c)原图像、目的图像列号j,tmpSrcColumn值初始化为0;
d)通过i,j和tmpSrcLine,tmpSrcColumn分别获得目的图像、原图像的缓冲位置;
e)取出原图像缓冲的YUV数据,转换为RGB,保存到目的图像缓冲位置;
f)获得下一个列号:j增加1,tmpSrcColumn增加水平方向缩小因子factorX;
g)如果j小于LCD屏幕的宽度,执行d),否则执行h);
h)获得下一个行号:i增加1,tmpSrcLine增加垂直方向缩小因子factorY,执行b);
i)获得下一次分段解码的原图像第一个象素行(定点数)firstSrcLine、目的图像的下一个象素行(正整数)nextDstLine,结束本次分段解码。
(4)使用依次对图象分成的下一个MCU行重复步骤(2)、(3)、直至整幅图象解码完毕。
(5)、把解码完毕的整幅图片,缓冲送到显示屏显示。也可以每当解完一段就显示已经解完的部分。