
/**
 * Zigzag 映射：将有符号字节映射为非负字节
 * 0→0, -1→1, 1→2, -2→3, 2→4, ...
 */
uchar zigzag_map(char x) {
    int v = (int)x;  // char 转为 int（保留符号）
    return (uchar)((v >= 0) ? (v << 1) : ((-v << 1) - 1));
}

/**
 * Zigzag 逆映射：将非负字节还原为有符号字节
 * 0→0, 1→-1, 2→1, 3→-2, 4→2, ...
 */
char zigzag_unmap(uchar y) {
    int v = (int)y;        // 转为无符号 0~255
    return (char)((v & 1) == 0 ? (v >> 1) : (-((v + 1) >> 1)));
}




/**
 * 像素安全加法：RGBA 四个通道分别相加，结果裁剪到 0~255
 */
int pixelAdd(int a, int b) {
    int ar = (a >> 16) & 0xFF;
    int ag = (a >> 8) & 0xFF;
    int ab = a & 0xFF;
    int aa = (a >> 24) & 0xFF;
    
    int br = (b >> 16) & 0xFF;
    int bg = (b >> 8) & 0xFF;
    int bb = b & 0xFF;
    int ba = (b >> 24) & 0xFF;
    
    int r = ar + br;
    int g = ag + bg;
    int bv = ab + bb;
    int av = aa + ba;
    
    // 用 &0xFF 替代 min/max，保留低 8 位（自动溢出，等同于裁剪）
    return ((av & 0xFF) << 24) |
           ((r & 0xFF) << 16) |
           ((g & 0xFF) << 8) |
           (bv & 0xFF);
}
/**
 * 像素安全减法（等效于 Java 的 pixelSub）
 * 逐通道相减，结果裁剪到 0~255，组装回 ARGB
 */
int pixelSub(int a, int b) {
    int ar = (a >> 16) & 0xFF;
    int ag = (a >> 8) & 0xFF;
    int ab = a & 0xFF;
    int aa = (a >> 24) & 0xFF;
    
    int br = (b >> 16) & 0xFF;
    int bg = (b >> 8) & 0xFF;
    int bb = b & 0xFF;
    int ba = (b >> 24) & 0xFF;
    
    int r = ar - br;
    int g = ag - bg;
    int bv = ab - bb;
    int av = aa - ba;
    
    return ((av & 0xFF) << 24) |
           ((r & 0xFF) << 16) |
           ((g & 0xFF) << 8) |
           (bv & 0xFF);
}


/**
 * 位平面编码（矩阵转置风格）- 等效于 Java 版本
 * 
 * 核心逻辑：
 *   对于输出数组的每个字节，依次从输入数组的8个位平面各取1个bit
 *   即：输出字节的 bit i = 输入数组第 i 个位平面的当前位
 * 
 * 输出数组的每个字节，由8个位平面的各1个bit组成
 * 等价于：把 8×len 的 bit 矩阵转置为 len×8 的 bit 矩阵
 */
__kernel void encodePacked(
    __global const uchar* input,   // 输入字节数组
    __global uchar* output,        // 输出字节数组（长度与输入相同）
    int len                        // 输入/输出长度
) {
    int outIdx = get_global_id(0);
    if (outIdx >= len) return;
    
    int outByte = 0;
    
    // 从8个位平面各取1个bit，组装成一个字节
    for (int plane = 0; plane < 8; plane++) {
        int bitpos = (outIdx << 3) + plane;
        int inputPos = bitpos % len;
        int bitShift = bitpos / len;
        int bit = (input[inputPos] >> (7 - bitShift)) & 1;
        outByte |= (bit << plane);
    }
    
    output[outIdx] = (uchar)outByte;
}

__kernel void decodePacked(__global const unsigned char* datain, 
                           __global unsigned char* dataout, 
                           int size) {
    int outIdx = get_global_id(0);
    
    // 边界检查
    if (outIdx >= size) {
        return;
    }
    
    int outByte = 0;
    
    // 从 8 个位平面各取 1 个 bit，组装成一个字节
    // plane 0 → bit7, plane 1 → bit6, ..., plane 7 → bit0
    for (int plane = 0; plane < 8; plane++) {
        int bitpos = plane * size + outIdx;
        int inputpos = bitpos >> 3;
        int inputshift = bitpos & 0b111;
        int bit = (datain[inputpos] >> inputshift) & 1;
        outByte |= (bit << (7 - plane));
    }
    
    dataout[outIdx] = (unsigned char)outByte;
}

/**
 * 序列化 + Zigzag 映射（RGBA 交错）
 */
