I have to read a .pgm file for an assignment and decode the least significant bit in every byte to get some hidden text. I have the reading and writing code from the professor but when I try to read the file color has an issue being written to. I think I know how to actually get the hidden text out but the I/O always gives me trouble.
Thanks in advance for your help.
It wouldnt let me add the .pgm so i ranamed it as .png, so if you download it make sure to rename it to .pgm
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned char uchar;
/****************************************/
/* Clear PGM (XV) comments. */
/****************************************/
void pgmCommentClear(FILE* disk) {
uchar ch;
fread(&ch, 1, 1, disk);
if (ch != '#') {
fseek(disk, -1, SEEK_CUR);
return;
}
do {
while (ch != '\n') fread(&ch, 1, 1, disk);
} while (ch == '#');
pgmCommentClear(disk);
}
/****************************************/
/* Read PGM formatted image (1D array). */
/****************************************/
uchar* PGM_FILE_READ_1D(char* FileName, int* Width, int* Height, int* color) {
int pmax;
char ch;
char type[3];
uchar* Image;
FILE* disk;
if ((disk = fopen(FileName, "rb")) == NULL) {
return NULL;
}
fscanf(disk, "%s", type);
if (!strcmp(type, "P6")) *color = 1;
else *color = 0;
fread(&ch, 1, 1, disk);
pgmCommentClear(disk);
fscanf(disk, "%d", Width);
fscanf(disk, "%d", Height);
fscanf(disk, "%d", &pmax);
fread(&ch, 1, 1, disk);
if (*color == 1) {
Image = (uchar*)calloc(*Height * *Width * 3, sizeof(uchar));
fread(Image, 1, (*Height * *Width * 3), disk);
}
else {
Image = (uchar*)calloc(*Height * *Width, sizeof(uchar));
fread(Image, 1, (*Height * *Width), disk);
}
fclose(disk);
return Image;
}
/****************************************/
/* Write PGM formatted image (1D array).*/
/****************************************/
void PGM_FILE_WRITE_1D(char* FileName, uchar* Image, int Width, int Height, int color) {
FILE* disk;
disk = fopen(FileName, "wb");
if (color == 1) fprintf(disk, "P6\n");
else fprintf(disk, "P5\n");
fprintf(disk, "%d %d\n", Width, Height);
fprintf(disk, "255\n");
if (color == 1) {
fwrite(Image, 1, (Height * Width * 3), disk);
}
else {
fwrite(Image, 1, (Height * Width), disk);
}
fclose(disk);
}
int main(int argc, char const* argv[]) {
// do command line args stuff for extra credit
//if (argv == 2) { }
// read the file
//int width = 876
//int height = 594
uchar* image = PGM_FILE_READ_1D("./hw10.pgm", 876, 594, 0);
printf("%c", *image);
}
Pretty cool assignment, Ron Marsh ;-)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned char uchar;
/****************************************/
/* Clear PGM (XV) comments. */
/****************************************/
void pgmCommentClear(FILE* disk) {
uchar ch;
fread(&ch, 1, 1, disk);
if (ch != '#') {
fseek(disk, -1, SEEK_CUR);
return;
}
do {
while (ch != '\n') fread(&ch, 1, 1, disk);
} while (ch == '#');
pgmCommentClear(disk);
}
/****************************************/
/* Read PGM formatted image (1D array). */
/****************************************/
uchar* PGM_FILE_READ_1D(char* FileName, int* Width, int* Height, int* color) {
int pmax;
char ch;
char type[3];
uchar* Image;
FILE* disk;
if ((disk = fopen(FileName, "rb")) == NULL) {
return NULL;
}
fscanf(disk, "%s", type);
if (!strcmp(type, "P6")) *color = 1;
else *color = 0;
fread(&ch, 1, 1, disk);
pgmCommentClear(disk);
fscanf(disk, "%d", Width);
fscanf(disk, "%d", Height);
fscanf(disk, "%d", &pmax);
fread(&ch, 1, 1, disk);
if (*color == 1) {
Image = (uchar*)calloc(*Height * *Width * 3, sizeof(uchar));
fread(Image, 1, (*Height * *Width * 3), disk);
}
else {
Image = (uchar*)calloc(*Height * *Width, sizeof(uchar));
fread(Image, 1, (*Height * *Width), disk);
}
fclose(disk);
return Image;
}
/****************************************/
/* Write PGM formatted image (1D array).*/
/****************************************/
void PGM_FILE_WRITE_1D(char* FileName, uchar* Image, int Width, int Height, int color) {
FILE* disk;
disk = fopen(FileName, "wb");
if (color == 1) fprintf(disk, "P6\n");
else fprintf(disk, "P5\n");
fprintf(disk, "%d %d\n", Width, Height);
fprintf(disk, "255\n");
if (color == 1) {
fwrite(Image, 1, (Height * Width * 3), disk);
}
else {
fwrite(Image, 1, (Height * Width), disk);
}
fclose(disk);
}
int main(int argc, char const* argv[]) {
// do command line args stuff for extra credit
char newMsg[100] = "";
if (argc >= 2)
for (int i = 1; i < argc; i++) {
strcat(newMsg, argv[i]);
strcat(newMsg, " ");
}
else
strcat(newMsg, "Greetings from the other side");
strcat(newMsg, "\0");
int width, height, color;
// read the file
uchar* image = PGM_FILE_READ_1D("./hw10.pgm", &width, &height, &color);
printf("width = %d, height = %d, color = %d\n", width, height, color);
// Read encoded message
int size = width * height, bitCount = 8;
uchar hiddenChar = 0;
for (int i = 0; i < size; i++) {
//shift least-significant bit left `bitCount` times and overlay onto `hidden`
hiddenChar |= ((image[i] & 0x01) << --bitCount);
// After 8 bits we have the hidden byte
if (bitCount == 0) {
// If character is null terminator then we're done
if (hiddenChar == 0)
break;
// Print hidden character and reset
printf("%c", hiddenChar);
bitCount = 8;
hiddenChar = 0;
}
}
// Encode new message
int len = strlen(newMsg) + 1;
for (int i = 0; i < len; i++)
for (int j = 0; j < 8; j++)
if ( newMsg[i] & (0x01 << (7-j) ) )
image[i * 8 + j] |= 0x01;
else
image[i * 8 + j] &= 0xfe;
PGM_FILE_WRITE_1D("./hw10-out.pgm", image, width, height, color);
return 0;
}