Какой эффективный способ преобразовать массив unsigned char в его аналог unsigned short? - PullRequest
0 голосов
/ 13 июня 2011

Какой эффективный способ преобразовать массив "unsigned char" в его аналог "unsigned short"?Для этого я обычно использую следующий фрагмент кода.

#define CH_LINE_PIXELS       2291
#define SCANLINE_SIZE        57301
#define CH1_INDEX            2297
#define CH2_INDEX            4592
#define CH3_INDEX            6887
#define CH4_INDEX            9182

unsigned char* pUChar = new unsigned char[SCANLINE_SIZE];

unsigned short *pUS1, *pUS2, *pUS3, *pUS4;
pUS1 = reinterpret_cast<unsigned short *>(&pUChar[CH1_INDEX]);
pUS2 = reinterpret_cast<unsigned short *>(&pUChar[CH2_INDEX]);
pUS3 = reinterpret_cast<unsigned short *>(&pUChar[CH3_INDEX]);
pUS4 = reinterpret_cast<unsigned short *>(&pUChar[CH4_INDEX]);

unsigned short us1, us2;

for (unsigned int i = 0; i < CH_LINE_PIXELS; i++) 
{   
    us1 = pUChar[CH1_INDEX + 2 * i];
    us2 = pUChar[CH1_INDEX + 2 * x + 1];
    pUS1[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH2_INDEX + 2 * i];
    us2 = pUChar[CH2_INDEX + 2 * i + 1];
    pUS2[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH3_INDEX + 2 * i];
    us2 = pUChar[CH3_INDEX + 2 * i + 1];
    pUS3[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH4_INDEX + 2 * i];
    us2 = pUChar[CH4_INDEX + 2 * i + 1];
    pUS4[x] = us1 * 0x100 + us2;
}

Ответы [ 2 ]

0 голосов
/ 13 июня 2011

Ну, во-первых, вы должны сделать:

us1 << 8 + us2 вместо умножения на 0x100, потому что вы хотите переместить первые 8 бит в верхние позиции, и сдвиг быстрее, чем умножение.

Например, у вас есть us1 = aaaaaaaa (8 бит) и us2 = bbbbbbbb (еще 8 бит).Расширение этих символов до шорт будет просто дополнением их 8 нулями слева.

Тогда приведенная выше формула даст вам:

00000000aaaaaaaa
<< 8
aaaaaaaa00000000
+ 00000000bbbbbbbb
aaaaaaaabbbbbbbb

С другой стороны, вам следует выделить новый массив шорт для ваших результатов.

0 голосов
/ 13 июня 2011

Адресация short на границе байта может (или не может) вызывать проблемы с выравниванием, в зависимости от платформы.

Кроме того, умножение очень неэффективно, почему бы вместо этого не использовать сдвиг?(некоторые компиляторы могут оптимизировать x * 0x100, но если они этого не делают - это огромный удар по производительности, когда все, что вам нужно, это просто x << 8 ...)

Кроме того, как отмечалось, reinterpret_cast может неработать так, как вы ожидаете.

Я бы посоветовал, поскольку вы все равно выполняете присваивания, копировать значения из массива char в отдельный массив short.Это стоит немного памяти, но избавит вас от неприятностей с неожиданными сбоями и чем-то еще.

...