]> git.sesse.net Git - ffmpeg/blob - libswscale/cs_test.c
Replace huge switch statement by a lookup table.
[ffmpeg] / libswscale / cs_test.c
1 /*
2  * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include <stdio.h>
22 #include <string.h>              /* for memset() */
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <inttypes.h>
26
27 #include "swscale.h"
28 #include "rgb2rgb.h"
29
30 #define SIZE 1000
31 #define srcByte 0x55
32 #define dstByte 0xBB
33
34 #define FUNC(s,d,n) {s,d,#n,n}
35
36 static int cpu_caps;
37
38 static char *args_parse(int argc, char *argv[])
39 {
40     int o;
41
42     while ((o = getopt(argc, argv, "m23")) != -1) {
43         switch (o) {
44             case 'm':
45                 cpu_caps |= SWS_CPU_CAPS_MMX;
46                 break;
47             case '2':
48                 cpu_caps |= SWS_CPU_CAPS_MMX2;
49                 break;
50             case '3':
51                 cpu_caps |= SWS_CPU_CAPS_3DNOW;
52                 break;
53             default:
54                 av_log(NULL, AV_LOG_ERROR, "Unknown option %c\n", o);
55         }
56     }
57
58     return argv[optind];
59 }
60
61 int main(int argc, char **argv)
62 {
63         int i, funcNum;
64         uint8_t *srcBuffer= (uint8_t*)av_malloc(SIZE);
65         uint8_t *dstBuffer= (uint8_t*)av_malloc(SIZE);
66         int failedNum=0;
67         int passedNum=0;
68         
69         av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n");
70         args_parse(argc, argv);
71         av_log(NULL, AV_LOG_INFO, "CPU capabilities forced to %x\n", cpu_caps);
72         sws_rgb2rgb_init(cpu_caps);
73         
74         for(funcNum=0; ; funcNum++){
75                 struct func_info_s {
76                         int src_bpp;
77                         int dst_bpp;
78                         char *name;
79                         void (*func)(const uint8_t *src, uint8_t *dst, long src_size);
80                 } func_info[] = {
81                         FUNC(2, 2, rgb15to16),
82                         FUNC(2, 3, rgb15to24),
83                         FUNC(2, 4, rgb15to32),
84                         FUNC(2, 3, rgb16to24),
85                         FUNC(2, 4, rgb16to32),
86                         FUNC(3, 2, rgb24to15),
87                         FUNC(3, 2, rgb24to16),
88                         FUNC(3, 4, rgb24to32),
89                         FUNC(4, 2, rgb32to15),
90                         FUNC(4, 2, rgb32to16),
91                         FUNC(4, 3, rgb32to24),
92                         FUNC(2, 2, rgb16to15),
93                         FUNC(2, 2, rgb15tobgr15),
94                         FUNC(2, 2, rgb15tobgr16),
95                         FUNC(2, 3, rgb15tobgr24),
96                         FUNC(2, 4, rgb15tobgr32),
97                         FUNC(2, 2, rgb16tobgr15),
98                         FUNC(2, 2, rgb16tobgr16),
99                         FUNC(2, 3, rgb16tobgr24),
100                         FUNC(2, 4, rgb16tobgr32),
101                         FUNC(3, 2, rgb24tobgr15),
102                         FUNC(3, 2, rgb24tobgr16),
103                         FUNC(3, 3, rgb24tobgr24),
104                         FUNC(3, 4, rgb24tobgr32),
105                         FUNC(4, 2, rgb32tobgr15),
106                         FUNC(4, 2, rgb32tobgr16),
107                         FUNC(4, 3, rgb32tobgr24),
108                         FUNC(4, 4, rgb32tobgr32),
109                         FUNC(0, 0, NULL)
110                 };
111                 int width;
112                 int failed=0;
113                 int srcBpp=0;
114                 int dstBpp=0;
115
116                 if (!func_info[funcNum].func) break;
117
118                 av_log(NULL, AV_LOG_INFO,".");
119                 memset(srcBuffer, srcByte, SIZE);
120
121                 for(width=32; width<64; width++){
122                         int dstOffset;
123                         for(dstOffset=128; dstOffset<196; dstOffset+=4){
124                                 int srcOffset;
125                                 memset(dstBuffer, dstByte, SIZE);
126
127                                 for(srcOffset=128; srcOffset<196; srcOffset+=4){
128                                         uint8_t *src= srcBuffer+srcOffset;
129                                         uint8_t *dst= dstBuffer+dstOffset;
130                                         char *name=NULL;
131                                         
132                                         if(failed) break; //don't fill the screen with shit ...
133
134                                         srcBpp = func_info[funcNum].src_bpp;
135                                         dstBpp = func_info[funcNum].dst_bpp;
136                                         name   = func_info[funcNum].name;
137
138                                         func_info[funcNum].func(src, dst, width*srcBpp);
139
140                                         if(!srcBpp) break;
141
142                                         for(i=0; i<SIZE; i++){
143                                                 if(srcBuffer[i]!=srcByte){
144                                                         av_log(NULL, AV_LOG_INFO, "src damaged at %d w:%d src:%d dst:%d %s\n", 
145                                                                 i, width, srcOffset, dstOffset, name);
146                                                         failed=1;
147                                                         break;
148                                                 }
149                                         }
150                                         for(i=0; i<dstOffset; i++){
151                                                 if(dstBuffer[i]!=dstByte){
152                                                         av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", 
153                                                                 i, width, srcOffset, dstOffset, name);
154                                                         failed=1;
155                                                         break;
156                                                 }
157                                         }
158                                         for(i=dstOffset + width*dstBpp; i<SIZE; i++){
159                                                 if(dstBuffer[i]!=dstByte){
160                                                         av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", 
161                                                                 i, width, srcOffset, dstOffset, name);
162                                                         failed=1;
163                                                         break;
164                                                 }
165                                         }
166                                 }
167                         }
168                 }
169                 if(failed) failedNum++;
170                 else if(srcBpp) passedNum++;
171         }
172         
173         av_log(NULL, AV_LOG_INFO, "\n%d converters passed, %d converters randomly overwrote memory\n", passedNum, failedNum);
174         return failedNum;
175 }