//
// Copyright 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// copyimage.cpp: Defines image copying functions

#include "image_util/copyimage.h"
#include "common/unsafe_buffers.h"

namespace angle
{

namespace
{
inline uint32_t SwizzleBGRAToRGBA(uint32_t argb)
{
    return ((argb & 0x000000FF) << 16) |  // Move BGRA blue to RGBA blue
           ((argb & 0x00FF0000) >> 16) |  // Move BGRA red to RGBA red
           ((argb & 0xFF00FF00));         // Keep alpha and green
}

void CopyBGRA8ToRGBA8Fast(const uint8_t *source,
                          int srcYAxisPitch,
                          uint8_t *dest,
                          int destYAxisPitch,
                          int destWidth,
                          int destHeight)
{
    for (int y = 0; y < destHeight; ++y)
    {
        const uint32_t *src32 =
            reinterpret_cast<const uint32_t *>(ANGLE_UNSAFE_TODO(source + y * srcYAxisPitch));
        uint32_t *dest32 =
            reinterpret_cast<uint32_t *>(ANGLE_UNSAFE_TODO(dest + y * destYAxisPitch));
        const uint32_t *end32 = ANGLE_UNSAFE_TODO(src32 + destWidth);
        while (src32 != end32)
        {
            ANGLE_UNSAFE_TODO(*dest32++ = SwizzleBGRAToRGBA(*src32++));
        }
    }
}

void CopyRGBA8ToRGBA8Fast(const uint8_t *source,
                          int srcYAxisPitch,
                          uint8_t *dest,
                          int destYAxisPitch,
                          int destWidth,
                          int destHeight)
{
    // If Y axis pitch is packed and the source is also packed and stored contiguously, copy the
    // whole source to the dest in a single memcpy operation.
    if (destYAxisPitch == destWidth * 4 && srcYAxisPitch == destWidth * 4)
    {
        size_t totalSize = destHeight * destWidth * 4;
        ANGLE_UNSAFE_TODO(memcpy(dest, source, totalSize));
        return;
    }

    // If X axis pitch is 4 bytes but Y axis pitch is not packed, copy the source to dest line by
    // line.
    for (int y = 0; y < destHeight; ++y)
    {
        const uint8_t *src = ANGLE_UNSAFE_TODO(source + y * srcYAxisPitch);
        uint8_t *dst       = ANGLE_UNSAFE_TODO(dest + y * destYAxisPitch);
        ANGLE_UNSAFE_TODO(memcpy(dst, src, destWidth * 4));
    }
}
}  // namespace

void CopyBGRA8ToRGBA8(const uint8_t *source,
                      int srcXAxisPitch,
                      int srcYAxisPitch,
                      uint8_t *dest,
                      int destXAxisPitch,
                      int destYAxisPitch,
                      int destWidth,
                      int destHeight)
{
    if (srcXAxisPitch == 4 && destXAxisPitch == 4)
    {
        CopyBGRA8ToRGBA8Fast(source, srcYAxisPitch, dest, destYAxisPitch, destWidth, destHeight);
        return;
    }

    for (int y = 0; y < destHeight; ++y)
    {
        uint8_t *dst       = ANGLE_UNSAFE_TODO(dest + y * destYAxisPitch);
        const uint8_t *src = ANGLE_UNSAFE_TODO(source + y * srcYAxisPitch);
        const uint8_t *end = ANGLE_UNSAFE_TODO(src + destWidth * srcXAxisPitch);

        while (src != end)
        {
            *reinterpret_cast<uint32_t *>(dst) =
                SwizzleBGRAToRGBA(*reinterpret_cast<const uint32_t *>(src));
            ANGLE_UNSAFE_TODO({
                src += srcXAxisPitch;
                dst += destXAxisPitch;
            })
        }
    }
}

void CopyRGBA8ToRGBA8(const uint8_t *source,
                      int srcXAxisPitch,
                      int srcYAxisPitch,
                      uint8_t *dest,
                      int destXAxisPitch,
                      int destYAxisPitch,
                      int destWidth,
                      int destHeight)
{
    if (srcXAxisPitch == 4 && destXAxisPitch == 4)
    {
        CopyRGBA8ToRGBA8Fast(source, srcYAxisPitch, dest, destYAxisPitch, destWidth, destHeight);
        return;
    }

    for (int y = 0; y < destHeight; ++y)
    {
        uint8_t *dst       = ANGLE_UNSAFE_TODO(dest + y * destYAxisPitch);
        const uint8_t *src = ANGLE_UNSAFE_TODO(source + y * srcYAxisPitch);
        const uint8_t *end = ANGLE_UNSAFE_TODO(src + destWidth * srcXAxisPitch);

        while (src != end)
        {
            *reinterpret_cast<uint32_t *>(dst) = *reinterpret_cast<const uint32_t *>(src);
            ANGLE_UNSAFE_TODO({
                src += srcXAxisPitch;
                dst += destXAxisPitch;
            })
        }
    }
}

}  // namespace angle
