From 6032c98faeb35ac16a15a5a65b5bd13185c36aca Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Sat, 29 Oct 2022 13:04:45 +0200 Subject: [PATCH] add quantization table laoding --- src/CMakeLists.txt | 2 +- src/loader.c | 77 +++++++++++++++++++++++++++++++++++++++++----- src/loader.h | 11 +++++++ src/main.c | 5 ++- 4 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc2b8bb..a76e217 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,6 @@ add_executable (jpeg-dissect "main.c" "loader.c" -) + ) set_property(TARGET jpeg-dissect PROPERTY C_STANDARD 11) diff --git a/src/loader.c b/src/loader.c index 740786c..1dacd5a 100644 --- a/src/loader.c +++ b/src/loader.c @@ -4,10 +4,13 @@ #include #include +#define MAX_QUANTIZATION_TABLES 255 + #define memzero(buffer, size) memset(buffer, 0, size) static int load_segment(JPEG* jpeg, FILE* fp); +static int load_quantization_table(JPEG* jpeg, FILE* fp); static int load_rst_segment(JPEG* jpeg, FILE* fp, uint8_t n); static int load_app_segment(JPEG* jpeg, FILE* fp, uint8_t n); @@ -15,7 +18,7 @@ static int load_app0_segment(JPEG* jpeg, FILE* fp); JPEG* load_jpeg(const char* filename) { - FILE* fp = fopen(filename, "r"); + FILE* fp = fopen(filename, "r+b"); if (fp == NULL) { return NULL; @@ -49,9 +52,23 @@ void free_jpeg(JPEG* jpeg) if (jpeg->app0->thumbnail_data) { free(jpeg->app0->thumbnail_data); + jpeg->app0->thumbnail_data = NULL; } free(jpeg->app0); + jpeg->app0 = NULL; + } + + if (jpeg->quantization_tables) + { + for (size_t i = 0; i < jpeg->num_quantization_tables; i++) + { + free(jpeg->quantization_tables[i].data); + jpeg->quantization_tables[i].data = NULL; + } + + free(jpeg->quantization_tables); + jpeg->quantization_tables = NULL; } } @@ -95,6 +112,9 @@ int load_segment(JPEG* jpeg, FILE* fp) DEBUG_LOG("SOI marker encountered"); break; + case 0xDB: // Quantization table + return load_quantization_table(jpeg, fp); + default: fprintf(stderr, "Unimplemented marker 0xFF 0x%02X\n", segment_marker[1]); return 1; @@ -104,6 +124,49 @@ int load_segment(JPEG* jpeg, FILE* fp) return 0; } +int load_quantization_table(JPEG* jpeg, FILE* fp) +{ + DEBUG_LOG("DQT encountered"); + + if (jpeg->quantization_tables == NULL) + { + jpeg->quantization_tables = (QuantizationTable*)malloc(sizeof(QuantizationTable) * MAX_QUANTIZATION_TABLES); + if (jpeg->quantization_tables == NULL) + { + fprintf(stderr, "Failed to allocate memory for quantization tables\n"); + return 1; + } + } + + QuantizationTable* current_table = jpeg->quantization_tables + jpeg->num_quantization_tables; + if (fread(¤t_table->length, sizeof(uint8_t), sizeof(uint16_t), fp) != sizeof(uint16_t)) + { + fprintf(stderr, "Failed to read quantization table length\n"); + return 1; + } + + jpeg->num_quantization_tables++; + current_table->length = bswap_16(current_table->length) - 2; + DEBUG_LOG("qt length = %u", current_table->length); + + current_table->data = (uint8_t*)malloc(sizeof(uint8_t) * current_table->length); + if (current_table->data == NULL) + { + fprintf(stderr, "Failed to allocate memory for quantization table data\n"); + return 1; + } + + size_t tmp = fread(current_table->data, sizeof(uint8_t), current_table->length, fp); + if (tmp != current_table->length) + { + fprintf(stderr, "Failed to read quantization table data\n"); + return 1; + } + + + return 0; +} + int load_rst_segment(JPEG* jpeg, FILE* fp, uint8_t n) { DEBUG_LOG("RST%d marker encountered", n); @@ -176,12 +239,12 @@ int load_app0_segment(JPEG* jpeg, FILE* fp) DEBUG_LOG( "JFIFAPP0Segment\n" - "length = %u\n" - "identifier = %s\n" - "version = %u.%02u\n" - "density units = %u\n" - "density x, y = %u, %u\n" - "thumbnail x, y = %u, %u", + "\tlength = %u\n" + "\tidentifier = %s\n" + "\tversion = %u.%02u\n" + "\tdensity units = %u\n" + "\tdensity x, y = %u, %u\n" + "\tthumbnail x, y = %u, %u", jpeg->app0->length, jpeg->app0->identifier, jpeg->app0->version.major, jpeg->app0->version.minor, diff --git a/src/loader.h b/src/loader.h index 739a1ef..92cf13d 100644 --- a/src/loader.h +++ b/src/loader.h @@ -4,6 +4,14 @@ #include #include "util.h" +PACK( +typedef struct QuantizationTable +{ + uint16_t length; + uint8_t* data; +} QuantizationTable; +) + PACK ( typedef struct JFIFAPP0Segment { @@ -29,6 +37,9 @@ typedef struct JFIFAPP0Segment typedef struct JPEG { JFIFAPP0Segment* app0; + + size_t num_quantization_tables; + QuantizationTable* quantization_tables; } JPEG; JPEG* load_jpeg(const char* filename); diff --git a/src/main.c b/src/main.c index c41dfb2..7527697 100644 --- a/src/main.c +++ b/src/main.c @@ -17,11 +17,14 @@ int main(int argc, char** argv) const char* filename = argv[1]; printf("Supplied file: %s\n", filename); - if (load_jpeg(filename) != 0) + JPEG* jpeg = load_jpeg(filename); + if (jpeg == NULL) { fprintf(stderr, "Failed to load jpeg\n"); return 1; } + free_jpeg(jpeg); + return 0; }