/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"

/* This is the software implementation of the YUV texture support */

#include "SDL_assert.h"

#include "SDL_yuv_sw_c.h"


SDL_SW_YUVTexture *
SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
{
    SDL_SW_YUVTexture *swdata;

    switch (format) {
    case SDL_PIXELFORMAT_YV12:
    case SDL_PIXELFORMAT_IYUV:
    case SDL_PIXELFORMAT_YUY2:
    case SDL_PIXELFORMAT_UYVY:
    case SDL_PIXELFORMAT_YVYU:
    case SDL_PIXELFORMAT_NV12:
    case SDL_PIXELFORMAT_NV21:
        break;
    default:
        SDL_SetError("Unsupported YUV format");
        return NULL;
    }

    swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata));
    if (!swdata) {
        SDL_OutOfMemory();
        return NULL;
    }

    swdata->format = format;
    swdata->target_format = SDL_PIXELFORMAT_UNKNOWN;
    swdata->w = w;
    swdata->h = h;
    {
        const int sz_plane         = w * h;
        const int sz_plane_chroma  = ((w + 1) / 2) * ((h + 1) / 2);
        const int sz_plane_packed  = ((w + 1) / 2) * h;
        int dst_size = 0;     
        switch(format) 
        {
            case SDL_PIXELFORMAT_YV12: /**< Planar mode: Y + V + U  (3 planes) */
            case SDL_PIXELFORMAT_IYUV: /**< Planar mode: Y + U + V  (3 planes) */
                dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma;
                break;

            case SDL_PIXELFORMAT_YUY2: /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */
            case SDL_PIXELFORMAT_UYVY: /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */
            case SDL_PIXELFORMAT_YVYU: /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */
                dst_size = 4 * sz_plane_packed;
                break;

            case SDL_PIXELFORMAT_NV12: /**< Planar mode: Y + U/V interleaved  (2 planes) */
            case SDL_PIXELFORMAT_NV21: /**< Planar mode: Y + V/U interleaved  (2 planes) */
                dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma;
                break;

            default:
                SDL_assert(0 && "We should never get here (caught above)");
                break;
        }
        swdata->pixels = (Uint8 *) SDL_malloc(dst_size);
        if (!swdata->pixels) {
            SDL_SW_DestroyYUVTexture(swdata);
            SDL_OutOfMemory();
            return NULL;
        }
    }

    /* Find the pitch and offset values for the texture */
    switch (format) {
    case SDL_PIXELFORMAT_YV12:
    case SDL_PIXELFORMAT_IYUV:
        swdata->pitches[0] = w;
        swdata->pitches[1] = (swdata->pitches[0] + 1) / 2;
        swdata->pitches[2] = (swdata->pitches[0] + 1) / 2;
        swdata->planes[0] = swdata->pixels;
        swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
        swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2);
        break;
    case SDL_PIXELFORMAT_YUY2:
    case SDL_PIXELFORMAT_UYVY:
    case SDL_PIXELFORMAT_YVYU:
        swdata->pitches[0] = ((w + 1) / 2) * 4;
        swdata->planes[0] = swdata->pixels;
        break;

    case SDL_PIXELFORMAT_NV12:
    case SDL_PIXELFORMAT_NV21:
        swdata->pitches[0] = w;
        swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2);
        swdata->planes[0] = swdata->pixels;
        swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
        break;

    default:
        SDL_assert(0 && "We should never get here (caught above)");
        break;
    }

    /* We're all done.. */
    return (swdata);
}

int
SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels,
                             int *pitch)
{
    *pixels = swdata->planes[0];
    *pitch = swdata->pitches[0];
    return 0;
}

