This was rewritten by Michael, switch copyrights to him and license to LGPL.
[ffmpeg.git] / 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 Street, 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=63; width>0; 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 }