https://cs50.harvard.edu/x/2023/labs/4/smiley/
[컴파일러]makefile 에 대하여
https://kthdev.tistory.com/40 (작성중) smily project 를 작성하고 컴파일까지 완료, 정상작동 확인을 했고 제출까지 했다. [chat gpt는 제출하는 과제에는 사용하지 않았습니다.] 아무리 찾아봐도 나는 분명 h
kthdev.tistory.com
Lab 4: Smiley - CS50x 2023
Harvard University's introduction to the intellectual enterprises of computer science and the art of programming.
cs50.harvard.edu
[제출 완료되었으며 작성중 입니다.]
colorize.c
#include <stdio.h>
#include <stdlib.h>
#include "helpers.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 3)
{
printf("Usage: colorize infile outfile\n");
return 1;
}
// remember filenames
char *infile = argv[1];
char *outfile = argv[2];
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
printf("Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
bi.biBitCount != 24 || bi.biCompression != 0)
{
fclose(outptr);
fclose(inptr);
printf("Unsupported file format.\n");
return 6;
}
int height = abs(bi.biHeight);
int width = bi.biWidth;
// allocate memory for image
//RGBTRIPLE 요소가 width개 있는 배열을 가르킬수 있는 포인터 선언.
//그리고 width개의 배열을 가진 image 포인터배열을
//height 갯수만큼 메모리에 할당함으로서, 2차원 배열이 된다.
//접근할때는 image[height][width] 형식으로 접근 가능하다.
RGBTRIPLE (*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
if (image == NULL)
{
printf("Not enough memory to store image.\n");
fclose(outptr);
fclose(inptr);
return 7;
}
// determine padding for scanlines
int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0; i < height; i++)
{
// read row into pixel array
//fread 를 통해 image[i] 에다가 RGBTRIPLE 크기의 데이터를 width갯수만큼
//(아까 width 갯수만큼의 크기를 가진 배열을 가르키는 포인터로 선언함)
//또한 그 배열포인터를 또 height만큼의 배열로 메모리를 동적할당하였음.
//inptr에서 가져온 값을 입력함.
fread(image[i], sizeof(RGBTRIPLE), width, inptr);
// skip over padding
//이 padding은 bmp파일의 특성으로,
//각 행의 픽셀이 4바이트 단위로 끝나야 읽어올 수 있으므로,
// padding을 넣어줘야 한다. 이는 bmp 알고리즘 특성이다.
fseek(inptr, padding, SEEK_CUR);
}
//이제 image에 값을 다 불러와서 처리만 하면 된다.
colorize(height, width, image);
// write outfile's BITMAPFILEHEADER 파일헤더 입력
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER 인포헤더 입력
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// write new pixels to outfile
//이 루프를 돌리는 가장 큰 이유는
//각 열 마다 패딩을 넣어줘야 하기 때문이다.
for (int i = 0; i < height; i++)
{
// write row to outfile
fwrite(image[i], sizeof(RGBTRIPLE), width, outptr);
//이렇게 가능한 아유는
//이미지 파일, bmp는 좌우 가로 데이터 사이즈가 똑같으므로
//각 열의 padding 사이즈는 모든 열에서 동일하다.
// write padding at end of row
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}
// free memory for image
free(image);
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
return 0;
}
helpers.c
#include "helpers.h"
void colorize(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
if (
image[i][j].rgbtBlue == 0X00 &&
image[i][j].rgbtGreen == 0x00 &&
image[i][j].rgbtRed == 0x00)
//when color is black
{
image[i][j].rgbtBlue = 0x00;
image[i][j].rgbtGreen = 0x00;
image[i][j].rgbtRed = 0xAA;
//change color to red
};
};
};
// Change all black pixels to a color of your choosing
}