1 /*****************************************************************************
2  *
3  *  XVID MPEG-4 VIDEO CODEC
4  *  - CBP related function  -
5  *
6  *  Copyright(C) 2002-2003 Edouard Gomez <ed.gomez@free.fr>
7  *               2003      Christoph Lampert <gruel@web.de>
8  *
9  *  This program is free software ; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation ; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program ; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  *
23  * $Id: cbp.c 1985 2011-05-18 09:02:35Z Isibaar $
24  *
25  ****************************************************************************/
26 
27 #include "../portab.h"
28 #include "cbp.h"
29 
30 cbpFuncPtr calc_cbp;
31 
32 /*
33  * Returns a field of bits that indicates non zero ac blocks
34  * for this macro block
35  */
36 
37 /* naive C */
38 uint32_t
calc_cbp_plain(const int16_t codes[6* 64])39 calc_cbp_plain(const int16_t codes[6 * 64])
40 {
41 	int i, j;
42 	uint32_t cbp = 0;
43 
44 	for (i = 0; i < 6; i++) {
45 		for (j=1; j<64;j++) {
46 			if (codes[64*i+j]) {
47             	cbp |= 1 << (5-i);
48 				break;
49 			}
50 		}
51 	}
52 	return cbp;
53 }
54 
55 /* optimized C */
56 uint32_t
calc_cbp_c(const int16_t codes[6* 64])57 calc_cbp_c(const int16_t codes[6 * 64])
58 {
59 	unsigned int i=6;
60 	uint32_t cbp = 0;
61 
62 /* uses fixed relation: 4*codes = 1*codes64 */
63 /* if prototype is changed (e.g. from int16_t to something like int32) this routine
64    has to be changed! */
65 
66 	do  {
67 		uint64_t *codes64 = (uint64_t*)codes;	/* the compiler doesn't really make this */
68 		uint32_t *codes32 = (uint32_t*)codes;	/* variables, just "addressing modes" */
69 
70 		cbp += cbp;
71         if (codes[1] || codes32[1]) {
72 			cbp++;
73 		}
74         else if (codes64[1] | codes64[2] | codes64[3]) {
75 			cbp++;
76 		}
77         else if (codes64[4] | codes64[5] | codes64[6] | codes64[7]) {
78 			cbp++;
79 		}
80         else if (codes64[8] | codes64[9] | codes64[10] | codes64[11]) {
81 			cbp++;
82 		}
83         else if (codes64[12] | codes64[13] | codes64[14] | codes64[15]) {
84 			cbp++;
85 		}
86 		codes += 64;
87 		i--;
88     } while (i != 0);
89 
90 	return cbp;
91 }
92 
93 
94 
95 
96 /* older code maybe better on some plattforms? */
97 #if 0
98 	for (i = 5; i >= 0; i--) {
99 		if (codes[1] | codes[2] | codes[3])
100                         cbp |= 1 << i;
101 		else {
102 			for (j = 4; j <= 56; j+=4) 	/* [60],[61],[62],[63] are last */
103 				if (codes[j] | codes[j+1] | codes[j+2] | codes[j+3]) {
104 				cbp |= 1 << i;
105 				break;
106 			}
107 		}
108 		codes += 64;
109 	}
110 
111 	return cbp;
112 #endif
113