/*
 * 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 <unistd.h>
#include <stdlib.h>
#include <inttypes.h>

#include "swscale.h"
#include "rgb2rgb.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, 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, 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(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;
}
