[완료]frame buffer 에서 덤프뜬 16bit raw 를 24bit 로 변환하는 문제
글쓴이: poplinux / 작성시간: 금, 2007/07/06 - 4:14오후
안녕하세요. 16bit frame buffer 에서 덤프뜬 파일을 24bit rgb 로 변환하면 그림은 제대로 나오는데 색이 어둡게 나옵니다.
이 상태에서 포토샵에서 "오토레벨" 한 번 때리면 원색으로 제대로 나오는데 제가 변환할 때 어떤 부분을 잘못했을까요?
다음은 제가 짠 소스입니다.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define WIDTH 320
#define HEIGHT 240
struct RGB{
unsigned char red;
unsigned char green;
unsigned char blue;
} __attribute__ ((packed));
struct BGR{
unsigned char blue;
unsigned char green;
unsigned char red;
} __attribute__ ((packed));
void help(void);
unsigned short int getRED(unsigned short int pixel);
unsigned short int getGREEN(unsigned short int pixel);
unsigned short int getBLUE(unsigned short int pixel);
int main(int argc, char *argv[])
{
int readFD;
int writeFD;
int ret;
int i;
int c16BitSize;
int c24BitSize;
unsigned short int c16BitBuf[WIDTH * HEIGHT];
struct RGB RGB[WIDTH * HEIGHT];
struct BGR BGR[WIDTH * HEIGHT];
if(argc != 3){
help();
exit(-1);
}
fprintf(stdout, "read file open [ %s ]\n", argv[1]);
readFD = open(argv[1], O_RDONLY);
if(readFD < 0){
fprintf(stderr, "16Bit soure file open fail\n");
fprintf(stderr, "check filename\n");
exit(-1);
}
fprintf(stdout, "write file open [ %s ]\n", argv[2]);
writeFD = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
if(writeFD < 0){
fprintf(stderr, "24Bit dest file open fail\n");
fprintf(stderr, "check filename\n");
exit(-1);
}
/* 각 색상수별로 크기 알아내기 */
c16BitSize = sizeof(c16BitBuf);
c24BitSize = sizeof(RGB);
/* 원본 덤프 파일 읽기 */
ret = read(readFD, c16BitBuf, c16BitSize);
if(ret < c16BitSize) {
fprintf(stderr, "16Bit raw file read error\n");
exit(-1);
} else {
fprintf(stdout, "read size %d\n", ret);
}
/* 원본 16bit raw 를 24bit raw 로 확장함 */
for(i=0; i < WIDTH * HEIGHT; i++)
{
RGB[i].red = getRED(c16BitBuf[i]);
RGB[i].green = getGREEN(c16BitBuf[i]);
RGB[i].blue = getBLUE(c16BitBuf[i]);
}
ret = write(writeFD, RGB, sizeof(RGB));
return 0;
}
void help(void)
{
fprintf(stderr, " Ver. 1.0\n\n");
fprintf(stderr, " useage\n");
fprintf(stderr, " 16BitRawTo24BitRaw [16bit Raw file] [24bit Raw file]\n\n");
}
/* 16Bit raw 에서 RED pixel 정보를 추출한다. */
unsigned short int getRED(unsigned short int pixel)
{
return (unsigned short int)pixel >> 11;
}
/* 16Bit raw 에서 GREEN pixel 정보를 추출한다. */
unsigned short int getGREEN(unsigned short int pixel)
{
return (unsigned short int)((pixel & 0x7E0) >> 5);
}
/* 16Bit raw 에서 BLUE pixel 정보를 추출한다. */
unsigned short int getBLUE(unsigned short int pixel)
{
return (unsigned short int)(pixel & 0x1F);
}위 소스에 보면 16bit raw 데이터를 24bit rgb로 바꾸는 부분이 있습니다. 이 부분을 제대로 처리한 게 맞을 까요? 아무래도 색상 정보를 제대로 변환 못해서 화면이
어둡게 나오는 것 같습니다.
다음은 제 보드의 fb 정보 입니다.
=========================================
FRAME BUFFER INFOMATION
=========================================
= Resolution information =
X - resolution : 800
Y - resolution : 480
X - resolution(virtual) : 800
Y - resolution(virtual) : 480
BPP : 16
length of frame buffer memory : 768000
= RGB pixel infomation =
RED info
length : 5
offset : 11
GREEN info
length : 6
offset : 5
BLUE info
length : 5
offset : 0Forums:


스케일을
스케일을 안하셨네요.
예를 들어, blue component 를 얻으면 mask 0x1F 로 하위 5비트 값을 취하므로 최대값 31 입니다. 이것을 최대값 255 가 되게 스케일을 해주셔야됩니다.
다른 컴포넌트도 마찬가지 입니다.
( 이 경우 green 은 6비트가 사용된 565 포맷이므로, 스케일 값이 다르구요. )
Orion Project : http://orionids.org
참고로 16 bit 565 에서
참고로 16 bit 565 에서 24 비트로 스케일할 때 속도를 높이기 위해 비례값을 곱하는대신 다음 테이블을 이용합니다.
red 및 blue component 에 대해
unsigned char table_5_to_8[32] =
{
0, 8, 16, 24, 32, 41, 49, 57,
65, 74, 82, 90, 98, 106, 115, 123,
131, 139, 148, 156, 164, 172, 180, 189,
197, 205, 213, 222, 230, 238, 246, 255,
};
green component 에 대해
unsigned char table_6_to_8[64] =
{
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 44, 48, 52, 56, 60,
64, 68, 72, 76, 80, 85, 89, 93,
97, 101, 105, 109, 113, 117, 121, 125,
129, 133, 137, 141, 145, 149, 153, 157,
161, 165, 170, 174, 178, 182, 186, 190,
194, 198, 202, 206, 210, 214, 218, 222,
226, 230, 234, 238, 242, 246, 250, 255
};
Orion Project : http://orionids.org
앗. 그렇군요.
앗. 그렇군요. 감사합니다. blue 도 red 와 같은 스케일 테이블 사용하면 되는 거지요? ㅎㅎ
========================
조직 : E.L.D(Embedded Linux Developer/Designer)
블로그 : poplinux@tistory.com
카페 : cafe.naver.com/poplinux
임베디드 리눅스 관련 프리렌서 지향
감사합니다. 해결
감사합니다. 해결 되었습니다.
========================
조직 : E.L.D(Embedded Linux Developer/Designer)
블로그 : poplinux@tistory.com
카페 : cafe.naver.com/poplinux
임베디드 리눅스 관련 프리렌서 지향
댓글 달기