1. /*
  2.     Project  : H.264 encoder test    
  3.     Module   : Tranform algorithms
  4.  
  5.     Author   : Marko 'Fador' Viitanen
  6.  
  7.     Date     : 27/6/2009
  8.     Modified : 28/6/2009
  9. */
  10.  
  11. #include "common.h"
  12.  
  13. //Octave
  14. //a=1/2
  15. //b=sqrt(2/5)
  16. //d=1/2
  17.  
  18. //E2=[a^2, a*b, a^2, a*b;a*b, b^2, a*b, b^2;a^2, a*b, a^2, a*b;a*b, b^2, a*b, b^2]
  19.  
  20.  
  21. //4x4 Integer Cosine Transform
  22. uint8 transform_4x4(sint32 *block, sint32 *target)
  23. {
  24.     sint32 helper[4*4];
  25.     uint8 i;
  26.  
  27.     //[1, 1, 1, 1
  28.     // 2, 1,-1,-2
  29.     // 1,-1,-1, 1
  30.     // 1,-2, 2,-1
  31.     helper[0]=block[0]+block[4]+block[8]+block[12];
  32.     helper[4]=2*block[0]+block[4]-block[8]-2*block[12];
  33.     helper[8]=block[0]-block[4]-block[8]+block[12];
  34.     helper[12]=block[0]-2*block[4]+2*block[8]-block[12];
  35.  
  36.     helper[1]=block[1]+block[5]+block[9]+block[13];
  37.     helper[5]=2*block[1]+block[5]-block[9]-2*block[13];
  38.     helper[9]=block[1]-block[5]-block[9]+block[13];
  39.     helper[13]=block[1]-2*block[5]+2*block[9]-block[13];
  40.  
  41.     helper[2]=block[2]+block[6]+block[10]+block[14];
  42.     helper[6]=2*block[2]+block[6]-block[10]-2*block[14];
  43.     helper[10]=block[2]-block[6]-block[10]+block[14];
  44.     helper[14]=block[2]-2*block[6]+2*block[10]-block[14];
  45.  
  46.     helper[3]=block[3]+block[7]+block[11]+block[15];
  47.     helper[7]=2*block[3]+block[7]-block[11]-2*block[15];
  48.     helper[11]=block[3]-block[7]-block[11]+block[15];
  49.     helper[15]=block[3]-2*block[7]+2*block[11]-block[15];
  50.  
  51.     // [1, 2, 1, 1
  52.     //  1, 1,-1,-2
  53.     //  1,-1,-1, 2
  54.     //  1,-2, 1,-1]
  55.  
  56.     target[0]=helper[0]+helper[1]+helper[2]+helper[3];
  57.     target[1]=2*helper[0]+helper[1]-helper[2]-2*helper[3];
  58.     target[2]=helper[0]-helper[1]-helper[2]+helper[3];
  59.     target[3]=helper[0]-2*helper[1]+2*helper[2]-helper[3];
  60.  
  61.     target[4]=helper[4]+helper[5]+helper[6]+helper[7];
  62.     target[5]=2*helper[4]+helper[5]-helper[6]-2*helper[7];
  63.     target[6]=helper[4]-helper[5]-helper[6]+helper[7];
  64.     target[7]=helper[4]-2*helper[5]+2*helper[6]-helper[7];
  65.  
  66.     target[8]=helper[8]+helper[9]+helper[10]+helper[11];
  67.     target[9]=2*helper[8]+helper[9]-helper[10]-2*helper[11];
  68.     target[10]=helper[8]-helper[9]-helper[10]+helper[11];
  69.     target[11]=helper[8]-2*helper[9]+2*helper[10]-helper[11];
  70.  
  71.     target[12]=helper[12]+helper[13]+helper[14]+helper[15];
  72.     target[13]=2*helper[12]+helper[13]-helper[14]-2*helper[15];
  73.     target[14]=helper[12]-helper[13]-helper[14]+helper[15];
  74.     target[15]=helper[12]-2*helper[13]+2*helper[14]-helper[15];
  75.  
  76.     //for(i=0;i<16;i++)
  77.         //target[i]=round(target[i]*E_f[i]);
  78.     return 1;
  79. }
  80.  
  81. //4x4 Inverse Integer Cosine Transform
  82. uint8 itransform_4x4(sint32 *block, sint32 *target)
  83. {
  84.     sint32 helper[4*4];
  85.  
  86.     uint8 i;
  87.     //[1,  1,  1, 1/2
  88.     // 1, 1/2,-1, -1
  89.     // 1,-1/2,-1  ,1
  90.     // 1, -1,  1,-1/2
  91.     helper[0]=block[0]+block[4]+block[8]+block[12]/2;
  92.     helper[4]=block[0]+block[4]/2-block[8]-block[12];
  93.     helper[8]=block[0]-block[4]/2-block[8]+block[12];
  94.     helper[12]=block[0]-block[4]+block[8]-block[12]/2;
  95.  
  96.     helper[1]=block[1]+block[5]+block[9]+block[13]/2;
  97.     helper[5]=block[1]+block[5]/2-block[9]-block[13];
  98.     helper[9]=block[1]-block[5]/2-block[9]+block[13];
  99.     helper[13]=block[1]-block[5]+block[9]-block[13]/2;    
  100.    
  101.     helper[2]=block[2]+block[6]+block[10]+block[14]/2;
  102.     helper[6]=block[2]+block[6]/2-block[10]-block[14];
  103.     helper[10]=block[2]-block[6]/2-block[10]+block[14];
  104.     helper[14]=block[2]-block[6]+block[10]-block[14]/2;    
  105.    
  106.     helper[3]=block[3]+block[7]+block[11]+block[15]/2;
  107.     helper[7]=block[3]+block[7]/2-block[11]-block[15];
  108.     helper[11]=block[3]-block[7]/2-block[11]+block[15];
  109.     helper[15]=block[3]-block[7]+block[11]-block[15]/2;
  110.  
  111.     //for(i=0;i<16;i++)
  112.         //helper[i]= round(helper[i]*E_i[i]);
  113.  
  114.     // [1,  1,   1,   1
  115.     //  1, 1/2,-1/2,-1
  116.     //  1, -1,  -1,   1
  117.     //  1/2,-1,  1, -1/2]
  118.  
  119.     target[0]=(helper[0]+helper[1]+helper[2]+helper[3]/2);
  120.     target[1]=(helper[0]+helper[1]/2-helper[2]-helper[3]);
  121.     target[2]=(helper[0]-helper[1]/2-helper[2]+helper[3]);
  122.     target[3]=(helper[0]-helper[1]+helper[2]-helper[3]/2);
  123.  
  124.     target[4]=(helper[4]+helper[5]+helper[6]+helper[7]/2);
  125.     target[5]=(helper[4]+helper[5]/2-helper[6]-helper[7]);
  126.     target[6]=(helper[4]-helper[5]/2-helper[6]+helper[7]);
  127.     target[7]=(helper[4]-helper[5]+helper[6]-helper[7]/2);
  128.  
  129.     target[8]=(helper[8]+helper[9]+helper[10]+helper[11]/2);
  130.     target[9]=(helper[8]+helper[9]/2-helper[10]-helper[11]);
  131.     target[10]=(helper[8]-helper[9]/2-helper[10]+helper[11]);
  132.     target[11]=(helper[8]-helper[9]+helper[10]-helper[11]/2);
  133.  
  134.     target[12]=(helper[12]+helper[13]+helper[14]+helper[15]/2);
  135.     target[13]=(helper[12]+helper[13]/2-helper[14]-helper[15]);
  136.     target[14]=(helper[12]-helper[13]/2-helper[14]+helper[15]);
  137.     target[15]=(helper[12]-helper[13]+helper[14]-helper[15]/2);  
  138.  
  139.  
  140.     return 1;
  141. }
  142.  
  143. //4x4 Hadamard transformation
  144. uint8 transformDC_4x4(sint32 *block, sint32 *target)
  145. {
  146.     sint32 helper[4*4];
  147.  
  148.     //[1,  1,  1,  1
  149.     // 1,  1, -1, -1
  150.     // 1, -1, -1  ,1
  151.     // 1, -1,  1, -1
  152.     helper[0]=block[0]+block[4]+block[8]+block[12];
  153.     helper[4]=block[0]+block[4]-block[8]-block[12];
  154.     helper[8]=block[0]-block[4]-block[8]+block[12];
  155.     helper[12]=block[0]-block[4]+block[8]-block[12];
  156.  
  157.     helper[1]=block[1]+block[5]+block[9]+block[13];
  158.     helper[5]=block[1]+block[5]-block[9]-block[13];
  159.     helper[9]=block[1]-block[5]-block[9]+block[13];
  160.     helper[13]=block[1]-block[5]+block[9]-block[13];    
  161.    
  162.     helper[2]=block[2]+block[6]+block[9]+block[14];
  163.     helper[6]=block[2]+block[6]-block[9]-block[14];
  164.     helper[10]=block[2]-block[6]-block[9]+block[14];
  165.     helper[14]=block[2]-block[6]+block[9]-block[14];    
  166.    
  167.     helper[3]=block[3]+block[7]+block[10]+block[15];
  168.     helper[7]=block[3]+block[7]-block[10]-block[15];
  169.     helper[11]=block[3]-block[7]-block[10]+block[15];
  170.     helper[15]=block[3]-block[7]+block[10]-block[15];
  171.  
  172.  
  173.     //[1,  1,  1,  1
  174.     // 1,  1, -1, -1
  175.     // 1, -1, -1  ,1
  176.     // 1, -1,  1, -1
  177.  
  178.     target[0]=round(helper[0]+helper[1]+helper[2]+helper[3])>>1;
  179.     target[1]=round(helper[0]+helper[1]-helper[2]-helper[3])>>1;
  180.     target[2]=round(helper[0]-helper[1]-helper[2]+helper[3])>>1;
  181.     target[3]=round(helper[0]-helper[1]+helper[2]-helper[3])>>1;
  182.  
  183.     target[4]=round(helper[4]+helper[5]+helper[6]+helper[7])>>1;
  184.     target[5]=round(helper[4]+helper[5]-helper[6]-helper[7])>>1;
  185.     target[6]=round(helper[4]-helper[5]-helper[6]+helper[7])>>1;
  186.     target[7]=round(helper[4]-helper[5]+helper[6]-helper[7])>>1;
  187.  
  188.     target[6]=round(helper[8]+helper[9]+helper[10]+helper[11])>>1;
  189.     target[9]=round(helper[8]+helper[9]-helper[10]-helper[11])>>1;
  190.     target[10]=round(helper[8]-helper[9]-helper[10]+helper[11])>>1;
  191.     target[11]=round(helper[8]-helper[9]+helper[10]-helper[11])>>1;
  192.  
  193.     target[12]=round(helper[12]+helper[13]+helper[14]+helper[15])>>1;
  194.     target[13]=round(helper[12]+helper[13]-helper[14]-helper[15])>>1;
  195.     target[14]=round(helper[12]-helper[13]-helper[14]+helper[15])>>1;
  196.     target[15]=round(helper[12]-helper[13]+helper[14]-helper[15])>>1;  
  197.  
  198.  
  199.     return 1;
  200.  
  201.  
  202. }
  203.  
  204.  
  205. //2x2 Hadamard transformation
  206. uint8 transformDC_2x2(sint32 *block, sint32 *target)
  207. {
  208.     sint32 helper[2*2];
  209.  
  210.     //[1,  1,
  211.     // 1,  -1]
  212.  
  213.     helper[0]=block[0]+block[2];
  214.     helper[2]=block[0]-block[2];
  215.  
  216.     helper[1]=block[1]+block[3];
  217.     helper[3]=block[1]-block[3];
  218.  
  219.     //[1,  1,
  220.     // 1,  -1]
  221.  
  222.     target[0]=round(helper[0]+helper[1])>>1;
  223.     target[1]=round(helper[0]+helper[1])>>1;
  224.  
  225.     target[2]=round(helper[2]-helper[3])>>1;
  226.     target[3]=round(helper[2]-helper[3])>>1;
  227.  
  228.     return 1;
  229.  
  230. }
  231.