ref: 1a3f7ac2dc211ff277d45e3dac690680fdb87bc6
parent: 6ea15ae0d18aa67aa2064137329e285e13a4af9a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Mar 10 21:29:48 EDT 2025
add -G GAMMA option
--- a/hj264.c
+++ b/hj264.c
@@ -64,6 +64,8 @@
static uvlong tstart, debug;
static int opt, noenc;
+static double gamma = 1.0;
+static u8int gammatbl[256];
#pragma varargck type "ℏ" int
static int
@@ -222,25 +224,42 @@
static void
encthread(void *p)
{
- u8int *data, v[12];
+ u8int *data, v[12], *bgrx;
+ int sz, w, h, x, y;
Img *img, *prev;
uvlong ts;
- Hj264 *h;
- int sz;
+ Hj264 *hj;
threadsetname("hj264/encthread");
- h = p;
+ hj = p;
prev = nil;
for(;;){
- if(recv(h->frame, &img) < 0)
+ if(recv(hj->frame, &img) < 0)
break;
- if(opt && prev != nil && memcmp(img->bgrx, prev->bgrx, img->w*img->h*4) == 0){
+
+ bgrx = img->bgrx;
+ w = img->w;
+ h = img->h;
+
+ if(opt && prev != nil && memcmp(bgrx, prev->bgrx, w*h*4) == 0){
free(img);
continue;
}
- xrgb2yuv420(img->bgrx, img->w, img->h, &h->yuv);
+ if(gamma != 1.0){
+ for(y = 0; y < h; y++){
+ for(x = 0; x < w; x++){
+ bgrx[0] = gammatbl[bgrx[0]];
+ bgrx[1] = gammatbl[bgrx[1]];
+ bgrx[2] = gammatbl[bgrx[2]];
+ bgrx += 4;
+ }
+ }
+ bgrx = img->bgrx;
+ }
+
+ xrgb2yuv420(bgrx, w, h, &hj->yuv);
ts = img->ns / Nmsec;
if(opt){
free(prev);
@@ -251,9 +270,9 @@
if(noenc)
continue;
- if(hj264_encode(h, &data, &sz) != 0)
+ if(hj264_encode(hj, &data, &sz) != 0)
sysfatal("hj264_encode: %r");
- if(h->fmt == FmtIVF){
+ if(hj->fmt == FmtIVF){
v[0] = sz;
v[1] = sz >> 8;
v[2] = sz >> 16;
@@ -266,18 +285,18 @@
v[9] = ts >> 40;
v[10] = ts >> 48;
v[11] = ts >> 56;
- if(Bwrite(&h->out, v, 12) != 12)
+ if(Bwrite(&hj->out, v, 12) != 12)
break;
}
- if(Bwrite(&h->out, data, sz) != sz)
+ if(Bwrite(&hj->out, data, sz) != sz)
break;
}
- Bflush(&h->out);
+ Bflush(&hj->out);
- chanclose(h->frame);
- if(h->done != nil)
- sendp(h->done, nil);
+ chanclose(hj->frame);
+ if(hj->done != nil)
+ sendp(hj->done, nil);
free(prev);
@@ -327,7 +346,7 @@
static void
usage(void)
{
- fprint(2, "usage: %s [-D] [-f FPS] [-F FORMAT] [-g GOP] [-n THREADS] [-o] [-k KBPS] [-q 0…10] [-Q QP] FILE\n", argv0);
+ fprint(2, "usage: %s [-D] [-f FPS] [-F FORMAT] [-g GOP] [-G GAMMA] [-n THREADS] [-o] [-k KBPS] [-q 0…10] [-Q QP] FILE\n", argv0);
threadexitsall("usage");
}
@@ -334,7 +353,7 @@
int
main(int argc, char **argv)
{
- int nthreads, fps, kbps, denoise, quality, qp, gop;
+ int i, nthreads, fps, kbps, denoise, quality, qp, gop;
uvlong fstart, fend, f₀, nframes;
char *s, tmp[61], *f[5];
int ww₀, hh₀, ww, hh, in, fmt;
@@ -378,6 +397,9 @@
case 'g':
gop = atoi(EARGF(usage()));
break;
+ case 'G':
+ gamma = atof(EARGF(usage()));
+ break;
case 'k':
kbps = atoi(EARGF(usage()));
break;
@@ -410,6 +432,12 @@
sysfatal("input: %r");
fmtinstall(L'ℏ', hjerror);
+
+ if(gamma != 1.0){
+ gamma = 1.0/gamma;
+ for(i = 0; i < nelem(gammatbl); i++)
+ gammatbl[i] = 255.0*pow((double)i/255.0, gamma);
+ }
tmp[60] = 0;
if(readn(in, tmp, 60) != 60 || tokenize(tmp, f, 5) != 5)
--
⑨