sframe

Simple Frame — extract unique frames from videos
git clone git clone https://git.krisyotam.com/krisyotam/sframe.git
Log | Files | Refs | README | LICENSE

CLAUDE.md (3577B)


      1 # sframe — CLAUDE.md
      2 
      3 ## Project
      4 
      5 sframe (Simple Frame) is a lightweight command-line tool written in C
      6 following the suckless philosophy. It extracts unique frames from video
      7 files for research purposes, using perceptual hashing to eliminate
      8 duplicates and embedding timestamps in filenames.
      9 
     10 ## Coding Standards — Suckless C Style
     11 
     12 All code in this project MUST follow the suckless.org coding style:
     13 
     14 ### Language
     15 - C99 (ISO/IEC 9899:1999), no extensions
     16 - POSIX.1-2008 (`_POSIX_C_SOURCE 200809L`)
     17 
     18 ### Indentation & Whitespace
     19 - Tabs for indentation (1 tab = 1 level)
     20 - Spaces for alignment only, never for indentation
     21 - No tabs except at the beginning of a line
     22 - Maximum line length: 79 characters
     23 
     24 ### Comments
     25 - Use `/* */` only, never `//`
     26 - Comment fallthrough cases in switch statements
     27 
     28 ### Variables
     29 - All declarations at the top of the block
     30 - Pointer `*` adjacent to variable name: `char *p`, not `char* p`
     31 - No C99 `bool`; use `int` (0/1)
     32 - Global/static variables not used outside TU must be `static`
     33 
     34 ### Functions
     35 - Return type on its own line
     36 - Function name at column 0 on next line (enables `grep ^funcname`)
     37 - Opening `{` on its own line for functions
     38 - Functions not used outside their file: `static`
     39 
     40 ```c
     41 static void
     42 usage(void)
     43 {
     44 	fprintf(stderr, "usage: sframe [-t thresh] [-f fmt] video\n");
     45 	exit(1);
     46 }
     47 ```
     48 
     49 ### Braces
     50 - Opening `{` on same line for control flow (if, for, while, switch)
     51 - Closing `}` on its own line unless continuing (else, do-while)
     52 - Use braces even for single statements when sibling branches use them
     53 
     54 ### Naming
     55 - lowercase_with_underscores for functions and variables
     56 - UPPERCASE for macros and constants
     57 - CamelCase for typedef'd struct types
     58 - No `_t` suffix (reserved by POSIX)
     59 - Prefix module functions: `dec_open()`, `diff_hash()`, `util_die()`
     60 
     61 ### Control Flow
     62 - Space after `if`, `for`, `while`, `switch`
     63 - No space after `(` or before `)`
     64 - Use `goto` for cleanup/unwind, not nested ifs
     65 - Return/exit early on failure
     66 - Test against 0, not -1: `if (func() < 0)`
     67 
     68 ### Error Handling
     69 - All allocation checked; goto cleanup on failure
     70 - `die()` for fatal errors (prints message, exits)
     71 - `warn()` for recoverable errors (prints, continues)
     72 
     73 ### File Organization Order
     74 1. License header
     75 2. System includes (alphabetical)
     76 3. Local includes
     77 4. Macros
     78 5. Type definitions
     79 6. Function declarations
     80 7. Global variables
     81 8. Function definitions (same order as declarations)
     82 
     83 ### Headers
     84 - System headers first, alphabetical
     85 - Local headers after blank line
     86 - No cyclic dependencies
     87 - Include only what is needed
     88 
     89 ## Architecture Rules
     90 
     91 - **No global mutable state.** Pass context structs explicitly.
     92 - **No `system()` calls.** Use `fork()/execvp()` or `popen()`.
     93 - **No hardcoded paths** except sensible defaults (`~/frames`).
     94 - **Separate compilation.** Every .c file compiles independently.
     95 
     96 ## Module Prefixes
     97 
     98 | Module | Prefix | File |
     99 |--------|--------|------|
    100 | Main/CLI | — | main.c |
    101 | Decode | `dec_` | decode.c |
    102 | Diff | `diff_` | diff.c |
    103 | Utilities | `die()`, `warn()`, `ecalloc()` | util.c |
    104 
    105 ## Build
    106 
    107 ```sh
    108 make        # build sframe binary
    109 make clean  # remove build artifacts
    110 make install PREFIX=/usr/local  # install
    111 ```
    112 
    113 ## Dependencies
    114 
    115 - FFmpeg libraries: libavformat, libavcodec, libavutil, libswscale
    116 
    117 ## Git Conventions
    118 
    119 - No `Co-Authored-By: Claude` lines
    120 - Commit messages: imperative, <72 chars, no period
    121 - One logical change per commit
    122 
    123 ## CRITICAL: No Building on Moirai
    124 
    125 NEVER run `make`, `sudo make install`, or any build command unless
    126 Kris explicitly says "build" in his message.