티스토리 뷰

C언어

[C언어] 1. raw파일 복사하는 방법

용감한 우디 2024. 11. 7. 13:35

안녕하세요!
오늘은 원본 raw파일에 대해 새로운 raw파일을 만들어 이미지를 복사하는  방법에 대해서 알아보겠습니다.



일단 raw파일이 무엇인지부터 알아야겠죠.


●raw파일이란?

RAW 파일은 압축 및 가공이 되지 않은 이미지 데이터를 포함하고 있는 파일입니다.

RAW 파일을 사용하면 화이트 밸런스, 노출, 색상 보정 등을 후처리에서 더 유연하게 조정할 수 있어서 사진이나 영상 편집에 유용합니다.

 

raw파일의 크기로써 512x512 가 많이 사용되는데,

이는 raw파일의 표준해상도이고 메모리 용량도 적합하고

고해상도를 잘 표현할수 있는 256KB의 좋은 크기를 가지고 있기 때문입니다.

 

● raw파일 복사하는 코드

저희는 다음과 같은 순서로 raw파일을 복사할겁니다.
1) 원본 raw파일을 저장할 메모리를 할당( 이 메모리의 주소를 *ori_pic 이라 하겠습니다. )
2) 복사본 raw파일을 저장할 메모리를 할당( 이 메모리의 주소를 *modi_pic 이라 하겠습니다. )

3) 원본 raw파일의 데이터를 *ori_pic 에 저장한다.

4) *ori_pic 에 있는 데이터를 그대로 *modi_pic 에 복사한다.

5) *modi_pic 에 있는 데이터를 복사본 raw파일에 쓴다.

 

흥미로운 점은 메모리 할당이 한 가지 방법이 아니라 여러가지 방법이 있는데요.

그 중 1차원 배열과 2차원 배열을 활용한 메모리 할당을 통해 raw파일을 복사 해보도록 하겠습니다.

 

아래의 코드는 1차월 배열을 이용한 raw파일 복사 코드 입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VER 512 // FILE의 수직방향 크기
#define HOR 512 // FILE의 수평방향 크기
#define F_SIZE (VER*HOR) // FILE의 크기

unsigned char * alloc_pic (int SIZE);

int main()
{
	unsigned char *ori_pic = alloc_pic(F_SIZE); // 원본 raw 데이터를 담을 메모리를 할당.
	unsigned char *modi_pic = alloc_pic(F_SIZE); // 복사본 raw 데이터를 담을 메모리를 할당.
	
	FILE *fin1, *fout1;
	
	fin1 = fopen("Lena_512.raw", "rb"); // 읽기모드 스트림 생성
	fout1 = fopen("Copy_Lena_512.raw","wb"); // 쓰기모드 스트림 생성

	if(!fin1) {printf("ERROR :: File Can't Read\n"); exit(1);} // 파일을 읽는데 문제가 있습니다.
	if(!fout1) {printf("ERROR :: File Can't Save\n"); exit(1);} // 파일을 저장하는데 문제가 있습니다.

	/*** 데이터 복사 과정 ***/
	fread(ori_pic,sizeof(unsigned char),F_SIZE,fin1); // *ori_pic에 원본 raw데이터를 저장.
	memcpy(modi_pic,ori_pic,F_SIZE*sizeof(unsigned char)); // *ori_pic에 있는 데이터를 그대로 *modi_pic에 저장.
	fwrite(modi_pic,sizeof(unsigned char),F_SIZE,fout1); // *modi_pic에 있는 데이터를 복사본 raw파일에 쓰기.	

	/*** 파일 닫고 메모리 해제 ***/
	fclose(fin1);
	fclose(fout1);
	free(ori_pic);
	free(modi_pic);
    
	printf("success"); // 프로그램이 잘 작동 되는지 확인하는 출력문
    
	return 0;
}


/*** 1차원 배열 메모리 할당 function ***/
unsigned char * alloc_pic (int SIZE)
{
	unsigned char * pic;
	
	if((pic=(unsigned char*)calloc(SIZE,sizeof(unsigned char))) == NULL) {
		printf("\n malloc_picture : Picture structure \n");
		exit(1);
	}
	return pic;
}

 

 

다음은 2차원 배열을 이용한  raw파일 복사 코드입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VER 512 // FILE의 수직방향 크기
#define HOR 512 // FILE의 수평방향 크기
#define F_SIZE (VER*HOR) // FILE의 크기

unsigned char ** alloc_pic_2d (int width, int height);

