1

Gingerbread (Android 2.3) をサポートして、Jelly Bean (Android 4.2+) にあるギャラリー アプリから画像フィルターを自分のアプリに移植しようとしています。JNI NDK ソースからフィルターを抽出し、アプリに移植することができました。Android 4.2 (Galaxy Nexus) と Android 4.1 (Nexus S) では正常に動作しますが、signal 11 (SIGSEGV)Android 2.3 (HTC Wildfire S) で試してみると、セグメンテーション エラーでクラッシュします。

ソース ファイルは次のようになります。

void JNIFUNCF(ImageFilterFx, nativeApplyFilter, jobject bitmap, jint width, jint height, jobject lutbitmap,jint lutwidth, jint lutheight )
{
    char* destination = 0;
    char* lut = 0;
    AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
    AndroidBitmap_lockPixels(env, lutbitmap, (void**) &lut);

    unsigned char * rgb = (unsigned char * )destination;
    unsigned char * lutrgb = (unsigned char * )lut;

    int lutdim_r   = lutheight;
    int lutdim_g   = lutheight;;
    int lutdim_b   = lutwidth/lutheight;;
    int STEP = 4;

    int off[8] =  {
        0,
        STEP*1,
        STEP*lutdim_r,
        STEP*(lutdim_r + 1),
        STEP*(lutdim_r*lutdim_b),
        STEP*(lutdim_r*lutdim_b+1),
        STEP*(lutdim_r*lutdim_b+lutdim_r),
        STEP*(lutdim_r*lutdim_b+lutdim_r + 1)
    };

    float scale_R = (lutdim_r-1.f)/256.f;
    float scale_G = (lutdim_g-1.f)/256.f;
    float scale_B = (lutdim_b-1.f)/256.f;

    int i;
    int len = width * height * STEP;

    for (i = 0; i < len; i+=STEP)
    {
        int r = rgb[i];
        int g = rgb[i+1];
        int b = rgb[i+2];

        float fb = b*scale_B;
        float fg = g*scale_G;
        float fr = r*scale_R;

        int lut_b = (int)fb;
        int lut_g = (int)fg;
        int lut_r = (int)fr;

        int p = lut_r+lut_b*lutdim_r+lut_g*lutdim_r*lutdim_b;
        p*=STEP;

        float dr = fr-lut_r;
        float dg = fg-lut_g;
        float db = fb-lut_b;

        rgb[i]   = clamp(interp(lutrgb,p  ,off,dr,dg,db));
        rgb[i+1] = clamp(interp(lutrgb,p+1,off,dr,dg,db));
        rgb[i+2]  = clamp(interp(lutrgb,p+2,off,dr,dg,db));
    }

    AndroidBitmap_unlockPixels(env, bitmap);
    AndroidBitmap_unlockPixels(env, lutbitmap);
}

LogCat に表示されるエラーは次のようになります。

