What's an efficient way to convert “unsigned char” array to its “unsigned short” counterpart?

StackOverflow https://stackoverflow.com/questions/6328191

  •  27-10-2019
  •  | 
  •  

سؤال

What's an efficient way to convert "unsigned char" array to its "unsigned short" counterpart? I usually use the following code snippet to do so.

#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;
}
هل كانت مفيدة؟

المحلول

Addressing short on byte boundary may (or may not) cause alignment issues, depending on platform.

Also, multiplying is very ineffective, why not use shifting instead? (some compilers may optimize x * 0x100, but if they don't - it's a huge performance hit when all you want is just x << 8...)

Also, as noted, reinterpret_cast may not work as you expect it to.

I would suggest, since you do assignments anyway, to copy values from array of char to a separate array of short. It costs some memory, but will save you oh so much trouble with unexpected crashes and what else.

نصائح أخرى

Well first of all you should do:

us1 << 8 + us2 instead of multiplying by 0x100, because you want to move the first 8 bits in the upper positions, and shifting is faster then multiplication.

E.g. you have us1 = aaaaaaaa (8bits) and us2 = bbbbbbbb (another 8bits). Extending these chars to shorts would be simply padding them with 8 zeroes on the left.

Then the formula above would give you:

00000000aaaaaaaa
<< 8
aaaaaaaa00000000
+ 00000000bbbbbbbb
aaaaaaaabbbbbbbb

On the other hand you should allocate a new array of shorts for your results.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top