'RGBQUAD'에 해당되는 글 2건

  1. 2009.05.19 libjpeg - jmorecfg.h
  2. 2009.03.28 완전 날로먹는 Bitmap 구조분석하기 (6)
/*
 * Ordering of RGB data in scanlines passed to or from the application.
 * If your application wants to deal with data in the order B,G,R, just
 * change these macros.  You can also deal with formats such as R,G,B,X
 * (one extra byte per pixel) by changing RGB_PIXELSIZE.  Note that changing
 * the offsets will also change the order in which colormap data is organized.
 * RESTRICTIONS:
 * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
 * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
 *    useful if you are using JPEG color spaces other than YCbCr or grayscale.
 * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
 *    is not 3 (they don't understand about dummy color components!).  So you
 *    can't use color quantization if you change that value.
 */
#define RGB_RED		0	/* Offset of Red in an RGB scanline element */
#define RGB_GREEN	1	/* Offset of Green */
#define RGB_BLUE	2	/* Offset of Blue */
#define RGB_PIXELSIZE	3	/* JSAMPLEs per RGB scanline element */

libjpeg를 일반적인 표준 Bitmap 파일에 적용하기 위해서는 (혹은 Blit 함수에)
RGBQUADRGBTRIPLE과 동일한 구조로 나오는 것이 좋다.