__kernel void serializeRGBAWithZigzag(
    __global int* pixels,
    __global uchar* output,
    int size
) {
    int i = get_global_id(0);
    if (i >= size) return;

    int pixel = pixels[i];

    char r = (char)((pixel >> 16) & 0xFF);
    char g = (char)((pixel >> 8) & 0xFF);
    char b = (char)(pixel & 0xFF);
    char a = (char)((pixel >> 24) & 0xFF);

    int idx = i * 4;
    output[idx + 0] = zigzag_map(r);
    output[idx + 1] = zigzag_map(g);
    output[idx + 2] = zigzag_map(b);
    output[idx + 3] = zigzag_map(a);
}
// 对应 deserializeRGBAWithZigzag
__kernel void deserializeRGBAWithZigzag(
    __global const uchar* data,    // 输入：Zigzag 映射后的字节流（RGBA 交错）
    __global int* pixels,          // 输出：像素数组（ARGB）
    int size                       // 像素数量 (w * h)
) {
    int i = get_global_id(0);
    if (i >= size) return;
    
    int idx = i * 4;
    
    // 读取并逆映射四个通道
    uchar r_raw = data[idx];
    uchar g_raw = data[idx + 1];
    uchar b_raw = data[idx + 2];
    uchar a_raw = data[idx + 3];
    
    char r = zigzag_unmap(r_raw);
    char g = zigzag_unmap(g_raw);
    char b = zigzag_unmap(b_raw);
    char a = zigzag_unmap(a_raw);
    
    // 组装成 ARGB (Java 的 int 格式)
    // 注意：OpenCL 的 int 是 32 位有符号，和 Java 一致
    pixels[i] = ((int)(a & 0xFF) << 24) |
                ((int)(r & 0xFF) << 16) |
                ((int)(g & 0xFF) << 8)  |
                (int)(b & 0xFF);
}
/**
 * 序列化 + Zigzag 映射（平面 RGBA）
 */
__kernel void serializePlannarRGBAWithZigzag(
    __global int* pixels,
    __global uchar* output,
    int size
) {
    int i = get_global_id(0);
    if (i >= size) return;

    int pixel = pixels[i];

    char r = (char)((pixel >> 16) & 0xFF);
    char g = (char)((pixel >> 8) & 0xFF);
    char b = (char)(pixel & 0xFF);
    char a = (char)((pixel >> 24) & 0xFF);

    int rOffset = 0;
    int gOffset = size;
    int bOffset = size * 2;
    int aOffset = size * 3;

    output[rOffset + i] = zigzag_map(r);
    output[gOffset + i] = zigzag_map(g);
    output[bOffset + i] = zigzag_map(b);
    output[aOffset + i] = zigzag_map(a);
}
// 对应 deserializePlannarRGBAWithZigzag
__kernel void deserializePlannarRGBAWithZigzag(
    __global const uchar* data,    // 输入：Zigzag 映射后的字节流（RRRR...GGGG...BBBB...AAAA...）
    __global int* pixels,          // 输出：像素数组（ARGB）
    int size                       // 像素数量 (w * h)
) {
    int i = get_global_id(0);
    if (i >= size) return;
    
    int rOffset = 0;
    int gOffset = size;
    int bOffset = size * 2;
    int aOffset = size * 3;
    
    // 从四个平面分别读取并逆映射
    uchar r_raw = data[rOffset + i];
    uchar g_raw = data[gOffset + i];
    uchar b_raw = data[bOffset + i];
    uchar a_raw = data[aOffset + i];
    
    char r = zigzag_unmap(r_raw);
    char g = zigzag_unmap(g_raw);
    char b = zigzag_unmap(b_raw);
    char a = zigzag_unmap(a_raw);
    
    // 组装成 ARGB
    pixels[i] = ((int)(a & 0xFF) << 24) |
                ((int)(r & 0xFF) << 16) |
                ((int)(g & 0xFF) << 8)  |
                (int)(b & 0xFF);
}

/**
 * 水平预测（非原地，完美并行）
 * residual = pixelSub(current, left)
 * 每个线程独立处理一个像素
 */
__kernel void horizontalPredictParallel(
    __global const int* input,   // 原始像素
    __global int* output,        // 残差输出
    int w,
    int h
) {
    int idx = get_global_id(0);
    int size = w * h;
    if (idx >= size) return;

    int x = idx % w;

    if (x == 0) {
        // 第一列：残差 = 原值（没有左邻居）
        output[idx] = input[idx];
    } else {
        int left = input[idx - 1];
        output[idx] = pixelSub(input[idx], left);
    }
}

/**
 * 垂直预测（非原地，完美并行）
 * residual = pixelSub(current, above)
 * 每个线程独立处理一个像素
 */
__kernel void verticalPredictParallel(
    __global const int* input,   // 原始像素（或水平预测后的残差）
    __global int* output,        // 残差输出
    int w,
    int h
) {
    int idx = get_global_id(0);
    int size = w * h;
    if (idx >= size) return;

    int y = idx / w;

    if (y == 0) {
        // 第一行：残差 = 原值（没有上邻居）
        output[idx] = input[idx];
    } else {
        int above = input[idx - w];
        output[idx] = pixelSub(input[idx], above);
    }
}

/**
 * 水平预测（使用 pixelSub）
 * residual = pixelSub(current, left)
 * 从右向左，保证 left 是原始值
 */