int main()
{
	int i, j;
	
	unsigned char **ori_pic_2d = alloc_pic_2d(HOR,VER); // 원본 raw 데이터를 담을 메모리를 할당.
	unsigned char **modi_pic_2d = alloc_pic_2d(HOR,VER); // 복사본 raw 데이터를 담을 메모리를 할당.
    
	FILE *fin1, *fout1;

	fin1 = fopen("Lena_512.raw","rb"); // 읽기모드 스트림 생성
	fout1 = fopen("Copy_Lena_512_2d.raw","wb"); // 쓰기모드 스트림 생성
	
	if(!fin1) {printf("ERROR :: File Can't Read\n"); exit(1);} // 파일을 읽는데 문제가 있습니다.
	if(!fout1) {printf("ERROR :: File Can't Save\n"); exit(1);} // 파일을 저장하는데 문제가 있습니다.
	
    /*** 데이터 복사 과정 ***/
	for( i = 0; i < VER; i++) fread(ori_pic_2d[i],sizeof(unsigned char),VER,fin1); 
	for( j = 0; j < VER; j++)
	{
		for( i = 0; i < HOR; i++) modi_pic_2d[j][i] = ori_pic_2d[j][i];
	}
	for( i = 0; i < VER; i++) fwrite(modi_pic_2d[i],sizeof(unsigned char),HOR,fout1);
	
    /*** 스트림 종료, 메모리 해제 ***/
	fclose(fin1);
	fclose(fout1);
	
	for ( i = 0; i < VER; i++)
	{
		free(ori_pic_2d[i]);
		free(modi_pic_2d[i]);
	}
	
	free(ori_pic_2d);
	free(modi_pic_2d);

	printf("success"); // 프로그램이 잘 작동 되는지 확인하는 출력문
	return 0;
}


/*** 2차원 배열 메모리 할당 function ***/
unsigned char ** alloc_pic_2d(int width, int height)
{
	unsigned char **pic;
	int i;
	
	if((pic=(unsigned char **)calloc(height,sizeof(unsigned char*)))==NULL){
		printf("\n malloc_picture : Picture structure \n");
		exit(1);
	}
	
	for(i=0;i<height;i++)
	{
		if((pic[i]=(unsigned char*)calloc(width,sizeof(unsigned char)))==NULL){
			printf("\n malloc_picture : Picture structure \n");
			exit(1);
		}
	}
	return pic;
}

 

 

1차원 배열과 2차원 배열을 활용한 메모리 생성에 대해 자세하게 알아보겠습니다.

 

1. 1차원 배열을 이용한 메모리 생성

unsigned char * alloc_pic (int SIZE)
{
	unsigned char * pic;
	
	if((pic=(unsigned char*)calloc(SIZE,sizeof(unsigned char))) == NULL) {
		printf("\n malloc_picture : Picture structure \n");
		exit(1);
	}
	return pic;
}

 

이 함수는 SIZE 만큼 1차원 으로 픽셀의 값을 저장할 수 있는 메모리를 할당해주는 함수입니다.

if문 안에서 메모리를 할당해주고,

할당되지 않았다면( ==NULL) 오류 메시지를 출력한 후에 즉시 프로그램을 종료 시킵니다.

제대로 할당이 됐으면 할당된 제일 앞 주소를 반환!

 

아래의 그림과 같이 *picSIZE 만큼 메모리가 할당됩니다!

< alloc_pic 호출 시 할당되는 메모리 >

 

raw파일의 경우 SIZE == F_SIZE 이므로 512*512의 크기를 가진 1차원 배열이 생성되는 겁니다!

 

 

2. 2차원 배열을 이용한 메모리 생성

unsigned char ** alloc_pic_2d(int width, int height)
{
	unsigned char **pic;
	int i;
	
	if((pic=(unsigned char **)calloc(height,sizeof(unsigned char*)))==NULL){
		printf("\n malloc_picture : Picture structure \n");
		exit(1);
	}
	
	for(i=0;i<height;i++)
	{
		if((pic[i]=(unsigned char*)calloc(width,sizeof(unsigned char)))==NULL){
			printf("\n malloc_picture : Picture structure \n");
			exit(1);
		}
	}
	return pic;

 

이 함수는 width * height 만큼 2차원으로 픽셀의 값을 저장할 수 있는 메모리를 할당해주는 함수입니다.

설명에 앞서 그림으로 먼저 이해하도록 해봅시다.

먼저 첫번째 if문에서는 pic( 파란 부분) 메모리를 생성하는 부분입니다.

마찬가지로, 메모리 생성에 실패했다면 오류메세지를 출력하고 프로그램을 즉시 종료 시킵니다.

두 번째 if문에서는 pic[i] (초록 부분 ) 메모리를 생성합니다.

 

여기서 주의깊게 보셔야 하는 것은

pic[i] 는 각각 unsigned char의 값(0~255)들로 이루어져 있는 배열의 주소인 것.

pic 은 각각 unsigned char * 의 값( pic[0] ~ pic[Height-1] )들로 이루어져 있는 배열의 주소인 것 입니다.

 

그렇다면 raw파일의 실질 데이터 ( pixel값 )은 그림의 초록부분 메모리에 위치하게됩니다.

 

또한, 이 과정을 통해 생성되는 메모리의 크기는

sizeof(unsigned char) * Width * Height + sizeof(unsigned char *) *  Height 가 됩니다.

( sizeof(unsgined char*)의 값은 윈도우 운영체제 32비트기준 -> 4, 64비트 기준 -> 8 입니다.)

 

이 개념을 가지고 코드부분으로 돌아가 이해하도록 합시다.

 

 결과

잘 알려진 Lena.raw파일 (흑백)을 이용해 복사 하도록 하겠습니다.

 

1차원 배열 복사코드 실행 결과

< 1차원 배열 복사코드 실행 전 >
< 1차원 배열 복사코드 실행 >
< 1차원 배열 복사코드 실행 후 >

 

 

2차원 배열 복사코드 실행 결과

< 2차원 배열 복사코드 실행 전 >
< 2차원 배열 복사코드 실행 >
< 2차원 배열 복사코드 실행 후 >

 

원본 raw파일을 새로운 raw파일에 복사 완료 했습니다!

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함