Skip to content

Instantly share code, notes, and snippets.

@untodesu
Created November 21, 2022 17:22
Show Gist options
  • Save untodesu/ff11b95e844a3269f3443d4b318defd9 to your computer and use it in GitHub Desktop.
Save untodesu/ff11b95e844a3269f3443d4b318defd9 to your computer and use it in GitHub Desktop.
I sold this for 1500 RUB :)
/* note: most of unix editors such as
* vi/vim put a CR (newline character)
* at the very end of files, so the resulting
* amount of characters is increased by one. */
#include <stdio.h>
#include <stddef.h> /* size_t */
/* gets a specific bit of an integer */
#define bitval(c, bit) ((int)(((c) & (1 << (bit))) >> (bit)))
int main(int argc, char **argv)
{
int c;
size_t z, l;
FILE *infile;
char *s, path[256] = { 0 };
if(argc < 2) {
printf("usage: %s <filename>\n", argv[0]);
return 1;
}
/* open the source file */
infile = fopen(argv[1], "rb");
if(!infile) {
perror(path);
return 1;
}
z = 0;
l = 0;
while((c = fgetc(infile)) != EOF) {
/* 0XXXXXXX: a single-byte character */
if(bitval(c, 7) == 0) {
z++;
l = 1;
continue;
}
/* 110XXXXX: first byte of a double-byte character */
if(bitval(c, 7) == 1 && bitval(c, 6) == 1 && bitval(c, 5) == 0) {
l = 2;
continue;
}
/* 1110XXXX: first byte of a triple-byte character */
if(bitval(c, 7) == 1 && bitval(c, 6) == 1 && bitval(c, 5) == 1 && bitval(c, 4) == 0) {
l = 3;
continue;
}
/* 11110XXX: first byte of a quadruple-byte character */
if(bitval(c, 7) == 1 && bitval(c, 6) == 1 && bitval(c, 5) == 1 && bitval(c, 4) == 1 && bitval(c, 3) == 0) {
l = 4;
continue;
}
/* 10XXXXXX: second, third and fourth bytes */
if(bitval(c, 7) == 1 && bitval(c, 6) == 0) {
if(--l == 1) {
z++;
l = 0;
}
continue;
}
}
fclose(infile);
printf("%zu %s\n", z, argv[1]);
return 0;
}
#include <stdio.h>
#include <stddef.h>
/* writes a unicode character encoded in UTF8 */
static unsigned short fputc_utf8(unsigned long uc, FILE *file)
{
/* sequence: 0XXXXXXX */
if(uc <= 0x00007F) {
fputc(uc & 0x7F, file);
return 1;
}
/* sequence: 110XXXXX 10XXXXXX */
if(uc <= 0x0007FF) {
fputc((0xC0 | ((uc >> 0x06) & 0x1F)), file);
fputc((0x80 | ((uc >> 0x00) & 0x3F)), file);
return 2;
}
/* sequence: 1110XXXX 10XXXXXX 10XXXXXX */
if(uc <= 0x00FFFF) {
fputc((0xE0 | ((uc >> 0x0C) & 0x0F)), file);
fputc((0x80 | ((uc >> 0x06) & 0x3F)), file);
fputc((0x80 | ((uc >> 0x00) & 0x3F)), file);
return 3;
}
/* sequence: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX */
if(uc <= 0x10FFFF) {
fputc((0xF0 | ((uc >> 0x12) & 0x07)), file);
fputc((0x80 | ((uc >> 0x0C) & 0x3F)), file);
fputc((0x80 | ((uc >> 0x06) & 0x3F)), file);
fputc((0x80 | ((uc >> 0x00) & 0x3F)), file);
return 4;
}
/* too big for utf8? */
return 0;
}
static unsigned short swap_ushort(unsigned short uv)
{
return (((uv & 0x00FF) << 8) | ((uv & 0xFF00) >> 8));
}
static int fgetc_ushort(FILE *file, unsigned short *uv)
{
int x, y;
x = fgetc(file);
y = fgetc(file);
if(x == EOF || y == EOF) {
uv[0] = 0x0000;
return 0;
}
/* assume big endian */
uv[0] = ((x & 0xFF) << 8) | (y & 0xFF);
return 1;
}
static int utf16_le = 0;
static unsigned long utf16_uc = 0;
static void parse_ushort(FILE *file, unsigned short uv)
{
if(utf16_le)
uv = swap_ushort(uv);
if(uv >= 0xD800 && uv <= 0xD8FF) {
if(utf16_uc == 0) {
/* high surrogate */
utf16_uc |= ((uv & 0x3FF) << 10);
return;
}
else {
/* low surrogate */
utf16_uc |= ((uv & 0x3FF) << 0);
fputc_utf8(utf16_uc, file);
utf16_uc = 0;
return;
}
}
/* single-ushort character */
fputc_utf8(uv, file);
}
int main(int argc, char **argv)
{
int c;
FILE *infile;
FILE *outfile;
unsigned short uv;
if(argc < 3) {
printf("usage: %s <in filename> <out filename>\n", argv[0]);
return 1;
}
infile = fopen(argv[1], "rb");
if(!infile) {
perror(argv[1]);
return 1;
}
outfile = fopen(argv[2], "wb");
if(!outfile) {
perror(argv[2]);
return 1;
}
if(!fgetc_ushort(infile, &uv)) {
printf("%s: file too small\n", argv[1]);
fclose(outfile);
fclose(infile);
return 1;
}
switch(uv) {
case 0xFEFF:
printf("%s: byte order is big-endian\n", argv[1]);
utf16_le = 0;
break;
case 0xFFFE:
printf("%s: byte order is little-endian\n", argv[1]);
utf16_le = 1;
break;
default:
/* on windows it should (hopefully) be a valid prediction */
printf("%s: no byte order mark (BOM), assuming little-endian.\n", argv[1]);
utf16_le = 1;
parse_ushort(outfile, uv);
break;
}
while(fgetc_ushort(infile, &uv))
parse_ushort(outfile, uv);
fclose(outfile);
fclose(infile);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* size_t */
static void write_uint16LE(unsigned short v, FILE *file)
{
fputc((v & 0x00FF) >> 0, file);
fputc((v & 0xFF00) >> 8, file);
}
static void write_uint32LE(unsigned long v, FILE *file)
{
fputc((v & 0x000000FF) >> 0, file);
fputc((v & 0x0000FF00) >> 8, file);
fputc((v & 0x00FF0000) >> 16, file);
fputc((v & 0xFF000000) >> 24, file);
}
static void write_pixel(unsigned char pix, FILE *file)
{
fputc(pix, file);
fputc(pix, file);
fputc(pix, file);
}
static unsigned long round2_ulong(unsigned long lv)
{
unsigned long p = 1;
while(p < lv)
p <<= 1;
return p;
}
int main(int argc, char **argv)
{
int cond;
size_t size;
FILE *outfile;
unsigned long x, y;
unsigned long width, qwidth;
if(argc < 3) {
printf("usage: %s <out filename> <width> <quad width>\n", argv[0]);
return 1;
}
width = strtoul(argv[2], NULL, 10);
qwidth = strtoul(argv[3], NULL, 10);
/* ensure the bitmap doesn't get too bulky so
* we don't eat insane amounts of system's drive space.
* An image of 16384x16384 size is already about 760 MiB! */
if(width == 0 || width > 16384) {
printf("invalid width of %lu\n", width);
return 1;
}
/* we want at least four subquads per image */
if(qwidth == 0 || qwidth > (width / 2)) {
printf("invalid qwidth of %lu\n", qwidth);
return 1;
}
size = 54 + 3 * width * width;
/* Ensures that the checkerboard pattern
* doesn't have any inadequate quads. This
* isn't really a technical issue but rather
* a cosmetic, I hate things out of order. */
/* COMMENTING THIS OUT WILL NOT AFFECT THE CODE PERFORMANCE IN ANY WAY */
x = round2_ulong(width);
y = round2_ulong(qwidth);
printf("rounding width: %lu -> %lu\n", width, x);
printf("rounding qwidth: %lu -> %lu\n", qwidth, y);
width = x;
qwidth = y;
outfile = fopen(argv[1], "wb");
if(!outfile) {
perror(argv[1]);
return 1;
}
/* BMPv2 header:
* U16LE magic
* U32LE file_size (>= 54)
* U16LE zero
* U16LE zero
* U32LE bitmap_offset */
fputc('B', outfile);
fputc('M', outfile);
write_uint32LE(size, outfile);
write_uint16LE(0, outfile);
write_uint16LE(0, outfile);
write_uint32LE(54, outfile);
/* BMPv3 info header:
* U32LE header_size (40)
* U32LE width
* U32LE height
* U16LE planes
* U16LE bpp
* U32LE compression
* U32LE bitmap_size
* U32LE resolution_h
* U32LE resolution_v
* U32LE colors_used
* U32LE colors_important */
write_uint32LE(40, outfile);
write_uint32LE(width, outfile);
write_uint32LE(width, outfile);
write_uint16LE(1, outfile);
write_uint16LE(24, outfile);
write_uint32LE(0, outfile);
write_uint32LE(0, outfile);
write_uint32LE(2880, outfile);
write_uint32LE(2880, outfile);
write_uint32LE(0, outfile);
write_uint32LE(0, outfile);
printf("writing...");
for(y = 0; y < width; y++) {
cond = !((y / qwidth) % 2);
for(x = 0; x < width; x++) {
if(cond)
write_pixel(((x / qwidth) % 2) ? 0x00 : 0xFF, outfile);
else
write_pixel(((x / qwidth) % 2) ? 0xFF : 0x00, outfile);
}
}
printf("written %s, %lux%lu, %zu KiB\n", argv[1], width, width, size / 1024);
fclose(outfile);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment