add quantization table laoding
This commit is contained in:
parent
af827f2c7f
commit
6032c98fae
|
@ -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)
|
||||||
|
|
77
src/loader.c
77
src/loader.c
|
@ -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(¤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)
|
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,
|
||||||
|
|
11
src/loader.h
11
src/loader.h
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue