mirror of
https://github.com/Harshit-Dhanwalkar/AsciiCam.git
synced 2026-06-24 11:08:06 +02:00
Update README and format code
This commit is contained in:
parent
7b39cd09c3
commit
2d75b96c39
6 changed files with 52 additions and 43 deletions
|
|
@ -39,12 +39,7 @@ void do_edge_boost(uint8_t *gray, int w, int h, void *ctx) {
|
|||
}
|
||||
|
||||
#ifndef TESTING
|
||||
static filter_plugin_t self = {
|
||||
do_edge_boost,
|
||||
"edge_boost"
|
||||
};
|
||||
static filter_plugin_t self = {do_edge_boost, "edge_boost"};
|
||||
|
||||
filter_plugin_t *plugin_get(void) {
|
||||
return &self;
|
||||
}
|
||||
filter_plugin_t *plugin_get(void) { return &self; }
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -12,12 +12,7 @@ void do_invert(uint8_t *gray, int w, int h, void *ctx) {
|
|||
}
|
||||
|
||||
#ifndef TESTING
|
||||
static filter_plugin_t self = {
|
||||
.process = do_invert,
|
||||
.name = "invert"
|
||||
};
|
||||
static filter_plugin_t self = {.process = do_invert, .name = "invert"};
|
||||
|
||||
filter_plugin_t *plugin_get(void) {
|
||||
return &self;
|
||||
}
|
||||
filter_plugin_t *plugin_get(void) { return &self; }
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
void thresh_process(uint8_t *gray, int w, int h, void *ctx) {
|
||||
// uint8_t thresh = (uint8_t)(ctx ? *(int *)ctx : DEFAULT_THRESH);
|
||||
int thresh = ctx ? *(int *)ctx : DEFAULT_THRESH; // reads &plugin_param from main
|
||||
int thresh =
|
||||
ctx ? *(int *)ctx : DEFAULT_THRESH; // reads &plugin_param from main
|
||||
int total_pixels = w * h;
|
||||
for (int i = 0; i < total_pixels; i++)
|
||||
gray[i] = (gray[i] > thresh) ? 255 : 0;
|
||||
|
|
@ -17,7 +18,5 @@ static filter_plugin_t self = {
|
|||
.name = "threshold",
|
||||
};
|
||||
|
||||
filter_plugin_t *plugin_get(void) {
|
||||
return &self;
|
||||
}
|
||||
filter_plugin_t *plugin_get(void) { return &self; }
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ extern int main(int argc, char *argv[]);
|
|||
__attribute__((naked)) void _start(void) {
|
||||
__asm__ volatile(
|
||||
"xor %%rbp, %%rbp \n"
|
||||
"pop %%rdi \n" /* rdi = argc */
|
||||
"mov %%rsp, %%rsi \n" /* rsi = argv */
|
||||
"and $-16, %%rsp \n" /* 16-byte align stack */
|
||||
"pop %%rdi \n" // rdi = argc
|
||||
"mov %%rsp, %%rsi \n" // rsi = argv
|
||||
"and $-16, %%rsp \n" // 16-byte align stack
|
||||
"call main \n"
|
||||
"mov %%rax, %%rdi \n" /* exit code = return value of main() */
|
||||
"mov $231, %%rax \n" /* SYS_exit_group */
|
||||
"mov %%rax, %%rdi \n" // exit code = return value of main()
|
||||
"mov $231, %%rax \n" // SYS_exit_group
|
||||
"syscall \n" ::
|
||||
: "memory");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#define _SYS_SELECT_H 1
|
||||
#define __FD_SETSIZE 1024
|
||||
|
||||
// IWYU pragma: begin_exports
|
||||
#include "nl_alloc.h"
|
||||
#include "nl_errno.h"
|
||||
#include "nl_getopt.h"
|
||||
|
|
@ -12,5 +13,6 @@
|
|||
#include "nl_signal.h"
|
||||
#include "nl_string.h"
|
||||
#include "nl_syscall.h"
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#endif
|
||||
|
|
|
|||
58
README.md
58
README.md
|
|
@ -12,24 +12,25 @@ Real-time ASCII video from your webcam in the terminal - pure C99, no heavy runt
|
|||
|
||||
## Features
|
||||
|
||||
| Feature | Details |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| **YUYV to grayscale** | SSE2 SIMD (`yuyv_to_gray_simd`) - 16 pixels per iteration on x86_64, NEON on ARM64 |
|
||||
| **YUYV to RGB** | Fixed‑point BT.601 conversion for truecolor output |
|
||||
| **Multiple render modes** | Braille (`⠿`), Blocks (`█ ░`), ASCII ramp, Half‑block, Dots - switch live with `m`/`M` |
|
||||
| **Edge detection** | Sobel, Sobel with direction, Laplacian - toggle with `x`/`X` |
|
||||
| **Hot‑reloadable charsets**| Load `.txt` ramps from a directory, switch with `n`/`N`, monitor with inotify |
|
||||
| **Pseudo‑3D depth pop** | Parallax effect based on brightness - adjust with `+`/`-`/`v` |
|
||||
| **Floyd‑Steinberg dither**| Error‑diffusion to reduce banding |
|
||||
| **ANSI truecolor** | `\033[38;2;R;G;Bm` per‑cell coloring |
|
||||
| **Hot‑reload plugin system**| `inotify` + `dlopen` - rebuild a filter `.so`, it reloads live |
|
||||
| **FPS‑capped render loop**| `CLOCK_MONOTONIC` + `nanosleep` frame pacing |
|
||||
| **Producer/consumer threads**| Double‑buffered capture + render (stubbed in main loop, active in `thread_sharing.c`) |
|
||||
| **Cross‑platform** | Linux (V4L2, nolibc) and macOS (AVFoundation, system libc) |
|
||||
|
||||
| Feature | Details |
|
||||
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **YUYV to grayscale** | SSE2 SIMD (`yuyv_to_gray_simd`) - 16 pixels per iteration on x86_64, NEON on ARM64 |
|
||||
| **YUYV to RGB** | Fixed‑point BT.601 conversion for truecolor output |
|
||||
| **Multiple render modes** | Braille (`⠿`), Blocks (`█ ░`), ASCII ramp, Half‑block, Dots - switch live with `m`/`M` |
|
||||
| **Edge detection** | Sobel, Sobel with direction, Laplacian - toggle with `x`/`X` |
|
||||
| **Hot‑reloadable charsets** | Load `.txt` ramps from a directory, switch with `n`/`N`, monitor with inotify |
|
||||
| **Pseudo‑3D depth pop** | Parallax effect based on brightness - adjust with `+`/`-`/`v` |
|
||||
| **Floyd‑Steinberg dither** | Error‑diffusion to reduce banding |
|
||||
| **ANSI truecolor** | `\033[38;2;R;G;Bm` per‑cell coloring |
|
||||
| **Hot‑reload plugin system** | `inotify` + `dlopen` - rebuild a filter `.so`, it reloads live |
|
||||
| **FPS‑capped render loop** | `CLOCK_MONOTONIC` + `nanosleep` frame pacing |
|
||||
| **Producer/consumer threads** | Double‑buffered capture + render (stubbed in main loop, active in `thread_sharing.c`) |
|
||||
| **Hardware camera controls** | V4L2 exposure, contrast, white-balance via `ioctl` — live keys `e`/`E`, `c`/`C`, `w`/`W` (Linux only; macOS/Windows display `n/a`) |
|
||||
| **Cross‑platform** | Linux (V4L2, nolibc), macOS (AVFoundation, system libc), Windows (Media Foundation) |
|
||||
|
||||
Linux: requires `gcc`, `linux/videodev2.h` (kernel headers), `libdl`, `libpthread`.
|
||||
macOS: requires `Clang` and `AVFoundation` frameworks (linked automatically).
|
||||
Windows: requires MinGW-w64; links `mfplat`, `mf`, `mfreadwrite`, `mfuuid`, `ole32` (Media Foundation). See Makefile `windows` branch.
|
||||
|
||||
No other external dependencies.
|
||||
|
||||
|
|
@ -87,6 +88,13 @@ gcc -O2 -fPIC -shared -Iinclude filters/my_filter.c -o build/my_filter.so
|
|||
**Runtime controls:**
|
||||
| Key | Action |
|
||||
|---|---|
|
||||
| `m` / `M` | cycle render mode forward / backward |
|
||||
| `x` / `X` | cycle edge detection mode forward / backward |
|
||||
| `n` / `N` | cycle loaded charset forward / backward |
|
||||
| `p` / `o` | increase / decrease depth-pop strength |
|
||||
| `e` / `E` | hw exposure down / up _(V4L2, Linux only)_ |
|
||||
| `w` / `W` | hw white-balance down / up _(V4L2, Linux only)_ |
|
||||
| `c` / `C` | hw contrast down / up _(V4L2, Linux only)_ |
|
||||
| `↑` / `↓` | select plugin |
|
||||
| `[` / `]` | param $\pm$1 |
|
||||
| `{` / `}` | param $\pm$10 |
|
||||
|
|
@ -108,20 +116,30 @@ gcc -O2 -fPIC -shared -Iinclude filters/my_filter.c -o build/my_filter.so
|
|||
- [x] Hot-reload plugin system
|
||||
- [x] nolibc - zero libc calls
|
||||
- [x] Custom charset via config file
|
||||
- [x] Hardware camera controls (V4L2 exposure / contrast / white-balance)
|
||||
- [x] MacOS support
|
||||
- [x] Windows support (Media Foundation capture backend)
|
||||
- [ ] Windows console raw-mode and signal handling (`SetConsoleMode` / `SetConsoleCtrlHandler`)
|
||||
- [ ] Hardware controls via `IAMCameraControl` / `IAMVideoProcAmp` (capture works, controls stubbed)
|
||||
- [ ] macOS hardware controls via `AVCaptureDevice` exposure/white-balance APIs (capture works, controls stubbed)
|
||||
- [ ] Cature frame resizing
|
||||
- [ ] Record to `.mp4` / `.gif`
|
||||
- [ ] Inter-frame delta compression
|
||||
- [ ] LUT cache optimization
|
||||
- [ ] Replace `pthread` with raw `futex` syscalls
|
||||
- [ ] Replace `dlopen` with a minimal ELF loader
|
||||
- [ ] Custom threading library using `clone()` + `futex` to eliminate `-lpthread` (`pthread` functions) dependency
|
||||
- [ ] Implement an ELF loader (or statically link plugins) to eliminate `-ldl` (`dlopen`/`dlsym`/`dlclose` which are part of `libdl.so` also `glibc`) dependency
|
||||
- [x] MacOS support
|
||||
- [ ] Custom threading library using `clone()` + `futex` to eliminate `-lpthread` dependency
|
||||
- [ ] Implement an ELF loader (or statically link plugins) to eliminate `-ldl` dependency
|
||||
- [ ] Color support for MacOS
|
||||
- [ ] Windows support
|
||||
|
||||
## Fixes
|
||||
|
||||
- [x] [Issue #2](https://github.com/Harshit-Dhanwalkar/AsciiCam/issues/2) MacOS support
|
||||
- [x] Rewrite `capture.c` for MacOS port using [AVFoundation](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html). ([Stackoverflow : how do I set up a video input using the AVFoundation framework](https://stackoverflow.com/questions/32053460/how-do-i-set-up-a-video-input-using-the-avfoundation-framework))
|
||||
- [x] Rewrite `capture.c` for MacOS port using [AVFoundation](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html).
|
||||
- [x] `nl_calloc`: zero-fill loop was commented out (returned uninitialized memory) and the `SIZE_MAX` overflow guard ran _after_ the allocation, leaking the spurious block on overflow. Both fixed.
|
||||
- [x] `nl_free`: backward coalescing was a `TODO` stub — non-LIFO frees (e.g. edge-detection scratch buffers) left permanently unmerged holes. Implemented by walking from arena start to find the preceding block.
|
||||
- [x] `main.c` double-buffer bug: a second `out_buf` was `malloc`/`free`'d every frame inside the loop, shadowing the persistent pre-loop allocation. Frame-loop malloc removed; the single persistent buffer is reused for the program's lifetime.
|
||||
- [x] `ascii.c` `RENDER_HALF_BLOCK` height rounding: `safe_dst_h` was rounded down to a multiple of 4 unconditionally, but half-block mode only needs multiples of 2 (it stacks 2 subpixel rows per glyph, not 4). Fixed to be mode-aware.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue