/*
 * Copyright (C) 2003-2011 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 <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <stdarg.h>

#undef HAVE_AV_CONFIG_H
#include "libavutil/imgutils.h"
#include "libavutil/mem.h"
#include "libavutil/avutil.h"
#include "libavutil/crc.h"
#include "libavutil/pixdesc.h"
#include "libavutil/lfg.h"
#include "swscale.h"

/* HACK Duplicated from swscale_internal.h.
 * Should be removed when a cleaner pixel format system exists. */
#define isGray(x)                      \
    ((x) == AV_PIX_FMT_GRAY8       ||     \
     (x) == AV_PIX_FMT_Y400A       ||     \
     (x) == AV_PIX_FMT_GRAY16BE    ||     \
     (x) == AV_PIX_FMT_GRAY16LE)
#define hasChroma(x)                   \
    (!(isGray(x)                ||     \
       (x) == AV_PIX_FMT_MONOBLACK ||     \
       (x) == AV_PIX_FMT_MONOWHITE))
#define isALPHA(x)                     \
    ((x) == AV_PIX_FMT_BGR32   ||         \
     (x) == AV_PIX_FMT_BGR32_1 ||         \
     (x) == AV_PIX_FMT_RGB32   ||         \
     (x) == AV_PIX_FMT_RGB32_1 ||         \
     (x) == AV_PIX_FMT_YUVA420P)

static uint64_t getSSD(const uint8_t *src1, const uint8_t *src2, int stride1,
                       int stride2, int w, int h)
{
    int x, y;
    uint64_t ssd = 0;

    for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
            int d = src1[x + y * stride1] - src2[x + y * stride2];
            ssd += d * d;
        }
    }
    return ssd;
}

struct Results {
    uint64_t ssdY;
    uint64_t ssdU;
    uint64_t ssdV;
    uint64_t ssdA;
    uint32_t crc;
};

// test by ref -> src -> dst -> out & compare out against ref
// ref & out are YV12
static int doTest(uint8_t *ref[4], int refStride[4], int w, int h,
                  enum AVPixelFormat srcFormat, enum AVPixelFormat dstFormat,
                  int srcW, int srcH, int dstW, int dstH, int flags,
                  struct Results *r)
{
    const AVPixFmtDescriptor *desc_yuva420p = av_pix_fmt_desc_get(AV_PIX_FMT_YUVA420P);
    const AVPixFmtDescriptor *desc_src      = av_pix_fmt_desc_get(srcFormat);
    const AVPixFmtDescriptor *desc_dst      = av_pix_fmt_desc_get(dstFormat);
    static enum AVPixelFormat cur_srcFormat;
    static int cur_srcW, cur_srcH;
    static uint8_t *src[4];
    static int srcStride[4];
    uint8_t *dst[4] = { 0 };
    uint8_t *out[4] = { 0 };
    int dstStride[4] = {0};
    int i;
    uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0;
    struct SwsContext *dstContext = NULL, *outContext = NULL;
    uint32_t crc = 0;
    int res      = 0;

    if (cur_srcFormat != srcFormat || cur_srcW != srcW || cur_srcH != srcH) {
        struct SwsContext *srcContext = NULL;
        int p;

        for (p = 0; p < 4; p++)
            av_freep(&src[p]);

        av_image_fill_linesizes(srcStride, srcFormat, srcW);
        for (p = 0; p < 4; p++) {
            srcStride[p] = FFALIGN(srcStride[p], 16);
            if (srcStride[p])
                src[p] = av_mallocz(srcStride[p] * srcH + 16);
            if (srcStride[p] && !src[p]) {
                perror("Malloc");
                res = -1;
                goto end;
            }
        }
        srcContext = sws_getContext(w, h, AV_PIX_FMT_YUVA420P, srcW, srcH,
                                    srcFormat, SWS_BILINEAR, NULL, NULL, NULL);
        if (!srcContext) {
            fprintf(stderr, "Failed to get %s ---> %s\n",
                    desc_yuva420p->name,
                    desc_src->name);
            res = -1;
            goto end;
        }
        sws_scale(srcContext, (const uint8_t * const*)ref, refStride, 0, h, src, srcStride);
        sws_freeContext(srcContext);

        cur_srcFormat = srcFormat;
        cur_srcW      = srcW;
        cur_srcH      = srcH;
    }

    av_image_fill_linesizes(dstStride, dstFormat, dstW);
    for (i = 0; i < 4; i++) {
        /* Image buffers passed into libswscale can be allocated any way you
         * prefer, as long as they're aligned enough for the architecture, and
         * they're freed appropriately (such as using av_free for buffers
         * allocated with av_malloc). */
        /* An extra 16 bytes is being allocated because some scalers may write
         * out of bounds. */
        dstStride[i] = FFALIGN(dstStride[i], 16);
        if (dstStride[i])
            dst[i] = av_mallocz(dstStride[i] * dstH + 16);
        if (dstStride[i] && !dst[i]) {
            perror("Malloc");
            res = -1;

            goto end;
        }
    }

