This commit is contained in:
2026-07-26 22:35:06 +08:00
commit c92cf914fc
58 changed files with 5954 additions and 0 deletions
+471
View File
@@ -0,0 +1,471 @@
/**
* 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);
}