Merge "configure: detect toolchain if not specified"
[profile/ivi/libvpx.git] / vp8 / encoder / preproc.c
1 /*
2  *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license and patent
5  *  grant that can be found in the LICENSE file in the root of the source
6  *  tree. All contributing project authors may be found in the AUTHORS
7  *  file in the root of the source tree.
8  */
9
10
11 /****************************************************************************
12 *
13 *   Module Title :     preproc.c
14 *
15 *   Description  :     Simple pre-processor.
16 *
17 ****************************************************************************/
18
19 /****************************************************************************
20 *  Header Files
21 ****************************************************************************/
22
23 #include "memory.h"
24 #include "preproc7.h"
25 #include "vpx_mem/vpx_mem.h"
26
27 /****************************************************************************
28 *  Macros
29 ****************************************************************************/
30 #define FRAMECOUNT 7
31 #define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
32
33 /****************************************************************************
34 *  Imports
35 ****************************************************************************/
36 extern void vp8_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled);
37
38 /****************************************************************************
39 *  Exported Global Variables
40 ****************************************************************************/
41 void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength);
42 void temp_filter_mmx
43 (
44     pre_proc_instance *ppi,
45     unsigned char *s,
46     unsigned char *d,
47     int bytes,
48     int strength
49 );
50 void temp_filter_wmt
51 (
52     pre_proc_instance *ppi,
53     unsigned char *s,
54     unsigned char *d,
55     int bytes,
56     int strength
57 );
58
59 /****************************************************************************
60  *
61  *  ROUTINE       : temp_filter_c
62  *
63  *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
64  *                  unsigned char *s     : Pointer to source frame.
65  *                  unsigned char *d     : Pointer to destination frame.
66  *                  int bytes            : Number of bytes to filter.
67  *                  int strength         : Strength of filter to apply.
68  *
69  *  OUTPUTS       : None.
70  *
71  *  RETURNS       : void
72  *
73  *  FUNCTION      : Performs a closesness adjusted temporarl blur
74  *
75  *  SPECIAL NOTES : Destination frame can be same as source frame.
76  *
77  ****************************************************************************/
78 void temp_filter_c
79 (
80     pre_proc_instance *ppi,
81     unsigned char *s,
82     unsigned char *d,
83     int bytes,
84     int strength
85 )
86 {
87     int byte = 0;
88     unsigned char *frameptr = ppi->frame_buffer;
89
90     if (ppi->frame == 0)
91     {
92         do
93         {
94             int frame = 0;
95
96             do
97             {
98                 *frameptr = s[byte];
99                 ++frameptr;
100                 ++frame;
101             }
102             while (frame < FRAMECOUNT);
103
104             d[byte] = s[byte];
105
106             ++byte;
107         }
108         while (byte < bytes);
109     }
110     else
111     {
112         int modifier;
113         int offset = (ppi->frame % FRAMECOUNT);
114
115         do
116         {
117             int accumulator = 0;
118             int count = 0;
119             int frame = 0;
120
121             frameptr[offset] = s[byte];
122
123             do
124             {
125                 int pixel_value = *frameptr;
126
127                 modifier   = s[byte];
128                 modifier  -= pixel_value;
129                 modifier  *= modifier;
130                 modifier >>= strength;
131                 modifier  *= 3;
132
133                 if (modifier > 16)
134                     modifier = 16;
135
136                 modifier = 16 - modifier;
137
138                 accumulator += modifier * pixel_value;
139
140                 count += modifier;
141
142                 frameptr++;
143
144                 ++frame;
145             }
146             while (frame < FRAMECOUNT);
147
148             accumulator += (count >> 1);
149             accumulator *= ppi->fixed_divide[count];
150             accumulator >>= 16;
151
152             d[byte] = accumulator;
153
154             ++byte;
155         }
156         while (byte < bytes);
157     }
158
159     ++ppi->frame;
160 }
161 /****************************************************************************
162  *
163  *  ROUTINE       : delete_pre_proc
164  *
165  *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
166  *
167  *  OUTPUTS       : None.
168  *
169  *  RETURNS       : void
170  *
171  *  FUNCTION      : Deletes a pre-processing instance.
172  *
173  *  SPECIAL NOTES : None.
174  *
175  ****************************************************************************/
176 void delete_pre_proc(pre_proc_instance *ppi)
177 {
178     if (ppi->frame_buffer_alloc)
179         vpx_free(ppi->frame_buffer_alloc);
180
181     ppi->frame_buffer_alloc = 0;
182     ppi->frame_buffer      = 0;
183
184     if (ppi->fixed_divide_alloc)
185         vpx_free(ppi->fixed_divide_alloc);
186
187     ppi->fixed_divide_alloc = 0;
188     ppi->fixed_divide      = 0;
189 }
190
191 /****************************************************************************
192  *
193  *  ROUTINE       : init_pre_proc
194  *
195  *  INPUTS        : pre_proc_instance *ppi : Pointer to pre-processor instance.
196  *                  int frame_size        : Number of bytes in one frame.
197  *
198  *  OUTPUTS       : None.
199  *
200  *  RETURNS       : int: 1 if successful, 0 if failed.
201  *
202  *  FUNCTION      : Initializes prepprocessor instance.
203  *
204  *  SPECIAL NOTES : None.
205  *
206  ****************************************************************************/
207 int init_pre_proc7(pre_proc_instance *ppi, int frame_size)
208 {
209     int i;
210     int mmx_enabled;
211     int xmm_enabled;
212     int wmt_enabled;
213
214     vp8_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
215
216     if (wmt_enabled)
217         temp_filter = temp_filter_wmt;
218     else if (mmx_enabled)
219         temp_filter = temp_filter_mmx;
220     else
221         temp_filter = temp_filter_c;
222
223
224     delete_pre_proc(ppi);
225
226     ppi->frame_buffer_alloc = vpx_malloc(32 + frame_size * FRAMECOUNT * sizeof(unsigned char));
227
228     if (!ppi->frame_buffer_alloc)
229     {
230         delete_pre_proc(ppi);
231         return 0;
232     }
233
234     ppi->frame_buffer = (unsigned char *) ROUNDUP32(ppi->frame_buffer_alloc);
235
236     ppi->fixed_divide_alloc = vpx_malloc(32 + 255 * sizeof(unsigned int));
237
238     if (!ppi->fixed_divide_alloc)
239     {
240         delete_pre_proc(ppi);
241         return 0;
242     }
243
244     ppi->fixed_divide = (unsigned int *) ROUNDUP32(ppi->fixed_divide_alloc);
245
246     for (i = 1; i < 255; i++)
247         ppi->fixed_divide[i] = 0x10000 / i;
248
249     return 1;
250 }