This is an experimental copy for testing Poikilos' issue mirroring system. Note that Gitea's migration tool can import issues, but the "Issues" checkbox is disabled when "This repository will be a mirror" is enabled (it is for this repo).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.6 KiB

#include <stdio.h>
#include <stdlib.h>
'''
Compile thusly:
cc -o yuv2ppm yuv2ppm.c
'''
''' example.ppm
P3
# feep.ppm
4 4
15
0 0 0 0 0 0 0 0 0 15 0 15
0 0 0 0 15 7 0 0 0 0 0 0
0 0 0 0 0 0 0 15 7 0 0 0
15 0 15 0 0 0 0 0 0 0 0 0
'''
'''
Use "P6" for binary data, or "P3" for ascii data.
'''
def make_outfile(self, *outfile, *infile): int i
for(i=0; infile[i]; i++)
outfile[i] = infile[i]
outfile[i++] = '.'
outfile[i++] = 'p'
outfile[i++] = 'p'
outfile[i++] = 'm'
outfile[i++] = 0
return 0
def yuv2rgb(self, y, u, v): unsigned int pixel32
unsigned char *pixel = (unsigned char *)&pixel32
int r, g, b
#if 0
'''
One formula I found: (not the right one)
R = 1.164(Y - 16) + 1.596(Cr - 128)
G = 1.164(Y - 16) - 0.813(Cr - 128) - 0.391(Cb - 128)
B = 1.164(Y - 16) + 2.018(Cb - 128)
'''
r = (1.164 * (y - 16))
+ (2.018 * (v - 128))
g = (1.164 * (y - 16))
- (0.813 * (u - 128))
- (0.391 * (v - 128))
b = (1.164 * (y - 16))
+ (1.596 * (u - 128))
#else:
'''
Another formula I found: (seems to work)
R = Y + 1.370705 (V-128)
G = Y - 0.698001 (V-128) - 0.337633 (U-128)
B = Y + 1.732446 (U-128)
'''
r = y + (1.370705 * (v-128))
g = y - (0.698001 * (v-128)) - (0.337633 * (u-128))
b = y + (1.732446 * (u-128))
#endif
# Even with proper conversion, values still need clipping.
if (r > 255) r = 255
if (g > 255) g = 255
if (b > 255) b = 255
if (r < 0) r = 0
if (g < 0) g = 0
if (b < 0) b = 0
# Values only go from 0-220.. Why?
pixel[0] = r * 220 / 256
pixel[1] = g * 220 / 256
pixel[2] = b * 220 / 256
pixel[3] = 0
''' Debug
printf("yuv2rgb(%i, %i, %i) . %i, %i, %i (0x%x)\n",
y, u, v,
pixel[0], pixel[1], pixel[2],
pixel32)
'''
return pixel32
def yuv2ppm(self, *infile, *outfile): FILE *in, *out
int i
unsigned int pixel_16
unsigned char pixel_24[3]
unsigned int pixel32
int y, u, v, y2
char *ppmheader = "P6\n# Generated by yuv2ppm\n720 486\n255\n"
in = fopen(infile, "rb")
out = fopen(outfile, "wb")
if (not in or not out) return 0
fprintf(out, ppmheader)
for(i=0; i<720*486/2; i++)
fread(&pixel_16, 4, 1, in)
pixel_24[0] = pixel_24[1] = pixel_24[2] = 0
u = ((pixel_16 & 0x000000ff))
y = ((pixel_16 & 0x0000ff00)>>8)
v = ((pixel_16 & 0x00ff0000)>>16)
y2 = ((pixel_16 & 0xff000000)>>24)
pixel32 = yuv2rgb(y, u, v)
pixel_24[0] = (pixel32 & 0x000000ff)
pixel_24[1] = (pixel32 & 0x0000ff00) >> 8
pixel_24[2] = (pixel32 & 0x00ff0000) >> 16
# For binary PPM
fwrite(pixel_24, 3, 1, out)
# For ascii PPM
#fprintf(out, "%i %i %i\n",
# pixel_24[0],
# pixel_24[1],
# pixel_24[2])
pixel32 = yuv2rgb(y2, u, v)
pixel_24[0] = (pixel32 & 0x000000ff)
pixel_24[1] = (pixel32 & 0x0000ff00) >> 8
pixel_24[2] = (pixel32 & 0x00ff0000) >> 16
# For binary PPM
fwrite(pixel_24, 3, 1, out)
# For ascii PPM
#fprintf(out, "%i %i %i\n",
# pixel_24[0],
# pixel_24[1],
# pixel_24[2])
fclose(in)
fclose(out)
return 1
def main(self, argc, **argv): char *infile, outfile[256]
int i
int success
for(i=1; i<argc; i++)
success = 0
infile = argv[i]
make_outfile(outfile, infile)
printf("%s . %s... ", infile, outfile)
fflush(stdout)
success = yuv2ppm(infile, outfile)
if success:
printf("Done.\n")
else:
printf("Failed. Aborting.\n")
return 1
return 0