I want to read a PNG image file with C without any library. From PNG (Portable Network Graphics) Specification Version 1.0 any PNG file has a signature that distinguishes it from other image formats. The signature is the first 8 bytes of the image.
Some sources like the above RFC mentioned the signature as:
137 80 78 71 13 10 26 10 (decimal)
Or like Not able to read IHDR chunk of a PNG file mentioned the signature as:
89 50 4E 47 0D 0A 1A 0A (ASCii)
So, I write a simple code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE (8)
int main(int argc, char **argv){
if(argc != 2) {
printf("Usage: %s <png file>\n", argv[0]);
return 1;
}
char *buf = (char *)malloc(MAX_SIZE);
if(!buf) {
fprintf(stderr, "Couldn't allocate memory\n");
return 1;
}
FILE *f = fopen(argv[1], "r");
if(!f) {
perror("fopen");
printf("Invalid file\n");
free(buf);
return 1;
}
int size = fread(buf, 1, MAX_SIZE, f);
printf(%c\n", buf[1]);
printf(%c\n", buf[2]);
printf(%c\n", buf[3]);
printf(%c\n", buf[4]);
printf(%c\n", buf[5]);
printf(%c\n", buf[6]);
printf(%c\n", buf[7]);
printf(%c\n", buf[8]);
fclose(f);
free(buf);
system("pause");
return 0;
}
When I print the bytes by printf
, the output is not like the above.
This is what it shows:
ëPNG→►v@,
Can someone describe what happened and what can I do to modify it?
CodePudding user response:
You need to print each value with the correct format specifier. Here we want numerical representations, not character ones.
From the documentation on printf
:
%c
writes a single character%d
converts a signed integer into decimal representation%x
converts an unsigned integer into hexadecimal representation
X
prints a hexadecimal with a minimum width of two characters, padding with leading zeroes, using ABCDEF (instead of abcdef).
See also implicit conversions.
An example:
#include <stdio.h>
#define SIZE 8
int main(int argc, char **argv) {
unsigned char magic[SIZE];
FILE *file = fopen(argv[1], "rb");
if (!file || fread(magic, 1, SIZE, file) != SIZE) {
fprintf(stderr, "Failure to read file magic.\n");
return 1;
}
/* Decimal */
for (size_t i = 0; i < SIZE; i )
printf("%d ", magic[i]);
printf("\n");
/* Hexadecimal */
for (size_t i = 0; i < SIZE; i )
printf("X ", magic[i]);
printf("\n");
fclose(file);
}
Output:
137 80 78 71 13 10 26 10
89 50 4E 47 0D 0A 1A 0A