    dstContext = sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat,
                                flags, NULL, NULL, NULL);
    if (!dstContext) {
        fprintf(stderr, "Failed to get %s ---> %s\n",
                desc_src->name, desc_dst->name);
        res = -1;
        goto end;
    }

    printf(" %s %dx%d -> %s %3dx%3d flags=%2d",
           desc_src->name, srcW, srcH,
           desc_dst->name, dstW, dstH,
           flags);
    fflush(stdout);

    sws_scale(dstContext, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride);

    for (i = 0; i < 4 && dstStride[i]; i++)
        crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i],
                     dstStride[i] * dstH);

    if (r && crc == r->crc) {
        ssdY = r->ssdY;
        ssdU = r->ssdU;
        ssdV = r->ssdV;
        ssdA = r->ssdA;
    } else {
        for (i = 0; i < 4; i++) {
            refStride[i] = FFALIGN(refStride[i], 16);
            if (refStride[i])
                out[i] = av_mallocz(refStride[i] * h);
            if (refStride[i] && !out[i]) {
                perror("Malloc");
                res = -1;
                goto end;
            }
        }
        outContext = sws_getContext(dstW, dstH, dstFormat, w, h,
                                    AV_PIX_FMT_YUVA420P, SWS_BILINEAR,
                                    NULL, NULL, NULL);
        if (!outContext) {
            fprintf(stderr, "Failed to get %s ---> %s\n",
                    desc_dst->name,
                    desc_yuva420p->name);
            res = -1;
            goto end;
        }
        sws_scale(outContext, (const uint8_t * const*)dst, dstStride, 0, dstH, out, refStride);

        ssdY = getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
        if (hasChroma(srcFormat) && hasChroma(dstFormat)) {
            //FIXME check that output is really gray
            ssdU = getSSD(ref[1], out[1], refStride[1], refStride[1],
                          (w + 1) >> 1, (h + 1) >> 1);
            ssdV = getSSD(ref[2], out[2], refStride[2], refStride[2],
                          (w + 1) >> 1, (h + 1) >> 1);
        }
        if (isALPHA(srcFormat) && isALPHA(dstFormat))
            ssdA = getSSD(ref[3], out[3], refStride[3], refStride[3], w, h);

        ssdY /= w * h;
        ssdU /= w * h / 4;
        ssdV /= w * h / 4;
        ssdA /= w * h;

        sws_freeContext(outContext);

        for (i = 0; i < 4; i++)
            if (refStride[i])
                av_free(out[i]);
    }

    printf(" CRC=%08x SSD=%5"PRId64 ",%5"PRId64 ",%5"PRId64 ",%5"PRId64 "\n",
           crc, ssdY, ssdU, ssdV, ssdA);

end:
    sws_freeContext(dstContext);

    for (i = 0; i < 4; i++)
        if (dstStride[i])
            av_free(dst[i]);

    return res;
}

static void selfTest(uint8_t *ref[4], int refStride[4], int w, int h,
                     enum AVPixelFormat srcFormat_in,
                     enum AVPixelFormat dstFormat_in)
{
    const int flags[] = { SWS_FAST_BILINEAR, SWS_BILINEAR, SWS_BICUBIC,
                          SWS_X, SWS_POINT, SWS_AREA, 0 };
    const int srcW   = w;
    const int srcH   = h;
    const int dstW[] = { srcW - srcW / 3, srcW, srcW + srcW / 3, 0 };
    const int dstH[] = { srcH - srcH / 3, srcH, srcH + srcH / 3, 0 };
    enum AVPixelFormat srcFormat, dstFormat;
    const AVPixFmtDescriptor *desc_src, *desc_dst;

    for (srcFormat = srcFormat_in != AV_PIX_FMT_NONE ? srcFormat_in : 0;
         srcFormat < AV_PIX_FMT_NB; srcFormat++) {
        if (!sws_isSupportedInput(srcFormat) ||
            !sws_isSupportedOutput(srcFormat))
            continue;

        desc_src = av_pix_fmt_desc_get(srcFormat);

        for (dstFormat = dstFormat_in != AV_PIX_FMT_NONE ? dstFormat_in : 0;
             dstFormat < AV_PIX_FMT_NB; dstFormat++) {
            int i, j, k;
            int res = 0;

            if (!sws_isSupportedInput(dstFormat) ||
                !sws_isSupportedOutput(dstFormat))
                continue;

            desc_dst = av_pix_fmt_desc_get(dstFormat);

            printf("%s -> %s\n", desc_src->name, desc_dst->name);
            fflush(stdout);

            for (k = 0; flags[k] && !res; k++)
                for (i = 0; dstW[i] && !res; i++)
                    for (j = 0; dstH[j] && !res; j++)
                        res = doTest(ref, refStride, w, h,
                                     srcFormat, dstFormat,
                                     srcW, srcH, dstW[i], dstH[j], flags[k],
                                     NULL);
            if (dstFormat_in != AV_PIX_FMT_NONE)
                break;
        }
        if (srcFormat_in != AV_PIX_FMT_NONE)
            break;
    }
}

