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 のハードウェアのバグですか? 誰もこのようなものを見たことがありますか?