00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "dsputil.h"
00028 #include "binkdsp.h"
00029
00030 #define A1 2896
00031 #define A2 2217
00032 #define A3 3784
00033 #define A4 -5352
00034
00035 #define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
00036 const int a0 = (src)[s0] + (src)[s4]; \
00037 const int a1 = (src)[s0] - (src)[s4]; \
00038 const int a2 = (src)[s2] + (src)[s6]; \
00039 const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
00040 const int a4 = (src)[s5] + (src)[s3]; \
00041 const int a5 = (src)[s5] - (src)[s3]; \
00042 const int a6 = (src)[s1] + (src)[s7]; \
00043 const int a7 = (src)[s1] - (src)[s7]; \
00044 const int b0 = a4 + a6; \
00045 const int b1 = (A3*(a5 + a7)) >> 11; \
00046 const int b2 = ((A4*a5) >> 11) - b0 + b1; \
00047 const int b3 = (A1*(a6 - a4) >> 11) - b2; \
00048 const int b4 = ((A2*a7) >> 11) + b3 - b1; \
00049 (dest)[d0] = munge(a0+a2 +b0); \
00050 (dest)[d1] = munge(a1+a3-a2+b2); \
00051 (dest)[d2] = munge(a1-a3+a2+b3); \
00052 (dest)[d3] = munge(a0-a2 -b4); \
00053 (dest)[d4] = munge(a0-a2 +b4); \
00054 (dest)[d5] = munge(a1-a3+a2-b3); \
00055 (dest)[d6] = munge(a1+a3-a2-b2); \
00056 (dest)[d7] = munge(a0+a2 -b0); \
00057 }
00058
00059
00060 #define MUNGE_NONE(x) (x)
00061 #define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
00062
00063 #define MUNGE_ROW(x) (((x) + 0x7F)>>8)
00064 #define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
00065
00066 static inline void bink_idct_col(int *dest, const int32_t *src)
00067 {
00068 if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
00069 dest[0] =
00070 dest[8] =
00071 dest[16] =
00072 dest[24] =
00073 dest[32] =
00074 dest[40] =
00075 dest[48] =
00076 dest[56] = src[0];
00077 } else {
00078 IDCT_COL(dest, src);
00079 }
00080 }
00081
00082 static void bink_idct_c(int32_t *block)
00083 {
00084 int i;
00085 int temp[64];
00086
00087 for (i = 0; i < 8; i++)
00088 bink_idct_col(&temp[i], &block[i]);
00089 for (i = 0; i < 8; i++) {
00090 IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
00091 }
00092 }
00093
00094 static void bink_idct_add_c(uint8_t *dest, int linesize, int32_t *block)
00095 {
00096 int i, j;
00097
00098 bink_idct_c(block);
00099 for (i = 0; i < 8; i++, dest += linesize, block += 8)
00100 for (j = 0; j < 8; j++)
00101 dest[j] += block[j];
00102 }
00103
00104 static void bink_idct_put_c(uint8_t *dest, int linesize, int32_t *block)
00105 {
00106 int i;
00107 int temp[64];
00108 for (i = 0; i < 8; i++)
00109 bink_idct_col(&temp[i], &block[i]);
00110 for (i = 0; i < 8; i++) {
00111 IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
00112 }
00113 }
00114
00115 static void scale_block_c(const uint8_t src[64], uint8_t *dst, int linesize)
00116 {
00117 int i, j;
00118 uint16_t *dst1 = (uint16_t *) dst;
00119 uint16_t *dst2 = (uint16_t *)(dst + linesize);
00120
00121 for (j = 0; j < 8; j++) {
00122 for (i = 0; i < 8; i++) {
00123 dst1[i] = dst2[i] = src[i] * 0x0101;
00124 }
00125 src += 8;
00126 dst1 += linesize;
00127 dst2 += linesize;
00128 }
00129 }
00130
00131 void ff_binkdsp_init(BinkDSPContext *c)
00132 {
00133 c->idct_add = bink_idct_add_c;
00134 c->idct_put = bink_idct_put_c;
00135 c->scale_block = scale_block_c;
00136 }