__kernel void horizontalPredictInPlace(
    __global int* data,
    int w,
    int h
) {
    int row = get_global_id(0);
    if (row >= h) return;

    int base = row * w;

    // 从右向左（第一列不变）
    for (int x = w - 1; x >= 1; x--) {
        int idx = base + x;
        int left = data[idx - 1];
        data[idx] = pixelSub(data[idx], left);
    }
}
/**
 * 水平逆预测（原地操作）
 * 每个工作组处理一行，行内从左到右串行
 * 
 * 数据依赖：左侧像素 (x-1, y) 必须先被还原
 *//**
 * 水平逆预测（寄存器优化版）
 * 
 * 核心优化：预测值在寄存器中传递，减少显存读取
 */
__kernel void horizontalInverseInPlace(
    __global int* data,
    int w,
    int h
) {
    int row = get_global_id(0);
    if (row >= h) return;
    
    int base = row * w;
    
    // 第一列保持不变
    // 直接用 data[base] 作为初始预测值
    int pred = data[base];  // ✅ 只读一次显存
    
    // 行内从左到右串行，但 pred 在寄存器中传递
    for (int x = 1; x < w; x++) {
        int idx = base + x;
        int residual = data[idx];  // ✅ 只读残差
        int result = pixelAdd(pred, residual);
        data[idx] = result;        // ✅ 只写一次显存
        pred = result;             // ✅ 寄存器传递（下次循环直接使用）
    }

}
/**
 * 垂直预测（使用 pixelSub）
 * residual = pixelSub(current, above)
 * 从下向上，保证 above 是原始值
 */
__kernel void verticalPredictInPlace(
    __global int* data,
    int w,
    int h
) {
    int col = get_global_id(0);
    if (col >= w) return;

    // 从下向上（第一行不变）
    for (int y = h - 1; y >= 1; y--) {
        int idx = y * w + col;
        int above = data[(y - 1) * w + col];
        data[idx] = pixelSub(data[idx], above);
    }
}
/**
 * 垂直逆预测（原地操作）
 * 每个工作组处理一列，列内从上到下串行
 * 
 * 数据依赖：上方像素 (x, y-1) 必须先被还原
 *//**
 * 垂直逆预测（寄存器优化版）
 */
__kernel void verticalInverseInPlace(
    __global int* data,
    int w,
    int h
) {
    int col = get_global_id(0);
    if (col >= w) return;
    
    // 第一行：用 data[col] 作为初始预测值
    int pred = data[col];  // ✅ 只读一次显存
    
    for (int y = 1; y < h; y++) {
        int idx = y * w + col;
        int residual = data[idx];  // ✅ 只读残差
        int result = pixelAdd(pred, residual);
        data[idx] = result;
        pred = result;  // ✅ 寄存器传递
    }
}
/**
 * RGBA 颜色变换（原地版本）- 等效于 Java 的 colorTransformRGBAInPlace
 * 
 * 编码：R' = R - G, G' = G, B' = B - G, A' = A
 * 结果存储为：A | R' | G | B'（与 Java 版本完全一致）
 */
__kernel void colorTransformRGBAInPlace(
    __global int* data,    // 输入/输出像素数组
    int size               // 像素总数 (w * h)
) {
    int idx = get_global_id(0);
    if (idx >= size) return;
    
    int pixel = data[idx];
    
    int r = (pixel >> 16) & 0xFF;
    int g = (pixel >> 8) & 0xFF;
    int b = pixel & 0xFF;
    int a = (pixel >> 24) & 0xFF;
    
    int rg = r - g;   // 范围 -255 ~ 255
    int bg = b - g;   // 范围 -255 ~ 255
    
    // 与 Java 版本完全一致：
    // ((a & 0xFF) << 24) | ((rg & 0xFF) << 16) | ((g & 0xFF) << 8) | (bg & 0xFF)
    data[idx] = ((a & 0xFF) << 24) |
                ((rg & 0xFF) << 16) |
                ((g & 0xFF) << 8) |
                (bg & 0xFF);
}

/**
 * 颜色逆变换（RGBA，逐像素并行）- 与 colorTransformRGBAInPlace 完全对应
 * 
 * Java 版本：
 *   a = (packed >> 24) & 0xFF
 *   rg = (packed >> 16) & 0xFF
 *   g  = (packed >> 8) & 0xFF
 *   bg = packed & 0xFF
 *   r = g + rg
 *   b = g + bg
 *   result = (a << 24) | (r << 16) | (g << 8) | b
 */
__kernel void colorInverseRGBAInPlace(
    __global int* data,    // 输入：颜色差分数据，输出：还原后的 RGBA
    int size               // 像素总数 (w * h)
) {
    int idx = get_global_id(0);
    if (idx >= size) return;
    
    int packed = data[idx];
    
    // 提取各通道
    int a = (packed >> 24) & 0xFF;
    int rg = (packed >> 16) & 0xFF;
    int g  = (packed >> 8) & 0xFF;
    int bg = packed & 0xFF;
    
    // 还原 R 和 B
    int r = g + rg;
    int b = g + bg;
    
    // 裁剪到 0~255（用 &0xFF 保留低 8 位）
    r = r & 0xFF;
    b = b & 0xFF;
    
    // 组装回 ARGB
    data[idx] = ((a & 0xFF) << 24) |
                ((r & 0xFF) << 16) |
                ((g & 0xFF) << 8) |
                (b & 0xFF);
}