add quantization table laoding

This commit is contained in:
Lauchmelder 2022-10-29 13:04:45 +02:00
parent af827f2c7f
commit 6032c98fae
4 changed files with 86 additions and 9 deletions

View file

@ -3,6 +3,6 @@
add_executable (jpeg-dissect add_executable (jpeg-dissect
"main.c" "main.c"
"loader.c" "loader.c"
) )
set_property(TARGET jpeg-dissect PROPERTY C_STANDARD 11) set_property(TARGET jpeg-dissect PROPERTY C_STANDARD 11)

View file

@ -4,10 +4,13 @@
#include <memory.h> #include <memory.h>
#include <assert.h> #include <assert.h>
#define MAX_QUANTIZATION_TABLES 255
#define memzero(buffer, size) memset(buffer, 0, size) #define memzero(buffer, size) memset(buffer, 0, size)
static int load_segment(JPEG* jpeg, FILE* fp); 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_rst_segment(JPEG* jpeg, FILE* fp, uint8_t n);
static int load_app_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) JPEG* load_jpeg(const char* filename)
{ {
FILE* fp = fopen(filename, "r"); FILE* fp = fopen(filename, "r+b");
if (fp == NULL) if (fp == NULL)
{ {
return NULL; return NULL;
@ -49,9 +52,23 @@ void free_jpeg(JPEG* jpeg)
if (jpeg->app0->thumbnail_data) if (jpeg->app0->thumbnail_data)
{ {
free(jpeg->app0->thumbnail_data); free(jpeg->app0->thumbnail_data);
jpeg->app0->thumbnail_data = NULL;
} }
free(jpeg->app0); 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"); DEBUG_LOG("SOI marker encountered");
break; break;
case 0xDB: // Quantization table
return load_quantization_table(jpeg, fp);
default: default:
fprintf(stderr, "Unimplemented marker 0xFF 0x%02X\n", segment_marker[1]); fprintf(stderr, "Unimplemented marker 0xFF 0x%02X\n", segment_marker[1]);
return 1; return 1;
@ -104,6 +124,49 @@ int load_segment(JPEG* jpeg, FILE* fp)
return 0; 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(&current_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) int load_rst_segment(JPEG* jpeg, FILE* fp, uint8_t n)
{ {
DEBUG_LOG("RST%d marker encountered", n); DEBUG_LOG("RST%d marker encountered", n);
@ -176,12 +239,12 @@ int load_app0_segment(JPEG* jpeg, FILE* fp)
DEBUG_LOG( DEBUG_LOG(
"JFIFAPP0Segment\n" "JFIFAPP0Segment\n"
"length = %u\n" "\tlength = %u\n"
"identifier = %s\n" "\tidentifier = %s\n"
"version = %u.%02u\n" "\tversion = %u.%02u\n"
"density units = %u\n" "\tdensity units = %u\n"
"density x, y = %u, %u\n" "\tdensity x, y = %u, %u\n"
"thumbnail x, y = %u, %u", "\tthumbnail x, y = %u, %u",
jpeg->app0->length, jpeg->app0->length,
jpeg->app0->identifier, jpeg->app0->identifier,
jpeg->app0->version.major, jpeg->app0->version.minor, jpeg->app0->version.major, jpeg->app0->version.minor,

View file

@ -4,6 +4,14 @@
#include <stdint.h> #include <stdint.h>
#include "util.h" #include "util.h"
PACK(
typedef struct QuantizationTable
{
uint16_t length;
uint8_t* data;
} QuantizationTable;
)
PACK ( PACK (
typedef struct JFIFAPP0Segment typedef struct JFIFAPP0Segment
{ {
@ -29,6 +37,9 @@ typedef struct JFIFAPP0Segment
typedef struct JPEG typedef struct JPEG
{ {
JFIFAPP0Segment* app0; JFIFAPP0Segment* app0;
size_t num_quantization_tables;
QuantizationTable* quantization_tables;
} JPEG; } JPEG;
JPEG* load_jpeg(const char* filename); JPEG* load_jpeg(const char* filename);

View file

@ -17,11 +17,14 @@ int main(int argc, char** argv)
const char* filename = argv[1]; const char* filename = argv[1];
printf("Supplied file: %s\n", filename); 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"); fprintf(stderr, "Failed to load jpeg\n");
return 1; return 1;
} }
free_jpeg(jpeg);
return 0; return 0;
} }