A minimal, zero-dependency Intel Indeo Video 3.2 (FOURCC IV32)
decoder written in C99.
Indeo Video 3 was developed by Intel Corporation and released ca. 1993 as part of their Intel Smart Video Recorder product line. It was widely used in CD-ROM multimedia titles and games throughout the mid-1990s, particularly on Windows where it shipped as a Video for Windows (VfW) system codec.
All Indeo 3 patents have expired (filed ca. 1993–1994, 20-year term → expired ca. 2013–2014).
Indeo3 uses 24 hardcoded VQ codebooks (ir3_delta_codebook[24][256][4],
24,576 bytes total) that are baked into the Intel reference codec binary.
These tables are mathematical lookup data, not creative work.
This library ships with a working codebook (indeo3_codebook.h) whose
provenance is independently documented.
The shipped indeo3_codebook.h was produced by static analysis of the
Intel VfW codec DLL (ir32_32.dll). The extraction process is
computed from the DLL's parameters, not a binary copy:
- The DLL's static
.datasection contains a descriptor table of(b2, b1)parameter pairs — not the codebook itself. tools/ir32_static_extract.pyparses the PE file, locates the descriptor table via BFS over the DLL's call graph (no hardcoded offsets), and computes the codebook entries by applying the reconstruction function (InitCodebookTableslogic, reverse-engineered from the DLL).- The result was cross-validated across 15 independent genuine builds of the codec (1994–2016, including a 16-bit driver older than every 32-bit build tested): all fifteen produce a byte-for-byte identical table, 0 differences across all 6,144 entries.
The tool only works on DLLs that actually contain the codec. Some Windows releases ship a same-named security stub (Microsoft disabled the Indeo codec family system-wide after historical vulnerabilities were found in it) with no real decoder inside — the tool correctly refuses to extract from these rather than guessing.
python tools/ir32_static_extract.py ir32_32.dll indeo3_codebook.h- Decodes both intra (I-frame) and inter (P-frame / delta) frames
- Full recursive binary-tree plane splitting
- Three color planes decoded independently: Y (luma), V (Cb), U (Cr)
- Output: RGBA8888, caller-supplied buffer and stride
- Stateful context for inter-frame reference (current ↔ reference swap)
- Pure C99, no external dependencies
#include "indeo3.h"
// Allocate a decoder context for frames of the given dimensions.
// Returns NULL on allocation failure.
Indeo3Context *indeo3_alloc(int width, int height);
// Free a decoder context. Safe to call with NULL.
void indeo3_free(Indeo3Context *ctx);
// Decode one Indeo3 frame.
// data — raw frame bytes from the AVI stream chunk
// size — byte count of data
// rgba — output buffer, RGBA8888, must be >= height * stride bytes
// stride — bytes per output row (typically width * 4)
// Frames must be decoded in presentation order.
// Returns INDEO3_OK (0) on success, negative on error.
int indeo3_decode(Indeo3Context *ctx,
const uint8_t *data, int size,
uint8_t *rgba, int stride);#include "indeo3.h"
// Create decoder once per video stream
Indeo3Context *ctx = indeo3_alloc(width, height);
// For each frame (in order):
uint8_t *rgba = malloc(width * height * 4);
int stride = width * 4;
if (indeo3_decode(ctx, frame_data, frame_size, rgba, stride) == INDEO3_OK) {
// use rgba...
}
// When done:
indeo3_free(ctx);
free(rgba);Requires CMake 3.14+ and a C99 compiler.
mkdir build && cd build
cmake ..
cmake --build .To use as a subdirectory in another CMake project:
add_subdirectory(libindeo3)
target_link_libraries(your_target PRIVATE indeo3)Or via FetchContent:
include(FetchContent)
FetchContent_Declare(libindeo3
GIT_REPOSITORY https://github.com/ifcaro/libindeo3
GIT_TAG main)
FetchContent_MakeAvailable(libindeo3)
target_link_libraries(your_target PRIVATE indeo3)libindeo3 ships with a working codebook and requantization table whose
provenance is independently documented:
- The codebook is computed from the DLL descriptor table, not copied from the binary.
- The requantization table has no descriptor to compute from — it's a flat
lookup table, located by a structural scan (see
docs/codebook-extraction.md) rather than a hardcoded address. - Both extraction algorithms are published in
tools/ir32_static_extract.pyand are reproducible from any genuine build ofir32_32.dll. - Both have been cross-validated across 15 independent genuine DLL builds: byte-for-byte identical in every case.
Regeneration is optional and intended for verification, not for normal use.
docs/codec-algorithm.md— full technical reference for the bitstream format and decoding algorithm.docs/codebook-extraction.md— how the shipped VQ codebook was extracted and verified.
The implementation was written from scratch using the following public resources:
-
MultimediaWiki — Indeo 3 https://wiki.multimedia.cx/index.php/Indeo_3 Primary format reference: frame header layout, plane bitstream structure, binary tree splitting, VQ coding modes (INTRA_NULL, INTRA_VQ, INTER_COPY, INTER_VQ), YVU 4:1:0 color space with 7-bit pixel values.
-
Kostya's Boring Codec World — Indeo 3 series (January–February 2023) https://codecs.multimedia.cx/2023/01/indeo-3-overview/ https://codecs.multimedia.cx/2023/01/indeo-3-splitting-the-frame/ https://codecs.multimedia.cx/2023/01/indeo-3-cell-coding/ https://codecs.multimedia.cx/2023/02/indeo-3-codebooks/ https://codecs.multimedia.cx/2023/02/indeo-3-encoder-done-2/ Detailed analysis of the codec internals, binary tree structure, codebook organisation, and encoder implementation — the most thorough modern documentation of the format. Used together with MultimediaWiki to verify frame header field offsets and the primary/secondary bitstream split.
| Property | Value |
|---|---|
| Color space | YVU 4:1:0, 7-bit values (range 0–127) |
| Plane layout | Planar: Y full-res, V and U at 1/4 width × 1/4 height |
| Codebooks | 24 hardcoded tables, 256 entries × 4 bytes each |
| Tree structure | Two-level recursive binary tree per plane: a motion/partition tree selects intra vs. inter leaves, then a VQ tree selects null (reference copy) vs. data-carrying leaves — both levels share one interleaved byte stream |
| Coding modes | Intra/inter leaf selection (level 1) + VQ-NULL/VQ-DATA leaf selection (level 2) |
| Frame types | Intra (I-frame) and inter/delta (P-frame) |
| Container | AVI (RIFF) |
| FourCC | IV32 (version 3.2) |
MIT — see LICENSE.