/*
* 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 함수에) RGBQUAD나 RGBTRIPLE과 동일한 구조로 나오는 것이 좋다.
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;
BYTE rgbBlue; // RGB 중 파랑(Blue)에 대한 값
BYTE rgbGreen; // RGB 중 녹색(Green)에 대한 값
BYTE rgbRed; // RGB 중 빨강(Red)에 대한 값
BYTE rgbReserved; // 사용하지 않음
---------------------------------------------------------------------------------------------------
1.
bitmap은 단순하게, 하나의 pixel에 대한 RGB 정보나 index 정보를 이용하여 이미지를 표시한다. pixel은 Picture 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을 맞춰준다.
예를들어 256색 이미지라면, 각각은 1byte로 표시되며, 이미지가 309 x 200 이라고 한다면, 309은 4의 배수가 아니므로
4의 배수가 되어 포함할 수 있는 312 의 width를 사용해야 하고 남는 3pixel은 padding으로 무시하거나 0값을 갖는다.
그리고 24bit의 경우 RGBQUAD가 아닌 RGBTRIPLE을 이용함으로, 309pixel의 width를 지닐경우
927byte를 사용하게 되고, 927을 포함하는 가장 작은 4의 배수는 928 이므로, 1바이트의 padding을 가지게 된다.
4. 256색 미만의 비트맵은 팔레트라는 것을 사용한다. (팔레트는 RGBQUAD 구조체 사용)
이러한 팔레트는 8bit로 표현이 가능하므로, 256가지의 색상을 팔레트로 주로 사용가능하다.
예를 들어
이러한 팔레트를 만들고, 번호만으로 각 픽셀별로 색상을 지정해준다. 그렇다면 상당한 저장 공간을 아낄 수 있다.
그런 이유로, 팔레트를 사용하는 경우에는 팔레트를 Lookup(참조) 하여 변환을 해야하는 작업이 추가되게 된다.
300x200 크기의 이미지를 저장한다고 할 때, 팔레트를 사용하지 않고 RGBQUAD를 이용한다면
sizeof(RGBQUAD) = 4 이고, 이로 인해 60,000개의 픽셀을 각각 4바이트가 필요하게된다.
60,000 * 4 = 240,000 대략 240KB의 용량을 필요로 하게 된다.
하지만 팔레트를 이용하여 256새가지의 색상만을 사용하는 비트맵이라면
256 * 4 = 1024의 용량과 300 * 200 * 1의 용량을 계산하면
60,000 + 1024 = 61,024 대략 62KB의 용량을 필요로 하게 된다.
이러한 이유로 색상수가 적을 경우에는 팔레트를 사용하게 된다.
grayscale의 경우에는 256color RGBQUAD 구조체
팔레트가 없을 경우(jpeg 변환등) for(i=0;i<256;i++) ; 을 이용하여 생성하면 된다.
5.
이유는 모르겠지만, 24bit 비트맵의 경우는 RGBQUAD가 아닌 RGBTRIPLE이라는 구조를 사용한다.