0

「unsignedchar」配列を「unsignedshort」配列に変換する効率的な方法は何ですか?私は通常、次のコードスニペットを使用してこれを行います。

#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;
}
4

2 に答える 2

0

まず第一に、次のことを行う必要があります。

us1 << 8 + us2最初の8ビットを上位の位置に移動したいので、0x100で乗算する代わりに、シフトは乗算よりも高速です。

たとえば、us1 = aaaaaaaa(8 ビット) とus2 = bbbbbbbb(別の 8 ビット) があります。これらの文字を short に拡張すると、単純に左側に 8 つのゼロがパディングされます。

次に、上記の式は次のようになります。

00000000aaaaaaaa
<< 8
aaaaaaaa00000000
+ 00000000bbbbbbbb
aaaaaaaabbbbbbbb

一方で、結果にはショートの新しい配列を割り当てる必要があります。

于 2011-06-13T08:50:15.817 に答える
-1

プラットフォームによっては、バイト境界でアドレス指定shortすると、アラインメントの問題が発生する場合と発生しない場合があります。

また、乗算は非常に効果的ではありません。代わりにシフトを使用してみませんか? (一部のコンパイラは最適化する x * 0x100場合がありますが、そうでない場合は、必要なだけの場合にパフォーマンスが大幅に低下しますx << 8...)

また、前述のとおり、reinterpret_cast期待どおりに動作しない場合があります。

とにかく割り当てを行うので、配列の値charを の別の配列にコピーすることをお勧めしますshort。いくらかのメモリを消費しますが、予期しないクラッシュなどのトラブルを大幅に軽減します。

于 2011-06-13T08:49:51.997 に答える