Instructions
Objective
Write a C assignment program to implement functions to encode, decode message ppm image.
Requirements and Specifications
For this assignments you will have at a minimal eight files:
- driver.c – This is where main lives.
- ppm.h – I will provide this file. It will contain the prototypes of the functions I implement. These functions deal specifically with a ppm file. It will also provide the definition of two structs.
- One for the header
- One for the pixels
- ppm.c – This file is where I implemented the functions listed in the ppm.h file.
- EncodeDecode.h – I will provide this file. It will contain additional prototypes of functions I needed to encode and decode a message in an image.
- EncodeDecode.c – This file is where I implement the functions listed in EncodeDecode.h
- utils.h – this provides the prototypes for two functions needed to check the number of command line arguments passed to the program. It also contains a function that check if the file pointers opened successfully.
- utils.c – this file is where I implement the functions for utils.h
- makefile
- Each of your header files (.h) must have header guards. Points will be deducted if you do not provide header guards I also removed all of the #include statements, you will need to provide these.
Screenshots of output
Source Code
Driver.c
//*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#include
#include
#include "utils.h"
#include "EncodeDecode.h"
int main(int argc, char* argv[])
{
checkArgs(argc, 2);
FILE* in = fopen(argv[1], "r");
checkFile(in);
FILE* out = fopen(argv[2], "w");
checkFile(out);
/*This is my test message. It can be something different*/
char* msg = "I hope this works!";
encodeMsg(in, out, msg);
FILE* dec = fopen(argv[2], "r");
checkFile(dec);
decodeMsg(dec);
fclose(in);
fclose(out);
fclose(dec);
return EXIT_SUCCESS;
}
EncodeDecode.h
/*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#ifndef ENCODEDECODE_H
#define ENCODEDECODE_H
#include
#include
#include "ppm.h"
void removeDigit(pixel_t** , header_t );
void encodeMsg(FILE* in, FILE* out, char* msg);
void charToBinary(char , int *);
unsigned char binToCharacter(int*);
void queue(int, int*, int*);
void dec2bin(int*, int);
void decodeMsg(FILE*);
#endif /* ENCODEDECODE_H */
Ppm.c
/*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#include
#include
#include
#include "ppm.h"
/* Parameters: f - FILE pointer to an input ppm file
* Return: output - header_t that contains the ppm header
* This function reads the PPM header information from the given file.
*/
header_t readHeader(FILE* f)
{
header_t header;
// read the magic numbers
fread(header.magicNum, 2, 1, f);
// clear whitespace and comments
ckws_comments(f);
// read the width
fscanf(f, "%d", &header.width);
// clear whitespace and comments
ckws_comments(f);
// read the height
fscanf(f, "%d", &header.height);
// clear whitespace and comments
ckws_comments(f);
// read the max value
fscanf(f, "%d", &header.maxVal);
// read the last whitespace
fgetc(f);
return header;
}
/* Parameters: f - FILE pointer to an input ppm file
* header - header_t that contains the ppm header
* Return: output - pixel_t double pointer that contains the ppm
* pixel information.
* This function reads the PPM pixel information from the given file.
* It allocates a 2D array to read the pixel data and returns it.
*/
pixel_t** readPixel(FILE* f, header_t header)
{
pixel_t** pixels;
int i;
int j;
int bytes;
char buffer[2];
// number of bytes per sample (r,g,b), 1 if < 256, 2 otherwise
bytes = (header.maxVal < 256) ? 1 : 2;
// allocate space for all row pointers
pixels = (pixel_t**) malloc(header.height * sizeof(pixel_t*));
// go through all pixels rows
for (i = 0; i < header.height; i++)
{
// allocate space for all pixels in the row
pixels[i] = (pixel_t*) malloc(header.width * sizeof(pixel_t));
// go through all pixels in row
for (j = 0; j < header.width; j++)
{
// read the red part
fread(buffer, bytes, 1, f);
// if maxvalue fits in 1 byte
if (header.maxVal < 256)
pixels[i][j].r = buffer[0];
// if maxvalue fits in 2 bytes, first byte is msb
else
pixels[i][j].r = (buffer[0] << 8) | buffer[1];
// read the green part
fread(buffer, bytes, 1, f);
// if maxvalue fits in 1 byte
if (header.maxVal < 256)
pixels[i][j].g = buffer[0];
// if maxvalue fits in 2 bytes, first byte is msb
else
pixels[i][j].g = (buffer[0] << 8) | buffer[1];
// read the blue part
fread(buffer, bytes, 1, f);
// if maxvalue fits in 1 byte
if (header.maxVal < 256)
pixels[i][j].b = buffer[0];
// if maxvalue fits in 2 bytes, first byte is msb
else
pixels[i][j].b = (buffer[0] << 8) | buffer[1];
}
}
return pixels;
}
/* Parameters: f - FILE pointer to an output ppm file
* header - header_t that contains the ppm header
* Return: output - none
* This function writes the PPM header information into the given file.
*/
void writeHeader(FILE* f, header_t header)
{
// write the magic numbers
fprintf(f, "%c%c\n", header.magicNum[0], header.magicNum[1]);
// write the width x height
fprintf(f, "%d %d\n", header.width, header.height);
// write the max value and newline
fprintf(f, "%d\n", header.maxVal);
}
/* Parameters: f - FILE pointer to an output ppm file
* pixels - pixel_t double pointer that contains the ppm
* pixel information.
* header - header_t that contains the ppm header
* Return: output - none
* This function writes the PPM pixel information into the given file.
*/
void writePixels(FILE* f, pixel_t** pixels, header_t header)
{
int i;
int j;
int bytes;
char buffer[2];
// number of bytes per sample (r,g,b), 1 if < 256, 2 otherwise
bytes = (header.maxVal < 256) ? 1 : 2;
// go through all pixels rows
for (i = 0; i < header.height; i++)
{
// go through all pixels in row
for (j = 0; j < header.width; j++)
{
// if maxvalue fits in 1 byte
if (bytes == 1)
buffer[0] = pixels[i][j].r;
// if maxvalue fits in 2 bytes, first byte is msb
else
{
buffer[0] = pixels[i][j].r >> 8;
buffer[1] = pixels[i][j].r;
}
// write the red part
fwrite(buffer, bytes, 1, f);
// if maxvalue fits in 1 byte
if (bytes == 1)
buffer[0] = pixels[i][j].g;
// if maxvalue fits in 2 bytes, first byte is msb
else
{
buffer[0] = pixels[i][j].g >> 8;
buffer[1] = pixels[i][j].g;
}
// write the green part
fwrite(buffer, bytes, 1, f);
// if maxvalue fits in 1 byte
if (bytes == 1)
buffer[0] = pixels[i][j].b;
// if maxvalue fits in 2 bytes, first byte is msb
else
{
buffer[0] = pixels[i][j].b >> 8;
buffer[1] = pixels[i][j].b;
}
// write the blue part
fwrite(buffer, bytes, 1, f);
}
}
}
/* Parameters: f - FILE pointer pointing to a ppm input file
* Return: output - none
* This function removes all the whitespace and comments found from
* the current position.
*/
void ckws_comments (FILE *f)
{
int c;
while (1)
{
// ignore all whitespace
while (isspace(c = fgetc(f)));
// if a comment
if (c == '#')
// read until newline
while ((c = fgetc(f)) != '\n');
// if not a comment
else
{
// undo the last read
ungetc(c, f);
// exit the loop to return
break;
}
}
}
/* Parameters: pixels - pixel_t double pointer that contains the ppm
* pixel information.
* header - header_t that contains the ppm header
* Return: output - none
* This function frees all the allocated memory used by the pixel 2D array
*/
void freeMemory(pixel_t** pixels, header_t header)
{
int i;
// go through all pixels rows
for (i = 0; i < header.height; i++)
// free space for all pixels
free(pixels[i]);
// free space for all rows
free(pixels);
}
Ppm.h
/*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#ifndef PPM_H
#define PPM_H
#include
typedef struct
{
unsigned char r;
unsigned char g;
unsigned char b;
}pixel_t;
typedef struct
{
char magicNum[3];
int width;
int height;
int maxVal;
}header_t;
header_t readHeader(FILE*);
pixel_t** readPixel(FILE*, header_t);
void writeHeader(FILE*, header_t);
void writePixels(FILE*, pixel_t**, header_t);
void ckws_comments (FILE *);
void freeMemory(pixel_t**, header_t);
#endif /* PPM_H */
Utils.c
/*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#include
#include
#include "utils.h"
/* Parameters: argc - number of command line arguments
* n - required number of command line arguments
* Return: output - none
* This function verifies that the number of command line arguments
* is at least the required n. If not, it exits with error.
*/
void checkArgs(int argc, int n)
{
// if not enough arguments, exit with error
if (argc < n)
{
fprintf(stderr, "Error: Not enough command line arguments\n");
exit(EXIT_FAILURE);
}
}
/* Parameters: f - FILE pointer pointing to a file that has been opened
* Return: output - none
* This function verifies that the file has been opened coorrectly.
* If not, it exits with error.
*/
void checkFile(FILE* f)
{
// if file was not opened, exit with error
if (f == NULL)
{
fprintf(stderr, "Error: Unable to open file\n");
exit(EXIT_FAILURE);
}
}
Utils.h
/*************************
*Your names
*CPSC 2310 F21 Section 00?
*Your emails
*************************/
#ifndef UTILS_H
#define UTILS_H
#include
void checkArgs(int, int);
void checkFile(FILE*);
#endif /* UTILS_H */
Similar Samples
Visit ProgrammingHomeworkHelp.com to explore our diverse collection of programming assignment samples. These examples illustrate our proficiency across Java, Python, C++, and more, showcasing our ability to deliver high-quality solutions tailored to your academic or professional requirements. See how our expertise can help you excel in programming challenges.
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C