Useless library/toolkit/scribble that reimplements solved problems for the sake of learning. Contains mostly over-engineered solutions to the programming challenges suggested by Jens Gustedt in Modern C.
If you can't install Clang 18 using a package manager, you can use Docker:
./scripts/build_image.sh
./scripts/run_image.sh
make DEBUG=1 -j && make DEBUG=1 test \
&& make -j && make test \
&& make -j integration_test
Source: ./src/tools/png.c
Simple PNG decoder implemented without dependencies.
./build/debug/tools/png info png_path
./build/debug/tools/png dump_raw png_path block_type [block_types...]
./build/debug/tools/png segment png_src_path png_dst_path [--threshold-percent=N] [-v]
Decode a PNG image and output information in JSON.
This example requires jq
for formatting the output.
If you don't want to install jq
, remove | jq .
from the below example to get the unformatted JSON on a single line.
./build/debug/tools/png info ./docs/img/tokyo.png | jq .
stdout
:
{
"chunks": {
"IHDR": 1,
"IDAT": 13,
"IEND": 1,
"bKGD": 1,
"cHRM": 1,
"gAMA": 1,
"pHYs": 1,
"tEXt": 11,
"tIME": 1
},
"header": {
"width": 500,
"height": 500,
"bit depth": 8,
"color type": "rgb",
"compression": 0,
"filter": 0,
"interlace": 0
},
"data": {
"length": 756012,
"filters": {
"Sub": 31,
"Average": 228,
"Paeth": 241
}
}
}
Apply mean segmentation on PNG images.
Merges adjacent image segments by comparing the Euclidian distance between the average RGB-pixel of each segment, where each RGB-pixel (3 bytes) is interpreted as a vector of length 3: [R, G, B]
.
./build/debug/tools/png segment \
--threshold-percent=10 \
./docs/img/tokyo.png \
./docs/img/tokyo_segmented_10p.png
./build/debug/tools/png segment \
--threshold-percent=20 \
./docs/img/tokyo.png \
./docs/img/tokyo_segmented_20p.png
./build/debug/tools/png segment \
--threshold-percent=30 \
./docs/img/tokyo.png \
./docs/img/tokyo_segmented_30p.png
Decode a PNG image into chunks and write raw chunk data to stdout. Use positional arguments to filter a subset of chunk types.
This example requires xxd
.
./build/debug/tools/png dump_raw ./test-data/png/ff0000-1x1-rgb-fixed.png IHDR IDAT | xxd -b
stdout
:
00000000: 00000000 00000000 00000000 00000001 00000000 00000000 ......
00000006: 00000000 00000001 00001000 00000010 00000000 00000000 ......
0000000c: 00000000 00001000 00011101 01100011 11111000 11001111 ...c..
00000012: 11000000 00000000 00000000 00000011 00000001 00000001 ......
00000018: 00000000 .
Source: ./src/tools/sort.c
Simple line sorting.
./build/debug/tools/sort { numeric | ascii } path
Create data (on macOS, use gfind
) by calculating the size of each input file used during testing:
find ./test-data/png -printf '%s\n' > test-data-sizes.txt
./build/debug/tools/sort numeric ./test-data-sizes.txt
stdout
:
69
69
69
72
72
72
72
160
237
238
238
1554
2970
4096
11223
24733
./build/debug/tools/sort ascii ./test-data-sizes.txt
stdout
:
11223
1554
160
237
238
238
24733
2970
4096
69
69
69
72
72
72
72
./build/debug/tools/sort numeric --reverse ./test-data-sizes.txt
stdout
:
24733
11223
4096
2970
1554
238
238
237
160
72
72
72
72
69
69
69
Source: ./src/tools/txt.c
./build/debug/tools/txt concat path [paths...]
./build/debug/tools/txt count pattern path
./build/debug/tools/txt slicelines begin end path
./build/debug/tools/txt replace pattern replacement path
./build/debug/tools/txt linefreq path
./build/debug/tools/txt concat ./test-data/txt/wikipedia/water_{ja,is,hi,zh}.txt
stdout
:
水(みず、(英: water、他言語呼称は「他言語での呼称」の項を参照)とは、化学式 H2O で表される、水素と酸素の化合物である。日本語においては特に湯と対比して用いられ、液体ではあるが温度が低く、かつ凝固して氷にはなっていない物を言う。また、液状の物全般を指す。
Vatn er ólífrænn lyktar-, bragð- og nær litlaus vökvi sem er lífsnauðsynlegur öllum þekktum lífverum, þrátt fyrir að gefa þeim hvorki fæðu, orku né næringarefni. Vatnssameindin er samsett úr tveimur vetnisfrumeindum og einni súrefnisfrumeind sem tengjast með samgildistengi og hefur efnaformúluna H2O. Vatn er uppistaðan í vatnshvolfi jarðar. Orðið „vatn“ á við um efnið eins og það kemur fyrir við staðalhita og staðalþrýsting.
जल या पानी एक आम रासायनिक पदार्थ है जिसका अणु दो हाइड्रोजन परमाणु और एक प्राणवायु परमाणु से बना है - H2O। यह सारे प्राणियों के जीवन का आधार है। आमतौर पर जल शब्द का प्रयोग द्रव अवस्था के लिए उपयोग में लाया जाता है पर यह ठोस अवस्था (बर्फ) और गैसीय अवस्था (भाप या जल वाष्प) में भी पाया जाता है। पानी जल-आत्मीय सतहों पर तरल-क्रिस्टल के रूप में भी पाया जाता है।
水是地球上最常见的物质之一,是由氢、氧两种元素經過化學反應後组成的无机化合物(分子式:H2O),在常温常压下为无色无味的透明液体。
./build/debug/tools/txt count '#' README.md
./build/debug/tools/txt count '##' README.md
./build/debug/tools/txt count 'ある' README.md
stdout
:
105
42
3
./build/debug/tools/txt slicelines 312 336 ./src/tools/txt.c
stdout
:
int main(int argc, char* const argv[argc + 1]) {
struct sl_args args = sl_args_from_argv(argc, argv);
bool ok = false;
const char* command = sl_args_get_positional(&args, 0);
if (command) {
if (strcmp(command, "concat") == 0) {
ok = concat(&args);
} else if (strcmp(command, "count") == 0) {
ok = count(&args);
} else if (strcmp(command, "slicelines") == 0) {
ok = slicelines(&args);
} else if (strcmp(command, "replace") == 0) {
ok = replace(&args);
} else if (strcmp(command, "linefreq") == 0) {
ok = linefreq(&args);
} else {
SL_LOG_ERROR("unknown command %s", command);
}
}
if (!ok) {
print_usage(&args);
}
sl_args_destroy(&args);
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
./build/debug/tools/txt replace sl_iterator it ./include/stufflib_iterator.h
stdout
:
#ifndef _SL_ITERATOR_H_INCLUDED
#define _SL_ITERATOR_H_INCLUDED
#include <stdlib.h>
#include <string.h>
struct it;
typedef void* it_get_item(struct it*);
typedef void it_advance(struct it*);
typedef bool it_is_done(struct it*);
struct it {
size_t index;
size_t pos;
void* data;
it_get_item* get_item;
it_advance* advance;
it_is_done* is_done;
};
#endif // _SL_ITERATOR_H_INCLUDED
clang-18 -std=c2x -E -I./include ./src/tools/txt.c \
| ./build/debug/tools/txt replace ' ' '' /dev/stdin \
| ./build/debug/tools/txt replace $'\n ' $'\n' /dev/stdin \
| ./build/debug/tools/txt linefreq /dev/stdin \
| ./build/debug/tools/sort numeric --reverse /dev/stdin \
| ./build/debug/tools/txt slicelines 0 25 /dev/stdin
stdout
:
249 }
24 };
18 __attribute__ ((__const__));
17 {
13 goto done;
11 } break;
10 return false;
9 __attribute__ ((__nothrow__ )) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
8 __extension__
8 return dst;
7 for (size_t i = 0; i < n; ++i) {
6 bool ok = false;
6 done:
6 __attribute__ ((__nothrow__ )) __attribute__ ((__nonnull__ (1)));
6 } else {
6 if (0x80 <= byte && byte <= 0xbf) {
6 # 1 "/usr/include/aarch64-linux-gnu/bits/libc-header-start.h" 1 3 4
5 struct sl_string content = sl_string_from_file(path);
5 ok = true;
5 sl_string_delete(&content);
5 "\n"
5 # 1 "/usr/include/aarch64-linux-gnu/bits/wordsize.h" 1 3 4
5 return ok;
5 return 0;
5 const size_t args_count = sl_args_count_positional(args) - 1;
./build/debug/tools/png dump_raw ./docs/img/tokyo.png tEXt \
| ./build/debug/tools/txt replace date: $'\n'date= /dev/stdin \
| ./build/debug/tools/txt replace exif: $'\n'exif= /dev/stdin \
| ./build/debug/tools/txt replace 0x00 ': ' /dev/stdin \
&& echo
stdout
:
date=create: 2023-01-23T21:22:19+00:00
date=modify: 2023-01-23T21:22:19+00:00
exif=ColorSpace: 1
exif=ComponentsConfiguration: 1, 2, 3, 0
exif=ExifOffset: 90
exif=ExifVersion: 48, 50, 50, 49
exif=FlashPixVersion: 48, 49, 48, 48
exif=PixelXDimension: 2100
exif=PixelYDimension: 2100
exif=SceneCaptureType: 0
exif=YCbCrPositioning: 1: :