苏泊尔耗的JPEG解码器[五(完)]

本文详细介绍了JPEG图像解码过程中的IDCT(反离散余弦变换)算法,包括AA&N算法和LLM算法的实现。通过对8x8系数矩阵的处理,演示了如何通过优化将复杂的矩阵运算分解为更简单的计算步骤,以提高解码效率。同时,代码示例展示了如何将这些算法应用于实际解码过程中,最后给出了算法的性能比较。
摘要由CSDN通过智能技术生成

[最终话]最惊心动魄的单元了,IDCT变换。近代图像处理技术的灵魂。本作可使用两种算法。AA&N和LLM算法。其中LLM算法的代码是在网站上找来的,仅可供教学用途。AA&N算法是偶整理的(当然,还是免不了参考别人的代码。)

介于各网站上基本都是抄来的文章,没有详细讲解的,偶就多写一点了。偶数学也不好,花了很多时间来学,理解上可能还是有不少问题,还请多包涵了^^b。

DCT算法是一个矩阵的乘法运算,并且是可逆的。因此,正向变换和反向变换可使用非常类似的算法。

JPEG的发明者曾经在FFT和DCT之间做出取舍,最终选择了DCT,是因为它有很多快速算法。

其基本的优化是,将8*8矩阵的乘法分解成两次矩阵乘法(即人们常说的二维IDCT分解为两次一维IDCT)。公式如下:

Z = AXA(t)

其中A(t)表示A的转置。

X是8*8的输入矩阵。这样,计算起来,就先对X的每一列和A的行进行计算,结果是一列,然后这一列再和A(t)的相对应行进行计算,结果又成为一行。由于每一列或一行的的每一个元素计算包括8次乘法和7次加法,所以一共有8*8*8*2次乘法和7*8*8*2次加法。(大概是这么多,偶数学也不咋滴-___-b)

然后,一维DCT还可以进一步优化,分为奇数列/行和偶数列/行:

  / Y[0] /     / a  c  a  f / / X[0] /     / b  d  e  g / / X[1] /
  | Y[1] |  =  | a  f -a -c | | X[2] |  +  | d -g -b -e | | X[3] |
  | Y[2] |     | a -f -a  c | | X[4] |     | e -b  g  d | | X[5] |
  / Y[3] /     / a -c  a -f / / X[6] /     / g -e  d -b / / X[7] /

  / Y[7] /     / a  c  a  f / / X[0] /     / b  d  e  g / / X[1] /
  | Y[6] |  =  | a  f -a -c | | X[2] |  -  | d -g -b -e | | X[3] |
  | Y[5] |  | a -f -a  c | | X[4] |     | e -b  g  d | | X[5] |
  / Y[4] /  / a -c  a -f / / X[6] /     / g -e  d -b / / X[7] /

其中Y[0]-Y[7]都是1*8的矩阵,X[1]-X[7]也都是1*8的矩阵。

{a, b, c, d, e, f, g} =  1/2 { cos(pi/4), cos(pi/16), cos(pi/8), cos(3pi/16), cos(5pi/16), cos(3pi/8), cos(7pi/16) }

在这之后的优化算法,就是各有千秋了,比较著名的有ChenDCT,LeeDCT,AA&N算法和LLM算法。其中AA&N算法只需要29次加法和5次乘法。(注意,它是指每次一维运算要29次加法和5次乘法,一共是需要29*8*2次加法和5*8*2次乘法的)。但它的条件是要对输入的矩阵首先各乘以一个因子。因为在矩阵从哈夫曼解开后,是游程码,游程码解开后,要进行反量化,这一次乘法是省不了的,所以把因子先乘到量化表上,就可以省去这些时间了(2007/1/26: 原来写成4次了,经Mr.Chen提醒现改正)。

本作因考虑移植性,使用的AA&N算法是整数算法,对小数进行了乘以256的操作。本作中的任何地方都不会用到浮点数。

LLM算法的速度和AA&N差不多(可能是偶写得太差了?-___-b)

jpegidct.h(这个头文件需要包含,以下两个c文件只能任选一个加到工程中。)

************************************************************************************************************

/**************************************************************************************************

  superarhow's JPEG decoder

  by superarhow(superarhow@hotmail.com).  All rights reserved.

 **************************************************************************************************/

#pragma once

#include "jpegdec2.h"

/* 2D-IDCT 变换 */
void jpeg_idct( p_jpeg_quality_table p_table, SHORT* in );
void jpeg_idct_prepare_qualitytable( p_jpeg_quality_table p_table ); 

*******************************************************************************************************

jpegidct.c(AA&N算法)

********************************************************************************************************

#include "jpegidct.h"
#include "memory.h"

/*
 *  AA&N reverse-dct arithmetic implemention
 * {a, b, c, d, e, f, g} =  1/2 { cos(pi/4), cos(pi/16), cos(pi/8), cos(3pi/16), cos(5pi/16), cos(3pi/8), cos(7pi/16) }
 *  if we let: (out[8][8] is the temporary place to hold our first 1D-DCT data)
 * X[0] = ( in[0, 0], in[1, 0], in[2, 0] ... in[7, 0] )
 * X[1] = ( in[0, 1], in[1, 1], in[2, 1] ... in[7, 1] )
 * ...
 * X[7] = ( in[0, 7], in[1, 7], in[2, 7] ... in[7, 7] )
 * Y[0] = ( out[0, 0], out[1, 0], out[2, 0] ... out[7, 0] )
 * Y[1] = ( out[0, 1], out[1, 1], out[2, 1] ... out[7, 1] )
 * ...
 * Y[7] = ( out[0, 7], out[1, 7], out[2, 7] ... out[7, 7] )
 * we'll have:
 *
 *  / Y[0] /     / a  c  a  f / / X[0] /     / b  d  e  g / / X[1] /
 *  | Y[1] |  &

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值