mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 22:02:27 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
333
test/tool/viz/lib/fun_test.c
Normal file
333
test/tool/viz/lib/fun_test.c
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "tool/viz/lib/ycbcr.h"
|
||||
|
||||
#define C1331(A, B, C, D) \
|
||||
({ \
|
||||
unsigned short Ax, Bx; \
|
||||
unsigned char Al, Bl, Cl, Dl; \
|
||||
Al = (A); \
|
||||
Bl = (B); \
|
||||
Cl = (C); \
|
||||
Dl = (D); \
|
||||
Bx = Bl; \
|
||||
Bx += Cl; \
|
||||
Bx *= 3; \
|
||||
Ax = Al; \
|
||||
Ax += Dl; \
|
||||
Ax += Bx; \
|
||||
Ax += 4; \
|
||||
Ax >>= 3; \
|
||||
Al = Ax; \
|
||||
Al; \
|
||||
})
|
||||
|
||||
TEST(C1331, test) {
|
||||
EXPECT_EQ(0, C1331(0, 0, 0, 0));
|
||||
EXPECT_EQ(255, C1331(255, 255, 255, 255));
|
||||
EXPECT_EQ(79, C1331(33, 100, 77, 69));
|
||||
EXPECT_EQ(80, C1331(39, 100, 77, 69));
|
||||
}
|
||||
|
||||
#define C161(A, B, C) \
|
||||
({ \
|
||||
short Dx; \
|
||||
unsigned char Dl; \
|
||||
unsigned char Al, Bl, Cl; \
|
||||
unsigned short Ax, Bx, Cx; \
|
||||
Al = (A); \
|
||||
Bl = (B); \
|
||||
Cl = (C); \
|
||||
\
|
||||
Bx = Bl; \
|
||||
Bx += 3; \
|
||||
Bx >>= 1; \
|
||||
Bx += Bl; \
|
||||
\
|
||||
Ax = Al; \
|
||||
Ax += 4; \
|
||||
Ax >>= 2; \
|
||||
\
|
||||
Cx = Cl; \
|
||||
Cx += 4; \
|
||||
Cx >>= 2; \
|
||||
\
|
||||
Dx = Bx; \
|
||||
Dx -= Ax; \
|
||||
Dx -= Cx; \
|
||||
\
|
||||
Dx = MAX(0, Dx); \
|
||||
Dx = MIN(255, Dx); \
|
||||
Dl = Dx; \
|
||||
Dl; \
|
||||
})
|
||||
|
||||
TEST(C161, test) {
|
||||
EXPECT_EQ(0, C161(0, 0, 0));
|
||||
EXPECT_EQ(255, C161(255, 255, 255));
|
||||
EXPECT_EQ(124, C161(33, 100, 69)); /* 124.50 = 3/2.*100 -1/4.*33 -1/4.*69 */
|
||||
EXPECT_EQ(124, C161(33, 100, 70)); /* 124.25 = 3/2.*100 -1/4.*33 -1/4.*70 */
|
||||
EXPECT_EQ(126, C161(33, 101, 69)); /* 126.00 = 3/2.*101 -1/4.*33 -1/4.*69 */
|
||||
}
|
||||
|
||||
#define C121(A, B, C) \
|
||||
({ \
|
||||
short Dx; \
|
||||
unsigned char Dl; \
|
||||
unsigned char Al, Bl, Cl; \
|
||||
unsigned short Ax, Bx, Cx; \
|
||||
Al = (A); \
|
||||
Bl = (B); \
|
||||
Cl = (C); \
|
||||
\
|
||||
Bx = Bl; \
|
||||
Bx += 3; \
|
||||
Bx >>= 1; \
|
||||
Bx += Bl; \
|
||||
\
|
||||
Ax = Al; \
|
||||
Ax += 4; \
|
||||
Ax >>= 2; \
|
||||
\
|
||||
Cx = Cl; \
|
||||
Cx += 4; \
|
||||
Cx >>= 2; \
|
||||
\
|
||||
Dx = Bx; \
|
||||
Dx -= Ax; \
|
||||
Dx -= Cx; \
|
||||
\
|
||||
Dx = MAX(0, Dx); \
|
||||
Dx = MIN(255, Dx); \
|
||||
Dl = Dx; \
|
||||
Dl; \
|
||||
})
|
||||
|
||||
TEST(C121, test) {
|
||||
EXPECT_EQ(0, C161(0, 0, 0));
|
||||
EXPECT_EQ(255, C161(255, 255, 255));
|
||||
EXPECT_EQ(124, C161(33, 100, 69)); /* 124.50 = 3/2.*100 -1/4.*33 -1/4.*69 */
|
||||
EXPECT_EQ(124, C161(33, 100, 70)); /* 124.25 = 3/2.*100 -1/4.*33 -1/4.*70 */
|
||||
EXPECT_EQ(126, C161(33, 101, 69)); /* 126.00 = 3/2.*101 -1/4.*33 -1/4.*69 */
|
||||
}
|
||||
|
||||
#define BLERP(A, B, P) \
|
||||
({ \
|
||||
unsigned char Al, Bl, Cl, Dl; \
|
||||
unsigned short Bx; \
|
||||
Al = (A); \
|
||||
Bl = (B); \
|
||||
Cl = MAX(Al, Bl); \
|
||||
Al = MIN(Al, Bl); \
|
||||
Dl = Cl - Al; \
|
||||
Bl = (P); \
|
||||
Bx = Bl; \
|
||||
Bx *= Dl; \
|
||||
Bx += 255; \
|
||||
Bx >>= 8; \
|
||||
Bx += Al; \
|
||||
Al = Bx; \
|
||||
Al; \
|
||||
})
|
||||
|
||||
TEST(BLERP, test) {
|
||||
EXPECT_EQ(0, BLERP(0, 0, 128));
|
||||
EXPECT_EQ(255, BLERP(255, 255, 128));
|
||||
EXPECT_EQ(64, BLERP(0, 128, 128));
|
||||
EXPECT_EQ(64, BLERP(128, 0, 128));
|
||||
EXPECT_EQ(32, BLERP(0, 128, 64));
|
||||
EXPECT_EQ(32, BLERP(128, 0, 64));
|
||||
EXPECT_EQ(8, BLERP(0, 128, 16));
|
||||
EXPECT_EQ(8, BLERP(128, 0, 16));
|
||||
EXPECT_EQ(0, BLERP(0, 128, 0));
|
||||
EXPECT_EQ(0, BLERP(128, 0, 0));
|
||||
EXPECT_EQ(128, BLERP(0, 128, 255));
|
||||
EXPECT_EQ(128, BLERP(128, 0, 255));
|
||||
}
|
||||
|
||||
#define MIX(A, B) \
|
||||
({ \
|
||||
short Ax, Bx; \
|
||||
Ax = (A); \
|
||||
Bx = (B); \
|
||||
Ax += Bx; \
|
||||
Ax += 1; \
|
||||
Ax /= 2; \
|
||||
Ax; \
|
||||
})
|
||||
|
||||
TEST(MIX, test) {
|
||||
EXPECT_EQ(0, MIX(0, 0));
|
||||
EXPECT_EQ(255, MIX(255, 255));
|
||||
EXPECT_EQ(64, MIX(0, 128));
|
||||
EXPECT_EQ(64, MIX(128, 0));
|
||||
EXPECT_EQ(127, MIX(0, 254));
|
||||
}
|
||||
|
||||
void ExpandLuminosityRange(unsigned n, unsigned char *Y) {
|
||||
unsigned i, j;
|
||||
unsigned char b[16];
|
||||
unsigned short s[16];
|
||||
CHECK_ALIGNED(16, Y);
|
||||
for (i = 0; i < n; i += 16) {
|
||||
memcpy(b, Y + i, 16);
|
||||
for (j = 0; j < 16; ++j) b[j] = MAX(0, b[j] - 16);
|
||||
for (j = 0; j < 16; ++j) s[j] = b[j];
|
||||
for (j = 0; j < 16; ++j) s[j] *= 150;
|
||||
for (j = 0; j < 16; ++j) s[j] /= 128;
|
||||
for (j = 0; j < 16; ++j) s[j] = MIN(255, s[j]);
|
||||
for (j = 0; j < 16; ++j) b[j] = s[j];
|
||||
memcpy(Y + i, b, 16);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ExpandLuminosityRange, test) {
|
||||
unsigned char Y[32];
|
||||
Y[0] = 0;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(0, Y[0]);
|
||||
Y[0] = 16;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(0, Y[0]);
|
||||
Y[0] = 17;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(1, Y[0]);
|
||||
Y[0] = 128;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(131, Y[0]);
|
||||
Y[0] = 233;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(254, Y[0]);
|
||||
Y[0] = 235;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(255, Y[0]);
|
||||
Y[0] = 255;
|
||||
ExpandLuminosityRange(16, Y);
|
||||
EXPECT_EQ(255, Y[0]);
|
||||
}
|
||||
|
||||
#if 1
|
||||
void NtscItu601YCbCrToStandardRgb(unsigned n, unsigned char *restrict Y,
|
||||
unsigned char *restrict Cb,
|
||||
unsigned char *restrict Cr) {
|
||||
unsigned i;
|
||||
short r, g, b;
|
||||
unsigned char y;
|
||||
for (i = 0; i < n; ++i) {
|
||||
y = MIN(255, (MIN(235, MAX(16, Y[i])) - 16) * 150 / 128);
|
||||
r = y + ((Cr[i] + ((Cr[i] * 103) / 256)) - 179);
|
||||
g = y - (((Cb[i] * 88) / 256) - 44 + ((Cr[i] * 183) / 256) - 91);
|
||||
b = y + ((Cb[i] + ((Cb[i] * 198) / 256)) - 227);
|
||||
Y[i] = MIN(255, MAX(0, r));
|
||||
Cb[i] = MIN(255, MAX(0, g));
|
||||
Cr[i] = MIN(255, MAX(0, b));
|
||||
}
|
||||
}
|
||||
#else
|
||||
void NtscItu601YCbCrToStandardRgb(size_t n, unsigned char *restrict Y,
|
||||
unsigned char *restrict Cb,
|
||||
unsigned char *restrict Cr) {
|
||||
unsigned i;
|
||||
short y, gb, gr, r, g, b;
|
||||
unsigned char gs, cb, cr;
|
||||
unsigned short bw, ky, kr, kb, kgb, kgr;
|
||||
for (i = 0; i < n; ++i) {
|
||||
y = Y[i];
|
||||
cb = Cb[i];
|
||||
cr = Cr[i];
|
||||
y -= 16; /* luminance (expand tv range [16,235] for pc [0,255]) */
|
||||
y = MAX(0, y);
|
||||
y = MIN(234 - 16, y);
|
||||
ky = y;
|
||||
ky *= 150;
|
||||
ky /= 128;
|
||||
gs = ky;
|
||||
kr = cr; /* red */
|
||||
kr *= 103;
|
||||
kr /= 256;
|
||||
kr += cr;
|
||||
r = kr;
|
||||
r -= 179;
|
||||
r += gs;
|
||||
kb = cb; /* blue */
|
||||
kb *= 198;
|
||||
kb /= 256;
|
||||
kb += cb;
|
||||
b = kb;
|
||||
b -= 227;
|
||||
b += gs;
|
||||
kgb = cb; /* green */
|
||||
kgb *= 88;
|
||||
kgb /= 256;
|
||||
gb = kgb;
|
||||
gb -= 44;
|
||||
kgr = cr;
|
||||
kgr *= 183;
|
||||
kgr /= 256;
|
||||
gr = kgr;
|
||||
gr -= 91;
|
||||
g = gs;
|
||||
g -= gr;
|
||||
g -= gb;
|
||||
r = MAX(0, r); /* clamp */
|
||||
g = MAX(0, g);
|
||||
b = MAX(0, b);
|
||||
r = MIN(255, r);
|
||||
g = MIN(255, g);
|
||||
b = MIN(255, b);
|
||||
Y[i] = r;
|
||||
Cb[i] = g;
|
||||
Cr[i] = b;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(NtscItu601YCbCrToStandardRgb, testWhite) {
|
||||
unsigned char a, b, c;
|
||||
a = 234;
|
||||
b = 128;
|
||||
c = 128;
|
||||
NtscItu601YCbCrToStandardRgb(1, &a, &b, &c);
|
||||
EXPECT_EQ(255, a);
|
||||
EXPECT_EQ(255, b);
|
||||
EXPECT_EQ(255, c);
|
||||
a = 235;
|
||||
b = 128;
|
||||
c = 128;
|
||||
NtscItu601YCbCrToStandardRgb(1, &a, &b, &c);
|
||||
EXPECT_EQ(255, a);
|
||||
EXPECT_EQ(255, b);
|
||||
EXPECT_EQ(255, c);
|
||||
a = 255;
|
||||
b = 128;
|
||||
c = 128;
|
||||
NtscItu601YCbCrToStandardRgb(1, &a, &b, &c);
|
||||
EXPECT_EQ(255, a);
|
||||
EXPECT_EQ(255, b);
|
||||
EXPECT_EQ(255, c);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue