요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
==========================
Understanding fbdev's cmap
==========================
These notes explain how X's dix layer uses fbdev's cmap structures.
- example of relevant structures in fbdev as used for a 3-bit grayscale cmap::
struct fb_var_screeninfo {
.bits_per_pixel = 8,
.grayscale = 1,
.red = { 4, 3, 0 },
.green = { 0, 0, 0 },
.blue = { 0, 0, 0 },
}
struct fb_fix_screeninfo {
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
}
for (i = 0; i < 8; i++)
info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
- X11 apps do something like the following when trying to use grayscale::
for (i=0; i < 8; i++) {
char colorspec[64];
memset(colorspec,0,64);
sprintf(colorspec, "rgb:%x/%x/%x", i*36,i*36,i*36);
if (!XParseColor(outputDisplay, testColormap, colorspec, &wantedColor))
printf("Can't get color %s\n",colorspec);
XAllocColor(outputDisplay, testColormap, &wantedColor);
grays[i] = wantedColor;
}
There's also named equivalents like gray1..x provided you have an rgb.txt.
Somewhere in X's callchain, this results in a call to X code that handles the
colormap. For example, Xfbdev hits the following:
xc-011010/programs/Xserver/dix/colormap.c::
FindBestPixel(pentFirst, size, prgb, channel)
dr = (long) pent->co.local.red - prgb->red;
dg = (long) pent->co.local.green - prgb->green;
db = (long) pent->co.local.blue - prgb->blue;
sq = dr * dr;
UnsignedToBigNum (sq, &sum);
BigNumAdd (&sum, &temp, &sum);
co.local.red are entries that were brought in through FBIOGETCMAP which come
directly from the info->cmap.red that was listed above. The prgb is the rgb
that the app wants to match to. The above code is doing what looks like a least
squares matching function. That's why the cmap entries can't be set to the left
hand side boundaries of a color range.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
3-bit grayscale fbdev cmap 구성
1-23이 note는 X의 DIX(Device Independent X) layer가 fbdev의 cmap structure를 사용하는 방식을 설명합니다.
예제 `fb_var_screeninfo`는 8 bits per pixel에서 `grayscale=1`을 사용하고 red bitfield를 `{ offset=4, length=3, msb_right=0 }`으로 둡니다. `fb_fix_screeninfo.visual`은 `FB_VISUAL_STATIC_PSEUDOCOLOR`입니다.
8개 grayscale entry는 `(((2*i)+1)*(0xFFFF))/16`으로 red channel의 각 구간 중앙값에 배치하고, 같은 값을 green과 blue cmap으로 복사합니다.
==========================
Understanding fbdev's cmap
==========================
These notes explain how X's dix layer uses fbdev's cmap structures.
- example of relevant structures in fbdev as used for a 3-bit grayscale cmap::
struct fb_var_screeninfo {
.bits_per_pixel = 8,
.grayscale = 1,
.red = { 4, 3, 0 },
.green = { 0, 0, 0 },
.blue = { 0, 0, 0 },
}
struct fb_fix_screeninfo {
.visual = FB_VISUAL_STATIC_PSEUDOCOLOR,
}
for (i = 0; i < 8; i++)
info->cmap.red[i] = (((2*i)+1)*(0xFFFF))/16;
memcpy(info->cmap.green, info->cmap.red, sizeof(u16)*8);
memcpy(info->cmap.blue, info->cmap.red, sizeof(u16)*8);
X11 application의 grayscale 요청
24-37X11 application은 8개 grayscale color specification을 만들고 `XParseColor()`로 parsing한 뒤 `XAllocColor()`로 colormap entry를 할당합니다. 예제의 `rgb:%x/%x/%x`는 red, green, blue를 같은 값으로 요청합니다.
`rgb.txt`가 있으면 `gray1`부터 이어지는 이름 기반 equivalent도 사용할 수 있습니다.
Application이 문자열 color를 pixel entry로 배정받는 과정입니다.
- X11 apps do something like the following when trying to use grayscale::
for (i=0; i < 8; i++) {
char colorspec[64];
memset(colorspec,0,64);
sprintf(colorspec, "rgb:%x/%x/%x", i*36,i*36,i*36);
if (!XParseColor(outputDisplay, testColormap, colorspec, &wantedColor))
printf("Can't get color %s\n",colorspec);
XAllocColor(outputDisplay, testColormap, &wantedColor);
grays[i] = wantedColor;
}
There's also named equivalents like gray1..x provided you have an rgb.txt.
DIX colormap의 least squares matching
38-56X call chain의 colormap 처리에서 Xfbdev는 `xc-011010/programs/Xserver/dix/colormap.c`의 `FindBestPixel(pentFirst, size, prgb, channel)`에 도달합니다.
`co.local.red`, `green`, `blue`는 `FBIOGETCMAP`을 통해 가져온 값으로, 앞서 설정한 `info->cmap.red` 등의 entry에서 직접 옵니다. `prgb`는 application이 맞추려는 RGB 값입니다.
Code는 각 channel 차이 `dr`, `dg`, `db`를 구하고 제곱합을 누적해 가장 가까운 color를 찾는 least squares matching으로 보입니다. 이 때문에 cmap entry를 color range의 왼쪽 경계값에 둘 수 없고 각 구간을 대표하는 중앙값이 필요합니다.
요청 RGB와 cmap entry의 제곱 거리를 비교합니다.
Somewhere in X's callchain, this results in a call to X code that handles the
colormap. For example, Xfbdev hits the following:
xc-011010/programs/Xserver/dix/colormap.c::
FindBestPixel(pentFirst, size, prgb, channel)
dr = (long) pent->co.local.red - prgb->red;
dg = (long) pent->co.local.green - prgb->green;
db = (long) pent->co.local.blue - prgb->blue;
sq = dr * dr;
UnsignedToBigNum (sq, &sum);
BigNumAdd (&sum, &temp, &sum);
co.local.red are entries that were brought in through FBIOGETCMAP which come
directly from the info->cmap.red that was listed above. The prgb is the rgb
that the app wants to match to. The above code is doing what looks like a least
squares matching function. That's why the cmap entries can't be set to the left
hand side boundaries of a color range.
요약·해설
cmap_xfbdev.rst:1-56Xfbdev는 `FBIOGETCMAP`으로 받은 fbdev cmap entry와 application이 요청한 RGB 사이의 제곱 거리를 계산해 가장 가까운 pixel을 선택합니다. 따라서 grayscale entry는 구간 경계가 아니라 대표 중앙값에 놓아야 합니다.
Kernel cmap에서 X11 pixel 선택까지의 경로입니다.