SDK: 图片解码真缩解后端 —— JPEG DCT 域 / PNG 逐行 / BMP 跳行(M23)
stb 的 stbi_load_scaled 是「先整幅解、再重采样」:2000x3000 baseline 峰值 10.07MB、 渐进式 25.84MB、1600x2400 PNG 25.65MB,真机解码余量只有 ~4.2MB。新增解码后端在 解码期只算目标分辨率,峰值只与输出尺寸相关: - meow_jpeg.c:自写纯 C JPEG 解码(baseline + progressive,Huffman)。按 ceil(8*maxdim/长边) 选 N 点 DCT 缩解(N=1..7),基函数为「8 点 IDCT 按像素区间 盒式平均」的 Q12 定点(DC 恒为 F00/8,N 之间亮度一致);系数边解边累加进分量平面, 不留整幅系数阵列;渐进式跳过精细化扫描(Ah>0)、只解各频带首次扫描 —— 渐进式与 baseline 内存足迹相同(这是 libjpeg 系列做不到的:它对渐进式必须整幅驻留 JBLOCK)。 不支持项(4 分量 CMYK/YCCK、算术/无损/分层、12bit 精度)返回 0 回退 stb。 - meow_png_stream.c:libz 逐行 inflate + 反滤波,只把需要的列写进目标行; gray/gray+A/RGB/RGBA/调色板,1/2/4/8/16bit(16→8 取高字节);Adam7 等回退 stb。 BMP 按目标行 seek + 行内跳列(8bpp 调色板/16bpp RGB555/24/32bpp),不读全图。 - meow_ui_img.c:load_file_dim / load_mem_dim 先进后端,失败/不支持回落 stb 旧路径 (stbi_load_scaled + 精修);输出尺寸与 meow_img_downscale 同公式,对外语义不变。 宿主实测(--wrap malloc,maxdim=720,M23 前后同一夹具): 2000x3000 baseline 10.07 → 1.86 MiB 2000x3000 progressive 25.84 → 1.86 MiB 1600x2400 PNG 25.65 → 1.33 MiB 1600x2400 BMP 15.97 → 1.32 MiB 4MP/8MP/12MP JPEG 9.67/13.37/20.12 → 2.30/2.20/2.29 MiB(不随分辨率线性增长) sdk/test_meow_img_stream.c:峰值断言(≤2.5MiB)、与 stb 整幅+降采样的像素比对 (平均差 4.4-13.7/255,块均值结构相关 ≥0.88)、内存入口逐字节一致、回退矩阵 (CMYK/1bpp BMP/Adam7 PNG)、restart marker、缩解阶扫描 N=4/5/7、坏图容错。 build_sdk.sh 增加 meow_jpeg / meow_png_stream 两个 TU(MIPS32 -Os 零警告)。 体积:目标码 +24.9KB(meow_ui.a +25.5KB),picbrowser 静态二进制 +18.2KB。
This commit is contained in:
1 parent
88f3d861b0
commit
d84dd949c7
8 files changed
+2320
-15
No files matched your search
+20
-2
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* meow_ui_img.c — 图片层(B1.2)。基于 stb_image(单头文件、静态编入),
|
||||
* 解 PNG/JPEG/BMP → RGBA,统一最近邻缩放/居中裁方。
|
||||
* meow_ui_img.c — 图片层(B1.2)。解码:M23 真缩解后端(meow_jpeg.c / meow_png_stream.c)
|
||||
* 优先,不支持/失败回退 stb_image(单头文件、静态编入);统一输出 RGBA,最近邻缩放/居中裁方。
|
||||
*/
|
||||
#include "meow_ui.h"
|
||||
#include "meow_ui_internal.h"
|
||||
#include "stb_image.h"
|
||||
#include "meow_jpeg.h" /* M23 真缩解后端(内部头,不对外导出) */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -79,6 +80,16 @@ meow_img *meow_img_load_file_dim(const char *path, int maxdim)
|
||||
{
|
||||
if (!path) return NULL;
|
||||
if (maxdim <= 0) return meow_img_load_file(path); /* 不限尺寸 = 旧入口 */
|
||||
/* 追加(M23):真缩解后端直接产出目标尺寸(JPEG 按 DCT 档位;PNG 逐行 inflate 丢行丢列;
|
||||
* BMP 按行 seek 跳采样)。峰值只与输出尺寸相关。
|
||||
* 不支持/失败/几乎等尺寸(4 分量 CMYK、算术编码、交错 PNG、RLE BMP、小图…)返回 0 →
|
||||
* 落回下面的 stb 旧路径,对外语义与档位表现不变。 */
|
||||
{
|
||||
unsigned char *bp = NULL;
|
||||
int bw = 0, bh = 0;
|
||||
if (meow_img_backend_file(path, maxdim, &bw, &bh, &bp) && bp)
|
||||
return img_finish_dim(bp, bw, bh, maxdim);
|
||||
}
|
||||
int w = 0, h = 0, c = 0;
|
||||
if (!stbi_info(path, &w, &h, &c)) return NULL;
|
||||
int longside = w > h ? w : h;
|
||||
@@ -121,6 +132,13 @@ meow_img *meow_img_load_mem_dim(const void *buf, int len, int maxdim)
|
||||
{
|
||||
if (!buf || len <= 0) return NULL;
|
||||
if (maxdim <= 0) return meow_img_load_mem(buf, len);
|
||||
/* 追加(M23):同文件入口,后端直接从调用方缓冲解码(不再整幅解 + 重采样)。 */
|
||||
{
|
||||
unsigned char *bp = NULL;
|
||||
int bw = 0, bh = 0;
|
||||
if (meow_img_backend_mem(buf, (size_t)len, maxdim, &bw, &bh, &bp) && bp)
|
||||
return img_finish_dim(bp, bw, bh, maxdim);
|
||||
}
|
||||
int w = 0, h = 0, c = 0;
|
||||
if (!stbi_info_from_memory((const unsigned char *)buf, len, &w, &h, &c)) return NULL;
|
||||
int longside = w > h ? w : h;
|
||||
|
||||
Reference in new issue
Block a user