Initial commit / Day0

This commit is contained in:
Casey 2022-10-06 19:52:59 +03:00
commit a9ffeca886
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
3 changed files with 305 additions and 0 deletions

104
hexdump.h Normal file
View File

@ -0,0 +1,104 @@
#ifndef _HEXDUMP_H_
#define _HEXDUMP_H_
#include <stdlib.h>
#include <stdint.h>
void hexdump(void *data, size_t len);
void rgbdump(void *data, uint16_t w, uint16_t h);
void rgbadump(void *data, uint16_t w, uint16_t h);
#endif
#ifdef HEXDUMP_IMPLEMENTATION
#if !defined(HEXDUMP_COLORS0) && !defined(HEXDUMP_COLORS1)
#define HEXDUMP_N_COLORS 8
const uint8_t hexdump_colors[2][8] = {
{ 197, 215, 227, 47, 39, 57, 135, 92 },
{ 124, 214, 226, 46, 31, 55, 127, 53 },
};
#else
#define HEXDUMP_RAINBOW
#ifndef HEXDUMP_N_COLORS
#define HEXDUMP_N_COLORS 8
#endif
const uint8_t hexdump_colors[2][HEXDUMP_N_COLORS] = {
HEXDUMP_COLORS0,
HEXDUMP_COLORS1,
};
#endif
#include <stdio.h>
void hexdump(void *data, size_t len)
{
uint8_t *ptr = data;
for (size_t i = 0; i < len;)
{
#ifdef HEXDUMP_RAINBOW
printf("\033[%dm%08zx\033[0m\t", ((i >> 4) & 1 ? 90 : 37), i);
#else
printf("%08zx\t", i);
#endif
for (int x = 0; x < 16; x++)
{
#ifdef HEXDUMP_RAINBOW
printf("\033[38;5;%dm",
hexdump_colors[(i >> 4) & 1][(x + i) % HEXDUMP_N_COLORS]);
#endif
if (i + x >= len) printf("-- ");
else printf("%02x ", ptr[i + x]);
#ifdef HEXDUMP_RAINBOW
printf("\033[0m");
#endif
if (x % 4 == 3) printf("\t");
}
#ifdef HEXDUMP_PRINTABLE
for (int x = 0; x < 16; x++)
{
if (i + x >= len) break;
#ifdef HEXDUMP_RAINBOW
printf("\033[38;5;%dm",
hexdump_colors[(i >> 4) & 1][(x + i) % HEXDUMP_N_COLORS]);
#endif
if (isprint(ptr[i + x]))
putchar(ptr[i + x]);
else
putchar('.');
#ifdef HEXDUMP_RAINBOW
printf("\033[0m");
#endif
}
#endif
printf("\n");
i += 16;
}
}
void rgbdump(void *data, uint16_t w, uint16_t h)
{
uint8_t *ptr = data;
for (int y = 0; y < h; y += 2)
{
for (int x = 0; x < w; x++)
{
int i1 = x + y * w, i2 = x + (y + 1) * w;
printf("\033[38;2;%d;%d;%d;48;2;%d;%d;%dm\xe2\x96\x80",
ptr[i1 * 3 + 0], ptr[i1 * 3 + 1], ptr[i1 * 3 + 2],
ptr[i2 * 3 + 0], ptr[i2 * 3 + 1], ptr[i2 * 3 + 2]);
}
printf("\033[0m\n");
}
}
void rgbadump(void *data, uint16_t w, uint16_t h)
{
uint8_t *ptr = data;
for (int y = 0; y < h; y += 2)
{
for (int x = 0; x < w; x++)
{
int i1 = x + y * w, i2 = x + (y + 1) * w;
printf("\033[38;2;%d;%d;%d;48;2;%d;%d;%dm\xe2\x96\x80",
ptr[i1 * 4 + 0], ptr[i1 * 4 + 1], ptr[i1 * 4 + 2],
ptr[i2 * 4 + 0], ptr[i2 * 4 + 1], ptr[i2 * 4 + 2]);
}
printf("\033[0m\n");
}
}
#endif

6
jfif.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef _JFIF_H_
#define _JFIF_H_
#endif

195
main.c Normal file
View File

