commit 421c593a6106ba7942870874c9558dcb61622814 Author: Lauchmelder Date: Fri Oct 28 18:53:52 2022 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..932896b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vs/ + +[Oo]ut/ +[Bb]uild/ + +*.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..85cf80e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +# CMakeList.txt : Top-level CMake project file, do global configuration +# and include sub-projects here. +# +cmake_minimum_required (VERSION 3.8) + +project ("jpeg-dissect") + +# Include sub-projects. +add_subdirectory ("src") diff --git a/img/lenna.jpg b/img/lenna.jpg new file mode 100644 index 0000000..7a0e4b7 Binary files /dev/null and b/img/lenna.jpg differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..14554ea --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required (VERSION 3.8) + +add_executable (jpeg-dissect + "main.c" + "loader.c" + "util.h") diff --git a/src/loader.c b/src/loader.c new file mode 100644 index 0000000..6800911 --- /dev/null +++ b/src/loader.c @@ -0,0 +1,110 @@ +#include "loader.h" + +#include +#include + +#include "util.h" + +static int load_segment(FILE* fp); + +static int load_rst_segment(FILE* fp, uint8_t n); +static int load_app_segment(FILE* fp, uint8_t n); + +static int load_app0_segment(FILE* fp); + +int load_jpeg(const char* filename) +{ + FILE* fp = fopen(filename, "r"); + if (fp == NULL) + { + return 1; + } + + while (!feof(fp)) + { + if (load_segment(fp) != 0) + { + fprintf(stderr, "Segment loading failed\n"); + return 1; + } + } + + fclose(fp); + return 0; +} + +int load_segment(FILE* fp) +{ + uint8_t segment_marker[2]; + size_t segment_marker_size = sizeof(segment_marker); + + if (fread(segment_marker, sizeof(uint8_t), segment_marker_size, fp) != segment_marker_size) + { + fprintf(stderr, "Marker terminated unexpectedly\n"); + return 1; + } + + if (segment_marker[0] != 0xFF) + { + fprintf(stderr, "Ill-formatted marker\n"); + return 1; + } + + // Handle special APPn/RSTn markers + if (segment_marker[1] >= 0xD0 && segment_marker[1] <= 0xD7) + { + if (load_rst_segment(fp, segment_marker[1] | 0x0F) != 0) + { + return 1; + } + } + else if ((segment_marker[1] & 0xF0) == 0xE0) + { + if (load_app_segment(fp, segment_marker[1] & 0x0F) != 0) + { + return 1; + } + } + else + { + switch (segment_marker[1]) + { + case 0xD8: // Start of image + DEBUG_LOG("SOI marker encountered"); + break; + + default: + fprintf(stderr, "Unimplemented marker 0xFF 0x%02X\n", segment_marker[1]); + return 1; + } + } + + return 0; +} + +int load_rst_segment(FILE* fp, uint8_t n) +{ + DEBUG_LOG("RST%d marker encountered", n); + return 1; +} + +int load_app_segment(FILE* fp, uint8_t n) +{ + DEBUG_LOG("APP%d marker encountered", n); + + switch (n) + { + case 0: return load_app0_segment(); + + default: + fprintf(stderr, "Unknown APP segment ID %d\n", n); + return 1; + } + + return 0; +} + +int load_app0_segment(FILE* fp) +{ + +} \ No newline at end of file diff --git a/src/loader.h b/src/loader.h new file mode 100644 index 0000000..856938d --- /dev/null +++ b/src/loader.h @@ -0,0 +1,6 @@ +#ifndef _LODAER_H +#define _LOADER_H + +int load_jpeg(const char* filename); + +#endif // _LOADER_H \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c41dfb2 --- /dev/null +++ b/src/main.c @@ -0,0 +1,27 @@ +#include +#include "loader.h" + +static void print_usage(void) +{ + printf("Usage: ./jpeg-dissect \n"); +} + +int main(int argc, char** argv) +{ + if (argc != 2) + { + print_usage(); + return 1; + } + + const char* filename = argv[1]; + printf("Supplied file: %s\n", filename); + + if (load_jpeg(filename) != 0) + { + fprintf(stderr, "Failed to load jpeg\n"); + return 1; + } + + return 0; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..64db194 --- /dev/null +++ b/src/util.h @@ -0,0 +1,12 @@ +#ifndef _UTIL_H +#define _UTIL_H + +#include + +#ifdef NDEBUG +#define DEBUG_LOG +#else +#define DEBUG_LOG(msg, ...) printf("[DEBUG] " ##msg "\n", __VA_ARGS__); +#endif + +#endif // _UTIL_H \ No newline at end of file