https://cs50.harvard.edu/x/2023/problems/4/bottomup/
Bottom Up - CS50x 2023
Harvard University's introduction to the intellectual enterprises of computer science and the art of programming.
cs50.harvard.edu
외부 파일을 다루는 과정으로 처음 들어가는 연습문제로, 코드 4줄만 추가하면 되는 간단한 문제이다.
Bottomup.c
// Copies a BMP file
#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// Ensure proper usage
if (argc != 3)
{
printf("Usage: copy 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 2;
}
// Open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
printf("Could not create %s.\n", outfile);
return 3;
}
// 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 4;
}
if (bi.biHeight < 0) //여기서부터
{
bi.biHeight = -(bi.biHeight);
} //여기까지만 추가된 부분
// Write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// Write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// Determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// Iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// Iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{
// Temporary storage
RGBTRIPLE triple;
// Read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
// Write RGB triple to outfile
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
// Skip over padding, if any
fseek(inptr, padding, SEEK_CUR);
// Then add it back (to demonstrate how)
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}
// Close infile
fclose(inptr);
// Close outfile
fclose(outptr);
// Success
return 0;
}
bmp.h 파일 (완성본 제공)
// BMP-related data types based on Microsoft's own
#include <stdint.h>
// Aliases for C/C++ primitive data types
// https://msdn.microsoft.com/en-us/library/cc230309.aspx
typedef uint8_t BYTE;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef uint16_t WORD;
// Information about the type, size, and layout of a file
// https://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} __attribute__((__packed__))
BITMAPFILEHEADER;
// Information about the dimensions and color format
// https://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx
typedef struct
{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} __attribute__((__packed__))
BITMAPINFOHEADER;
// Relative intensities of red, green, and blue
// https://msdn.microsoft.com/en-us/library/dd162939(v=vs.85).aspx
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
biHeight : 비트맵의 세로 픽셀 수.
이 값이 양수이면 DIB는 아래에서 위로 구성(Bottom-Up)되며, 원점은 좌하단이 된다.
이 값이 음수이면 DIB는 위에서 아래로 구성(Top-Down)되며, 원점은 좌상단이 된다.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=genofreedomi&logNo=220433010884
BITMAPFILEHEADER, BITMAPINFOHEADER 구조체
1. BITMAPFILEHEADER 구조체 DIB 파일의 제일 선두에 있는 구조체이며, 비...
blog.naver.com