@ -0,0 +1,195 @@
// x-run: gcc % -o main -g && ./main /home/hkc/images/wallpapers/photo_2020-09-18_10-05-14.jpg
#include <endian.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#define HEXDUMP_RAINBOW
#define HEXDUMP_PRINTABLE
#define HEXDUMP_IMPLEMENTATION
#include "./hexdump.h"
typedef uint16_t marker_t;
typedef enum {
SOF0 = 0xFFC0, // Baseline DCT
SOF1 = 0xFFC1, // Extended seq DCT
SOF2 = 0xFFC2, // Progressive DCT
SOF3 = 0xFFC3, // Lossless
DHT = 0xFFC4, // Define Huffman Table
SOF5 = 0xFFC5, //
SOF6 = 0xFFC6,
SOF7 = 0xFFC7,
JPG = 0xFFC8,
SOF9 = 0xFFC9,
SOF10 = 0xFFCA,
SOF11 = 0xFFCB,
DAC = 0xFFCC,
SOF13 = 0xFFCD,
SOF14 = 0xFFCE,
SOF15 = 0xFFCF,
} marker_type_t;
struct JFIF_SOF0_Component {
uint8_t id;
uint8_t TODO_0 : 4;
uint8_t TODO_1 : 4;
} __attribute__((packed));
struct JFIF_SOF0 {
uint16_t bit_depth;
uint16_t height;
uint8_t width;
uint8_t n_components;
struct JFIF_SOF0_Component *components;
} __attribute__((packed));
#define panic(...) { \
fprintf(stderr, "!PANIC! at %s:%d\n", __FILE__, __LINE__);\
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\nerrno=%d (%s)\n", errno, strerror(errno)); \
abort(); \
}
marker_t read_and_print_block(FILE *fp);
const char *marker_name(int marker);
int main(int argc, char **argv) {
static uint8_t tmp[8192];
FILE *fp = fopen(argv[1], "rb");
fread(tmp, 1, 2, fp);
if (memcmp(tmp, "\xFF\xD8", 2)) {
panic("Invalid header!");
}
marker_t last_marker;
do {
last_marker = read_and_print_block(fp);
} while (last_marker != 0xFFD9);
}
marker_t read_and_print_block(FILE *fp) {
static uint8_t buffer[65536];
marker_t marker;
uint16_t length;
long int pos = ftell(fp);
fread(&marker, sizeof(marker_t), 1, fp);
marker = be16toh(marker);
if ((marker & 0xFF00) != 0xFF00) {
printf("!!!!!!!!\n");
fseek(fp, pos & ~0xF, SEEK_SET);
fread(buffer, 1, 32, fp);
hexdump(buffer, 32);
panic("Invalid marker %04x at %ld (0x%lx)", marker, pos, pos);
}
if (marker == 0xFFD9) return marker;
fread(&length, sizeof(uint16_t), 1, fp);
length = be16toh(length) - 2;
printf("marker: %04x %8s (%d long) at %ld %lx\n", marker, marker_name(marker), length, pos, pos);
fread(buffer, 1, length, fp);
switch (marker) {
case SOF0:
printf("\033[91mSTART OF FRAME\033[0m\n");
hexdump(buffer, length);
break;
case 0xFFDA: // Start Of Scan
{
uint8_t n_components = buffer[0];
uint8_t *cur = &buffer[1];
printf("components: %d\n", n_components);
for (uint8_t i = 0; i < n_components; i++) {
uint8_t selector = *cur++,
tables = *cur++;
printf("\t%d: %d in %d/%d\n", i, selector, tables >> 4, tables & 0xf);
}
uint8_t spectral_selector_start = *cur++,
spectral_selector_end = *cur++,
successive_approx = *cur++;
printf("spectral selector: %d..%d\n", spectral_selector_start, spectral_selector_end);
int n_read = -1;
do {
n_read++;
fread(&buffer[n_read], 1, 1, fp);
} while (!(buffer[n_read - 1] == 0xFF && (buffer[n_read] & 0xF0) == 0xF0));
printf("stopped after %d bytes\n", n_read);
hexdump(buffer, n_read);
fseek(fp, ftell(fp) - 1, SEEK_SET);
}
break;
case 0xFFDB: // Quantization table
{
uint8_t destination = buffer[0];
printf("\tdestination: %d\n", destination);
for (int y = 0; y < 8; y++) {
printf("\t");
for (int x = 0; x < 8; x++) {
printf("%3d ", buffer[1 + x + y * 8]);
}
printf("\n");
}
}
break;
case 0xFFE0: // APP*
case 0xFFE1:
case 0xFFE2:
case 0xFFE3:
case 0xFFE4:
case 0xFFE5:
case 0xFFE6:
case 0xFFE7:
case 0xFFE8:
case 0xFFE9:
case 0xFFEA:
case 0xFFEB:
case 0xFFEC:
case 0xFFED:
case 0xFFEE:
case 0xFFEF:
break;
default:
hexdump(buffer, length);
break;
}
return marker;
}
const char *marker_name(int marker) {
switch (marker) {
case SOF0: return " SOF0";
case SOF1: return " SOF1";
case SOF2: return " SOF2";
case SOF3: return " SOF3";
case DHT: return " DHT";
case SOF5: return " SOF5";
case SOF6: return " SOF6";
case SOF7: return " SOF7";
case JPG: return " JPG";
case SOF9: return " SOF9";
case SOF10: return "SOF10";
case SOF11: return "SOF11";
case DAC: return " DAC";
case SOF13: return "SOF13";
case SOF14: return "SOF14";
case SOF15: return "SOF15";
default: return "N/A";
}
}