一个用于 [ImageGlass v10](https://imageglass.org) 的 C# Native AOT codec 插件,用于打开 Apple `.ithmb` 缩略图缓存文件 —— 这是 iPod Classic/Nano/Photo/Video、iPhone 2G 和 iPod Touch 用于存储照片和专辑封面缩略图的格式。
**主要特性**
- 53 个内置 profiles(+ 1 个推测性的已禁用 profile),涵盖已知的 iPod/iPhone 格式
- 7 个带有 SIMD 加速的 decoder(SSE2 + AVX-512 + ARM64 NEON)
- 经过往返(Roundtrip)验证的测试
- PhotoDB/ArtworkDB 的读取、写入和完整性检查
- 支持多帧 F 前缀 raw 文件
- 用于 iPhone 兼容性的 BGR15 channel-swap
- 跨平台构建(Windows x64/ARM64,Linux x64,macOS ARM64)
**T-prefix** — 包含一个内嵌的 JPEG。✅ 完全支持(已在 1,183 个真实文件上验证)。
**F-prefix**(例如 `F1019_1.ithmb`)— raw 未压缩缩略图(RGB565, RGB555, UYVY, YCbCr420, CLCL nibble-chroma)。✅ 与 iOpenPod 经验验证的集合(涵盖多种 iPod 型号的 50+ 个 profiles)进行了交叉比对,并在真实的 iPod Classic 6G 样本(F1061/F1055/F1060)上得到确认。
🎖️ 特别感谢 Savi 和 iOpenPod 社区
感谢其提供的硬件验证 —— 购买多种 iPod 型号并跨固件版本测试 profiles。Profile 调整结合了来自 iOpenPod 社区的反馈。
|
## 目录
- [工作原理](#how-it-works)
- [致谢](#acknowledgments)
- [安装](#install)
- [从源码构建](#build-from-source)
- [测试与验证](#testing--validation)
- [架构](#architecture)
- [性能](#performance)
- [工具](#tooling)
- [Profile 参考](#profile-reference)
- [限制](#limitations)
- [疑难解答](#troubleshooting)
- [开发](#development)
- [对生态系统的贡献](#contributions-to-the-ecosystem)
- [更新日志](#changelog)
- [许可协议](#license)
## 工作原理
1. **Peek read** — 读取文件的前 4 MB 用于 JPEG 扫描,然后从 FileStream 中 seek 到确切的 JPEG 字节范围(峰值内存主要由解码后的位图决定,对于 iPhone 照片通常只有几 MB)。
2. **JPEG 扫描** — SIMD 加速的 `Span.IndexOf`(x64 上使用 SSE2,ARM64 上使用 NEON)定位在 512 字节内跟随有 JFIF 或 Exif 的 SOI 标记(`FF D8`)。如果匹配,则提取 JPEG payload(SOI→EOI),通过 StbImageSharp 解码,并解析其 EXIF 方向标签 (0x0112) 以便在 ImageGlass 中进行自动旋转。
3. **Raw 回退** — 如果未找到 JPEG,decoder 会将前 4 个字节(big-endian 前缀)与 53 个已知 profiles 进行匹配,并运行相应的 raw decoder(RGB565, RGB555, Reordered RGB555, UYVY, YCbCr420, YUV422 interlaced, CLCL nibble-chroma 或 CL per-pixel chroma)以产生 BGRA 输出。如果前缀不匹配任何已知 profile,则在拒绝该文件之前,会扫描其内嵌的 JPEG 标记(byte-level carving)。可以通过 `profiles.json` 激活其他 decoder 变体:针对 YCbCr 4:2:0 的 swapped chroma planes,per-pixel 与 shared nibble chroma 的对比,endianness 切换,interlaced field ordering,padded frame handling,以及针对 BGR15 格式的 channel-swap。
4. **PhotoDB/ArtworkDB** — Apple 的 iPod 缩略图数据库(PhotoDB, ArtworkDB)使用基于二进制 chunk 的格式(MHFD→MHSD→MHNI 条目)。当文件以 `mhfd` 开头时,codec 会解析 chunk 树,提取单个缩略图(inline 像素数据或外部 `.ithmb` 文件引用),并通过匹配其格式 ID 的 raw decoder 解码每一个缩略图。支持读取、写入和完整性检查。
### 文件大小防护
## 安装
### 要求
- [ImageGlass v10](https://imageglass.org) (Windows 10/11 64-bit)
- 来自 iOS 设备照片缓存的 `.ithmb` 文件
### 步骤
1. 从 [最新发布版本](https://github.com/B67687/ithmb-codec/releases) 下载 `IthmbCodec_win-x64.zip` — 它包含 `IthmbCodec.dll`, `igplugin.json` 和 `profiles.json`。
2. 如果不存在 `IthmbCodec` 文件夹,则创建它,然后将其解压到 `%LocalAppData%\ImageGlass_10\_plugins\IthmbCodec\`。
3. 验证文件夹是否包含:`IthmbCodec.dll`(约 1.5 MB Native AOT),`igplugin.json`,`profiles.json`。
4. 重启 ImageGlass。
## 从源码构建
### Windows(发布二进制文件)
需要 .NET 10 SDK 和带有 "Desktop development with C++" 工作负载的 Visual Studio 2022。
```
dotnet publish src/IthmbCodec/IthmbCodec.csproj -c Release -r win-x64 -p:IlcInstructionSet=base
```
输出位于 `src/IthmbCodec/bin/Release/net10.0/win-x64/native/`。发布输出已包含 `igplugin.json` 和 `profiles.json` —— 将它们打包在一起以供分发。
### 跨平台
ImageGlass 仅在 **Windows**(10/11 64-bit)上运行。跨平台构建针对其他 runtime 进行测试或集成到其他项目中。Native AOT 交叉编译需要在构建机器上具有特定平台的工具链。
| Runtime | 命令 | 输出 |
| ----------- | ---------------------------------------- | -------- |
| Windows x64 | `dotnet publish -c Release -r win-x64` | `.dll` |
| Windows ARM | `dotnet publish -c Release -r win-arm64` | `.dll` |
| Linux x64 | `dotnet publish -c Release -r linux-x64` | `.so` |
| macOS ARM | `dotnet publish -c Release -r osx-arm64` | `.dylib` |
## 测试与验证
```
dotnet test src/IthmbCodec/test/IthmbCodec.Tests.csproj -c Release
```
**594 个测试**,涵盖往返(RGB565:65,536 个值,RGB555:32,768 个值)、模糊测试(覆盖所有 7 个 decoder 的 350+ 个输入 + 1,000 个随机字节突变)、SIMD 同一性(10 个测试)、YUV 容差、解析器、推测性 decoder 路径(CL, CLCL, rotation, swapped chroma)、buffer-too-small 防护、trailing-padding 容差、JPEG carving 回退、多帧 raw 解码、各 decoder 确定性 + 统计验证、SIMD tail path 模糊测试(5 个测试)、rotation 往返、BGR15 channel-swap、PhotoDB 往返写入/完整性/JPEG blob 解码,以及设备特定的格式表、损坏文件模糊测试、格式 ID profile 测试、encoder 辅助工具(interlace fields + BT.601 color conversion)以及标量 decoder 回退路径。
**真实设备验证:**
- **iPod Classic 6G (Reuhno):** 成功解码真实的 F1061/F1055/F1060 .ithmb 文件(BGR15 channel-swap,MSB 复制 —— 均已确认正确)。30 个参考 PNG 与 decoder 输出匹配。
- **iOpenPod (TheRealSavi):** 在购买并测试的多个 iPod 型号上,经验性地验证了 50+ 个 profiles。确认“对于 iPod Nano 和 iPod Classic 型号没有已知问题”。我们的 54 个 profiles 源自相同的格式 ID 来源 —— 硬件验证由 iOpenPod 的测试覆盖。详见 [iOpenPod#140](https://github.com/TheRealSavi/iOpenPod/issues/140)。
- **iPhone 5 (iOS 7):** 956 个 T-prefix 文件 — 100% 提取
- **Jakarade.com F00-F08:** 227 个公开的 T-prefix 文件 — 100% 检测到 JPEG+EXIF
- **MVS CTF 2026 (iOS 18):** 扫描了 iPhone 14 Plus 的完整文件系统镜像 —— 找到了 3 个 `.ithmb` 文件,但使用了不同的专有格式(iOS Photos 框架,无法被此 codec 解码)
## 架构
**Plugin ABI** — 唯一的 C 导出是 `ig_plugin_get_api()`,它返回一个遵循 ImageGlass v10 原生 codec 插件 ABI (v1.0.0.0) 的 `IGPluginApi` → `IGCodecApi` 链。
**源码布局** — 按领域划分的 24 个文件(以前是 6 个,为了单一职责而拆分):
| 文件 | 用途 |
|------|---------|
| `IthmbCodecPlugin.cs` | ABI 入口点、初始化、API 接口 |
| `IthmbCodecPlugin.Strings.cs` | 用于 ImageGlass ABI 的 UTF-16 字符串缓冲区 |
| `IthmbCodecPlugin.Helpers.cs` | 共享工具(rotate、缓冲区分配、日志记录) |
| `IthmbCodecPlugin.DecodePipeline.cs` | 核心解码 pipeline、两阶段 JPEG 扫描 |
| `IthmbCodecPlugin.DecodeInfrastructure.cs` | 有界 LRU 文件缓存、解码指标 |
| `IthmbCodecPlugin.DecodeRawProfile.cs` | Raw profile 解码调度 + 裁剪/旋转 |
| `IthmbCodecPlugin.JpegDecode.cs` | JPEG 扫描、EXIF 解析、StbImageSharp |
| `IthmbCodecPlugin.DecodeFormatYcbcr420.cs` | YCbCr 4:2:0 标量 + SIMD decoder |
| `IthmbCodecPlugin.Rgb565Rgb555.cs` | RGB565/RGB555 decoder + SSE2/AVX-512/NEON SIMD + REC_RGB555 |
| `IthmbCodecPlugin.UyvyYuv.cs` | UYVY 4:2:2 + Interlaced UYVY decoder + SSSE3/NEON SIMD |
| `IthmbCodecPlugin.DecodeFormatClcl.cs` | CLCL nibble-chroma decoder + SSSE3/NEON SIMD |
| `IthmbCodecPlugin.DecodeFormatCl.cs` | CL per-pixel chroma decoder + SSSE3/NEON SIMD |
| `IthmbCodecPlugin.SimdConstants.cs` | 共享的 SIMD shuffle 掩码和系数向量 |
| `IthmbCodecPlugin.ProfileSystem.cs` | Profile 解析、外部覆盖、启发式算法 |
| `IthmbCodecPlugin.VariantProfile.cs` | Profile 记录结构体(IthmbVariantProfile, IthmbEncoding) |
| `IthmbCodecPlugin.ProfilesJson.cs` | 内嵌的 54-profile JSON 字符串字面量 |
| `IthmbCodecPlugin.JsonParser.cs` | 用于 profiles 的 AOT 安全 JSON 解析器 |
| `IthmbCodecPlugin.DeviceProfiles.cs` | 按代际划分的 iPod 设备格式表(18 台设备) |
| `IthmbCodecPlugin.Encoding.cs` | 适用于所有 raw 格式的合成 encoder |
| `IthmbCodecPlugin.EncoderHelpers.cs` | 共享 encoder 辅助工具(InterlaceFields, BT.601) |
| `IthmbCodecPlugin.YuvUtils.cs` | 共享 YUV 转换辅助工具 |
| `PhotoDb/Core.cs` | PhotoDB/ArtworkDB chunk 解析器 + 格式 ID 映射 |
| `PhotoDb/Serialization.cs | PhotoDB 写入器 + 完整性检查器 |
| `PhotoDb/Types.cs` | PhotDB chunk 标头结构体 + 感知 endian 的读取辅助工具 |
**数据流:**
```
.ithmb file → JPEG/EXIF scan ──→ JPEG slice → StbImageSharp → BGRA
├─ No JPEG → prefix lookup → raw decoder → BGRA
│ └→ no prefix + JPEG scan → byte-level SOI carving → StbImageSharp → BGRA
│ └→ no prefix + mhfd magic → PhotoDB parser → entries → raw decoder → BGRA
└─ external .ithmb reference → read file → raw decoder → BGRA
```
**SIMD 加速:** RGB565/RGB555 → SSE2/AVX-512 或 NEON(x64/ARM64,4-6 倍增益,使用 AVX-512 最高可达 8-12 倍),UYVY → SSSE3 或 NEON(x64/ARM64,2-3 倍增益),YCbCr420 → 跨平台 Vector128(x64 上的 SSE2 + ARM64 上的 NEON,3-5 倍增益)。CLCL nibble-chroma 和 CL per-pixel chroma → SSSE3 或 NEON(x64/ARM64)。**BGR15 channel-swap**(`SwapRgbChannels` 标志)在所有 decoder 变体中均受支持 — SIMD 在像素循环外使用条件分支(未激活时每像素开销为零)。NEON CI 已在原生 ARM64 runner 上验证。
**多帧支持** — F-prefix `.ithmb` 文件可能包含多个连接的 raw 帧(由 Keith 的 iPod Photo Reader、ithmbrdr、libgpod 和 iOpenPod 确认)。codec 从文件大小检测帧数,并缓存文件以实现“读取一次,多次解码”的访问方式。调用者可以通过 `frameIndex`(从 0 开始)访问单个帧;超出范围的索引返回 `IGStatus.InvalidArg`。嵌入 JPEG 的 T-prefix 文件始终是单帧的。

## 性能
### Decoder 性能 (720×480, AMD Ryzen AI 9 HX 370, .NET 10.0.9, AVX-512)
| Decoder | Encoding | 宽度 | 高度 | 平均时间 | 分配 |
|---------|----------|-------|--------|-----------|-------------|
| RGB565 | 16-bit RGB | 720 | 480 | 54.35 µs | 0 B |
| RGB555 | 15-bit RGB | 720 | 480 | 52.92 µs | 0 B |
| UYVY | YUV 4:2:2 | 720 | 480 | 184.6 µs | 0 B |
| YCbCr 4:2:0 | YUV 4:2:0 | 720 | 480 | 212.9 µs | 0 B |
| YUV422 Interlaced | YUV 4:2:2 (fields) | 720 | 480 | 187.0 µs | 0 B |
| CLCL | Nibble-chroma YUV | 720 | 480 | 192.9 µs | 0 B |
| CL | Per-pixel chroma YUV | 720 | 480 | 196.0 µs | 0 B |
所有 decoder 均产生 BGRA 8-bit 输出。零堆分配 — 输出直接写入调用者提供的原生缓冲区。
### Decoder 格式参考
上表中的每一行对应于 Apple 在各 iPod/iPhone 固件版本中使用的一种 raw 像素格式:
| Decoder | 格式 | 详情 |
|---------|--------|---------|
| **RGB565** | 16-bit RGB (5/6/5) | 最常见的格式(约占 profiles 的 40%)。2 字节/像素。SIMD:SSE2/NEON(16 像素/迭代)。|
| **RGB555** | 15-bit RGB (5/5/5) | 在 iPod 4G/5G 上常见。2 字节/像素。SIMD:SSE2/NEON。|
| **Reordered RGB555** | 15-bit RGB (swapped) | 相同的 15-bit 数据,不同的字节顺序。见于一些固件变体。标量解码。|
| **BGR15** | 15-bit BGR (iPhone) | 反转的通道顺序(蓝->绿->红,而不是红->绿->蓝)。使用 `SwapRgbChannels` 标志。已在 iPhone 2G 样本上确认。|
| **UYVY** | YUV 4:2:2 packed | 两个像素共享 chroma(U 和 V)。布局:`[U, Y0, V, Y1]`(4 字节/2像素)。最常见的 raw 缩略图格式。SIMD:SSSE3/NEON(8 像素/迭代)。|
| **YCbCr 4:2:0** | YUV planar | 独立的 Y (luma), Cb, Cr 平面。Chroma 平面为半分辨率(四分之一面积)。由 iPod Nano 4G/5G 使用。SIMD:跨平台 Vector128。|
| **YUV422 Interlaced** | YUV 4:2:2 fields | Interlaced 场序:奇/偶行分开存储,然后合并。SIMD:SSSE3/NEON。|
| **CLCL** | Nibble-chroma YUV | 两个像素共享一个打包的 chroma 字节(Cb 为高 nibble,Cr 为低 nibble,各 4-bit)+ 2 个 luma 字节。布局:`[CbCr] [Y0] [CbCr] [Y1]`(4 字节/2像素)。SIMD:SSSE3/NEON(8 像素/迭代)。*推测性 — 尚未验证真实样本。*|
| **CL** | Per-pixel nibble YUV | 每个像素都有自己的 chroma nibble 对。布局:`[Cb:Cr_nibble] [Y]`(2 字节/像素)。SIMD:SSSE3/NEON(8 像素/迭代)。罕见 — 在 Keith 的 iPod Photo Reader 中被描述为方法 3/4。|
### 复现基准测试
这些数值是在上述列出的硬件上测量的。要在您自己的机器上复现:
```
dotnet run -c Release --project tools/IthmbCodec.Benchmark
```
或者从 GitHub Actions 选项卡中触发 [benchmark workflow](.github/workflows/benchmark.yml)(手动调度)— 结果将作为可下载的 artifact 上传。
基准测试项目使用 **BenchmarkDotNet**,每个 decoder 进行 3 次预热迭代和 10 次测量迭代。每个 decoder 解码一个 720×480 的合成缓冲区(随机像素数据),并报告平均时间和分配的内存。
## 工具
该仓库在 [`tools/`](tools/) 下包含几个 CLI 工具:
| 工具 | 描述 |
|------|-------------|
| [`IthmbDecoder`](tools/IthmbDecoder/) | 将 .ithmb 文件或 PhotoDB/ArtworkDB 条目解码为 BMP。Flags:`--list-pd` 枚举条目,`--pd-index N` 提取并解码第 N 条,`--extract-all-pd` 提取所有条目,`--check-pd` 验证 PhotoDB 完整性,`--list-devices` 显示设备格式表 |
| [`IthmbSampleGenerator`](tools/IthmbSampleGenerator/) | 生成用于测试的合成 .ithmb 文件 |
| [`ithmb-delegate.xml`](tools/ithmb-delegate.xml) | ImageMagick delegate 配置 — 直接在 `magick`/`convert` 中打开 `.ithmb` 文件 |
| [`install-ithmb-magick.sh`](tools/install-ithmb-magick.sh) | 在系统范围内安装 .ithmb ImageMagick delegate |
## Profile 参考
**53 个已知 profiles**(+ 1 个推测性已禁用 — 见代码库中的注释),涵盖从 iPod Photo 4G 到 iPhone 2G 和 iPod Nano 7G。最大帧大小:480×864(RGB565,830 KB)。有关包含尺寸、编码和设备映射的完整表格,请参见 [PROFILES.md](PROFILES.md)。可以在运行时通过 `profiles.json` 添加外部 profiles。
## 限制
- **T-prefix (JPEG-embedded) 已在 1,183 个真实文件(956 个 iPhone 5 + 227 个 Jakarade)上验证;F-prefix raw decoder 已在 iPod Classic 6G 样本(F1061/F1055/F1060)上验证。** 53 个已知 profiles 均有对应的 raw decoder,并通过了往返测试(共 594 个测试)。
## 疑难解答
| 症状 | 可能原因 / 解决办法 |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| 插件静默加载失败 | 缺少 `igplugin.json` 或文件名不匹配。验证 `_plugins\IthmbCodec\` 文件夹结构。 |
| 文件无法打开 | 可能使用了未知的格式变体。请携带样本[提交一个 codec issue](https://github.com/B67687/ithmb-codec/issues)。 |
| 图像乱码 / 颜色错误 | JPEG 误报或 raw decoder 不匹配(罕见)。[提交一个 codec issue](https://github.com/B67687/ithmb-codec/issues)。 |
| "File too large" 错误 | 文件超过了 **32 MB** 防护限制 — 对于正常的 iPhone 照片这绝不应该发生。如果发生,请提交一个 issue。 |
| 在“打开文件”对话框中找不到 | 将 `.ithmb` 添加到 `igconfig.json` 的 `FileFormats` 中。 |
## 开发
该插件的开发经历了迭代的调研、实现、审查和发布周期:
1. **格式调研** — 发现并分析了 33 个开源的 .ithmb 实现
2. **格式表提取** — iOpenPod (50+ 条目)、libgpod、iLounge 讨论帖和 Keith 的 iPod Photo Reader 提供了 54 个 profiles 的尺寸/编码表
3. **实现** — 带有 7 个 decoder 和 SIMD 加速(SSE2 + ARM64 NEON)的 C# Native AOT 插件
4. **测试** — 涵盖往返、模糊测试、SIMD 同一性、YUV 容差、解析器、推测性路径、buffer-too-small 防护、trailing-padding 容差、JPEG carving 回退、多帧 raw 解码、SIMD tail path 模糊测试、rotation 往返、字节级损坏模糊测试、BGR15 channel-swap、PhotoDB 往返写入、PhotoDB 完整性、PhotoDB JPEG blob 解码、特定设备格式表和格式 ID profile 测试的单元测试
5. **审查周期** — 5 轮多代理审查:修复了约 47 个问题,涵盖内存安全、线程、ABI 兼容性、SIMD 正确性、rotation 缓冲区溢出、crop 整数溢出和纵深防御
6. **发布** — 通过 GitHub Releases 发布 Windows Native AOT 二进制文件

完整的版本历史请参见 [CHANGELOG.md](CHANGELOG.md)。
### 质量流水线
发布前在本地运行质量检查:linting、密钥扫描、测试、静态分析、依赖审计和链接检查。
## 对生态系统的贡献
除了构建一个可用的 codec 外,该项目还为 .ithmb 逆向工程领域做出了几项原创贡献:
- **多开源实现格式合并** — 从 **22 个独立实现**(iOpenPod, libgpod, Keith's iPod Photo Reader, clickwheel, gnupod, pygpod, ithmb-rs, OrgZ, andrewmalta/ithmb, wrinklykong/pyithmb, Reuhno, podkit, Steee29, keyj (Jeff Luyten), Mixtape 等)中提取格式表,并将它们进行相互交叉比对,以及与现有表格进行比对。发现跨设备 profiles 的 **15 处尺寸差异**,包括颠倒的 Nano 5G/6G profiles、错误的 Nano 3G 格式,以及根据真实的 iPhone 2G (iOS 1.1.4) 样本对 iOS 1.x profiles 进行的修正。识别出 **18 个未出现在任何单一实现表格中的格式 ID**。合并后的交叉参考涵盖了 **54 个唯一的格式 ID** — 这是最完整的公开参考。
- **特定设备的格式表** — 所有以前的工具都维护着一个包含所有已知格式 ID 的扁平列表。该项目映射了 **18 代 iPod/iPhone** 中每一代实际需要哪些格式来显示缩略图和封面插图,从而使得同步工具能够进行按设备的 profile 选择。
- **PhotoDB/ArtworkDB 写入支持** — 所有现有工具都是只读的(从设备的照片数据库中提取缩略图)。该项目实现了 `TryBuildPhotoDb`,能够从零开始写入有效的 ArtworkDB 二进制文件 — 从而无需 iTunes 即可将封面插图同步到 iPod。
- **通过社区进行硬件验证** — 发起了与 iOpenPod 的跨项目合作,其开发者购买了多个 iPod 型号,并跨固件世代验证了 decoder。这填补了一个长期存在的空白:没有任何开源的 .ithmb decoder 曾经有过系统性的硬件确认。
- **32 MB 文件大小限制(从零开始研究)** — 所有以前的 decoder引用 libgpod 的 256 MB 限制,但没有证据证实它是一个真实的固件常量。该项目独立推导出了 32 MB:**54 个 profiles** 中的最大帧大小为 829 KB,来自 5 种逆向工程工具的多帧连接从未超过约 40 帧,并且一项公开的 .ithmb 文件调查发现没有大于 1 MB 的文件。32 MB 是 2 的幂,并且涵盖了所有已知数据。于 2026-06-30 再次验证:40×P1007 = 31.64 MB(余量 376 KB)。
- **BGR15 iPhone 兼容性** — 通过真实的 iPod Classic 6G 样本 (Reuhno) 确认,iPhone 缩略图使用了反转的通道顺序(`xBBBBBGGGGGRRRRR` 而不是标准的 `xRRRRRGGGGGBBBBB`)。添加了 `SwapRgbChannels` 标志 — 这是第一个将 iPhone 像素布局与 iPod 区分开来的 decoder。
- **推测性 profile 修正** — F1064 profile(320×240 YCbCr)在社区推测中流传了多年。与每个公开实现进行了交叉检查:都没有它。已附上理由将其禁用。还将 CLCL nibble 缩放比例从 ×17(最初的 2005 Whirlpool 逆向工程)修正为 ×16,并与 2 个独立的实现进行了交叉验证。
- **合成测试向量 (CC0)** — 在此项目之前,不存在公开的 F-prefix 测试数据。Reuhno 贡献了生成的 CC0 向量,涵盖了 3 种插槽几何结构(内容矩形变化的 56×55 插槽、128×128、320×320),并附有 30 个参考 PNG。这些是第一批用于 raw .ithmb 解码的公开测试向量。
- **反面知识:iOS Photos ≠ iPod Classic** — 下载并分析了两个 iOS 固件镜像(9.3.5 和 iOS 18),确认它们的 .ithmb 文件使用了一种完全不同的、专有的格式,无法被此 codec 解码。记录了关于 .ithmb 跨平台兼容性的一个常见误解。
## 更新日志
版本历史请参见 [CHANGELOG.md](CHANGELOG.md)。
## 许可协议
MIT — 详见 [LICENSE](LICENSE)。
最初的 IthmbDecoder 参考实现 (PR [#2316](https://github.com/d2phap/ImageGlass/pull/2316)) 采用 GPL-3.0 协议。本插件是针对 v10 SDK ABI 的净室实现(clean-room implementation),其设计参考了该 PR 中描述的格式行为,但未使用任何 GPL 代码。