static int fileTest(uint8_t *ref[4], int refStride[4], int w, int h, FILE *fp,
                    enum AVPixelFormat srcFormat_in,
                    enum AVPixelFormat dstFormat_in)
{
    char buf[256];

    while (fgets(buf, sizeof(buf), fp)) {
        struct Results r;
        enum AVPixelFormat srcFormat;
        char srcStr[12];
        int srcW, srcH;
        enum AVPixelFormat dstFormat;
        char dstStr[12];
        int dstW, dstH;
        int flags;
        int ret;

        ret = sscanf(buf,
                     " %12s %dx%d -> %12s %dx%d flags=%d CRC=%x"
                     " SSD=%"SCNd64 ", %"SCNd64 ", %"SCNd64 ", %"SCNd64 "\n",
                     srcStr, &srcW, &srcH, dstStr, &dstW, &dstH,
                     &flags, &r.crc, &r.ssdY, &r.ssdU, &r.ssdV, &r.ssdA);
        if (ret != 12) {
            srcStr[0] = dstStr[0] = 0;
            ret       = sscanf(buf, "%12s -> %12s\n", srcStr, dstStr);
        }

        srcFormat = av_get_pix_fmt(srcStr);
        dstFormat = av_get_pix_fmt(dstStr);

        if (srcFormat == AV_PIX_FMT_NONE || dstFormat == AV_PIX_FMT_NONE ||
            srcW > 8192U || srcH > 8192U || dstW > 8192U || dstH > 8192U) {
            fprintf(stderr, "malformed input file\n");
            return -1;
        }
        if ((srcFormat_in != AV_PIX_FMT_NONE && srcFormat_in != srcFormat) ||
            (dstFormat_in != AV_PIX_FMT_NONE && dstFormat_in != dstFormat))
            continue;
        if (ret != 12) {
            printf("%s", buf);
            continue;
        }

        doTest(ref, refStride, w, h,
               srcFormat, dstFormat,
               srcW, srcH, dstW, dstH, flags,
               &r);
    }

    return 0;
}

#define W 96
#define H 96

int main(int argc, char **argv)
{
    enum AVPixelFormat srcFormat = AV_PIX_FMT_NONE;
    enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
    uint8_t *rgb_data   = av_malloc(W * H * 4);
    const uint8_t * const rgb_src[4] = { rgb_data, NULL, NULL, NULL };
    int rgb_stride[4]   = { 4 * W, 0, 0, 0 };
    uint8_t *data       = av_malloc(4 * W * H);
    uint8_t *src[4]     = { data, data + W * H, data + W * H * 2, data + W * H * 3 };
    int stride[4]       = { W, W, W, W };
    int x, y;
    struct SwsContext *sws;
    AVLFG rand;
    int res = -1;
    int i;
    FILE *fp = NULL;

    if (!rgb_data || !data)
        return -1;

    for (i = 1; i < argc; i += 2) {
        if (argv[i][0] != '-' || i + 1 == argc)
            goto bad_option;
        if (!strcmp(argv[i], "-ref")) {
            fp = fopen(argv[i + 1], "r");
            if (!fp) {
                fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
                goto error;
            }
        } else if (!strcmp(argv[i], "-src")) {
            srcFormat = av_get_pix_fmt(argv[i + 1]);
            if (srcFormat == AV_PIX_FMT_NONE) {
                fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
                return -1;
            }
        } else if (!strcmp(argv[i], "-dst")) {
            dstFormat = av_get_pix_fmt(argv[i + 1]);
            if (dstFormat == AV_PIX_FMT_NONE) {
                fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
                return -1;
            }
        } else {
bad_option:
            fprintf(stderr, "bad option or argument missing (%s)\n", argv[i]);
            goto error;
        }
    }

    sws = sws_getContext(W / 12, H / 12, AV_PIX_FMT_RGB32, W, H,
                         AV_PIX_FMT_YUVA420P, SWS_BILINEAR, NULL, NULL, NULL);

    av_lfg_init(&rand, 1);

    for (y = 0; y < H; y++)
        for (x = 0; x < W * 4; x++)
            rgb_data[ x + y * 4 * W] = av_lfg_get(&rand);
    sws_scale(sws, rgb_src, rgb_stride, 0, H, src, stride);
    sws_freeContext(sws);
    av_free(rgb_data);

    if(fp) {
        res = fileTest(src, stride, W, H, fp, srcFormat, dstFormat);
        fclose(fp);
    } else {
        selfTest(src, stride, W, H, srcFormat, dstFormat);
        res = 0;
    }
error:
    av_free(data);

    return res;
}