typedef struct tagRGBQUAD { 
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;

typedef struct tagRGBTRIPLE { 
  BYTE rgbtBlue; 
  BYTE rgbtGreen; 
  BYTE rgbtRed;
} RGBTRIPLE;

이런 이유로 설정값을 바꾸지 않고 그냥 libjpeg를 사용하게 되면,
변환후에 RGB를 일일이 순서를 바꾸어 주어야 한다.

제약사항으로는
sample application인 djpeg cjpeg 는 적용이 되지 않고(어짜피 BGR로 표준 bitmap 포맷으로 나온다..)
YCbCr(YUV) <-> RGB 변환에만 적용이 된다는 것(JPEG가 YUV 아닌게 있던가?)
color quantizer는 RGBTIPLE(24bit)만 적용되지 RGBQUAD(32bit)는 적용되지 않는다.

솔찍히 먼소리인지 모르겠고.. 실질적으로 YUV->RGB 변환만 한다면 무시해도 될 듯하다.
신고
Posted by 구차니

댓글을 달아 주세요

300번째 글 기념(응?)
완전 날로먹는 Bitmap 구조 분석하기 입니다 ^^;
Visual Studio C++ 6.0 프로젝트이며, 헤더만 있다면 다른 플랫폼도 이식 가능할 듯 합니다.


알림 : 네이버 블로그 / 구차니의 잡동사니 모음에서 같은 거 있는데! 라고 하시면..
        동일 인물입니다라고 밖에 답변을 해드릴게 없습니다 -ㅁ-!

typedef struct tagBITMAPFILEHEADER
{
  WORD  bfType;
  DWORD bfSize;
  WORD  bfReserved1;
  WORD  bfReserved2;
  DWORD bfOffBits;
} BITMAPFILEHEADER,  *PBITMAPFILEHEADER;
WORD bfType;          // 위의 첫 바이트 BM 으로 Bitmap 이라는 의미를 지닌 헤더
DWORD bfSize;         // 0x00075736 = 481078 bytes, 파일 전체 크기(헤더 포함한 전체 파일)
WORD bfReserved1;  // 0x0000 으로 사용하지 않는 부분
WORD bfReserved2;  // 0x0000 으로 사용하지 않는 부분
DWORD bfOffBits;      // 현재 위치로부터 실제 데이터가 존재하는 곳 까지의 거리

bfOffBits는 약간의 설명이 필요하다. 일단 256색상 이하의 비트맵은 indexed color 방식으로
팔레트를 이용하게 된다. 팔레트 이후에는 1pixel = 1byte로 연결된 인덱스들이 나열되어 있다.
그런 이유로, 팔레트에 저장된 색상의 갯수가 다르거나, 팔레트를 사용하지 않는다면 이 값은 상당히 다른 값을 보이게 된다.
자세한 내용은 아래의 팔레트를 참고하면 된다.

typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO, *PBITMAPINFO;
256 색 이하의 이미지라면, RGBQUAD는 팔레트로 사용되고,
16bit 이상의 이미지라면 이 내용에 바로 pixel별 색상이 들어간다.

typedef struct tagBITMAPINFOHEADER
{
  DWORD biSize;
  LONG  biWidth;
  LONG  biHeight;
  WORD  biPlanes;
  WORD  biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG  biXPelsPerMeter;
  LONG  biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
} BITMAPINFOHEADER,  *PBITMAPINFOHEADER;
DWORD biSize;                      // BITMAPINFO 헤더의 크기
LONG  biWidth;                      // 이미지의 넓이(화면상에 보이는 크기)
LONG  biHeight;                     // 이미지의 높이(화면상에 보이는 크기)
WORD  biPlanes;                    // 이미지의 장수(bitmap은 layer가 존재하지 않으므로 항상 1)
WORD  biBitCount;                  // 한 픽셀의 컬러 비트수(256컬러는 2^8 이므로 8이 표기됨)
DWORD biCompression;          // 비트맵이 압축이 되었는지 어떠한 방식으로 압축이 되었는지 표시
DWORD biSizeImage;
LONG  biXPelsPerMeter;
LONG  biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;

typedef struct tagRGBQUAD
{
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;

BYTE rgbBlue;            // RGB 중 파랑(Blue)에 대한 값
BYTE rgbGreen;          // RGB 중 녹색(Green)에 대한 값
BYTE rgbRed;             // RGB 중 빨강(Red)에 대한 값
BYTE rgbReserved;     // 사용하지 않음

---------------------------------------------------------------------------------------------------
1.
bitmap은 단순하게, 하나의 pixel에 대한 RGB 정보나 index 정보를 이용하여 이미지를 표시한다.
pixelPicture Element의 약자이며, 우리가 말하는 점 하나를 의미한다.

2.
비트맵은 4사분면을 기준 좌표로 사용하며,
좌상단이 (0.0)이다. 하지만 pc에서는 1사분면을 기준 좌표로 사용하므로 우하단이 (0,0)이다.
그런 이유로, 좌표대로 출력을 하면 비트맵은 상하가 뒤집힌 채로 나오게 된다.
(다르게 말하면, 저장시에 데이터는 상하가 뒤집힌 채로 저장되어 있다)

3.
비트맵은 특정 크기의 데이터를 한번에 전송하기 위해 DMA(Direct Memory Access)나 BLIT(Bit-Block Transfer)를
사용한다. 그런 이유로 특정 블럭을 맞추어 주어야 하고, 그렇기 때문에 이미지는 byte align이나 DWORD align
사용하게 된다(DWORD = 4bytes = 64bit) 이 방법은 몇 비트 이미지냐에 따라 달라지게 되는데,
기본적으로는 4byte align을 맞춰준다.

지루한 계산


4.
256색 미만의 비트맵은 팔레트라는 것을 사용한다. (팔레트는 RGBQUAD 구조체 사용)
이러한 팔레트는 8bit로 표현이 가능하므로, 256가지의 색상을 팔레트로 주로 사용가능하다.
예를 들어

이러한 팔레트를 만들고, 번호만으로 각 픽셀별로 색상을 지정해준다. 그렇다면 상당한 저장 공간을 아낄 수 있다.
그런 이유로, 팔레트를 사용하는 경우에는 팔레트를 Lookup(참조) 하여 변환을 해야하는 작업이 추가되게 된다.

지루한 계산

grayscale의 경우에는 256color RGBQUAD 구조체
팔레트가 없을 경우(jpeg 변환등) for(i=0;i<256;i++) ; 을 이용하여 생성하면 된다.

5.
이유는 모르겠지만, 24bit 비트맵의 경우는 RGBQUAD가 아닌 RGBTRIPLE이라는 구조를 사용한다.

6. 정리를 하자면
1bit - RGBQUAD 팔레트 2개 / 1byte = 8 pixel / 1byte align 4byte align(2009.10.12 windows 그림판 확인)
2bit -
RGBQUAD 팔레트 4개 / 1byte = 4 pixel / 1byte align
4bit - RGBQUAD 팔레트 16개 / 1byte = 2 pixel / 1byte align
8bit - RGBQUAD 팔레트 256개 / 1byte = 1 pixel / 4byte align
16bit - RGBTRIPLE / 2byte = 1 pixel / 4byte align
24bit - RGBTRIPLE / 3byte = 1 pixel / 4byte align (width * 3)을 한뒤 align
32bit - RGBQUAD  / 4byte = 1 pixel / 4byte align 픽셀이 이미 4의 배수이므로 align 안해도 상관없음

 BITMAPFILEINFO
 http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx
 BITMAPINFO  http://msdn.microsoft.com/ko-kr/library/dd183375(en-us,VS.85).aspx
 BITMAPINFOHEADER  http://msdn.microsoft.com/ko-kr/library/dd183376(en-us,VS.85).aspx
 RGBQUAD  http://msdn.microsoft.com/ko-kr/library/dd162938(en-us,VS.85).aspx

 BITMAPCOREINFO  http://msdn.microsoft.com/en-us/library/dd183373(VS.85).aspx
 BITMAPCOREHEADER  http://msdn.microsoft.com/en-us/library/dd183372(VS.85).aspx
 RGBTRIPLE  http://msdn.microsoft.com/en-us/library/dd162939(VS.85).aspx

신고
Posted by 구차니

댓글을 달아 주세요

  1. 오~ 비트맵이다. 매트랩으로 짠거 C로도 짜볼까...

    2010.02.06 13:08 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 독한시키 ㄱ- c언어는 능동으로 배열 하기 힘들어서 힘들텐데? matlab이 배열이 강해서 쓰는데, 머.. matlab c api 쓰면 가능할지도 ㅋ

      2010.02.06 13:09 신고 [ ADDR : EDIT/ DEL ]
  2. 모르는사람

    저기 bfsize가 왜8바이트인가요? 다른데 보면 4바이트로 되어 있어서 질문 드립니다.

    2013.10.24 19:14 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • 음? 0x00000000 면 4바이트 표기 아닌가요? 8바이트는 어디에 있나요?
      소스에 실수했나요? ㅠㅠ

      2013.10.25 09:00 신고 [ ADDR : EDIT/ DEL ]
  3. 모르는사람

    이런 제가 잘못확인한거였군요. 죄송합니다. bfReserved를 확인안하고 거기까지 읽어버렸습니다.

    2013.10.28 11:15 신고 [ ADDR : EDIT/ DEL : REPLY ]