From 112535e8e784eea4310fa91b928b2d7ed0528757 Mon Sep 17 00:00:00 2001 From: Isaac Shoebottom Date: Tue, 5 Dec 2023 13:04:47 -0400 Subject: [PATCH] Use LF in a9 --- Assignment9/src/main.c | 102 ++++++------- Assignment9/src/png.c | 318 ++++++++++++++++++++--------------------- Assignment9/src/png.h | 150 +++++++++---------- 3 files changed, 285 insertions(+), 285 deletions(-) diff --git a/Assignment9/src/main.c b/Assignment9/src/main.c index 7c8d21a..0d977be 100644 --- a/Assignment9/src/main.c +++ b/Assignment9/src/main.c @@ -1,51 +1,51 @@ -#include -#include -#include -#include -#include -#include -#include "png.h" - -int main(int argc, char *argv[]) { - // Error handling - if (argc != 2) { - printf("Usage: %s \n", argv[0]); - exit(EXIT_FAILURE); - } - if (strlen(argv[1]) > PATH_MAX) { - printf("Path too long\n"); - exit(EXIT_FAILURE); - } - // Read file - char *path = argv[1]; - char *png_buffer = load_file(path); - if (!is_png(png_buffer)) { - printf("It's not a PNG file\n"); - exit(EXIT_FAILURE); - } else { - printf("It's a PNG file\n"); - } - png_chunk **chunks = get_png_chunks(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); - for (int i = 0; i < size; i++) { - // Check if header is IDAT or IEND - bool is_idat = memcmp(chunks[i]->type, "IDAT", 4) == 0; - bool is_iend = memcmp(chunks[i]->type, "IEND", 4) == 0; - if (is_idat || is_iend) { - printf("Found %.4s\n", chunks[i]->type); - if (is_idat) { - xor_data(chunks[i]); - } - } else { - printf("Found unknown: %.4s\n", chunks[i]->type); - } - printf("Chunk size is:%d\n", chunks[i]->length); - } - // Write file and free memory - write_png_chunks(path, chunks); - destroy_chunks(chunks); - return EXIT_SUCCESS; -} \ No newline at end of file +#include +#include +#include +#include +#include +#include +#include "png.h" + +int main(int argc, char *argv[]) { + // Error handling + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + exit(EXIT_FAILURE); + } + if (strlen(argv[1]) > PATH_MAX) { + printf("Path too long\n"); + exit(EXIT_FAILURE); + } + // Read file + char *path = argv[1]; + char *png_buffer = load_file(path); + if (!is_png(png_buffer)) { + printf("It's not a PNG file\n"); + exit(EXIT_FAILURE); + } else { + printf("It's a PNG file\n"); + } + png_chunk **chunks = get_png_chunks(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); + for (int i = 0; i < size; i++) { + // Check if header is IDAT or IEND + bool is_idat = memcmp(chunks[i]->type, "IDAT", 4) == 0; + bool is_iend = memcmp(chunks[i]->type, "IEND", 4) == 0; + if (is_idat || is_iend) { + printf("Found %.4s\n", chunks[i]->type); + if (is_idat) { + xor_data(chunks[i]); + } + } else { + printf("Found unknown: %.4s\n", chunks[i]->type); + } + printf("Chunk size is:%d\n", chunks[i]->length); + } + // Write file and free memory + write_png_chunks(path, chunks); + destroy_chunks(chunks); + return EXIT_SUCCESS; +} diff --git a/Assignment9/src/png.c b/Assignment9/src/png.c index 187a422..66430f6 100644 --- a/Assignment9/src/png.c +++ b/Assignment9/src/png.c @@ -1,159 +1,159 @@ -/* - * Copyright Notice - * ---------------- - * Copyright © 1998, 1999 by: Glenn Randers-Pehrson - * This specification is a modification of the PNG 1.0 specification. It is being - * provided by the copyright holder under the provisions of the 1996 MIT copyright and license: - * Copyright © 1996 by: Massachusetts Institute of Technology (MIT) - * This W3C specification is being provided by the copyright holders under - * the following license. By obtaining, using and/or copying this specification, you - * agree that you have read, understood, and will comply with the following terms - * and conditions: - * Permission to use, copy, and distribute this specification for any purpose - * and without fee or royalty is hereby granted, provided that the full text of - * this NOTICE appears on ALL copies of the specification or portions thereof, - * including modifications, that you make. - * THIS SPECIFICATION IS PROVIDED ”AS IS,” AND COPYRIGHT HOLD-ERS - * MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR - * IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, COPYRIGHT - * HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY - * OR FITNESS FOR ANY PARTICULAR PURPOSE OR - * THAT THE USE OF THE SPECIFICATION WILL NOT INFRINGE ANY - * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER - * RIGHTS. COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY - * USE OF THIS SPECIFICATION. - * The name and trademarks of copyright holders may NOT be used in - * advertising or publicity pertaining to the specification without specific, written - * prior permission. Title to copyright in this specification and any associated - * documentation will at all times remain with copyright holders. - */ - -#include -#include -#include -#include -#include -#include "png.h" - -FILE *get_file(char *path) { - FILE *fp = fopen(path, "rb"); - if (fp == NULL) { - perror("fopen"); - exit(EXIT_FAILURE); - } - return fp; -} - -char *load_file(char *path) { - FILE *fp = get_file(path); - fseek(fp, 0, SEEK_END); - long size = ftell(fp); - rewind(fp); - char *buffer = malloc(size); - if (buffer == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - fread(buffer, 1, size, fp); - fclose(fp); - return buffer; -} - -int is_png(char *buffer) { - return memcmp(buffer, PNG_SIGNATURE, PNG_SIGNATURE_SIZE) == 0; -} - -png_chunk *get_png_chunk(char *buffer, unsigned int offset) { - png_chunk *chunk = malloc(sizeof(png_chunk)); - if (chunk == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - 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); - memcpy(&chunk->type, buffer + offset + 4, 4); - chunk->data = malloc(chunk->length); - if (chunk->data == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - memcpy(chunk->data, buffer + offset + 8, chunk->length); - memcpy(&chunk->crc, buffer + offset + 8 + chunk->length, 4); - return chunk; -} - -png_chunk **get_png_chunks(char *buffer) { - png_chunk **chunks = malloc(sizeof(png_chunk *)); - if (chunks == NULL) { - perror("malloc"); - exit(EXIT_FAILURE); - } - // Running offset of the buffer - unsigned int offset = PNG_SIGNATURE_SIZE; - // Index of the current chunk - int i = 0; - while (true) { - chunks[i] = get_png_chunk(buffer, offset); - // 12 = 4 (length) + 4 (type) + 4 (crc) - offset += 12 + chunks[i]->length; - if (memcmp(chunks[i]->type, "IEND", 4) == 0) { - break; - } - i++; - // Add one because realloc is 1-indexed when multiplying by sizeof - png_chunk **err_check = realloc(chunks, sizeof(png_chunk *) * (i + 1)); - if (err_check == NULL) { - destroy_chunks(chunks); - perror("realloc"); - exit(EXIT_FAILURE); - } - chunks = err_check; - } - return chunks; -} - -int get_number_of_chunks(png_chunk **chunks) { - int i = 0; - while (memcmp(chunks[i]->type, "IEND", 4) != 0) { - i++; - } - // Add one for the IEND chunk - return ++i; -} - -void xor_data(png_chunk *chunk) { - for (int i = 0; i < chunk->length; i++) { - chunk->data[i] ^= KEY; - } -} - -void destroy_chunks(png_chunk **chunks) { - unsigned int size = get_number_of_chunks(chunks); - for (int i = 0; i < size; i++) { - free(chunks[i]->data); - free(chunks[i]); - } - free(chunks); -} - -void write_png_chunks(char *path, png_chunk **chunks) { - FILE *fp = fopen(path, "wb"); - if (fp == NULL) { - perror("fopen"); - exit(EXIT_FAILURE); - } - fwrite(PNG_SIGNATURE, PNG_SIGNATURE_SIZE, 1, fp); - unsigned int size = get_number_of_chunks(chunks); - for (int i = 0; i < size; i++) { - // Convert length to network byte order for writing - chunks[i]->length = htonl(chunks[i]->length); - fwrite(&chunks[i]->length, 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); - fwrite(chunks[i]->data, chunks[i]->length, 1, fp); - fwrite(&chunks[i]->crc, 4, 1, fp); - } - fclose(fp); -} +/* + * Copyright Notice + * ---------------- + * Copyright © 1998, 1999 by: Glenn Randers-Pehrson + * This specification is a modification of the PNG 1.0 specification. It is being + * provided by the copyright holder under the provisions of the 1996 MIT copyright and license: + * Copyright © 1996 by: Massachusetts Institute of Technology (MIT) + * This W3C specification is being provided by the copyright holders under + * the following license. By obtaining, using and/or copying this specification, you + * agree that you have read, understood, and will comply with the following terms + * and conditions: + * Permission to use, copy, and distribute this specification for any purpose + * and without fee or royalty is hereby granted, provided that the full text of + * this NOTICE appears on ALL copies of the specification or portions thereof, + * including modifications, that you make. + * THIS SPECIFICATION IS PROVIDED ”AS IS,” AND COPYRIGHT HOLD-ERS + * MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR + * IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, COPYRIGHT + * HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY + * OR FITNESS FOR ANY PARTICULAR PURPOSE OR + * THAT THE USE OF THE SPECIFICATION WILL NOT INFRINGE ANY + * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER + * RIGHTS. COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY + * USE OF THIS SPECIFICATION. + * The name and trademarks of copyright holders may NOT be used in + * advertising or publicity pertaining to the specification without specific, written + * prior permission. Title to copyright in this specification and any associated + * documentation will at all times remain with copyright holders. + */ + +#include +#include +#include +#include +#include +#include "png.h" + +FILE *get_file(char *path) { + FILE *fp = fopen(path, "rb"); + if (fp == NULL) { + perror("fopen"); + exit(EXIT_FAILURE); + } + return fp; +} + +char *load_file(char *path) { + FILE *fp = get_file(path); + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + rewind(fp); + char *buffer = malloc(size); + if (buffer == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + fread(buffer, 1, size, fp); + fclose(fp); + return buffer; +} + +int is_png(char *buffer) { + return memcmp(buffer, PNG_SIGNATURE, PNG_SIGNATURE_SIZE) == 0; +} + +png_chunk *get_png_chunk(char *buffer, unsigned int offset) { + png_chunk *chunk = malloc(sizeof(png_chunk)); + if (chunk == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + 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); + memcpy(&chunk->type, buffer + offset + 4, 4); + chunk->data = malloc(chunk->length); + if (chunk->data == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + memcpy(chunk->data, buffer + offset + 8, chunk->length); + memcpy(&chunk->crc, buffer + offset + 8 + chunk->length, 4); + return chunk; +} + +png_chunk **get_png_chunks(char *buffer) { + png_chunk **chunks = malloc(sizeof(png_chunk *)); + if (chunks == NULL) { + perror("malloc"); + exit(EXIT_FAILURE); + } + // Running offset of the buffer + unsigned int offset = PNG_SIGNATURE_SIZE; + // Index of the current chunk + int i = 0; + while (true) { + chunks[i] = get_png_chunk(buffer, offset); + // 12 = 4 (length) + 4 (type) + 4 (crc) + offset += 12 + chunks[i]->length; + if (memcmp(chunks[i]->type, "IEND", 4) == 0) { + break; + } + i++; + // Add one because realloc is 1-indexed when multiplying by sizeof + png_chunk **err_check = realloc(chunks, sizeof(png_chunk *) * (i + 1)); + if (err_check == NULL) { + destroy_chunks(chunks); + perror("realloc"); + exit(EXIT_FAILURE); + } + chunks = err_check; + } + return chunks; +} + +int get_number_of_chunks(png_chunk **chunks) { + int i = 0; + while (memcmp(chunks[i]->type, "IEND", 4) != 0) { + i++; + } + // Add one for the IEND chunk + return ++i; +} + +void xor_data(png_chunk *chunk) { + for (int i = 0; i < chunk->length; i++) { + chunk->data[i] ^= KEY; + } +} + +void destroy_chunks(png_chunk **chunks) { + unsigned int size = get_number_of_chunks(chunks); + for (int i = 0; i < size; i++) { + free(chunks[i]->data); + free(chunks[i]); + } + free(chunks); +} + +void write_png_chunks(char *path, png_chunk **chunks) { + FILE *fp = fopen(path, "wb"); + if (fp == NULL) { + perror("fopen"); + exit(EXIT_FAILURE); + } + fwrite(PNG_SIGNATURE, PNG_SIGNATURE_SIZE, 1, fp); + unsigned int size = get_number_of_chunks(chunks); + for (int i = 0; i < size; i++) { + // Convert length to network byte order for writing + chunks[i]->length = htonl(chunks[i]->length); + fwrite(&chunks[i]->length, 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); + fwrite(chunks[i]->data, chunks[i]->length, 1, fp); + fwrite(&chunks[i]->crc, 4, 1, fp); + } + fclose(fp); +} diff --git a/Assignment9/src/png.h b/Assignment9/src/png.h index 314c59b..5356f53 100644 --- a/Assignment9/src/png.h +++ b/Assignment9/src/png.h @@ -1,75 +1,75 @@ -/* - * Copyright Notice - * ---------------- - * Copyright © 1998, 1999 by: Glenn Randers-Pehrson - * This specification is a modification of the PNG 1.0 specification. It is being - * provided by the copyright holder under the provisions of the 1996 MIT copyright and license: - * Copyright © 1996 by: Massachusetts Institute of Technology (MIT) - * This W3C specification is being provided by the copyright holders under - * the following license. By obtaining, using and/or copying this specification, you - * agree that you have read, understood, and will comply with the following terms - * and conditions: - * Permission to use, copy, and distribute this specification for any purpose - * and without fee or royalty is hereby granted, provided that the full text of - * this NOTICE appears on ALL copies of the specification or portions thereof, - * including modifications, that you make. - * THIS SPECIFICATION IS PROVIDED ”AS IS,” AND COPYRIGHT HOLD-ERS - * MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR - * IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, COPYRIGHT - * HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY - * OR FITNESS FOR ANY PARTICULAR PURPOSE OR - * THAT THE USE OF THE SPECIFICATION WILL NOT INFRINGE ANY - * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER - * RIGHTS. COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY - * USE OF THIS SPECIFICATION. - * The name and trademarks of copyright holders may NOT be used in - * advertising or publicity pertaining to the specification without specific, written - * prior permission. Title to copyright in this specification and any associated - * documentation will at all times remain with copyright holders. - */ - -#pragma once - -// Needed for uint types -#include - -// 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_SIZE 8 - -// The key used to "encrypt/decrypt" the PNG chunks -#define KEY 42 - -typedef struct png_chunk { - uint32_t length; - char type[4]; - char *data; - uint32_t crc; -} png_chunk; - -// Get FILE from path -int get_fd(char *path); - -// Store file in heap memory -char *load_file(char *path); - -// Check if file is a PNG -int is_png(char *buffer); - -// Get PNG chunk -png_chunk *get_png_chunk(char *buffer, unsigned int offset); - -// Get all PNG chunks -png_chunk **get_png_chunks(char *buffer); - -// Get number of chunks -int get_number_of_chunks(png_chunk **chunks); - -// XOR chunk with key -void xor_data(png_chunk *chunk); - -// Destroy all chunks -void destroy_chunks(png_chunk **chunks); - -// Write PNG chunks to file -void write_png_chunks(char *path, png_chunk **chunks); \ No newline at end of file +/* + * Copyright Notice + * ---------------- + * Copyright © 1998, 1999 by: Glenn Randers-Pehrson + * This specification is a modification of the PNG 1.0 specification. It is being + * provided by the copyright holder under the provisions of the 1996 MIT copyright and license: + * Copyright © 1996 by: Massachusetts Institute of Technology (MIT) + * This W3C specification is being provided by the copyright holders under + * the following license. By obtaining, using and/or copying this specification, you + * agree that you have read, understood, and will comply with the following terms + * and conditions: + * Permission to use, copy, and distribute this specification for any purpose + * and without fee or royalty is hereby granted, provided that the full text of + * this NOTICE appears on ALL copies of the specification or portions thereof, + * including modifications, that you make. + * THIS SPECIFICATION IS PROVIDED ”AS IS,” AND COPYRIGHT HOLD-ERS + * MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR + * IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, COPYRIGHT + * HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY + * OR FITNESS FOR ANY PARTICULAR PURPOSE OR + * THAT THE USE OF THE SPECIFICATION WILL NOT INFRINGE ANY + * THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER + * RIGHTS. COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY + * USE OF THIS SPECIFICATION. + * The name and trademarks of copyright holders may NOT be used in + * advertising or publicity pertaining to the specification without specific, written + * prior permission. Title to copyright in this specification and any associated + * documentation will at all times remain with copyright holders. + */ + +#pragma once + +// Needed for uint types +#include + +// 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_SIZE 8 + +// The key used to "encrypt/decrypt" the PNG chunks +#define KEY 42 + +typedef struct png_chunk { + uint32_t length; + char type[4]; + char *data; + uint32_t crc; +} png_chunk; + +// Get FILE from path +int get_fd(char *path); + +// Store file in heap memory +char *load_file(char *path); + +// Check if file is a PNG +int is_png(char *buffer); + +// Get PNG chunk +png_chunk *get_png_chunk(char *buffer, unsigned int offset); + +// Get all PNG chunks +png_chunk **get_png_chunks(char *buffer); + +// Get number of chunks +int get_number_of_chunks(png_chunk **chunks); + +// XOR chunk with key +void xor_data(png_chunk *chunk); + +// Destroy all chunks +void destroy_chunks(png_chunk **chunks); + +// Write PNG chunks to file +void write_png_chunks(char *path, png_chunk **chunks);