elbg: check memory allocations and propagate errors
This commit is contained in:
		
							parent
							
								
									5d839778b9
								
							
						
					
					
						commit
						ae2d41ec87
					
				| @ -323,41 +323,48 @@ static void do_shiftings(elbg_data *elbg) | ||||
| 
 | ||||
| #define BIG_PRIME 433494437LL | ||||
| 
 | ||||
| void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
| int ff_init_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|                  int numCB, int max_steps, int *closest_cb, | ||||
|                  AVLFG *rand_state) | ||||
| { | ||||
|     int i, k; | ||||
|     int i, k, ret = 0; | ||||
| 
 | ||||
|     if (numpoints > 24*numCB) { | ||||
|         /* ELBG is very costly for a big number of points. So if we have a lot
 | ||||
|            of them, get a good initial codebook to save on iterations       */ | ||||
|         int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int)); | ||||
|         if (!temp_points) | ||||
|             return AVERROR(ENOMEM); | ||||
|         for (i=0; i<numpoints/8; i++) { | ||||
|             k = (i*BIG_PRIME) % numpoints; | ||||
|             memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int)); | ||||
|         } | ||||
| 
 | ||||
|         ff_init_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); | ||||
|         ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); | ||||
| 
 | ||||
|         ret = ff_init_elbg(temp_points, dim, numpoints / 8, codebook, | ||||
|                            numCB, 2 * max_steps, closest_cb, rand_state); | ||||
|         if (ret < 0) { | ||||
|             av_freep(&temp_points); | ||||
|             return ret; | ||||
|         } | ||||
|         ret = ff_do_elbg(temp_points, dim, numpoints / 8, codebook, | ||||
|                          numCB, 2 * max_steps, closest_cb, rand_state); | ||||
|         av_free(temp_points); | ||||
| 
 | ||||
|     } else  // If not, initialize the codebook with random positions
 | ||||
|         for (i=0; i < numCB; i++) | ||||
|             memcpy(codebook + i*dim, points + ((i*BIG_PRIME)%numpoints)*dim, | ||||
|                    dim*sizeof(int)); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
| int ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|                 int numCB, int max_steps, int *closest_cb, | ||||
|                 AVLFG *rand_state) | ||||
| { | ||||
|     int dist; | ||||
|     elbg_data elbg_d; | ||||
|     elbg_data *elbg = &elbg_d; | ||||
|     int i, j, k, last_error, steps=0; | ||||
|     int i, j, k, last_error, steps = 0, ret = 0; | ||||
|     int *dist_cb = av_malloc(numpoints*sizeof(int)); | ||||
|     int *size_part = av_malloc(numCB*sizeof(int)); | ||||
|     cell *list_buffer = av_malloc(numpoints*sizeof(cell)); | ||||
| @ -375,6 +382,12 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|     elbg->utility_inc = av_malloc(numCB*sizeof(int)); | ||||
|     elbg->scratchbuf = av_malloc(5*dim*sizeof(int)); | ||||
| 
 | ||||
|     if (!dist_cb || !size_part || !list_buffer || !elbg->cells || | ||||
|         !elbg->utility || !elbg->utility_inc || !elbg->scratchbuf) { | ||||
|         ret = AVERROR(ENOMEM); | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     elbg->rand_state = rand_state; | ||||
| 
 | ||||
|     do { | ||||
| @ -427,6 +440,7 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|     } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) && | ||||
|             (steps < max_steps)); | ||||
| 
 | ||||
| out: | ||||
|     av_free(dist_cb); | ||||
|     av_free(size_part); | ||||
|     av_free(elbg->utility); | ||||
| @ -434,4 +448,5 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|     av_free(elbg->cells); | ||||
|     av_free(elbg->utility_inc); | ||||
|     av_free(elbg->scratchbuf); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| @ -36,8 +36,9 @@ | ||||
|  * @param num_steps The maximum number of steps. One step is already a good compromise between time and quality. | ||||
|  * @param closest_cb Return the closest codebook to each point. Must be allocated. | ||||
|  * @param rand_state A random number generator state. Should be already initialized by av_lfg_init(). | ||||
|  * @return < 0 in case of error, 0 otherwise | ||||
|  */ | ||||
| void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
| int ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|                int numCB, int num_steps, int *closest_cb, | ||||
|                AVLFG *rand_state); | ||||
| 
 | ||||
| @ -47,8 +48,9 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|  * If numpoints < 8*numCB this function fills **codebook with random numbers. | ||||
|  * If not, it calls ff_do_elbg for a (smaller) random sample of the points in | ||||
|  * **points. Get the same parameters as ff_do_elbg. | ||||
|  * @return < 0 in case of error, 0 otherwise | ||||
|  */ | ||||
| void ff_init_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
| int ff_init_elbg(int *points, int dim, int numpoints, int *codebook, | ||||
|                  int numCB, int num_steps, int *closest_cb, | ||||
|                  AVLFG *rand_state); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user