2013-03-27 4 views
1

픽셀의 각 색상 채널에 액세스하기 위해 비트 필드 구조체를 사용합니다. 문제는 꽤 자주 각 채널에 동일한 방식으로 적용되는 코드가 있기 때문에 반복 할 수 없기 때문입니다. CI 구조체의 멤버를 통해 각 멤버에 대해 동일한 코드의 복사본을 3 개 이상 작성하거나 switch-case 문을 더 불편하게 사용해야합니다.구조체 멤버를 반복하는 매크로

.CHAN (i)가 .r, .g 또는 .b가되는 이상적인 매크로를 제공함으로써 회원에게 액세스 할 수 있도록 매크로를 사용할 수 있다면 더 멋지다고 생각했습니다. 정수 변수 i가 0, 1 또는 2를 포함하는지 여부에 따라 달라집니다. 나는 어떻게 그러한 매크로를 만들지, 또는 그것이 가능할지라도 전혀 알지 못합니다.

세부 사항이지만 각 멤버는 예상 할 수있는대로 12 비트가 아닌 8 개이므로 예상치 못한 배열로 만들거나 포인터로 유니온을 만들 수는 없습니다. 또한 X-Macros는 다른 채널에 동일한 작업을 수행하기 전에 각 채널에 많은 작업을 수행해야하기 때문에 필요하지 않습니다. 즉, 각 구성원을 처리하는 for 루프에는 단 한 줄 이상이 포함될 수 있습니다.

편집 : 여기에 몇 가지 코드는 먼저 구조체입니다 : 이제

typedef struct 
{ 
    uint32_t b:12; 
    uint32_t g:12; 
    uint32_t r:12; 
    uint32_t a:12; 
} lrgb_t; 

의 예를 들어 어떤 내 문제는 코드에서 다음과 같습니다 의견에서 지적

for (ic=0; ic<3; ic++) 
{ 
    for (i=0; i<curvecount; i++) 
    { 
     curve[i].p0.x = (double) i; 
     curve[i].p3.x = (double) i+1.; 

     switch (ic)  // this is what I'm trying to eliminate 
     { 
      case 0: 
       curve[i].p0.y = pancol[i].r/4095.; 
       curve[i].p3.y = pancol[i+1].r/4095.; 
       break; 
      case 1: 
       curve[i].p0.y = pancol[i].g/4095.; 
       curve[i].p3.y = pancol[i+1].g/4095.; 
       break; 
      case 2: 
       curve[i].p0.y = pancol[i].b/4095.; 
       curve[i].p3.y = pancol[i+1].b/4095.; 
       break; 
     } 
     // Ideally this would be replaced by something like this, CHAN() being an hypothetical macro 
     // curve[i].p0.y = pancol[i].CHAN(ic)/4095.; 
     // curve[i].p3.y = pancol[i+1].CHAN(ic)/4095.; 
    } 

    ... // more stuff that ultimately results in a bunch of pixels being written, channel after channel 
} 
+5

토론을 좀 더 구체적으로하기 위해 몇 가지 코드를 보여 주시겠습니까? – NPE

답변

2

이 아무튼 구조체의 멤버가 배열과 정렬되지 않는 비트 필드이기 때문에 OP 문제를 해결할 수 없습니다. 나는 여기서 대답을 계속 하겠지만, 그것이 여전히 누군가에게 유용 할 수 있기를 희망한다.

나는 union을 원한다고 생각합니다. 당신은 구조체 플로트 [3]로 메모리에 같은 장소에있을 것 같은

union 
{ 
    struct 
    { 
     float r; 
     float g; 
     float b; 
    }rgb; 
    float channel[3]; 
} color; 

이 방법을 당신의 구조체를 쓸 수 있습니다, 당신은 효과적으로 두 구조체의 멤버로 또는 같은 멤버를 액세스 할 수 있습니다 배열의 요소.

정확한 구문을 찾아야 할 수도 있지만 아이디어를 얻을 수 있습니다.

+0

-1 Union은 모든 구성원에 대해 동일한 메모리를 사용합니다. 전혀 출구가 아닙니다. – Alex

+0

@Alex 내가 의미하는 바를 더 잘 설명하여 업데이트했습니다. – filipe

+0

좋습니다. 제거 된 downvote. – Alex

1

하나의 가능성은 함수에 반복되는 코드를 포장하고 각 채널에 대한 호출 할 수 있습니다 : 매크로 제안 당신은 내가 내 일부 변경을 추가 한 코드를 읽은 후

typedef struct { 
    int r:12; 
    int g:12; 
    int b:12; 
} Pixel; 

int inc(int val) { 
    return val + 1; 
} 

int main(void) { 
    Pixel p = {0, 0, 0}; 
    p.r = inc(p.r); 
    p.g = inc(p.g); 
    p.b = inc(p.b); 
    return 0; 
} 
0

#define CHAN(ic) \ 
(ic == 1) ? curve[i].p0.y = pancol[i].r/4095; curve[i].p3.y = pancol[i+1].r/4095; : \ 
(ic == 2) ? curve[i].p0.y = pancol[i].g/4095; curve[i].p3.y = pancol[i+1].g/4095; : \ 
curve[i].p0.y = pancol[i].b/4095; curve[i].p3.y = pancol[i+1].b/4095; 

매크로 CHAN (ic)은 조작 할 멤버를 결정하기 위해 'ic'을 평가합니다. 'ic'이 1이면 'ic'이 2이면 '.r'이 조작되고 '.g'가 조작되고 'ic'이 1 또는 2가 아닌 경우 '.b'가 조작됩니다. 이 가정에서 'ic'이 적절히 설정되어 있는지 확인해야합니다. 그렇지 않으면 panco [i] .b 및 pancol [i + 1] .b의 값으로 고정 될 수 있습니다. 코드는 다음과 같이 보일 것입니다.하지만 질문이 있으면 매크로를 약간 조정해야합니다.

//#define CHAN(ic) here 

for (ic=0; ic<3; ic++) 
{ 
    for (i=0; i<curvecount; i++) 
    { 
    curve[i].p0.x = (double) i; 
    curve[i].p3.x = (double) i+1.; 
    CHAN(ic) 
    } 
    ... // more stuff that ultimately results in a bunch of pixels being written, channel after channel 
} 

또한 매크로는 스위치 케이스와 똑같을 것입니다. 유일한 차이점은 매크로에서 정의한 점은 스위치 케이스와 매크로의 차이가 순전히 시각적이라는 것입니다.