/************************************************************************* * Function Name: UartRead * Parameters: UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize * * Return: Int32U * * Description: Read received data from UART. * Return number of readied characters * *************************************************************************/ Int32U UartRead(UartNum_t Uart, pInt8U pBuffer, Int32U BufferSize) { Int32U Count; pUartFifo_t pUartFifo; switch(Uart) { case UART_1: pUartFifo = pUart1RxFifo; break; case UART_2: pUartFifo = pUart2RxFifo; break; case UART_3: pUartFifo = pUart3RxFifo; break; default: return(0); } for (Count = 0; Count < BufferSize; ++Count) { ENTR_CRT_SECTION(); if(!FifoPop(pUartFifo,pBuffer+Count)) { EXT_CRT_SECTION(); break; } EXT_CRT_SECTION(); } return(Count); }
int FifoGroupClose(Fifo **group) { int rv = 1; while (1) { Fifo **cgroup = group; char allEmpty = 1; struct timeval tv; int flushed; while (*cgroup) { if (!EMPTY(*cgroup)) { allEmpty = 0; break; } cgroup++; } if (allEmpty) break; tv.tv_sec = 1; tv.tv_usec = 0; flushed = FifoGroupFlushOnce(group, &tv, 1); if (flushed == -1) return -1; if (flushed == 0) break; } while (*group) { while (FifoPop(*group)) { rv = 0; } // free any entries that we were unable to write if ((*group)->Open && close((*group)->fd)==-1) return -1; group++; } return rv; }
uint8_t UartUsbGetChar( Uart_t *obj, uint8_t *data ) { if( IsFifoEmpty( &obj->FifoRx ) == false ) { BoardDisableIrq( ); *data = FifoPop( &obj->FifoRx ); BoardEnableIrq( ); return 0; } return 1; }
uint8_t UartMcuGetChar( Uart_t *obj, uint8_t *data ) { if( IsFifoEmpty( &obj->FifoRx ) == false ) { __disable_irq( ); *data = FifoPop( &obj->FifoRx ); __enable_irq( ); return 0; } return 1; }
/** * @brief VCP_DataTx * CDC received data to be send over USB IN endpoint are managed in * this function. * @param Buf: Buffer of data to be sent * @param Len: Number of data to be sent (in bytes) * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL */ static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len) { if (linecoding.datatype == 7) { APP_Rx_Buffer[APP_Rx_ptr_in] = FifoPop( &FifoTx ) & 0x7F; } else if (linecoding.datatype == 8) { APP_Rx_Buffer[APP_Rx_ptr_in] = FifoPop( &FifoTx ); } APP_Rx_ptr_in++; /* To avoid buffer overflow */ if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; } return USBD_OK; }
/************************************************************************* * Function Name: Uart2Isr * Parameters: none * * Return: none * * Description: UART 2 interrupt routine * *************************************************************************/ void Uart2Isr(void) { Int8U Data; // Recognizing the interrupt event if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)) { USART_ClearFlag(USART2,USART_FLAG_ORE); // Overrun Error Uart2LineEvents.bOE = TRUE; } if(USART_GetFlagStatus(USART2,USART_FLAG_FE)) { USART_ClearFlag(USART2,USART_FLAG_FE); // Framing Error Uart2LineEvents.bFE = TRUE; } if(USART_GetFlagStatus(USART2,USART_FLAG_NE)) { USART_ClearFlag(USART2,USART_FLAG_NE); // Noise Error Uart2LineEvents.bFE = TRUE; } if(USART_GetFlagStatus(USART2,USART_FLAG_PE)) { USART_ClearFlag(USART2,USART_FLAG_PE); // Parity Error Uart2LineEvents.bPE = TRUE; } // Push a new data into the receiver buffer if(USART_GetFlagStatus(USART2,USART_FLAG_RXNE)) { // Push a new data into the receiver buffer if(!FifoPush(pUart2RxFifo,USART_ReceiveData(USART2))) { // the FIFO is full Uart2LineEvents.bOE = TRUE; } } if( USART_GetFlagStatus(USART2,USART_FLAG_TXE) && (USART_GetITStatus (USART2,USART_IT_TXE) == SET)) { if(FifoPop(pUart2TxFifo,&Data)) { USART_SendData(USART2,Data); } else { USART_ITConfig(USART2,USART_IT_TXE ,DISABLE); } } }
uint8_t UartUsbGetChar( Uart_t *obj, uint8_t *data ) { if( UsbMcuIsDeviceConfigured( ) == false ) { return 2; } SetEPRxValid( ENDP3 ); if( IsFifoEmpty( &obj->FifoRx ) == false ) { __disable_irq( ); *data = FifoPop( &obj->FifoRx ); __enable_irq( ); return 0; } return 1; }
void USART1_IRQHandler( void ) { uint8_t data; if( USART_GetITStatus( USART1, USART_IT_TXE ) != RESET ) { //GpioWrite( &LedRed, 0 ); if( IsFifoEmpty( &Uart1.FifoTx ) == false ) { data = FifoPop( &Uart1.FifoTx ); // Write one byte to the transmit data register USART_SendData( USART1, data ); } else { // Disable the USART Transmit interrupt USART_ITConfig( USART1, USART_IT_TXE, DISABLE ); } if( Uart1.IrqNotify != NULL ) { Uart1.IrqNotify( UART_NOTIFY_TX ); } //GpioWrite( &LedRed, 1 ); } if( USART_GetITStatus( USART1, USART_IT_ORE_RX ) != RESET ) { USART_ReceiveData( USART1 ); } if( USART_GetITStatus( USART1, USART_IT_RXNE ) != RESET ) { //UartPrintf( &Uart1, "USART_GetITStatus( USART1, USART_IT_RXNE )\n" ); //GpioWrite( &LedGreen, 0 ); data = USART_ReceiveData( USART1 ); if( IsFifoFull( &Uart1.FifoRx ) == false ) { // Read one byte from the receive data register FifoPush( &Uart1.FifoRx, data ); } if( Uart1.IrqNotify != NULL ) { Uart1.IrqNotify( UART_NOTIFY_RX ); } //GpioWrite( &LedGreen, 1 ); } }
/* ==================================== */ void testmini(uint8_t *SOURCE, int32_t x, int32_t rs, int32_t N, Fifo *FIFO) /* ==================================== */ { int32_t k, y, kk, yy, w; uint8_t valmin; #ifdef REGULARISE for (k = 0; k < 8; k += 2) /* parcourt les voisins en 4-connexite */ { /* pour voir s'il existe un minimum voisin */ y = voisin(x, k, rs, N); /* a un niveau > a celui atteint par x */ if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] > SOURCE[x])) { /* ce n'est plus un minimum */ FifoPush(FIFO, y); UnSet(y, MINI); valmin = SOURCE[y]; while (! FifoVide(FIFO)) /* parcours pour demarquer l'ex minimum */ { w = FifoPop(FIFO); for (kk = 0; kk < 8; kk += 2) { yy = voisin(w, kk, rs, N); if ((yy != -1) && (SOURCE[yy] == valmin) && (IsSet(yy, MINI))) { FifoPush(FIFO, yy); UnSet(yy, MINI); } } /* for kk ... */ } /* while (! FifoVide(FIFO)) */ } /* if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] > SOURCE[x])) */ } /* for k */ #endif for (k = 0; k < 8; k += 2) /* parcourt les voisins en 4-connexite */ { /* pour voir s'il existe un minimum */ y = voisin(x, k, rs, N); /* au niveau atteint par x */ if ((y != -1) && (IsSet(y, MINI)) && (SOURCE[y] == SOURCE[x])) { Set(x, MINI); break; } } /* for k */ } /* testmini() */
static int FifoFlushOnce(Fifo *fifo) { int rv; if (EMPTY(fifo)) return 0; do { struct FifoElem *cur = &HEAD_ELEM(fifo); int written = TryWrite(fifo->fd, cur->DataCur, cur->Remaining); if (written == -1) { return -1; } rv += written; if (written == cur->Remaining) { FifoPop(fifo); continue; } else { cur->DataCur += written; cur->Remaining -= written; } } while (0); return rv; }
void EP1_IN_Callback (void) { UsbPacketTx = 1; UsbTxLength = 0; while( IsFifoEmpty( &UartUsb.FifoTx ) == false ) { UsbTxBuffer[UsbTxLength] = FifoPop( &UartUsb.FifoTx ); UsbTxLength++; } if( UsbTxLength > 0 ) { UsbPacketTx = 0; UserToPMABufferCopy( ( unsigned char* )UsbTxBuffer, ENDP1_TXADDR, UsbTxLength ); SetEPTxCount( ENDP1, UsbTxLength ); SetEPTxValid( ENDP1 ); } }
/* ==================================== */ int32_t lgeoeros3d( struct xvimage *g, struct xvimage *f, int32_t connex, int32_t niter) /* reconstruction de g sous f */ /* g : image marqueur */ /* f : image masque */ /* connex : 6 ou 18 ou 26 */ /* niter : nombre d'iterations (ou -1 pour saturation) */ /* resultat dans g */ /* ==================================== */ #undef F_NAME #define F_NAME "lgeoeros3d" { int32_t nbchang, iter; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t rs = rowsize(g); /* taille ligne */ int32_t cs = colsize(g); /* taille colonne */ int32_t d = depth(g); /* nombre plans */ int32_t n = rs * cs; /* taille plan */ int32_t N = n * d; /* taille image */ uint8_t *G = UCHARDATA(g); /* l'image marqueur */ uint8_t *F = UCHARDATA(f); /* l'image masque */ uint8_t *H; /* image de travail */ uint8_t *temp; uint8_t inf; Fifo * FIFO[2]; if ((rowsize(f) != rs) || (colsize(f) != cs) || (depth(f) != d)) { fprintf(stderr, "%s: incompatible sizes\n", F_NAME); return 0; } FIFO[0] = CreeFifoVide(N); FIFO[1] = CreeFifoVide(N); if ((FIFO[0] == NULL) || (FIFO[1] == NULL)) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } IndicsInit(N); for (x = 0; x < N; x++) /* mise en fifo initiale de tous les points */ { FifoPush(FIFO[1], x); Set(x, 1); } H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"%s : malloc failed for H\n", F_NAME); return(0); } for (x = 0; x < N; x++) /* force G à être >= F */ if (G[x] < F[x]) G[x] = F[x]; if (connex == 26) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k < 26; k += 1) { y = voisin26(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 26; k += 1) { y = voisin26(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else if (connex == 18) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k < 18; k += 1) { y = voisin18(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 18; k += 1) { y = voisin18(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else if (connex == 6) { iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); inf = G[x]; for (k = 0; k <= 10; k += 2) { y = voisin6(x, k, rs, n, N); if ((y != -1) && (G[y] < inf)) inf = G[y]; } /* for k */ inf = mcmax(inf, F[x]); if (G[x] != inf) { /* changement: on enregistre x ainsi que ses voisins */ nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k <= 10; k += 2) { y = voisin6(x, k, rs, n, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = inf; } /* while ! FifoVide */ temp = G; /* echange les roles de G et H */ G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); } else { fprintf(stderr, "%s: bad connexity\n", F_NAME); return 0; } /* remet le resultat dans g si necessaire */ if (G != UCHARDATA(g)) { for (x = 0; x < N; x++) (UCHARDATA(g))[x] = G[x]; free(G); } else free(H); FifoTermine(FIFO[0]); FifoTermine(FIFO[1]); IndicsTermine(); return 1; } // lgeoeros3d(
/* ==================================== */ int32_t lgeodilat( struct xvimage *g, struct xvimage *f, int32_t connex, int32_t niter) /* dilatation geodesique de g sous f */ /* g : image marqueur */ /* f : image masque */ /* connex : 4 ou 8 */ /* niter : nombre d'iterations (ou -1 pour saturation) */ /* resultat dans g */ /* ==================================== */ #undef F_NAME #define F_NAME "lgeodilat" { int32_t nbchang, iter; int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t rs = rowsize(g); /* taille ligne */ int32_t cs = colsize(g); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *G = UCHARDATA(g); /* l'image marqueur */ uint8_t *F = UCHARDATA(f); /* l'image masque */ uint8_t *H; /* image de travail */ uint8_t *temp; uint8_t sup; Fifo * FIFO[2]; int32_t incr_vois; switch (connex) { case 4: incr_vois = 2; break; case 8: incr_vois = 1; break; } /* switch (connex) */ if ((rowsize(f) != rs) || (colsize(f) != cs)) { fprintf(stderr, "%s: incompatible sizes\n", F_NAME); return 0; } if (depth(f) != 1) { fprintf(stderr, "%s: only works for 2d images\n", F_NAME); return 0; } FIFO[0] = CreeFifoVide(N); FIFO[1] = CreeFifoVide(N); if ((FIFO[0] == NULL) || (FIFO[1] == NULL)) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } IndicsInit(N); for (x = 0; x < N; x++) /* mise en fifo initiale de tous les points */ { FifoPush(FIFO[1], x); Set(x, 1); } H = (uint8_t *)calloc(1,N*sizeof(char)); if (H == NULL) { fprintf(stderr,"%s : malloc failed for H\n", F_NAME); return(0); } for (x = 0; x < N; x++) /* force G à être <= F */ if (G[x] > F[x]) G[x] = F[x]; iter = 0; do { iter += 1; nbchang = 0; while (! FifoVide(FIFO[iter % 2])) { x = FifoPop(FIFO[iter % 2]); UnSet(x, iter % 2); sup = G[x]; for (k = 0; k < 8; k += incr_vois) { y = voisin(x, k, rs, N); if ((y != -1) && (G[y] > sup)) sup = G[y]; } /* for k */ sup = mcmin(sup, F[x]); if (G[x] != sup) /* changement: on enregistre x ainsi que ses voisins */ { nbchang += 1; if (! IsSet(x, (iter + 1) % 2)) { FifoPush(FIFO[(iter + 1) % 2], x); Set(x, (iter + 1) % 2); } for (k = 0; k < 8; k += 1) { y = voisin(x, k, rs, N); if ((y != -1) && (! IsSet(y, (iter + 1) % 2))) { FifoPush(FIFO[(iter + 1) % 2], y); Set(y, (iter + 1) % 2); } } /* for k */ } H[x] = sup; } /* while ! FifoVide */ /* echange les roles de G et H */ temp = G; G = H; H = temp; #ifdef VERBOSE printf("iteration %d, nbchang %d\n", iter, nbchang); #endif } while (((niter == -1) || (iter < niter)) && (nbchang != 0)); /* remet le resultat dans g si necessaire */ if (G != UCHARDATA(g)) { for (x = 0; x < N; x++) (UCHARDATA(g))[x] = G[x]; free(G); } else free(H); FifoTermine(FIFO[0]); FifoTermine(FIFO[1]); IndicsTermine(); return 1; } /* lgeodilat() */
/* ==================================== */ int32_t lselectcomp( struct xvimage *f, int32_t connex, int32_t x, int32_t y, int32_t z) /* extrait la composante connexe de f (image binaire) qui contient le point (x,y,z) */ /* connex : 4, 8 (en 2D), 6, 18, 26 (en 3D) */ /* connex : 60, 260 (en 3D): idem 6 et 26 mais dans le plan xy seulement */ /* ==================================== */ #undef F_NAME #define F_NAME "lselectcomp" { int32_t i; /* index muet de pixel */ int32_t j; /* index muet (generalement un voisin de x) */ int32_t k; /* index muet */ int32_t rs = rowsize(f); /* taille ligne */ int32_t cs = colsize(f); /* taille colonne */ int32_t ds = depth(f); /* nb plans */ int32_t ps = rs * cs; /* taille plan */ int32_t N = ps * ds; /* taille image */ uint8_t *F = UCHARDATA(f); Fifo * FIFO; int32_t incr_vois; switch (connex) { case 4: incr_vois = 2; break; case 8: incr_vois = 1; break; } /* switch (connex) */ FIFO = CreeFifoVide(N); if (FIFO == NULL) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } for (i = 0; i < N; i++) if (F[i]) F[i] = 254; i = z*ps + y*rs + x; if (F[i]) { FifoPush(FIFO, i); F[i] += 1; } if ((connex == 4) || (connex == 8)) { if (ds != 1) { fprintf(stderr,"%s : connexity 4 or 8 not defined for 3D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 8; k += incr_vois) { j = voisin(i, k, rs, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 6) { if (ds == 1) { fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k <= 10; k += 2) { j = voisin6(i, k, rs, ps, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 18) { if (ds == 1) { fprintf(stderr,"%s : connexity 18 not defined for 2D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 18; k += 1) { j = voisin18(i, k, rs, ps, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 26) { if (ds == 1) { fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 26; k += 1) { j = voisin26(i, k, rs, ps, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 60) { if (ds == 1) { fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k <= 6; k += 2) { j = voisin6(i, k, rs, ps, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 260) { if (ds == 1) { fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME); return(0); } while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 9; k <= 16; k += 1) { j = voisin26(i, k, rs, ps, N); if ((j != -1) && (F[j]==254)) { FifoPush(FIFO, j); F[j] += 1; } } /* for k */ } /* while ! FifoVide */ } FifoTermine(FIFO); for (i = 0; i < N; i++) if (F[i] != 255) F[i] = 0; return 1; } /* lselectcomp() */
/* ==================================== */ int32_t lamont( struct xvimage *m, struct xvimage *f, int32_t connex, int32_t strict) /* connex : 4, 8 (en 2D), 6, 18, 26 (en 3D) */ /* ==================================== */ #undef F_NAME #define F_NAME "lamont" { int32_t i, j, k; /* index muet de pixel */ int32_t rs = rowsize(f); /* taille ligne */ int32_t cs = colsize(f); /* taille colonne */ int32_t ds = depth(f); /* nb plans */ int32_t ps = rs * cs; /* taille plan */ int32_t N = ps * ds; /* taille image */ int32_t *F = SLONGDATA(f); uint8_t *M = UCHARDATA(m); Fifo * FIFO; int32_t incr_vois; if ((rowsize(m) != rs) || (colsize(m) != cs) || (depth(m) != ds)) { fprintf(stderr, "%s: incompatible sizes\n", F_NAME); return 0; } if ((datatype(m) != VFF_TYP_1_BYTE) || (datatype(f) != VFF_TYP_4_BYTE)) { fprintf(stderr, "%s: incompatible types\n", F_NAME); return 0; } switch (connex) { case 4: incr_vois = 2; break; case 8: incr_vois = 1; break; } /* switch (connex) */ FIFO = CreeFifoVide(N); if (FIFO == NULL) { fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME); return(0); } for (i = 0; i < N; i++) if (M[i]) FifoPush(FIFO, i); if ((connex == 4) || (connex == 8)) { if (ds != 1) { fprintf(stderr,"%s : connexity 4 or 8 not defined for 3D\n", F_NAME); return(0); } if (strict) while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 8; k += incr_vois) { j = voisin(i, k, rs, N); if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ else while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 8; k += incr_vois) { j = voisin(i, k, rs, N); //printf("i=%d ; j=%d ; Mj=%d ; Fj=%ld ; Fi=%ld\n", i, j, M[j], F[j], F[i]); if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 6) { if (ds == 1) { fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME); return(0); } if (strict) while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k <= 10; k += 2) { j = voisin6(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ else while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k <= 10; k += 2) { j = voisin6(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 18) { if (ds == 1) { fprintf(stderr,"%s : connexity 18 not defined for 2D\n", F_NAME); return(0); } if (strict) while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 18; k += 1) { j = voisin18(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ else while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 18; k += 1) { j = voisin18(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ } else if (connex == 26) { if (ds == 1) { fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME); return(0); } if (strict) while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 26; k += 1) { j = voisin26(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ else while (! FifoVide(FIFO)) { i = FifoPop(FIFO); for (k = 0; k < 26; k += 1) { j = voisin26(i, k, rs, ps, N); if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; } } /* for k */ } /* while ! FifoVide */ } FifoTermine(FIFO); return 1; } /* lamont() */
/* ==================================== */ int32_t lsquel(struct xvimage *image, int32_t seuil, int32_t niseuil) /* ==================================== */ { int32_t x; /* index muet de pixel */ int32_t y; /* index muet (generalement un voisin de x) */ int32_t rs = rowsize(image); /* taille ligne */ int32_t cs = colsize(image); /* taille colonne */ int32_t N = rs * cs; /* taille image */ uint8_t *SOURCE = UCHARDATA(image); /* l'image de depart */ struct xvimage *lab; int32_t *M; /* l'image d'etiquettes de composantes connexes */ int32_t nminima; /* nombre de minima differents */ Fifo * FIFOn; Fifo * FIFOs; Fifo * FIFOe; Fifo * FIFOo; Fifo * FIFOna; Fifo * FIFOsa; Fifo * FIFOea; Fifo * FIFOoa; Fifo * FIFOtmp; Fifo * FIFO; int32_t niter; #ifdef PERF chrono chrono1; #endif if (depth(image) != 1) { fprintf(stderr, "lsquel: cette version ne traite pas les images volumiques\n"); exit(0); } #ifdef PERF start_chrono(&chrono1); /* pour l'analyse de performances */ #endif lab = allocimage(NULL, rs, cs, 1, VFF_TYP_4_BYTE); if (lab == NULL) { fprintf(stderr, "lhtkern: allocimage failed\n"); return 0; } M = SLONGDATA(lab); if (!llabelextrema(image, 4, LABMIN, lab, &nminima)) { fprintf(stderr, "lhtkern: llabelextrema failed\n"); return 0; } IndicsInit(N); FIFO = CreeFifoVide(N); FIFOn = CreeFifoVide(N/2); FIFOs = CreeFifoVide(N/2); FIFOe = CreeFifoVide(N/2); FIFOo = CreeFifoVide(N/2); if ((FIFO == NULL) && (FIFOn == NULL) && (FIFOs == NULL) && (FIFOe == NULL) && (FIFOo == NULL)) { fprintf(stderr, "lsquel() : CreeFifoVide failed\n"); return(0); } /* ================================================ */ /* DEBUT ALGO */ /* ================================================ */ /* ========================================================= */ /* INITIALISATION DES FIFOs: empile les voisins des minima */ /* ========================================================= */ for (x = 0; x < N; x++) { if (M[x] != 0) /* le pixel appartient a un minimum */ { Set(x, MINI); y = voisin(x, NORD, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOn, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, NORD+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOn, y); Set(y, EN_FIFO); } #endif y = voisin(x, EST, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOe, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, EST+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOe, y); Set(y, EN_FIFO); } #endif y = voisin(x, SUD, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOs, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, SUD+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOs, y); Set(y, EN_FIFO); } #endif y = voisin(x, OUEST, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOo, y); Set(y, EN_FIFO); } #ifdef DIAG y = voisin(x, OUEST+1, rs, N); if ((y!=-1) && (M[y]==0) && !IsSet(y,EN_FIFO) && nonbord(y,rs,N)) { FifoPush(FIFOo, y); Set(y, EN_FIFO); } #endif } /* if (M[x] != 0) */ } /* for x */ freeimage(lab); FIFOna = CreeFifoVide(N/4); FIFOsa = CreeFifoVide(N/4); FIFOea = CreeFifoVide(N/4); FIFOoa = CreeFifoVide(N/4); if ((FIFOna == NULL) && (FIFOsa == NULL) && (FIFOea == NULL) && (FIFOoa == NULL)) { fprintf(stderr, "lsquel() : CreeFifoVide failed\n"); return(0); } /* ================================================ */ /* DEBUT SATURATION */ /* ================================================ */ niter = 0; while (! (FifoVide(FIFOn) && FifoVide(FIFOe) && FifoVide(FIFOs) && FifoVide(FIFOo))) { niter++; while (! FifoVide(FIFOn)) { x = FifoPop(FIFOn); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOn)) */ while (! FifoVide(FIFOs)) { x = FifoPop(FIFOs); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOs)) */ while (! FifoVide(FIFOe)) { x = FifoPop(FIFOe); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOe)) */ while (! FifoVide(FIFOo)) { x = FifoPop(FIFOo); UnSet(x, EN_FIFO); if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) { /* modifie l'image le cas echeant */ testmini(SOURCE, x, rs, N, FIFO); /* reactualise l'image MINI */ empilevoisins(x, rs, N, FIFOna, FIFOea, FIFOsa, FIFOoa); } /* if (testabaisse(SOURCE, x, rs, N, seuil, niter, niseuil)) */ } /* while (! FifoVide(FIFOo)) */ FIFOtmp = FIFOn; FIFOn = FIFOna; FIFOna = FIFOtmp; FIFOtmp = FIFOe; FIFOe = FIFOea; FIFOea = FIFOtmp; FIFOtmp = FIFOs; FIFOs = FIFOsa; FIFOsa = FIFOtmp; FIFOtmp = FIFOo; FIFOo = FIFOoa; FIFOoa = FIFOtmp; } /* while (! (FifoVide(FIFOn) && FifoVide(FIFOe) && FifoVide(FIFOs) && FifoVide(FIFOo))) */ /* ================================================ */ /* UN PEU DE MENAGE */ /* ================================================ */ IndicsTermine(); FifoTermine(FIFO); FifoTermine(FIFOn); FifoTermine(FIFOe); FifoTermine(FIFOs); FifoTermine(FIFOo); FifoTermine(FIFOna); FifoTermine(FIFOea); FifoTermine(FIFOsa); FifoTermine(FIFOoa); #ifdef PERF save_time(N, read_chrono(&chrono1), "lsquel", image->name); #endif return(1); }