int
SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
                        const void *pixels, int pitch)
{
    switch (swdata->format) {
    case SDL_PIXELFORMAT_YV12:
    case SDL_PIXELFORMAT_IYUV:
        if (rect->x == 0 && rect->y == 0 &&
            rect->w == swdata->w && rect->h == swdata->h) {
                SDL_memcpy(swdata->pixels, pixels,
                           (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2));
        } else {
            Uint8 *src, *dst;
            int row;
            size_t length;

            /* Copy the Y plane */
            src = (Uint8 *) pixels;
            dst = swdata->pixels + rect->y * swdata->w + rect->x;
            length = rect->w;
            for (row = 0; row < rect->h; ++row) {
                SDL_memcpy(dst, src, length);
                src += pitch;
                dst += swdata->w;
            }
            
            /* Copy the next plane */
            src = (Uint8 *) pixels + rect->h * pitch;
            dst = swdata->pixels + swdata->h * swdata->w;
            dst += rect->y/2 * ((swdata->w + 1) / 2) + rect->x/2;
            length = (rect->w + 1) / 2;
            for (row = 0; row < (rect->h + 1)/2; ++row) {
                SDL_memcpy(dst, src, length);
                src += (pitch + 1)/2;
                dst += (swdata->w + 1)/2;
            }

            /* Copy the next plane */
            src = (Uint8 *) pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2);
            dst = swdata->pixels + swdata->h * swdata->w +
                  ((swdata->h + 1)/2) * ((swdata->w+1) / 2);
            dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
            length = (rect->w + 1) / 2;
            for (row = 0; row < (rect->h + 1)/2; ++row) {
                SDL_memcpy(dst, src, length);
                src += (pitch + 1)/2;
                dst += (swdata->w + 1)/2;
            }
        }
        break;
    case SDL_PIXELFORMAT_YUY2:
    case SDL_PIXELFORMAT_UYVY:
    case SDL_PIXELFORMAT_YVYU:
        {
            Uint8 *src, *dst;
            int row;
            size_t length;

            src = (Uint8 *) pixels;
            dst =
                swdata->planes[0] + rect->y * swdata->pitches[0] +
                rect->x * 2;
            length = 4 * ((rect->w + 1) / 2);
            for (row = 0; row < rect->h; ++row) {
                SDL_memcpy(dst, src, length);
                src += pitch;
                dst += swdata->pitches[0];
            }
        }
        break;
    case SDL_PIXELFORMAT_NV12:
    case SDL_PIXELFORMAT_NV21:
        {
            if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) {
                SDL_memcpy(swdata->pixels, pixels,
                        (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2));
            } else {

                Uint8 *src, *dst;
                int row;
                size_t length;

                /* Copy the Y plane */
                src = (Uint8 *) pixels;
                dst = swdata->pixels + rect->y * swdata->w + rect->x;
                length = rect->w;
                for (row = 0; row < rect->h; ++row) {
                    SDL_memcpy(dst, src, length);
                    src += pitch;
                    dst += swdata->w;
                }
                
                /* Copy the next plane */
                src = (Uint8 *) pixels + rect->h * pitch;
                dst = swdata->pixels + swdata->h * swdata->w;
                dst += 2 * ((rect->y + 1)/2) * ((swdata->w + 1) / 2) + 2 * (rect->x/2);
                length = 2 * ((rect->w + 1) / 2);
                for (row = 0; row < (rect->h + 1)/2; ++row) {
                    SDL_memcpy(dst, src, length);
                    src += 2 * ((pitch + 1)/2);
                    dst += 2 * ((swdata->w + 1)/2);
                }
            }
        }
    }
    return 0;
}

