Мои короткие указатели без знака возвращают неожиданные результаты. Зачем? - PullRequest
3 голосов
/ 02 февраля 2011

Я пишу на C для OSX, работаю на 64-битной машине в 32-битном режиме.Я собираю с использованием GCC для 386. Проект большой;Я не видел какого-либо странного поведения от компилятора (возможно, до сих пор). Приложение является многопоточным, и этот код должен быть, но в настоящее время выполняется однопоточным.Я компилирую, используя независимый от позиции clib, и использую потоки posix, когда создаю потокЭтот код, между прочим, действует точно так же, если я делаю заправляем его.

Ниже приведена упрощенная процедура, которая демонстрирует проблему в простейшей форме.По сути, я перемещаю 16-битные каналы изображения из одного набора из трех каналов RGB (mr, mg, mb) в другой набор из 3 каналов RGB (lr, lg, lb) точно такого же размера.Фрагмент, который я собираюсь записать, работает отлично:

void lrip_me(   unsigned short *mr, // RIP from source image
                unsigned short *mg,
                unsigned short *mb,
                unsigned short *lr, // into RGB layer
                unsigned short *lg,
                unsigned short *lb,
                struct layer *lay,
                long start,long finish)
{
long xw,yw;
long xf,yf;
long x,y;
unsigned long offset;

    xw = lay->parent->x;
    yw = lay->parent->y;
    xf = xw - 1;
    yf = yw - 1;

    for (y=start; y<finish; y++)
    {
        for (x=0; x<xw; x++)
        {
            offset = (y * xw) + x;
            if (x==0 || x==xf || y==0 || y==yf) // then on edge
            {
                lr[offset] = mr[offset];
                lg[offset] = mg[offset];
                lb[offset] = mb[offset];
            }
            else
            {
                lr[offset] = mr[offset];
                lg[offset] = mg[offset];
                lb[offset] = mb[offset];
            }
        }
    }
}

Как видите, действие на краю изображения и на его краях одинаково;Я просто перемещаю данные.И это работает - на выходе это изображение в каналах lr, lg и lb.

НО.Если внутри предложения else я поменяю строки следующим образом: *

            lr[offset] = mr[offset-xw];
            lg[offset] = mg[offset-xw];
            lb[offset] = mb[offset-xw];

... вы ожидаете, что внутренняя часть изображения переместится на одну строку сканирования, так как будут получены выборки данныхот расстояния полного сканирования линии, но иду к неизменной цели.Вместо этого вывод выглядит совершенно случайным.Как будто шорты были загружены на неправильных границах, возможно, или откуда-то еще.Это делает то же самое ...

            lr[offset] = mr[offset-1];
            lg[offset] = mg[offset-1];
            lb[offset] = mb[offset-1];

... там, я ожидаю, что изображение будет перемещаться на один пиксель по горизонтали.Нет. Тот же результат - самый чистый хэш.

Я попытался перейти к математике указателя вместо массивов // * (mr + offset-1) // и получить точно такой же результат.Я скомпилировал его в библиотеке и в среде objc.Я попытался использовать даже смещение, думая, что, возможно, компилятор смущен размером данных.Я получаю одинаковые результаты каждый раз.Значение смещения можно использовать как есть, но ТОЛЬКО как есть.Он не может быть изменен внутри скобок, и, кроме того, он не может быть изменен вне скобок, просто рассматривается как длинный.

Я понятия не имею, что здесь происходит.Я, безусловно, был бы признателен, если бы кто-нибудь помог мне понять, что это такое.

Немного предыстории;это операция RIP (удаление изолированного пикселя), или, по крайней мере, так будет, если я смогу получить 8 пикселей, окружающих тот, на который в данный момент смотрит цикл.Вот почему края обрабатываются по-разному;Я не хочу запускать 8-пиксельный обход по краям, только внутри них, где у меня всегда будет все 8, чтобы посмотреть:

ooo
oxo
ooo

В этом тестовом примере я удалил всекод RIP, поскольку он добавляет много сложности и не проливает свет на проблему.Это просто (ха-ха!) Ситуация, когда смещения массива и указателя, кажется, не работают разумно.

1 Ответ

1 голос
/ 02 февраля 2011

Ваша индексная функция предполагает, что двумерные массивы находятся в мажорном порядке строк .

offset = (y * xw) + x;

Возможно, они в мажорном порядке столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...