Working reader
This commit is contained in:
		| @@ -30,10 +30,14 @@ int main(int argc, char *argv[]) { | ||||
| 		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 %s chunk\n", chunks[i]->type); | ||||
| 			printf("Found %.4s chunk\n", chunks[i]->type); | ||||
| 			if (is_idat) { | ||||
| 				xor_data(chunks[i]); | ||||
| 			} | ||||
| 		} else { | ||||
| 			printf("Found unknown: %s\n", chunks[i]->type); | ||||
| 			printf("Found unknown: %.4s\n", chunks[i]->type); | ||||
| 		} | ||||
| 		printf("Chunk size is:%d\n", chunks[i]->length); | ||||
| 	} | ||||
| 	// write_png_chunks(path, chunks); | ||||
| } | ||||
| @@ -69,11 +69,6 @@ char *load_file(int fd) { | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	fread(buffer, 1, size, fp); | ||||
| 	// Iterate over buffer and convert from network byte order to host byte order | ||||
| 	//for (int i = 0; i < size; i += 4) { | ||||
| 	//	uint32_t *ptr = (uint32_t *)(buffer + i); | ||||
| 	//	*ptr = ntohl(*ptr); | ||||
| 	//} | ||||
| 	fclose(fp); | ||||
| 	return buffer; | ||||
| } | ||||
| @@ -111,7 +106,8 @@ png_chunk **get_png_chunks(char *buffer) { | ||||
| 	int i = 0; | ||||
| 	while (1) { | ||||
| 		chunks[i] = get_png_chunk(buffer, offset); | ||||
| 		offset += chunks[i]->length; | ||||
| 		// 12 = 4 (length) + 4 (type) + 4 (crc) | ||||
| 		offset += 12 + chunks[i]->length; | ||||
| 		if (memcmp(chunks[i]->type, "IEND", 4) == 0) { | ||||
| 			break; | ||||
| 		} | ||||
| @@ -125,18 +121,6 @@ png_chunk **get_png_chunks(char *buffer) { | ||||
| 	return chunks; | ||||
| } | ||||
|  | ||||
| int is_chunk_valid(png_chunk *chunk) { | ||||
| 	uint32_t crc = htonl(chunk->crc); | ||||
| 	//uint32_t calculated_crc = crc32(0, chunk->type, 4); | ||||
| 	//calculated_crc = crc32(calculated_crc, chunk->data, chunk->length); | ||||
| 	//return crc == calculated_crc; | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| int is_chunk_critical(png_chunk *chunk) { | ||||
| 	return chunk->type[0] >= 'A' && chunk->type[0] <= 'Z'; | ||||
| } | ||||
|  | ||||
| int get_number_of_chunks(png_chunk **chunks) { | ||||
| 	int i = 0; | ||||
| 	while (chunks[i] != NULL) { | ||||
| @@ -144,3 +128,25 @@ int get_number_of_chunks(png_chunk **chunks) { | ||||
| 	} | ||||
| 	return i; | ||||
| } | ||||
|  | ||||
| void xor_data(png_chunk *chunk) { | ||||
| 	for (int i = 0; i < chunk->length; i++) { | ||||
| 		chunk->data[i] ^= KEY; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void write_png_chunks(char *path, png_chunk **chunks) { | ||||
| 	FILE *fp = fopen(path, "wb"); | ||||
| 	if (fp == NULL) { | ||||
| 		perror("fopen"); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	fwrite(PNG_SIGNATURE, PNG_SIGNATURE_SIZE, 1, fp); | ||||
| 	for (int i = 0; chunks[i] != NULL; i++) { | ||||
| 		fwrite(&chunks[i]->length, 4, 1, fp); | ||||
| 		fwrite(chunks[i]->type, 4, 1, fp); | ||||
| 		fwrite(chunks[i]->data, chunks[i]->length, 1, fp); | ||||
| 		fwrite(&chunks[i]->crc, 4, 1, fp); | ||||
| 	} | ||||
| 	fclose(fp); | ||||
| } | ||||
|   | ||||
| @@ -39,6 +39,9 @@ | ||||
| // 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 | ||||
|  | ||||
| #define KEY 42 | ||||
|  | ||||
| typedef struct png_chunk { | ||||
| 	uint32_t length; | ||||
| 	char type[4]; | ||||
| @@ -67,8 +70,8 @@ png_chunk **get_png_chunks(char *buffer); | ||||
| // Get number of chunks | ||||
| int get_number_of_chunks(png_chunk **chunks); | ||||
|  | ||||
| // Check if chunk is critical | ||||
| int is_chunk_critical(png_chunk *chunk); | ||||
| // XOR chunk with key | ||||
| void xor_data(png_chunk *chunk); | ||||
|  | ||||
| // Is chunk valid? | ||||
| int is_chunk_valid(png_chunk *chunk); | ||||
| // Write PNG chunks to file | ||||
| void write_png_chunks(char *path, png_chunk **chunks); | ||||
		Reference in New Issue
	
	Block a user