2013-08-06 21 views
5

Sto provando a utilizzare un codice nativo per creare Gif. Disegno le immagini usando la pittura, creando alcuni tratti, facendo clic su Salva e l'immagine disegnata viene salvata in un formato JPG. quando faccio clic su crea Gif, prende tutte le immagini e inizia a creare una gif. Questo è quando ricevo un Fatal Signal 11 e l'app si riavvia.Gifflen Fatal Signal 11

utilizzare codice nativo quindi ho un backtrace dello schianto:

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 

Il codice in cui si blocca:

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 al registro ho scoperto che l'errore accade in NeuQuant :: learn(), ha eseguito alcuni debug e si blocca su questa riga esatta b = (((p)) & 0xff) < < netbiasshift ;.

The Crash non accade sempre, a volte ho un gif e tutto funziona, ma a volte si blocca in b = (((* p)) & 0xFF) < < netbiasshift ;.

Ho eseguito un altro debug e ho scoperto che quando si blocca su b = (((p)) & 0xff) < < netbiasshift; non si blocca quando entra la prima volta, si blocca come dopo il controllo 30 di b = (((p)) & 0xff) < < netbiasshift ;.

Qualcuno sa quale potrebbe essere il problema?

+0

Probabilmente 'p' diventa un riferimento non valido, causando un errore di segmentazione a causa dell'aritmetica del puntatore. – auselen

+0

Come posso risolvere questo problema? C'è un modo per controllare "p" e se stop non valido o qualcosa del genere? –

risposta

4

ho cambiato:

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

a:

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

e sembra a lavorare adesso.

+0

Questo approccio non è corretto. Ingrandisce le dimensioni dell'output GIF al 30%. Trovo un'altra buona soluzione. Copio solo il corpo del metodo 'learn()' dall'originale [NeuQuant algorythm] (http://members.ozemail.com.au/~dekker/NEUQUANT.C) e incollo in gifflen 'NeuQuant :: learn()' – danik

+0

Ho appena fatto dei test con il codice che hai compilato e il codice sopra. Non vedo differenze nelle dimensioni del GIF. Il GIF più piccolo è di circa 1000 KB, il più grande di circa 2500 KB in entrambe le situazioni. Ho cercato di disegnare le stesse immagini per i test in modo che la differenza di dimensioni fosse al massimo del 10% superiore/inferiore. –

+0

Sei il mio salvatore. GRAZIE! –