/*
 * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
 *
 * Blackfin video color space converter operations
 * convert I420 YV12 to RGB in various formats
 *
 * 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 <assert.h>
#include "config.h"
#include <unistd.h>
#include "libavutil/pixdesc.h"
#include "libswscale/rgb2rgb.h"
#include "libswscale/swscale.h"
#include "libswscale/swscale_internal.h"

#if defined(__FDPIC__) && CONFIG_SRAM
#define L1CODE __attribute__ ((l1_text))
#else
#define L1CODE
#endif

void ff_bfin_yuv2rgb555_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
                             int w, uint32_t *coeffs) L1CODE;

void ff_bfin_yuv2rgb565_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
                             int w, uint32_t *coeffs) L1CODE;

void ff_bfin_yuv2rgb24_line(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
                            int w, uint32_t *coeffs) L1CODE;

typedef void (* ltransform)(uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
                            int w, uint32_t *coeffs);


static void bfin_prepare_coefficients(SwsContext *c, int rgb, int masks)
{
    int oy;
    oy      = c->yOffset&0xffff;
    oy      = oy >> 3; // keep everything U8.0 for offset calculation

    c->oc   = 128*0x01010101U;
    c->oy   =  oy*0x01010101U;

    /* copy 64bit vector coeffs down to 32bit vector coeffs */
    c->cy  = c->yCoeff;
    c->zero = 0;

    if (rgb) {
        c->crv = c->vrCoeff;
        c->cbu = c->ubCoeff;
        c->cgu = c->ugCoeff;
        c->cgv = c->vgCoeff;
    } else {
        c->crv = c->ubCoeff;
        c->cbu = c->vrCoeff;
        c->cgu = c->vgCoeff;
        c->cgv = c->ugCoeff;
    }


    if (masks == 555) {
        c->rmask = 0x001f * 0x00010001U;
        c->gmask = 0x03e0 * 0x00010001U;
        c->bmask = 0x7c00 * 0x00010001U;
    } else if (masks == 565) {
        c->rmask = 0x001f * 0x00010001U;
        c->gmask = 0x07e0 * 0x00010001U;
        c->bmask = 0xf800 * 0x00010001U;
    }
}

static int core_yuv420_rgb(SwsContext *c,
                           uint8_t **in, int *instrides,
                           int srcSliceY, int srcSliceH,
                           uint8_t **oplanes, int *outstrides,
                           ltransform lcscf, int rgb, int masks)
{
    uint8_t *py,*pu,*pv,*op;
    int w  = instrides[0];
    int h2 = srcSliceH>>1;
    int i;

    bfin_prepare_coefficients(c, rgb, masks);

    py = in[0];
    pu = in[1+(1^rgb)];
    pv = in[1+(0^rgb)];

    op = oplanes[0] + srcSliceY*outstrides[0];

    for (i=0;i<h2;i++) {

        lcscf(py, pu, pv, op, w, &c->oy);

        py += instrides[0];
        op += outstrides[0];

        lcscf(py, pu, pv, op, w, &c->oy);

        py += instrides[0];
        pu += instrides[1];
        pv += instrides[2];
        op += outstrides[0];
    }

    return srcSliceH;
}


static int bfin_yuv420_rgb555(SwsContext *c,
                              uint8_t **in, int *instrides,
                              int srcSliceY, int srcSliceH,
                              uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb555_line, 1, 555);
}

static int bfin_yuv420_bgr555(SwsContext *c,
                              uint8_t **in, int *instrides,
                              int srcSliceY, int srcSliceH,
                              uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb555_line, 0, 555);
}

static int bfin_yuv420_rgb24(SwsContext *c,
                             uint8_t **in, int *instrides,
                             int srcSliceY, int srcSliceH,
                             uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb24_line, 1, 888);
}

static int bfin_yuv420_bgr24(SwsContext *c,
                             uint8_t **in, int *instrides,
                             int srcSliceY, int srcSliceH,
                             uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb24_line, 0, 888);
}

static int bfin_yuv420_rgb565(SwsContext *c,
                              uint8_t **in, int *instrides,
                              int srcSliceY, int srcSliceH,
                              uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb565_line, 1, 565);
}

static int bfin_yuv420_bgr565(SwsContext *c,
                              uint8_t **in, int *instrides,
                              int srcSliceY, int srcSliceH,
                              uint8_t **oplanes, int *outstrides)
{
    return core_yuv420_rgb(c, in, instrides, srcSliceY, srcSliceH, oplanes,
                           outstrides, ff_bfin_yuv2rgb565_line, 0, 565);
}


SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c)
{
    SwsFunc f;

    switch(c->dstFormat) {
    case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break;
    case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break;
    case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break;
    case PIX_FMT_BGR565: f = bfin_yuv420_bgr565; break;
    case PIX_FMT_RGB24:  f = bfin_yuv420_rgb24;  break;
    case PIX_FMT_BGR24:  f = bfin_yuv420_bgr24;  break;
    default:
        return 0;
    }

    av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
           av_get_pix_fmt_name(c->dstFormat));

    return f;
}
