2013-08-06 20 views
5

Próbuję użyć jakiegoś kodu Native do stworzenia GIF-ów. Rysuję obrazy za pomocą farby, tworząc kilka pociągnięć, kliknij przycisk Zapisz, a rysowany obraz zostanie zapisany w formacie JPG. kiedy klikam Utwórz Gif, wykonuje wszystkie obrazy i zaczyna tworzyć GIF. To wtedy dostaję Fatal Signal 11 i aplikacja uruchomi się ponownie.Gifflen Fatal Signal 11

używam kodu macierzystego więc mam ślad o katastrofie:

I/DEBUG(95): backtrace: 
I/DEBUG(95):  #00 pc 00002a04 /lib/libgifflen.so (NeuQuant::learn()+239) 
I/DEBUG(95):  #01 pc 00002b9d /lib/libgifflen.so (NeuQuant::quantise(DIB*, DIB*, int, int, int)+84) 
I/DEBUG(95):  #02 pc 00002d41 lib/libgifflen.so (Java_com_stay_gif_GifEncoder_addFrame+208) 
I/DEBUG(95):  #03 pc 0001deb0 /system/lib/libdvm.so (dvmPlatformInvoke+112) 
I/DEBUG(95):  #04 pc 0004d103 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+394) 
I/DEBUG(95):  #05 pc 0004f21f /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174) 
I/DEBUG(95):  #06 pc 000272e0 /system/lib/libdvm.so 
I/DEBUG(95):  #07 pc 0002bbe8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180) 
I/DEBUG(95):  #08 pc 0005fb37 /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+374) 
I/DEBUG(95):  #09 pc 000670e5 /system/lib/libdvm.so 
I/DEBUG(95):  #10 pc 000272e0 /system/lib/libdvm.so 
I/DEBUG(95):  #11 pc 0002bbe8 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180) 
I/DEBUG(95):  #12 pc 0005f871 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272) 
I/DEBUG(95):  #13 pc 000496f3 /system/lib/libdvm.so 
I/DEBUG(95):  #14 pc 00048581 /system/lib/libandroid_runtime.so 
I/DEBUG(95):  #15 pc 00049637 /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+390) 
I/DEBUG(95):  #16 pc 00000dcf /system/bin/app_process 

Kod gdzie wywala:

void NeuQuant::learn() 
{ 

    int i,j,b,g,r; 
    int radius,rad,alpha,step,delta,samplepixels; 
    //unsigned char *p; 
    int *p; 
    unsigned char *lim; 

    alphadec = 30 + ((samplefac-1)/3); 
    p = (int*)thepicture; 
    lim = thepicture + lengthcount; 
    samplepixels = lengthcount/samplefac; 
    delta = samplepixels/ncycles; 
    alpha = initalpha; 
    radius = initradius; 

    rad = radius >> radiusbiasshift; 
    if (rad <= 1) rad = 0; 
    for (i=0; i<rad; i++) 
      radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad)); 

    //fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad); 
    sprintf(s, "samplepixels = %d, rad = %d, a=%d, ad=%d, d=%d", samplepixels, rad, alpha, alphadec, delta); 
    __android_log_write(ANDROID_LOG_VERBOSE, "gifflen",s); 

    if ((lengthcount%prime1) != 0) step = prime1; 
    else { 
      if ((lengthcount%prime2) !=0) step = prime2; 
      else { 
        if ((lengthcount%prime3) !=0) step = prime3; 
        else step = prime4; 
      } 
    } 

    i = 0; 
    while (i < samplepixels) 
     { 
    /*  b = p[0] << netbiasshift; 
      g = p[1] << netbiasshift; 
      r = p[2] << netbiasshift;*/ 
      b = (((*p)) & 0xff) << netbiasshift; 
      g = (((*p) >> 8) & 0xff) << netbiasshift; 
      r = (((*p) >> 16) & 0xff) << netbiasshift; 
      j = contest(b, g, r); 
      altersingle(alpha,j,b,g,r); //these crashes 
      if (rad) alterneigh(rad,j,b,g,r); // alter neighbours 

      p += step; 
      if (p >= (int *)lim) p -= lengthcount; 

      i++; 
      if (i%delta == 0) 
      { 
       alpha -= alpha/alphadec; 
       radius -= radius/radiusdec; 
       rad = radius >> radiusbiasshift; 
       if (rad <= 1) rad = 0; 
       for (j=0; j<rad; j++) 
        radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad)); 
      } 
     } 

     //sprintf(s, "final alpha = %f", ((float)alpha)/initalpha); 
    // __android_log_write(ANDROID_LOG_VERBOSE, "gifflen",s); 
} 

Thx do dziennika I okazało się, że błąd dzieje się w NeuQuant :: learn(), wykonał kilka debugowań i zawiesił się na tym wierszu b = (((* p)) & 0xff) < < netbiasshift ;.

Crash robi się zdarzyć zawsze, czasami dostaję gif i wszystko działa, ale czasami wywala przy b = (((* p)) & 0xff) < < netbiasshift ;.

miałem trochę więcej debuging i okazało się, że w przypadku awarii na B = (((* p)) & 0xff) < < netbiasshift; nie ulega awarii po wejściu po raz pierwszy, ulega awarii po 30 sprawdzeniu b = (((* p)) & 0xff) < < netbiasshift ;.

Ktoś wie, co może być przyczyną problemu?

+0

Prawdopodobnie 'p' staje się nieprawidłową referencją, prowadzącą do błędu segmentacji z powodu arytmetyki wskaźnika. – auselen

+0

Jak mogę to naprawić? Czy istnieje sposób, aby sprawdzić "p" i czy nieprawidłowe zatrzymać lub coś takiego? –

Odpowiedz

4

zmieniłem:

if (p >= (int *)lim) 
    p -= lengthcount; 

do:

if (p >= (unsigned int *)lim) 
    p = (unsigned int*)thepicture; 

I wydaje się działać teraz.

+0

To podejście nie jest poprawne. Zwiększa rozmiar wyjściowego pliku GIF o 30%. Znajduję inne dobre rozwiązanie. Po prostu kopiuję treść metody 'learn()' z oryginalnego algorytmu [NeuQuant] (http://members.ozemail.com.au/~dekker/NEUQUANT.C) i wklej w gifflen 'NeuQuant :: learn()' – danik

+0

Po prostu wykonałem kilka testów z kodem z formularza i kodem powyżej. Nie widzę różnicy w rozmiarze GIF. Najmniejszy GIF wynosi około 1000 KB, a największy około 2500 KB w obu sytuacjach. Próbowałem narysować te same obrazy dla testów, aby różnica wielkości była o maksymalnie 10% większa/mniejsza. –

+0

Jesteś moim wybawcą. DZIĘKI! –