/* * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include <string.h> /* for memset() */ #include <stdlib.h> #include <inttypes.h> #include "swscale.h" #include "rgb2rgb.h" #include "libavutil/mem.h" #define SIZE 1000 #define srcByte 0x55 #define dstByte 0xBB #define FUNC(s, d, n) { s, d, #n, n } int main(int argc, char **argv) { int i, funcNum; uint8_t *srcBuffer = av_malloc(SIZE); uint8_t *dstBuffer = av_malloc(SIZE); int failedNum = 0; int passedNum = 0; if (!srcBuffer || !dstBuffer) return -1; av_log(NULL, AV_LOG_INFO, "memory corruption test ...\n"); sws_rgb2rgb_init(); for (funcNum = 0; ; funcNum++) { struct func_info_s { int src_bpp; int dst_bpp; const char *name; void (*func)(const uint8_t *src, uint8_t *dst, int src_size); } func_info[] = { FUNC(2, 2, rgb12to15), FUNC(2, 2, rgb15to16), FUNC(2, 3, rgb15to24), FUNC(2, 4, rgb15to32), FUNC(2, 3, rgb16to24), FUNC(2, 4, rgb16to32), FUNC(3, 2, rgb24to15), FUNC(3, 2, rgb24to16), FUNC(3, 4, rgb24to32), FUNC(4, 2, rgb32to15), FUNC(4, 2, rgb32to16), FUNC(4, 3, rgb32to24), FUNC(2, 2, rgb16to15), FUNC(2, 2, rgb12tobgr12), FUNC(2, 2, rgb15tobgr15), FUNC(2, 2, rgb15tobgr16), FUNC(2, 3, rgb15tobgr24), FUNC(2, 4, rgb15tobgr32), FUNC(2, 2, rgb16tobgr15), FUNC(2, 2, rgb16tobgr16), FUNC(2, 3, rgb16tobgr24), FUNC(2, 4, rgb16tobgr32), FUNC(3, 2, rgb24tobgr15), FUNC(3, 2, rgb24tobgr16), FUNC(3, 3, rgb24tobgr24), FUNC(3, 4, rgb24tobgr32), FUNC(4, 2, rgb32tobgr15), FUNC(4, 2, rgb32tobgr16), FUNC(4, 3, rgb32tobgr24), FUNC(4, 4, shuffle_bytes_2103), /* rgb32tobgr32 */ FUNC(6, 6, rgb48tobgr48_nobswap), FUNC(6, 6, rgb48tobgr48_bswap), FUNC(8, 6, rgb64to48_nobswap), FUNC(8, 6, rgb64to48_bswap), FUNC(8, 6, rgb64tobgr48_nobswap), FUNC(8, 6, rgb64tobgr48_bswap), FUNC(0, 0, NULL) }; int width; int failed = 0; int srcBpp = 0; int dstBpp = 0; if (!func_info[funcNum].func) break; av_log(NULL, AV_LOG_INFO, "."); memset(srcBuffer, srcByte, SIZE); for (width = 63; width > 0; width--) { int dstOffset; for (dstOffset = 128; dstOffset < 196; dstOffset += 4) { int srcOffset; memset(dstBuffer, dstByte, SIZE); for (srcOffset = 128; srcOffset < 196; srcOffset += 4) { uint8_t *src = srcBuffer + srcOffset; uint8_t *dst = dstBuffer + dstOffset; const char *name = NULL; // don't fill the screen with shit ... if (failed) break; srcBpp = func_info[funcNum].src_bpp; dstBpp = func_info[funcNum].dst_bpp; name = func_info[funcNum].name; func_info[funcNum].func(src, dst, width * srcBpp); if (!srcBpp) break; for (i = 0; i < SIZE; i++) { if (srcBuffer[i] != srcByte) { av_log(NULL, AV_LOG_INFO, "src damaged at %d w:%d src:%d dst:%d %s\n", i, width, srcOffset, dstOffset, name); failed = 1; break; } } for (i = 0; i < dstOffset; i++) { if (dstBuffer[i] != dstByte) { av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", i, width, srcOffset, dstOffset, name); failed = 1; break; } } for (i = dstOffset + width * dstBpp; i < SIZE; i++) { if (dstBuffer[i] != dstByte) { av_log(NULL, AV_LOG_INFO, "dst damaged at %d w:%d src:%d dst:%d %s\n", i, width, srcOffset, dstOffset, name); failed = 1; break; } } } } } if (failed) failedNum++; else if (srcBpp) passedNum++; } av_log(NULL, AV_LOG_INFO, "\n%d converters passed, %d converters randomly overwrote memory\n", passedNum, failedNum); return failedNum; }