0

我想在 Android 的 arm 程序集中迭代数组数组,但我遇到了 FATAL SIGNAL 错误和应用程序崩溃。

我会展示里面的东西。

首先,我使用 jni 从 java 访问 c 代码:

我声明了本机函数:

public native byte[] BitmapToGrayscale(byte[] bitmap);

之后我通过调用这个函数来调用我的代码:

 private void ConvertImageToGrayscale()
{
    if(image == null)
    {
        GetLenaBack();
        info("Nie było obrazu, ustawiono domyślny.");
    }

    ByteBuffer bb = ByteBuffer.allocate(image.getByteCount());
    image.copyPixelsToBuffer(bb);
    info("Start");
    ByteBuffer result = ByteBuffer.wrap(this.BitmapToGrayscale(bb.array()));
    info("Stop");
    image.copyPixelsFromBuffer(result);
    display.setImageBitmap(image);
}

C 中的函数如下所示:

JNIEXPORT jbyteArray JNICALL Java_pl_marekbar_Main_BitmapToGrayscale
(JNIEnv * env, jobject thisObj, jbyteArray bitmap)
{
    jbyte arraySize = (*env)->GetArrayLength(env, bitmap);
    jbyte *arrayAddress = (*env)->GetByteArrayElements(env, bitmap, 0);
    jbyte cellSize = sizeof((*env)->GetByteArrayElements(env, bitmap, 0));

    Grayscale(arrayAddress, arraySize, cellSize);
    return bitmap;
}

最后这是我的 asm 代码:

@ This file is jni/Grayscale.s
    .text
    .align  2
    .global Grayscale
    .type   Grayscale, %function
Grayscale:
@Convert to grayscale
    stmfd   sp!, {fp,ip,lr}
@r0 - pointer
@r1 - array length
@r2 - array element size
    mov r3, #0 @current element
array_loop:
    ldr r4, [r0] @load element to memory


    str r4, [r0] @store element in memory
    add r0, r0, r4 @move pointer
    add r3, r3, #1 @increment index

    cmp r3, r1 @compare current index with array length
    bne array_loop @when index smaller than array length still iterate


    ldmfd   sp!, {fp,ip,lr}
    bx  lr
    .size   Grayscale, .-Grayscale

我需要了解如何正确处理从 arm asm 中的 c 代码传递的数组。我不想在 C 中执行此操作,因为我正在为图像处理准备应用程序并且必须快速。

4

1 回答 1

2

您的arraySize和组合cellSize看起来不正确:

jbyte arraySize = (*env)->GetArrayLength(env, bitmap);
jbyte cellSize = sizeof((*env)->GetByteArrayElements(env, bitmap, 0));
  1. Ajbyte是一个int8_t(即有符号的 8 位类型)。因此arraySize可能无法保持数组的实际长度,除非您的图像非常小。

  2. 您正在设置cellSizea 的大小,jbyte*很可能是 4 个字节。这恰好对应于 32 位 ARGB 像素的大小,但它仍然不是确定每个像素大小的正确方法。该信息应该作为另一个参数从 Java 代码传递到 C 代码。

  3. 由于您的汇编代码迭代arraySize次数,它会尝试读取arraySize字(即arraySize * 4字节)。但是您的数组仅包含arraySize bytes


您在汇编代码中为数组指针使用了错误的增量:

ldr r4, [r0] @load element to memory
add r0, r0, r4 @move pointer

您添加到指针的是您刚刚从数组中读取的像素数据。就像@Masta79 评论的那样,您可能想要的是将r2(元素大小)添加到指针。

于 2013-11-11T16:04:11.273 回答