Files
KVFCodec/src/org/kne/codec/kif/KIFCodec.cl
T
2026-07-26 22:35:06 +08:00

471 lines
13 KiB
Common Lisp
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Zigzag 映射将有符号字节映射为非负字节
* 00, -11, 12, -23, 24, ...
*/
uchar zigzag_map(char x) {
int v = (int)x; // char 转为 int(保留符号)
return (uchar)((v >= 0) ? (v << 1) : ((-v << 1) - 1));
}
/**
* Zigzag 逆映射将非负字节还原为有符号字节
* 00, 1-1, 21, 3-2, 42, ...
*/
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);
}