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 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (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 GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License 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 <stdlib.h> 24#include <inttypes.h> 25 26#include "swscale.h" 27#include "rgb2rgb.h" 28#include "libavutil/mem.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 36int main(int argc, char **argv) 37{ 38 int i, funcNum; 39 uint8_t *srcBuffer = av_malloc(SIZE); 40 uint8_t *dstBuffer = av_malloc(SIZE); 41 int failedNum = 0; 42 int passedNum = 0; 43 44 if (!srcBuffer || !dstBuffer) 45 return -1; 46 47 av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); 48 sws_rgb2rgb_init(); 49 50 for (funcNum = 0; ; funcNum++) { 51 struct func_info_s { 52 int src_bpp; 53 int dst_bpp; 54 const char *name; 55 void (*func)(const uint8_t *src, uint8_t *dst, int src_size); 56 } func_info[] = { 57 FUNC(2, 2, rgb12to15), 58 FUNC(2, 2, rgb15to16), 59 FUNC(2, 3, rgb15to24), 60 FUNC(2, 4, rgb15to32), 61 FUNC(2, 3, rgb16to24), 62 FUNC(2, 4, rgb16to32), 63 FUNC(3, 2, rgb24to15), 64 FUNC(3, 2, rgb24to16), 65 FUNC(3, 4, rgb24to32), 66 FUNC(4, 2, rgb32to15), 67 FUNC(4, 2, rgb32to16), 68 FUNC(4, 3, rgb32to24), 69 FUNC(2, 2, rgb16to15), 70 FUNC(2, 2, rgb12tobgr12), 71 FUNC(2, 2, rgb15tobgr15), 72 FUNC(2, 2, rgb15tobgr16), 73 FUNC(2, 3, rgb15tobgr24), 74 FUNC(2, 4, rgb15tobgr32), 75 FUNC(2, 2, rgb16tobgr15), 76 FUNC(2, 2, rgb16tobgr16), 77 FUNC(2, 3, rgb16tobgr24), 78 FUNC(2, 4, rgb16tobgr32), 79 FUNC(3, 2, rgb24tobgr15), 80 FUNC(3, 2, rgb24tobgr16), 81 FUNC(3, 3, rgb24tobgr24), 82 FUNC(3, 4, rgb24tobgr32), 83 FUNC(4, 2, rgb32tobgr15), 84 FUNC(4, 2, rgb32tobgr16), 85 FUNC(4, 3, rgb32tobgr24), 86 FUNC(4, 4, shuffle_bytes_2103), /* rgb32tobgr32 */ 87 FUNC(6, 6, rgb48tobgr48_nobswap), 88 FUNC(6, 6, rgb48tobgr48_bswap), 89 FUNC(8, 6, rgb64to48_nobswap), 90 FUNC(8, 6, rgb64to48_bswap), 91 FUNC(8, 6, rgb64tobgr48_nobswap), 92 FUNC(8, 6, rgb64tobgr48_bswap), 93 FUNC(0, 0, NULL) 94 }; 95 int width; 96 int failed = 0; 97 int srcBpp = 0; 98 int dstBpp = 0; 99 100 if (!func_info[funcNum].func) 101 break; 102 103 av_log(NULL, AV_LOG_INFO, "."); 104 memset(srcBuffer, srcByte, SIZE); 105 106 for (width = 63; width > 0; width--) { 107 int dstOffset; 108 for (dstOffset = 128; dstOffset < 196; dstOffset += 4) { 109 int srcOffset; 110 memset(dstBuffer, dstByte, SIZE); 111 112 for (srcOffset = 128; srcOffset < 196; srcOffset += 4) { 113 uint8_t *src = srcBuffer + srcOffset; 114 uint8_t *dst = dstBuffer + dstOffset; 115 const char *name = NULL; 116 117 // don't fill the screen with shit ... 118 if (failed) 119 break; 120 121 srcBpp = func_info[funcNum].src_bpp; 122 dstBpp = func_info[funcNum].dst_bpp; 123 name = func_info[funcNum].name; 124 125 func_info[funcNum].func(src, dst, width * srcBpp); 126 127 if (!srcBpp) 128 break; 129 130 for (i = 0; i < SIZE; i++) { 131 if (srcBuffer[i] != srcByte) { 132 av_log(NULL, AV_LOG_INFO, 133 "src damaged at %d w:%d src:%d dst:%d %s\n", 134 i, width, srcOffset, dstOffset, name); 135 failed = 1; 136 break; 137 } 138 } 139 for (i = 0; i < dstOffset; i++) { 140 if (dstBuffer[i] != dstByte) { 141 av_log(NULL, AV_LOG_INFO, 142 "dst damaged at %d w:%d src:%d dst:%d %s\n", 143 i, width, srcOffset, dstOffset, name); 144 failed = 1; 145 break; 146 } 147 } 148 for (i = dstOffset + width * dstBpp; i < SIZE; i++) { 149 if (dstBuffer[i] != dstByte) { 150 av_log(NULL, AV_LOG_INFO, 151 "dst damaged at %d w:%d src:%d dst:%d %s\n", 152 i, width, srcOffset, dstOffset, name); 153 failed = 1; 154 break; 155 } 156 } 157 } 158 } 159 } 160 if (failed) 161 failedNum++; 162 else if (srcBpp) 163 passedNum++; 164 } 165 166 av_log(NULL, AV_LOG_INFO, 167 "\n%d converters passed, %d converters randomly overwrote memory\n", 168 passedNum, failedNum); 169 return failedNum; 170} 171