[CS50] 05-3 Problem Set
Published:
In this post, the solution for the problem set of the fifth lecture of CS50 is summarized.
Problem Set
volume
You may refer to https://cs50.harvard.edu/x/2024/psets/4/volume/.
Answer
// Modifies the volume of an audio file
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// Number of bytes in .wav header
const int HEADER_SIZE = 44;
int main(int argc, char *argv[])
{
// Check command-line arguments
if (argc != 4)
{
printf("Usage: ./volume input.wav output.wav factor\n");
return 1;
}
// Open files and determine scaling factor
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FILE *output = fopen(argv[2], "w");
if (output == NULL)
{
printf("Could not open file.\n");
return 1;
}
float factor = atof(argv[3]);
// TODO: Copy header from input file to output file
uint8_t header[HEADER_SIZE];
fread(header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(header, sizeof(uint8_t), HEADER_SIZE, output);
// TODO: Read samples from input file and write updated data to output file
int16_t sample;
while (fread(&sample, sizeof(int16_t), 1, input)){
sample *= factor;
fwrite(&sample, sizeof(int16_t), 1, output);
}
// Close files
fclose(input);
fclose(output);
}
filter-more
You may refer to https://cs50.harvard.edu/x/2024/psets/4/filter/more/.
Answer
#include "helpers.h"
#include <math.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
int mean = round((image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed) / (float) 3);
image[i][j].rgbtBlue = image[i][j].rgbtGreen = image[i][j].rgbtRed = mean;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++){
for (int j = 0; j < width / 2; j++){
RGBTRIPLE temp = image[i][j];
image[i][j] = image[i][width - j - 1];
image[i][width - j - 1] = temp;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{ int dx[3] = {0, -1, 1};
int dy[3] = {0, -1, 1};
RGBTRIPLE temp_image[height][width];
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
int validCnt = 0;
int blurRed = 0;
int blurGreen = 0;
int blurBlue = 0;
for (int x = 0; x < 3; x++){
for (int y = 0; y < 3; y++){
if (i + dy[y] >= 0 && i +dy[y] < height && j + dx[x] >= 0 && j + dx[x] < width){
blurRed += image[i + dy[y]][j + dx[x]].rgbtRed;
blurGreen += image[i + dy[y]][j + dx[x]].rgbtGreen;
blurBlue += image[i + dy[y]][j + dx[x]].rgbtBlue;
validCnt++;
}
}
}
blurRed = round(blurRed / (float) validCnt);
blurGreen = round(blurGreen / (float) validCnt);
blurBlue = round(blurBlue / (float) validCnt);
temp_image[i][j].rgbtRed = blurRed;
temp_image[i][j].rgbtGreen = blurGreen;
temp_image[i][j].rgbtBlue = blurBlue;
}
}
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
image[i][j] = temp_image[i][j];
}
}
return;
}
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
int dx[3] = {-1, 0, 1};
int dy[3] = {-1, 0, 1};
int gx_kernel[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1 , 0, 1}};
int gy_kernel[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1 , 2, 1}};
RGBTRIPLE temp_image[height][width];
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
int gxRed, gxGreen, gxBlue;
int gyRed, gyGreen, gyBlue;
gxRed = gxGreen = gxBlue = gyRed = gyGreen = gyBlue = 0;
for (int x = 0; x < 3; x++){
for (int y = 0; y < 3; y++){
if (i + dy[y] >= 0 && i +dy[y] < height && j + dx[x] >= 0 && j + dx[x] < width){
gxRed += image[i + dy[y]][j + dx[x]].rgbtRed * gx_kernel[y][x];
gxGreen += image[i + dy[y]][j + dx[x]].rgbtGreen * gx_kernel[y][x];
gxBlue += image[i + dy[y]][j + dx[x]].rgbtBlue * gx_kernel[y][x];
gyRed += image[i + dy[y]][j + dx[x]].rgbtRed * gy_kernel[y][x];
gyGreen += image[i + dy[y]][j + dx[x]].rgbtGreen * gy_kernel[y][x];
gyBlue += image[i + dy[y]][j + dx[x]].rgbtBlue * gy_kernel[y][x];
}
}
}
int edgeRed = round(sqrt(pow(gxRed, 2) + pow(gyRed, 2)));
int edgeGreen = round(sqrt(pow(gxGreen, 2) + pow(gyGreen, 2)));
int edgeBlue = round(sqrt(pow(gxBlue, 2) + pow(gyBlue, 2)));
temp_image[i][j].rgbtRed = (edgeRed > 255) ? 255 : edgeRed;
temp_image[i][j].rgbtGreen = (edgeGreen > 255) ? 255 : edgeGreen;
temp_image[i][j].rgbtBlue = (edgeBlue > 255) ? 255 : edgeBlue;
}
}
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++){
image[i][j] = temp_image[i][j];
}
}
return;
}
recover
You may refer to https://cs50.harvard.edu/x/2024/psets/4/recover/.
Answer
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
if (argc != 2){
printf("usage: ./recover filename\n");
return 1;
}
FILE *memCard = fopen("card.raw", "r");
uint8_t header[512];
int fileCnt = 0;
if (memCard == NULL){
printf("Could not open file.\n");
return 1;
}
char filename[8];
FILE *img = NULL;
while (fread(header, 1, 512, memCard) == 512){
if (header[0] == 0xff && header[1] == 0xd8 && header[2] == 0xff && (header[3] & 0xf0) == 0xe0){
if (fileCnt == 0){
//filename = malloc(8);
sprintf(filename, "%03i.jpg", fileCnt);
img = fopen(filename, "w");
fwrite(header, 1, 512, img);
fileCnt++;
}
else{
fclose(img);
sprintf(filename, "%03i.jpg", fileCnt);
img = fopen(filename, "w");
fwrite(header, 1, 512, img);
fileCnt++;
}
}
else{
if (fileCnt == 0){
continue;
}
fwrite(header, 1, 512, img);
}
}
fclose(img);
fclose(memCard);
//free(filename);
return 0;
}
/*pseudo
open memory card
while fread < 512:
if jpeg start:
if first:
write
else:
close
write
else:
write
close
*/

Leave a Comment