int
SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
                              const Uint8 *Yplane, int Ypitch,
                              const Uint8 *Uplane, int Upitch,
                              const Uint8 *Vplane, int Vpitch)
{
    const Uint8 *src;
    Uint8 *dst;
    int row;
    size_t length;

    /* Copy the Y plane */
    src = Yplane;
    dst = swdata->pixels + rect->y * swdata->w + rect->x;
    length = rect->w;
    for (row = 0; row < rect->h; ++row) {
        SDL_memcpy(dst, src, length);
        src += Ypitch;
        dst += swdata->w;
    }

    /* Copy the U plane */
    src = Uplane;
    if (swdata->format == SDL_PIXELFORMAT_IYUV) {
        dst = swdata->pixels + swdata->h * swdata->w;
    } else {
        dst = swdata->pixels + swdata->h * swdata->w +
              ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
    }
    dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
    length = (rect->w + 1) / 2;
    for (row = 0; row < (rect->h + 1)/2; ++row) {
        SDL_memcpy(dst, src, length);
        src += Upitch;
        dst += (swdata->w + 1)/2;
    }

    /* Copy the V plane */
    src = Vplane;
    if (swdata->format == SDL_PIXELFORMAT_YV12) {
        dst = swdata->pixels + swdata->h * swdata->w;
    } else {
        dst = swdata->pixels + swdata->h * swdata->w +
              ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
    }
    dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2;
    length = (rect->w + 1) / 2;
    for (row = 0; row < (rect->h + 1)/2; ++row) {
        SDL_memcpy(dst, src, length);
        src += Vpitch;
        dst += (swdata->w + 1)/2;
    }
    return 0;
}

int
SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect,
                      void **pixels, int *pitch)
{
    switch (swdata->format) {
    case SDL_PIXELFORMAT_YV12:
    case SDL_PIXELFORMAT_IYUV:
    case SDL_PIXELFORMAT_NV12:
    case SDL_PIXELFORMAT_NV21:
        if (rect
            && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w
                || rect->h != swdata->h)) {
            return SDL_SetError
                ("YV12, IYUV, NV12, NV21 textures only support full surface locks");
        }
        break;
    }

    if (rect) {
        *pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2;
    } else {
        *pixels = swdata->planes[0];
    }
    *pitch = swdata->pitches[0];
    return 0;
}

void
SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata)
{
}

int
SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect,
                    Uint32 target_format, int w, int h, void *pixels,
                    int pitch)
{
    int stretch;

    /* Make sure we're set up to display in the desired format */
    if (target_format != swdata->target_format && swdata->display) {
        SDL_FreeSurface(swdata->display);
        swdata->display = NULL;
    }

    stretch = 0;
    if (srcrect->x || srcrect->y || srcrect->w < swdata->w || srcrect->h < swdata->h) {
        /* The source rectangle has been clipped.
           Using a scratch surface is easier than adding clipped
           source support to all the blitters, plus that would
           slow them down in the general unclipped case.
         */
        stretch = 1;
    } else if ((srcrect->w != w) || (srcrect->h != h)) {
        stretch = 1;
    }
    if (stretch) {
        int bpp;
        Uint32 Rmask, Gmask, Bmask, Amask;

        if (swdata->display) {
            swdata->display->w = w;
            swdata->display->h = h;
            swdata->display->pixels = pixels;
            swdata->display->pitch = pitch;
        } else {
            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
                                       &Bmask, &Amask);
            swdata->display =
                SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask,
                                         Gmask, Bmask, Amask);
            if (!swdata->display) {
                return (-1);
            }
        }
        if (!swdata->stretch) {
            /* This must have succeeded in SDL_SW_SetupYUVDisplay() earlier */
            SDL_PixelFormatEnumToMasks(target_format, &bpp, &Rmask, &Gmask,
                                       &Bmask, &Amask);
            swdata->stretch =
                SDL_CreateRGBSurface(0, swdata->w, swdata->h, bpp, Rmask,
                                     Gmask, Bmask, Amask);
            if (!swdata->stretch) {
                return (-1);
            }
        }
        pixels = swdata->stretch->pixels;
        pitch = swdata->stretch->pitch;
    }
    if (SDL_ConvertPixels(swdata->w, swdata->h, swdata->format,
                          swdata->planes[0], swdata->pitches[0], 
                          target_format, pixels, pitch) < 0) {
        return -1;
    }
    if (stretch) {
        SDL_Rect rect = *srcrect;
        SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL);
    }
    return 0;
}

void
SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata)
{
    if (swdata) {
        SDL_free(swdata->pixels);
        SDL_FreeSurface(swdata->stretch);
        SDL_FreeSurface(swdata->display);
        SDL_free(swdata);
    }
}

/* vi: set ts=4 sw=4 expandtab: */
