What's an efficient way to convert “unsigned char” array to its “unsigned short” counterpart?
سؤال
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.