First
This commit is contained in:
commit
1e18558472
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.svcs/
|
144
README.md
Normal file
144
README.md
Normal file
@ -0,0 +1,144 @@
|
||||
# VNM
|
||||
Venom (vnm, virtual nano media) is an experimental
|
||||
image, audio, and video file format.
|
||||
|
||||
It's suppposed to be extremely simple and [suckless](https://suckless.org).
|
||||
Images are 16 color and run length encoded, It's like 'farbfeld' driven
|
||||
to its end conclusion. The default color palette is that of TempleOS'.
|
||||
|
||||
__Venom is the best set of multimedia formats in the world.__
|
||||
|
||||
---
|
||||
|
||||
## IMAGES
|
||||
|
||||
Magic number letter "V" (86)
|
||||
|
||||
uint8 width and height as a single value
|
||||
(must be power of two), this is multiplied by 8, max resulting resolution is
|
||||
1024x1024
|
||||
So to get 1024x1024 this value is 128, to get 512x512 you do 64.
|
||||
|
||||
row by row uint8 (color) and uint8 (run length)
|
||||
|
||||
---
|
||||
|
||||
## AUDIO
|
||||
|
||||
Audio is always 8000hz
|
||||
Magic number letter "A" (65)
|
||||
uint8 list of samples.
|
||||
|
||||
---
|
||||
|
||||
## VIDEO
|
||||
|
||||
Video is at the top, audio at the bottom, Video is 30FPS.
|
||||
Width and height is unchanging.
|
||||
|
||||
Sequence of "V" images
|
||||
The audio "A" sequence
|
||||
|
||||
---
|
||||
|
||||
## TOS COLOR PALETTE
|
||||
|
||||
This will be default for all the programs.
|
||||
|
||||
00. #000000 (Black) 0,0,0
|
||||
01. #0000AA (Blue) 0,0,170
|
||||
02. #00AA00 (Green) 0,170,0
|
||||
03. #00AAAA (Cyan) 0,170,170
|
||||
04. #AA0000 (Red) 170,0,0
|
||||
05. #AA00AA (Magenta) 170,0,170
|
||||
06. #AA5500 (Brown) 170,79,0
|
||||
07. #AAAAAA (Light Gray) 170,170,170
|
||||
08. #555555 (Dark Gray) 79,79,79
|
||||
09. #5555FF (Light Blue) 79,79,255
|
||||
10. #55FF55 (Light Green) 79,255,79
|
||||
11. #55FFFF (Light Cyan) 79,255,255
|
||||
12. #FF5555 (Light Red) 255,79,79
|
||||
13. #FF55FF (Light Magenta) 255,79,255
|
||||
14. #FFFF55 (Yellow) 255,255,79
|
||||
15. #FFFFFF (White) 255,255,255
|
||||
|
||||
---
|
||||
|
||||
## Why?
|
||||
|
||||
Multimedia sucks. You may notice that all the files are completely
|
||||
composed of eight bit integers, this allows for multimedia files to
|
||||
be easily modified by UNIX utilities in interesting interactions, or
|
||||
be generated very easily. I can see the feasibility of getting a VNM
|
||||
file to glitch out, but I don't really care, and it has never
|
||||
happened in practice. Ive discovered that 16 color isnt a such
|
||||
a hardship, it's quite liberating, especially with proper dithering
|
||||
images can look indistinguishable and 'cooler'. The palettes of the programs
|
||||
can also just be modified to best suite a set of images.
|
||||
VNM is also perfect for embedded assets in ROMs.
|
||||
|
||||
---
|
||||
|
||||
## PROGRAMS
|
||||
|
||||
ff2vnm - Convert farbfeld images to vnm images
|
||||
vnmstat - Program that identifies, validates, and makes stats for a vnm file
|
||||
vnmnoise - Example program that generates an unoptimized noisy image
|
||||
vnmbeat - Example program that generates a sound file
|
||||
vnmcarr - Convert VNM files into C arrays
|
||||
|
||||
VNM is so simple, you can just use your core utils to work
|
||||
with it.
|
||||
|
||||
Combining images into a video: cat baby.vnm recursion.vnm > slideshow.vnm
|
||||
Splitting video into images and audio: csplit -z slideshow.vnm /V/ '{*}'
|
||||
|
||||
---
|
||||
|
||||
## SCRIPTS
|
||||
|
||||
png2vnm.sh - Convert PNG to VNM given png2ff
|
||||
vid2vnm.sh - Convert video to VNM
|
||||
|
||||
|
||||
## PHILANTHROPY
|
||||
|
||||
_official VNM donation fund_
|
||||
|
||||
Monero (XMR): 48Sxa8J6518gqp4WeGtQ4rLe6SctPrEnnCqm6v6ydjLwRPi9Uh9gvVuUsU2AEDw75meTHCNY8KfU6Txysom4Bn5qPKMJ75w
|
||||
|
||||
Wownero (WOW): WW2L2yC6DMg7GArAH3nqXPA6UBoRogf64GodceqA32SeZQpx27xd6rqN82e36KE48a8SAMSoXDB5WawAgVEFKfkw1Q5KSGfX9
|
||||
|
||||
If you have philanthropic interest in VNM, contact Vilyaem.
|
||||
|
||||
---
|
||||
|
||||
## LICENSE
|
||||
|
||||
|
||||
CHRISTIAN FREE SOFTWARE LICENSE
|
||||
CFSL
|
||||
|
||||
This software is free and open source charity ware, users are asked
|
||||
to donate to the Eastern Orthodox Church by any means.
|
||||
|
||||
Redistribution of this project in source and/or binary forms with/without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions must retain this notice, the conditions, and the disclaimer.
|
||||
2. Redistributions must retain credit to the author, and signage to where the original
|
||||
work can be found.
|
||||
3. Redistributions cannot become a part of, in anyway shape or form, part of proprietary
|
||||
software, or software that is clearly out of line with Christian values.
|
||||
4. Redistributions must remain free, both in price, and what users may do with the software,
|
||||
the software must remain public and easily accessible.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
BIN
bin/ff2vnm
Executable file
BIN
bin/ff2vnm
Executable file
Binary file not shown.
BIN
bin/vnmbeat
Executable file
BIN
bin/vnmbeat
Executable file
Binary file not shown.
BIN
bin/vnmcarr
Executable file
BIN
bin/vnmcarr
Executable file
Binary file not shown.
BIN
bin/vnmnoise
Executable file
BIN
bin/vnmnoise
Executable file
Binary file not shown.
BIN
bin/vnmstat
Executable file
BIN
bin/vnmstat
Executable file
Binary file not shown.
10
c.sh
Executable file
10
c.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
cl
|
||||
rm bin/*
|
||||
CC="cc -O3 -std=c89 -Wall -Wpedantic -Wextra -Werror "
|
||||
$CC programs/ff2vnm.c -o bin/ff2vnm
|
||||
$CC programs/vnmbeat.c -o bin/vnmbeat
|
||||
$CC programs/vnmcarr.c -o bin/vnmcarr
|
||||
$CC programs/vnmnoise.c -o bin/vnmnoise
|
||||
$CC programs/vnmstat.c -o bin/vnmstat
|
||||
doas cp bin/* /usr/bin/
|
BIN
examples/baby.ff
Normal file
BIN
examples/baby.ff
Normal file
Binary file not shown.
BIN
examples/baby.vnm
Normal file
BIN
examples/baby.vnm
Normal file
Binary file not shown.
BIN
examples/black.ff
Normal file
BIN
examples/black.ff
Normal file
Binary file not shown.
BIN
examples/black.vnm
Normal file
BIN
examples/black.vnm
Normal file
Binary file not shown.
BIN
examples/church.ff
Normal file
BIN
examples/church.ff
Normal file
Binary file not shown.
BIN
examples/church.vnm
Normal file
BIN
examples/church.vnm
Normal file
Binary file not shown.
BIN
examples/empire.wav
Normal file
BIN
examples/empire.wav
Normal file
Binary file not shown.
BIN
examples/lord.ff
Normal file
BIN
examples/lord.ff
Normal file
Binary file not shown.
BIN
examples/noise.vnm
Normal file
BIN
examples/noise.vnm
Normal file
Binary file not shown.
BIN
examples/recursive.ff
Normal file
BIN
examples/recursive.ff
Normal file
Binary file not shown.
BIN
examples/recursive.vnm
Normal file
BIN
examples/recursive.vnm
Normal file
Binary file not shown.
156
programs/ff2vnm.c
Normal file
156
programs/ff2vnm.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*********************************************
|
||||
* Description - Convert Farbfeld images to VNM
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
|
||||
/*----------PREPROCESSOR----------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAXRES 512
|
||||
|
||||
/*----------DATA STRUCTURES----------*/
|
||||
|
||||
/*color*/
|
||||
typedef struct {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} Color;
|
||||
|
||||
/*----------GLOBALS----------*/
|
||||
|
||||
Color palette[16] = {
|
||||
{0, 0, 0}, /*#000000 (Black)*/
|
||||
{0, 0, 170}, /*#0000AA (Blue)*/
|
||||
{0, 170, 0}, /*#00AA00 (Green)*/
|
||||
{0, 170, 170}, /*#00AAAA (Cyan)*/
|
||||
{170, 0, 0}, /*#AA0000 (Red)*/
|
||||
{170, 0, 170}, /*#AA00AA (Magenta)*/
|
||||
{170, 79, 0}, /*#AA5500 (Brown)*/
|
||||
{170, 170, 170}, /*#AAAAAA (Light Gray)*/
|
||||
{79, 79, 79}, /*#555555 (Dark Gray)*/
|
||||
{79, 79, 255}, /*#5555FF (Light Blue)*/
|
||||
{79, 255, 79}, /*#55FF55 (Light Green)*/
|
||||
{79, 255, 255}, /*#55FFFF (Light Cyan)*/
|
||||
{255, 79, 79}, /*#FF5555 (Light Red)*/
|
||||
{255, 79, 255}, /*#FF55FF (Light Magenta)*/
|
||||
{255, 255, 79}, /*#FFFF55 (Yellow)*/
|
||||
{255, 255, 255} /*#FFFFFF (White)*/
|
||||
};
|
||||
|
||||
int i;
|
||||
|
||||
/*----------FUNCTIONS----------*/
|
||||
|
||||
/*********************************************
|
||||
* Description - Find closest colour in the palette
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
uint8_t findClosestColor(Color pixel) {
|
||||
uint8_t closestColor;
|
||||
int minDistance;
|
||||
closestColor = 0;
|
||||
minDistance = 255 * 255 * 3; /* Initialize with max distance value*/
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
int dr;
|
||||
int dg;
|
||||
int db;
|
||||
int distance;
|
||||
|
||||
dr = pixel.r - palette[i].r;
|
||||
dg = pixel.g - palette[i].g;
|
||||
db = pixel.b - palette[i].b;
|
||||
distance = dr * dr + dg * dg + db * db;
|
||||
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closestColor = i;
|
||||
}
|
||||
}
|
||||
|
||||
return closestColor;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Description - Main
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
int main(int argc, char* argv[]) {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
FILE* output;
|
||||
FILE* input;
|
||||
char magic[8];
|
||||
Color prevPixel = {0,0,0};
|
||||
uint8_t colorCount;
|
||||
|
||||
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s input_image.farbfeld output_image.rle\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
input = fopen(argv[1], "rb");
|
||||
if (!input) {
|
||||
puts("Error: Unable to open input file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*Reading header*/
|
||||
fread(magic, 1, 8, input);
|
||||
|
||||
/*Forced width and height*/
|
||||
width = MAXRES;
|
||||
height = MAXRES;
|
||||
|
||||
/*Output the RLE header*/
|
||||
output = fopen(argv[2], "wb");
|
||||
fputc('V', output); /* Magic number*/
|
||||
fputc(width / 8, output); /* Actual width*/
|
||||
fputc(height / 8, output); /* Actual height*/
|
||||
|
||||
/*Read and convert each pixel*/
|
||||
colorCount = 1;
|
||||
|
||||
for (i = 0; i < (int)width * (int)height; i++) {
|
||||
uint16_t rgba[4];
|
||||
uint8_t currentColor;
|
||||
Color pixel;
|
||||
|
||||
fread(rgba, sizeof(uint16_t), 4, input);
|
||||
|
||||
/*pixel = (Color){rgba[0] >> 8, rgba[1] >> 8, rgba[2] >> 8};*/
|
||||
pixel.r = rgba[0] >> 8;
|
||||
pixel.g = rgba[1] >> 8;
|
||||
pixel.b = rgba[2] >> 8;
|
||||
|
||||
currentColor = findClosestColor(pixel);
|
||||
|
||||
if (currentColor == findClosestColor(prevPixel) && colorCount < 64) { /*dont make V and A characters and break files!*/
|
||||
colorCount++;
|
||||
} else {
|
||||
fputc(findClosestColor(prevPixel), output);
|
||||
fputc(colorCount, output);
|
||||
prevPixel = pixel;
|
||||
colorCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*Output the last color run*/
|
||||
if (colorCount > 0) {
|
||||
fputc(findClosestColor(prevPixel), output);
|
||||
fputc(colorCount, output);
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
fclose(output);
|
||||
|
||||
puts("Conversion complete.\n");
|
||||
return 0;
|
||||
}
|
21
programs/vnmbeat.c
Normal file
21
programs/vnmbeat.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*********************************************
|
||||
* Description - VNMBeat, example program
|
||||
* that generates a sound in VNM
|
||||
*
|
||||
* ./vnmbeat > vnmbeat.vnm
|
||||
*
|
||||
* Author - Vilyaem
|
||||
* Date - Apr 28 2024
|
||||
* *******************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void){
|
||||
int i;
|
||||
putchar('A');
|
||||
for ( i = 0; i < 1000000; i++)
|
||||
putchar(
|
||||
( (i * i ^ i) | ((i % 73) * i*8 & i >> 24)) /*play with this to make music*/
|
||||
);
|
||||
return 0;
|
||||
}
|
30
programs/vnmcarr.c
Normal file
30
programs/vnmcarr.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*********************************************
|
||||
* Description - Convert VNM files to C arrays
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
|
||||
/*----------PREPROCESSOR----------*/
|
||||
#include <stdio.h>
|
||||
|
||||
/*----------FUNCTIONS----------*/
|
||||
|
||||
/*********************************************
|
||||
* Description - Main
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
int main(void){
|
||||
int c;
|
||||
puts("/* Generated by VNMCARR */\nuint8_t vnm[] = {");
|
||||
while((c = fgetc(stdin)) != EOF){
|
||||
if(c % 2 == 0){ /*Avoid the last indice having a comma*/
|
||||
printf(",%d",c);
|
||||
}
|
||||
else{
|
||||
printf("%d",c);
|
||||
}
|
||||
}
|
||||
puts("\n};");
|
||||
return 0;
|
||||
}
|
27
programs/vnmnoise.c
Normal file
27
programs/vnmnoise.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*********************************************
|
||||
* Description - Example VNM noise generator
|
||||
* THis does no attempt to make the output tiny,
|
||||
* this is a demonstration on how easy it is to produce
|
||||
* vnm files.
|
||||
*
|
||||
* ./vnmnoise > noise.vnm
|
||||
*
|
||||
* Author - Vilyaem
|
||||
* Date - Apr 26 2024
|
||||
* *******************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define RES 1024 /*Our resolution*/
|
||||
|
||||
int main(void){
|
||||
int i;
|
||||
putchar('V');
|
||||
putchar(RES/8);
|
||||
for(i = 0; i != RES*RES;i++){
|
||||
putchar(1);
|
||||
putchar(i%rand());
|
||||
}
|
||||
return 0;
|
||||
}
|
27
programs/vnmopt.c
Normal file
27
programs/vnmopt.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*********************************************
|
||||
* Description - VNM Image optimizer
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
|
||||
/*----------PREPROCESSOR----------*/
|
||||
#include <stdio.h>
|
||||
|
||||
/*----------FUNCTIONS----------*/
|
||||
|
||||
/*********************************************
|
||||
* Description - Main
|
||||
* Author - Vilyaem
|
||||
* Date - May 03 2024
|
||||
* *******************************************/
|
||||
int main(void){
|
||||
int c;
|
||||
int curcolour = 0;
|
||||
while((c = fgetc(stdin)) != EOF){
|
||||
if(c - 1 % 2 == 0){ /*it's run length*/
|
||||
}
|
||||
else { /*it's a colour*/
|
||||
curcolour = c;
|
||||
}
|
||||
}
|
||||
}
|
75
programs/vnmstat.c
Normal file
75
programs/vnmstat.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*********************************************
|
||||
* Description - VNM Stat, report and identify on VNM
|
||||
* files
|
||||
*
|
||||
* < file.vnm | ./vnmstat
|
||||
*
|
||||
* Author - Vilyaem
|
||||
* Date - Apr 26 2024
|
||||
* *******************************************/
|
||||
|
||||
|
||||
/*----------PREPROCESSOR----------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define IMG 0
|
||||
#define AUD 1
|
||||
#define VID 2
|
||||
|
||||
/*----------GLOBALS----------*/
|
||||
int c;
|
||||
int charcnt = 0;
|
||||
int framecnt = 0;
|
||||
int mode = -1;
|
||||
int res = 0;
|
||||
|
||||
/*----------FUNCTIONS----------*/
|
||||
|
||||
/*********************************************
|
||||
* Description - Main
|
||||
* Author - Vilyaem
|
||||
* Date - Apr 26 2024
|
||||
* *******************************************/
|
||||
int main(void){
|
||||
|
||||
/*Recieve file via STDIN*/
|
||||
while(c != EOF){
|
||||
c = fgetc(stdin);
|
||||
|
||||
/*Determine the type of file*/
|
||||
if(charcnt == 0 && c == 'V'){
|
||||
mode = IMG;
|
||||
}
|
||||
else if(charcnt == 0 && c == 'A'){
|
||||
mode = AUD;
|
||||
}
|
||||
/*Determine if the image is actually a video*/
|
||||
if((mode == IMG && charcnt != 0) && (c == 'V' || c == 'A')){
|
||||
mode = VID;
|
||||
framecnt = 1; /*(counting the first one)*/
|
||||
}
|
||||
/*Determine resolution*/
|
||||
if(mode == IMG && charcnt == 1){
|
||||
res = c * 8;
|
||||
}
|
||||
/*Count up frames*/
|
||||
if(mode == VID && c == 'V'){
|
||||
framecnt++;
|
||||
}
|
||||
|
||||
|
||||
charcnt++;
|
||||
}
|
||||
|
||||
/*Print the results*/
|
||||
puts("---VNM STATS---");
|
||||
switch(mode){
|
||||
case IMG: printf("This is an image, it has %d bytes of data, the resolution is %d.\n",charcnt,res); break;
|
||||
case AUD: printf("This is an audio file, it has %d bytes of data.\n",charcnt); break;
|
||||
case VID: printf("This is a video, it has %d bytes of data, it has %d frames, the resolution is %d.\n",charcnt,framecnt,res); break;
|
||||
default:puts("error: bad file");break;
|
||||
}
|
||||
return 0;
|
||||
}
|
4
scripts/png2vnm.sh
Executable file
4
scripts/png2vnm.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
png2ff < "$1" > "$1.png"
|
||||
cat "$1.png" | ff2.vnm > "$1.vnm"
|
||||
rm "$1.png"
|
20
scripts/vid2vnm.sh
Executable file
20
scripts/vid2vnm.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
clear
|
||||
input_video="$1"
|
||||
rm result.vnm
|
||||
## Convert video to PNG frames at 30 FPS
|
||||
ffmpeg -r 30 -i "$input_video" frame-%04d.png
|
||||
ls
|
||||
## Process the frames into farbfeld format with ff2png
|
||||
find -type f . -name "*.png" -exec cat {} | ff2png >> {}.ff \;
|
||||
ls
|
||||
## Process the farbfeld images to VNM images
|
||||
find -type f . -name "*.png.ff" -exec ff2vnm {} {}.vnm \;
|
||||
ls
|
||||
## Extract audio from video to an 8000hz WAV file
|
||||
ffmpeg -ar 8000 -ac 1 -i "$input_video" AUDIO.raw
|
||||
cat *.vnm > result.vnm
|
||||
echo "A" >> result.vnm
|
||||
cat AUDIO.wav >> result.vnm
|
||||
rm frame*
|
||||
rm AUDIO.wav
|
Loading…
Reference in New Issue
Block a user