Files
MeowOS-For-R3P2/patch_v2/reader_app/test/formats_smoke.c
T
AskaEth 0294553096 reader(R2): EPUB/FB2/MOBI/CBZ 加载器落地
- rdsrc 统一文档源抽象:TXT/FB2/EPUB/MOBI/CBZ 都产出「UTF-8 段序列+目录+元数据+图片」,
  与 R1 rdtxt 段契约一致;book.c 改喂 rd_src(文本)或图页(CBZ)。
- EPUB:miniz 解 ZIP → 自写 rdxml 回调解析 OPF(spine/manifest)+NCX/nav → 正文 XHTML 用
  rdhtml 逐行粗解析(坏标签/未闭合/实体容错,不建 DOM),章节按 RDSRC_SEG_MAX 分片。
- FB2:rdxml 严格解析抽 section 段落 + base64 内嵌图;段题进正文+目录。
- MOBI/AZW3:vendor libmobi 最小调用面(mobi_init→load→parse_kf7/8→parse_rawml_opt→
  flow/resources),HTML 走 rdhtml 同款粗解析;LGPL-3.0 合规见 NOTICE(版权+全文+锁定 commit)。
- CBZ:miniz 解 ZIP → 自然序图片序列,rdimg(stb_image) 解码+降采样,阅读页图页模式。
- 目录显示与跳转(EPUB NCX/FB2 section/MOBI 标题);书架开放四格式;进度按
  (段,字符偏移)(TXT/FB2/EPUB/MOBI)/页号(CBZ)。
- 宿主单测 loaders_smoke(四格式抽取/目录/图片/base64/页序)+ qemu-mipsel
  formats_smoke/book_smoke;R1 test_reader_core 58/0 不回归。
- build_reader.sh 集成 miniz/libmobi/stb/zlib 头;NOTICE 入仓;交叉 -Wall -Wextra 0 warning。

新 reader md5: e29036599300eb277b1c960a75b65dbf
2026-09-02 03:11:55 +08:00

67 lines
2.5 KiB
C

/* test/formats_smoke.c — R2 四格式 qemu-mipsel 全链冒烟:rd_book_open → 页数/渲染/目录/CBZ 图页。
* 用法:qemu-mipsel ./test/formats_smoke_mipsel <font.otf> <samples_dir>
* 跑于 qemu-mipsel(静态)。 */
#include "book.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int fails = 0;
#define CHECK(c, m) do { if (c) printf(" ok %s\n", m); else { printf("FAIL %s\n", m); fails++; } } while (0)
static void open_and_render(const char *name, const char *path, const char *font, int expect_img)
{
printf("-- %s --\n", name);
rd_book *b = NULL;
int rc = rd_book_open(&b, path, font, 20, 130, 480, 720, 16, 20, 62);
if (rc != 0) { CHECK(0, "rd_book_open"); printf(" open rc=%d path=%s\n", rc, path); return; }
int np = rd_book_pages(b);
printf(" pages=%d title=%s is_img=%d\n", np, rd_book_basename(b), rd_book_is_image(b));
CHECK(np > 0, "pages>0");
if (!expect_img) CHECK(rd_book_is_image(b) == 0, "text format");
else CHECK(rd_book_is_image(b) == 1, "cbz image format");
int W = 480, H = 720;
uint16_t *buf = (uint16_t *)malloc((size_t)W * H * 2);
uint16_t bg = 0xFFFF, fg = 0x0000;
rc = rd_book_render(b, 0, buf, W * 2, bg, fg);
CHECK(rc == 0, "render page0");
if (rc == 0) {
int ink = 0;
for (int i = 0; i < W * H; i++) if (buf[i] != bg) ink++;
printf(" page0 ink=%d\n", ink);
CHECK(ink > 50, "page0 has ink");
}
/* 目录 */
int tn = rd_book_toc_n(b);
printf(" toc=%d\n", tn);
if (!expect_img) CHECK(tn >= 1, "text has toc (>=1)");
/* 翻页 */
int nxt = rd_book_turn(b, 1);
CHECK(nxt >= 0 && nxt < np, "turn stays in range");
free(buf);
rd_book_close(b);
}
int main(int argc, char **argv)
{
const char *font = (argc > 1) ? argv[1] : "/home/Aska/Project/R3ProII/font/src/MiSans-Regular.otf";
const char *dir = (argc > 2) ? argv[2] : "/tmp/rd_samples";
char p[512];
const char *formats[][3] = {
{ "EPUB", "/%s/sample.epub", "0" },
{ "FB2", "/%s/sample.fb2", "0" },
{ "MOBI", "/%s/sample.mobi", "0" },
{ "CBZ", "/%s/sample.cbz", "1" },
};
for (int i = 0; i < 4; i++) {
snprintf(p, sizeof p, formats[i][1], dir);
FILE *f = fopen(p, "rb");
if (!f) { printf("-- %s -- missing %s (skip)\n", formats[i][0], p); continue; }
fclose(f);
open_and_render(formats[i][0], p, font, atoi(formats[i][2]));
}
printf("\nformats_smoke: %s\n", fails ? "FAIL" : "PASS");
return fails ? 1 : 0;
}