| /* |
| * 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"); |
| ff_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; |
| } |