Add comments and error checking to A9
This commit is contained in:
parent
bea609e01c
commit
530ab9a135
@ -7,16 +7,17 @@
|
|||||||
#include "png.h"
|
#include "png.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
// Error handling
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
printf("Usage: %s <png file>\n", argv[0]);
|
printf("Usage: %s <png file>\n", argv[0]);
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (strlen(argv[1]) > PATH_MAX) {
|
if (strlen(argv[1]) > PATH_MAX) {
|
||||||
printf("Path too long\n");
|
printf("Path too long\n");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
// Read file
|
||||||
char *path = argv[1];
|
char *path = argv[1];
|
||||||
|
|
||||||
char *png_buffer = load_file(get_fd(path));
|
char *png_buffer = load_file(get_fd(path));
|
||||||
if (!is_png(png_buffer)) {
|
if (!is_png(png_buffer)) {
|
||||||
printf("It's not a PNG file\n");
|
printf("It's not a PNG file\n");
|
||||||
@ -26,6 +27,8 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
png_chunk **chunks = get_png_chunks(png_buffer);
|
png_chunk **chunks = get_png_chunks(png_buffer);
|
||||||
free(png_buffer);
|
free(png_buffer);
|
||||||
|
// Done with buffer, as chunks are a structured way to access the data
|
||||||
|
// Iterate over chunks to display info and "decrypt" IDAT chunks
|
||||||
int size = get_number_of_chunks(chunks);
|
int size = get_number_of_chunks(chunks);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
// Check if header is IDAT or IEND
|
// Check if header is IDAT or IEND
|
||||||
@ -41,11 +44,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
printf("Chunk size is:%d\n", chunks[i]->length);
|
printf("Chunk size is:%d\n", chunks[i]->length);
|
||||||
}
|
}
|
||||||
// Uncomment to not overwrite original file
|
// Write file and free memory
|
||||||
//char new_path[PATH_MAX];
|
|
||||||
//getcwd(new_path, sizeof(new_path));
|
|
||||||
//strcat(new_path, "/output.png");
|
|
||||||
//write_png_chunks(new_path, chunks);
|
|
||||||
write_png_chunks(path, chunks);
|
write_png_chunks(path, chunks);
|
||||||
destroy_chunks(chunks);
|
destroy_chunks(chunks);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -39,12 +39,12 @@ int get_fd(char *path) {
|
|||||||
FILE *fp = fopen(path, "rb");
|
FILE *fp = fopen(path, "rb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
int fd = fileno(fp);
|
int fd = fileno(fp);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("fileno");
|
perror("fileno");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ FILE *get_fp(int fd) {
|
|||||||
FILE *fp = fdopen(fd, "rb");
|
FILE *fp = fdopen(fd, "rb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
perror("fdopen");
|
perror("fdopen");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ char *load_file(int fd) {
|
|||||||
char *buffer = malloc(size);
|
char *buffer = malloc(size);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
fread(buffer, 1, size, fp);
|
fread(buffer, 1, size, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -81,15 +81,16 @@ png_chunk *get_png_chunk(char *buffer, unsigned int offset) {
|
|||||||
png_chunk *chunk = malloc(sizeof(png_chunk));
|
png_chunk *chunk = malloc(sizeof(png_chunk));
|
||||||
if (chunk == NULL) {
|
if (chunk == NULL) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
memcpy(&chunk->length, buffer + offset + 0, 4);
|
memcpy(&chunk->length, buffer + offset + 0, 4);
|
||||||
|
// Convert length to host byte order because PNG lengths is in network byte order/Big Endian
|
||||||
chunk->length = ntohl(chunk->length);
|
chunk->length = ntohl(chunk->length);
|
||||||
memcpy(&chunk->type, buffer + offset + 4, 4);
|
memcpy(&chunk->type, buffer + offset + 4, 4);
|
||||||
chunk->data = malloc(chunk->length);
|
chunk->data = malloc(chunk->length);
|
||||||
if (chunk->data == NULL) {
|
if (chunk->data == NULL) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
memcpy(chunk->data, buffer + offset + 8, chunk->length);
|
memcpy(chunk->data, buffer + offset + 8, chunk->length);
|
||||||
memcpy(&chunk->crc, buffer + offset + 8 + chunk->length, 4);
|
memcpy(&chunk->crc, buffer + offset + 8 + chunk->length, 4);
|
||||||
@ -100,9 +101,11 @@ png_chunk **get_png_chunks(char *buffer) {
|
|||||||
png_chunk **chunks = malloc(sizeof(png_chunk *));
|
png_chunk **chunks = malloc(sizeof(png_chunk *));
|
||||||
if (chunks == NULL) {
|
if (chunks == NULL) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
// Running offset of the buffer
|
||||||
unsigned int offset = PNG_SIGNATURE_SIZE;
|
unsigned int offset = PNG_SIGNATURE_SIZE;
|
||||||
|
// Index of the current chunk
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
chunks[i] = get_png_chunk(buffer, offset);
|
chunks[i] = get_png_chunk(buffer, offset);
|
||||||
@ -112,11 +115,14 @@ png_chunk **get_png_chunks(char *buffer) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
chunks = realloc(chunks, sizeof(png_chunk *) * (i + 1));
|
// Add one because realloc is 1-indexed when multiplying by sizeof
|
||||||
if (chunks == NULL) {
|
png_chunk **err_check = realloc(chunks, sizeof(png_chunk *) * (i + 1));
|
||||||
|
if (err_check == NULL) {
|
||||||
|
destroy_chunks(chunks);
|
||||||
perror("realloc");
|
perror("realloc");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
chunks = err_check;
|
||||||
}
|
}
|
||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
@ -126,6 +132,7 @@ int get_number_of_chunks(png_chunk **chunks) {
|
|||||||
while (memcmp(chunks[i]->type, "IEND", 4) != 0) {
|
while (memcmp(chunks[i]->type, "IEND", 4) != 0) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
// Add one for the IEND chunk
|
||||||
return ++i;
|
return ++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,14 +155,16 @@ void write_png_chunks(char *path, png_chunk **chunks) {
|
|||||||
FILE *fp = fopen(path, "wb");
|
FILE *fp = fopen(path, "wb");
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
perror("fopen");
|
perror("fopen");
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
fwrite(PNG_SIGNATURE, PNG_SIGNATURE_SIZE, 1, fp);
|
fwrite(PNG_SIGNATURE, PNG_SIGNATURE_SIZE, 1, fp);
|
||||||
unsigned int size = get_number_of_chunks(chunks);
|
unsigned int size = get_number_of_chunks(chunks);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
// Convert length to network byte order for writing
|
||||||
chunks[i]->length = htonl(chunks[i]->length);
|
chunks[i]->length = htonl(chunks[i]->length);
|
||||||
fwrite(&chunks[i]->length, 4, 1, fp);
|
fwrite(&chunks[i]->length, 4, 1, fp);
|
||||||
fwrite(chunks[i]->type, 4, 1, fp);
|
fwrite(chunks[i]->type, 4, 1, fp);
|
||||||
|
// Convert back so we can accurately use it to write the length of the data
|
||||||
chunks[i]->length = ntohl(chunks[i]->length);
|
chunks[i]->length = ntohl(chunks[i]->length);
|
||||||
fwrite(chunks[i]->data, chunks[i]->length, 1, fp);
|
fwrite(chunks[i]->data, chunks[i]->length, 1, fp);
|
||||||
fwrite(&chunks[i]->crc, 4, 1, fp);
|
fwrite(&chunks[i]->crc, 4, 1, fp);
|
||||||
|
@ -30,15 +30,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Needed for uint types
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
// http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
||||||
#define PNG_SIGNATURE "\211PNG\r\n\032\n"
|
#define PNG_SIGNATURE "\211PNG\r\n\032\n"
|
||||||
#define PNG_SIGNATURE_SIZE 8
|
#define PNG_SIGNATURE_SIZE 8
|
||||||
|
|
||||||
|
// The key used to "encrypt/decrypt" the PNG chunks
|
||||||
#define KEY 42
|
#define KEY 42
|
||||||
|
|
||||||
typedef struct png_chunk {
|
typedef struct png_chunk {
|
||||||
|
Loading…
Reference in New Issue
Block a user