理论公式:
验证数据
1.正向,数据源为YCbCr 8×8 数据
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <linux/fb.h>
#include <stdlib.h>#include <math.h>
#define PI 3.141593int main()
{double o[8][8]={};char i[64] = {-76,-73,-67,-62,-58,-67,-64,-55,-65,-69,-73,-38,-19,-43,-59,-56,-66,-69,-60,-15,16,-24,-62,-55,-65,-70,-57,-6,26,-22,-58,-59,-61,-67,-60,-24,-2,-40,-60,-58,-49,-63,-68,-58,-51,-60,-70,-53,-43,-57,-64,-69,-73,-67,-63,-45,-41,-49,-59,-60,-63,-52,-50,-34};char (*p)[8]=(char (*)[8])i;double s;double au;double av;for(int u=0;u<8;u++){for(int v=0;v<8;v++){for(int y=0;y<8;y++){for(int x=0;x<8;x++){s=s+(1.0/4)*p[y][x]*cos((2*y+1)*u*PI/16)*cos((2*x+1)*v*PI/16);}}if(u==0){au=1.0/sqrt(2);}else{au=1.0;}if(v==0){av=1.0/sqrt(2);}else{av=1.0;}s=s*au*av; //-30.1856int s1=round(s*100); //-3019s=s1/100.0; //-30.19o[u][v]=s;s=0;}}for(int a=0;a<8;a++){for(int b=0;b<8;b++){printf("%0.2f, ",o[a][b]);}puts("");}
}
此源数据和输出数据是Matlab 软件生成的,经验证,本程序生成的数据完全正确。
特别注意,使用math.h头,编译器必须加上参数 -lm 否则报错。
2.逆向转换
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <unistd.h>
#include <linux/fb.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.141593int main(void){double i[64]={-415.38, -30.19, -61.20, 27.24, 56.12, -20.10, -2.39, 0.46,4.47, -21.86, -60.76, 10.25 ,13.15, -7.09, -8.54 , 4.88,-46.83, 7.37, 77.13, -24.56, -28.91, 9.93, 5.42, -5.65,-48.53, 12.07, 34.10, -14.76, -10.24, 6.30, 1.83, 1.95,12.12 , -6.55, -13.20, -3.95, -1.87, 1.75, -2.79,3.14,-7.73, 2.91, 2.38, -5.94, -2.38, 0.94, 4.30, 1.85,-1.03, 0.18, 0.42, -2.42, -0.88, -3.02, 4.12, -0.66,-0.17, 0.14, -1.07, -4.19, -1.17, -0.10 ,0.50, 1.68};char o[8][8]={};double (*p)[8]=(double (*)[8])i;double s;double au;double av;for(int y=0;y<8;y++){for(int x=0;x<8;x++){for(int u=0;u<8;u++){for(int v=0;v<8;v++){if(u==0){au=1.0/sqrt(2);}else{au=1.0;}if(v==0){av=1.0/sqrt(2);}else{av=1.0;}s=s+(1.0/4)*au*av*p[u][v]*cos((2*y+1)*u*PI/16)*cos((2*x+1)*v*PI/16);}}o[y][x]=s;s=0;}}for(int a=0;a<8;a++){for(int b=0;b<8;b++){printf("%d ",o[a][b]);}puts("");}return 0;
}
没有加上四舍五入,数据有微小差别。