I/DEBUG ( 3973): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 3973): Build fingerprint: 'htc_europe/htc_marvel/marvel:2.3.5/GRJ90/197017.3:user/release-keys'
I/DEBUG ( 3973): pid: 3976, tid: 4026 >>> com.company.app <<<
I/DEBUG ( 3973): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 45918002
I/DEBUG ( 3973): r0 00000000 r1 00111600 r2 ffffff01 r3 00088ff4
I/DEBUG ( 3973): r4 45918000 r5 00000000 r6 3f800000 r7 00000000
I/DEBUG ( 3973): r8 00000000 r9 00000000 10 3f800000 fp 00000002
I/DEBUG ( 3973): ip 00088ff8 sp 45acfa98 lr 80401d20 pc 804017e0 cpsr 20000010
I/DEBUG ( 3973): d0 43755b2443185b24 d1 41cc0000c2ba0000
I/DEBUG ( 3973): d2 41c8000041cc0000 d3 000000003f000000
I/DEBUG ( 3973): d4 0000000000000000 d5 bcb1a62633145c07
I/DEBUG ( 3973): d6 0000000041c80000 d7 0000001941c80000
I/DEBUG ( 3973): d8 0000000000000000 d9 0000000000000000
I/DEBUG ( 3973): d10 0000000000000000 d11 0000000000000000
I/DEBUG ( 3973): d12 0000000000000000 d13 0000000000000000
I/DEBUG ( 3973): d14 0000000000000000 d15 0000000000000000
I/DEBUG ( 3973): scr 60000012
I/DEBUG ( 3973): 
I/DEBUG ( 3973): #00 pc 000017e0 /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/DEBUG ( 3973): #01 pc 00018374 /system/lib/libdvm.so
I/DEBUG ( 3973): #02 pc 0000160c /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/DEBUG ( 3973): 
I/DEBUG ( 3973): code around pc:
I/DEBUG ( 3973): 804017c0 e58da038 e58d1034 e58d2030 e58db05c 
I/DEBUG ( 3973): 804017d0 e58d0060 e58d5024 e1a0c006 ea000157 
I/DEBUG ( 3973): 804017e0 e5d40002 eb0004b4 e59d1054 eb0004dd 
I/DEBUG ( 3973): 804017f0 e1a06000 e5d40001 eb0004af e59d1048 
I/DEBUG ( 3973): 80401800 eb0004d8 e1a0a000 e5d40000 eb0004aa 
I/DEBUG ( 3973): 
I/DEBUG ( 3973): code around lr:
I/DEBUG ( 3973): 80401d00 eb000307 e59d1028 eb000396 e1a01000 
I/DEBUG ( 3973): 80401d10 e1a00009 eb000302 eb000450 eb00002e 
I/DEBUG ( 3973): 80401d20 e59d3020 e59d1050 e5c40002 e283c004 
I/DEBUG ( 3973): 80401d30 e151000c e58dc020 e2844004 da000007 
I/DEBUG ( 3973): 80401d40 e35c0063 cafffea5 e59d105c e59d2060 
I/DEBUG ( 3973): 
I/DEBUG ( 3973): stack:
I/DEBUG ( 3973): 45acfa58 00000000 
I/DEBUG ( 3973): 45acfa5c afd11074 /system/lib/libc.so
I/DEBUG ( 3973): 45acfa60 002d1c18 
I/DEBUG ( 3973): 45acfa64 45acfb04 
I/DEBUG ( 3973): 45acfa68 00000000 
I/DEBUG ( 3973): 45acfa6c 00000100 
I/DEBUG ( 3973): 45acfa70 00000288 
I/DEBUG ( 3973): 45acfa74 203af046 
I/DEBUG ( 3973): 45acfa78 002d1c18 
I/DEBUG ( 3973): 45acfa7c 4588f068 
I/DEBUG ( 3973): 45acfa80 42ac5600 
I/DEBUG ( 3973): 45acfa84 3efe0000 
I/DEBUG ( 3973): 45acfa88 41bf8e90 
I/DEBUG ( 3973): 45acfa8c 80401d5c /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/DEBUG ( 3973): 45acfa90 df002777 
I/DEBUG ( 3973): 45acfa94 e3a070ad 
I/DEBUG ( 3973): #00 45acfa98 00000004 
I/DEBUG ( 3973): 45acfa9c 00000100 
I/DEBUG ( 3973): 45acfaa0 00000010 
I/DEBUG ( 3973): 45acfaa4 45636b66 
I/DEBUG ( 3973): 45acfaa8 0000002e 
I/DEBUG ( 3973): 45acfaac 00000000 
I/DEBUG ( 3973): 45acfab0 00000000 
I/DEBUG ( 3973): 45acfab4 00000000 
I/DEBUG ( 3973): 45acfab8 00088ff8 
I/DEBUG ( 3973): 45acfabc 0031be08 
I/DEBUG ( 3973): 45acfac0 3f800000 
I/DEBUG ( 3973): 45acfac4 0031be08 
I/DEBUG ( 3973): 45acfac8 0031be48 
I/DEBUG ( 3973): 45acfacc 0031be4c 
I/DEBUG ( 3973): 45acfad0 0031c208 
I/DEBUG ( 3973): 45acfad4 0031c20c 
I/DEBUG ( 3973): 45acfad8 0031c248 
I/DEBUG ( 3973): 45acfadc 0031c24c 
I/DEBUG ( 3973): 45acfae0 3d700000 
I/DEBUG ( 3973): 45acfae4 00000010 
I/DEBUG ( 3973): 45acfae8 00111600 
I/DEBUG ( 3973): 45acfaec 3d700000 
I/DEBUG ( 3973): 45acfaf0 002d1bf0 
I/DEBUG ( 3973): 45acfaf4 804043f8 /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/DEBUG ( 3973): 45acfaf8 804044b8 /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/DEBUG ( 3973): 45acfafc 4055d210 
I/DEBUG ( 3973): 45acfb00 4588f008 
I/DEBUG ( 3973): 45acfb04 0031be08 
I/DEBUG ( 3973): 45acfb08 80018540 /system/lib/libdvm.so
I/DEBUG ( 3973): 45acfb0c 45acfb60 
I/DEBUG ( 3973): 45acfb10 00000000 
I/DEBUG ( 3973): 45acfb14 00000000 
I/DEBUG ( 3973): 45acfb18 4429bf60 
I/DEBUG ( 3973): 45acfb1c 45acfb40 
I/DEBUG ( 3973): 45acfb20 4429bf48 
I/DEBUG ( 3973): 45acfb24 4429bf30 
I/DEBUG ( 3973): 45acfb28 4272be40 
I/DEBUG ( 3973): 45acfb2c 80018378 /system/lib/libdvm.so
I/DEBUG ( 3973): #01 45acfb30 00000288 
I/DEBUG ( 3973): 45acfb34 40572b20 
I/DEBUG ( 3973): 45acfb38 00000100 
I/DEBUG ( 3973): 45acfb3c 00000010 
I/DEBUG ( 3973): 45acfb40 4238ac24 
I/DEBUG ( 3973): 45acfb44 0024ce80 
I/DEBUG ( 3973): 45acfb48 00000000 
I/DEBUG ( 3973): 45acfb4c 80401610 /data/data/com.company.app/lib/libjni_filtershow_filters.so
I/ActivityManager( 119): Process com.company.app (pid 3976) has died.
I/WindowManager( 119): WIN DEATH: Window
{4098ae20 com.company.app/com.company.app.activity.MainActivity paused=false}

セグメンテーション違反は行で発生します

int r = rgb[i];

ループの途中のどこか。基本的に、ループはbitmap引数として受け取った をピクセルごとに処理し、入力 を使用してすべてのピクセルに変換を適用しますlutbitmap。432 x 648 ピクセルの画像の場合i = 561144、メモリにアクセスするだけでクラッシュします。小さいビットマップでもチェックしましたが、それでもクラッシュします。

rgb ポインタによってアドレス指定されるメモリは、AndroidBitmap_lockPixels()関数によって割り当てられる必要があります。ただし、アドレスがアクセスされると、セグメンテーション違反が発生します。これは機能の問題ですか、それとも HTC Wildfire S のハードウェアのバグですか? 誰もこのようなものを見たことがありますか?

4

0 に答える 0