package org.kne.codec.kif;

import org.kne.membandboost.MembandBoost;

public class ColorTransform {

    // ==================== RGB 版本（3通道） ====================

    /**
     * R-G 和 B-G 跨通道颜色变换（RGB）
     * 编码：R' = R - G, G' = G, B' = B - G
     */
    public static int[] colorTransform(int[] input, int w, int h) {
        int[] output = MembandBoost.allocateUninitializedIntArray(input.length);
        for (int i = 0; i < input.length; i++) {
            int rgb = input[i];
            int r = (rgb >> 16) & 0xFF;
            int g = (rgb >> 8) & 0xFF;
            int b = rgb & 0xFF;
            byte rg = (byte) (r - g);
            byte bg = (byte) (b - g);
            output[i] = ((rg & 0xFF) << 16) | ((g & 0xFF) << 8) | (bg & 0xFF);
        }
        return output;
    }

    public static int[] colorInverse(int[] input, int w, int h) {
        int[] output = MembandBoost.allocateUninitializedIntArray(input.length);
        for (int i = 0; i < input.length; i++) {
            int packed = input[i];
            int rg = (packed >> 16) & 0xFF;
            int g = (packed >> 8) & 0xFF;
            int bg = packed & 0xFF;
            int r = g + rg;
            int b = g + bg;
            output[i] = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
        }
        return output;
    }

    public static void colorTransformInPlace(int[] input, int w, int h) {
        for (int i = 0; i < input.length; i++) {
            int rgb = input[i];
            int r = (rgb >> 16) & 0xFF;
            int g = (rgb >> 8) & 0xFF;
            int b = rgb & 0xFF;
            byte rg = (byte) (r - g);
            byte bg = (byte) (b - g);
            input[i] = ((rg & 0xFF) << 16) | ((g & 0xFF) << 8) | (bg & 0xFF);
        }
    }

    public static void colorInverseInPlace(int[] input, int w, int h) {
        for (int i = 0; i < input.length; i++) {
            int packed = input[i];
            int rg = (packed >> 16) & 0xFF;
            int g = (packed >> 8) & 0xFF;
            int bg = packed & 0xFF;
            int r = g + rg;
            int b = g + bg;
            input[i] = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
        }
    }

    // ==================== RGBA 版本（4通道，Alpha 原封不动） ====================

    /**
     * RGBA 颜色变换：R' = R - G, G' = G, B' = B - G, A' = A（原封不动）
     */
    public static int[] colorTransformRGBA(int[] input, int w, int h) {
        int[] output = MembandBoost.allocateUninitializedIntArray(input.length);
        for (int i = 0; i < input.length; i++) {
            int pixel = input[i];
            int r = (pixel >> 16) & 0xFF;
            int g = (pixel >> 8) & 0xFF;
            int b = pixel & 0xFF;
            int a = (pixel >> 24) & 0xFF; // Alpha 原封不动
            byte rg = (byte) (r - g);
            byte bg = (byte) (b - g);
            output[i] = ((a & 0xFF) << 24) | ((rg & 0xFF) << 16) | ((g & 0xFF) << 8) | (bg & 0xFF);
        }
        return output;
    }

    public static int[] colorInverseRGBA(int[] input, int w, int h) {
        int[] output = MembandBoost.allocateUninitializedIntArray(input.length);
        for (int i = 0; i < input.length; i++) {
            int packed = input[i];
            int a = (packed >> 24) & 0xFF;
            int rg = (packed >> 16) & 0xFF;
            int g = (packed >> 8) & 0xFF;
            int bg = packed & 0xFF;
            int r = g + rg;
            int b = g + bg;
            output[i] = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
        }
        return output;
    }

    public static void colorTransformRGBAInPlace(int[] input, int w, int h) {
        for (int i = 0; i < input.length; i++) {
            int pixel = input[i];
            int r = (pixel >> 16) & 0xFF;
            int g = (pixel >> 8) & 0xFF;
            int b = pixel & 0xFF;
            int a = (pixel >> 24) & 0xFF;
            byte rg = (byte) (r - g);
            byte bg = (byte) (b - g);
            input[i] = ((a & 0xFF) << 24) | ((rg & 0xFF) << 16) | ((g & 0xFF) << 8) | (bg & 0xFF);
        }
    }

    public static void colorInverseRGBAInPlace(int[] input, int w, int h) {
        for (int i = 0; i < input.length; i++) {
            int packed = input[i];
            int a = (packed >> 24) & 0xFF;
            int rg = (packed >> 16) & 0xFF;
            int g = (packed >> 8) & 0xFF;
            int bg = packed & 0xFF;
            int r = g + rg;
            int b = g + bg;
            input[i] = ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
        }
    }
}