그릇된 인간의 그릇된 공간 http://dishdev.me/

닷넷에선 비트맵을 로우레벨 수준에서 건들기 위한 BitmapData 객체를 제공하고 있다.

실제로 비트맵은 메모리에 일직선으로 쭉 늘어서있고

BitmapData 객체에 이 비트맵의 첫 부분 주소와 비트맵의 너비, 높이가 들어있다.

너비, 높이 외에 Stride라는 값도 있는데

이는 수평 한 줄이 얼마만큼의 메모리를 차지하느냐는 값이다.

그러니까 24비트 비트맵의 경우 한 픽셀 크기가 3바이트이므로

Stride는 너비 * 3이 된다.

...라고 알고 있었다!

마비노기 봇 좀 만들어본다고 장난질하고 있는데

스샷을 찍어서 비트맵으로 이미지를 보는데 이상하게 원하는 결과가 안 나온다.

한참 삽질하다가 비트맵의 앞부분은 대충 맞는데 뒤로 갈수록 안 맞게 되는 걸 발견,

혹시 이건가~하고 당연히 같을 것이라 생각하고 있었던 두 값을 실제로 조사해보고는 충격을 받았다.

(너비 * 픽셀크기)와

(Stride)가

달랐다.

이 뭥미-_-;

검색해보다가 나온 메모리상의 비트맵 구조이다.

원문은 여기!

보면 Stride가 있고 너비 * 픽셀크기가 있는데 둘이 일치하지 않는다!

뒤에 unused space가 붙어있기 때문이다.

... 뭐야 이거 쓰지도 않는데 왜 있는 거야!?

날 엿먹이기 위해 우주가 창조될 때부터 존재했던 것인가??

대충 보니까 효율성을 위해 Stride는 4의 배수로 하기로 결정되어 있으므로

너비 * 픽셀크기가 4의 배수가 안 되는 경우 unused space를 몇 개 넣어 4의 배수로 만든다는 것.

정리하면, 너비 * 픽셀크기 + unused space(0~3개) = Stride 크기(4의 배수)

비트맵에서 주소 참조는 굉장히 여러번 일어나니까 Stride를 4의 배수로 해두면

인덱스 참조할 때 곱셈 연산 같은 걸 어떻게 최적화해서 되는 게 있나보다?

...라지만 정확한 이유는 찾지 못했다.

옛날에 그래픽스 과제할 때 bmp 파일을 바이트 수준에서 직접 쓴 적이 있는데

특정 크기에서 픽셀이 조금씩 밀리는 현상이 있었는데 그것도 이 문제였나보다 -_-;

너비가 4의 배수인 경우는 운 좋게 문제가 발생 안 했던 거고.

(구조 그림 만든 사람이 급하게 만들었는지 unsed라든지 picxel이라든지 오타가 막 보인다 ㅋ)

  1. 2009.01.09 Modify Delete Reply # 보통 byte alignment 때문. 보통 32bit(또는 64bit) 단위로 어드레싱 해서 패치하기 땜시 3byte씩 쓰면 당장 두번째 픽셀에 접근할때 2번 패치 해야되는 엿이 발생해서
    Dish 2009.01.09 Modify Delete # ㅇㅇ 아키텍쳐와 관련된 거였군. 최종식 맞지?
  2. Ntopia 2009.01.09 Modify Delete Reply # 아... align 의 편의를 위해서 저렇게 하는건가
    오오 신기
    Dish 2009.01.09 Modify Delete # 사춘기 소년 엔토피아다
  3. 샴푸 2009.01.09 Modify Delete Reply # 항상 느끼는거지만 컴퓨터쪽에 모든 규칙, 규격 등은 대충 만든건 없다는 거,,
    api 함수들보면 발로 만든것도 보이지만.

    bitmap이 저렇게 구성되기때문에 스테가노그래피에 이용하기도 좋은거군. 좋은걸 알았셈.
    RFC에도 이유는 안써있고, 비워두라고만 되있네.
    일반적으로 구조체에 패딩을 하는 이유는 이기종간 전송문제를 해결하기 위함이라고 하고,
    속도를 따지면 위에 ㅁ 님이 말한게 훨씬효율이 좋겠는데 (eax라 해봐야 4바이트니까.)
    왜 bmp가 정의된 옛날 시절부터 공간보다 속도를 중시하며 정의했을까는 의문이네.
    Dish 2009.01.10 Modify Delete # 공간 비용이 상대적으로 작은 거라 그런 거 아닐까.
    비트맵 데이타는 크고 훌륭하니 (...)
  4. rein 2009.01.14 Modify Delete Reply # 이거야 메모리 페치가 꽤나 부담될 때 만든거니까. (지금이라고 부담안되는건 아니지만(...))

    예전에 저거 고려해서 짤 때는 한 줄(row)에 들어갈 메모리를 모드 연산(%연산자) 안쓰고 계산하고 그러는 코드 짰는데 /먼산
    Dish 2009.01.15 Modify Delete # 이제 점점 성능 위주의 개발보단 프로그래머 위주의 개발로 (?) ...