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 | #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, |                  int numCB, int max_steps, int *closest_cb, | ||||||
|                   AVLFG *rand_state) |                  AVLFG *rand_state) | ||||||
| { | { | ||||||
|     int i, k; |     int i, k, ret = 0; | ||||||
| 
 | 
 | ||||||
|     if (numpoints > 24*numCB) { |     if (numpoints > 24*numCB) { | ||||||
|         /* ELBG is very costly for a big number of points. So if we have a lot
 |         /* 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       */ |            of them, get a good initial codebook to save on iterations       */ | ||||||
|         int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int)); |         int *temp_points = av_malloc(dim*(numpoints/8)*sizeof(int)); | ||||||
|  |         if (!temp_points) | ||||||
|  |             return AVERROR(ENOMEM); | ||||||
|         for (i=0; i<numpoints/8; i++) { |         for (i=0; i<numpoints/8; i++) { | ||||||
|             k = (i*BIG_PRIME) % numpoints; |             k = (i*BIG_PRIME) % numpoints; | ||||||
|             memcpy(temp_points + i*dim, points + k*dim, dim*sizeof(int)); |             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); |         ret = ff_init_elbg(temp_points, dim, numpoints / 8, codebook, | ||||||
|         ff_do_elbg(temp_points, dim, numpoints/8, codebook, numCB, 2*max_steps, closest_cb, rand_state); |                            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); |         av_free(temp_points); | ||||||
| 
 | 
 | ||||||
|     } else  // If not, initialize the codebook with random positions
 |     } else  // If not, initialize the codebook with random positions
 | ||||||
|         for (i=0; i < numCB; i++) |         for (i=0; i < numCB; i++) | ||||||
|             memcpy(codebook + i*dim, points + ((i*BIG_PRIME)%numpoints)*dim, |             memcpy(codebook + i*dim, points + ((i*BIG_PRIME)%numpoints)*dim, | ||||||
|                    dim*sizeof(int)); |                    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, |                 int numCB, int max_steps, int *closest_cb, | ||||||
|                 AVLFG *rand_state) |                 AVLFG *rand_state) | ||||||
| { | { | ||||||
|     int dist; |     int dist; | ||||||
|     elbg_data elbg_d; |     elbg_data elbg_d; | ||||||
|     elbg_data *elbg = &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 *dist_cb = av_malloc(numpoints*sizeof(int)); | ||||||
|     int *size_part = av_malloc(numCB*sizeof(int)); |     int *size_part = av_malloc(numCB*sizeof(int)); | ||||||
|     cell *list_buffer = av_malloc(numpoints*sizeof(cell)); |     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->utility_inc = av_malloc(numCB*sizeof(int)); | ||||||
|     elbg->scratchbuf = av_malloc(5*dim*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; |     elbg->rand_state = rand_state; | ||||||
| 
 | 
 | ||||||
|     do { |     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) && |     } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) && | ||||||
|             (steps < max_steps)); |             (steps < max_steps)); | ||||||
| 
 | 
 | ||||||
|  | out: | ||||||
|     av_free(dist_cb); |     av_free(dist_cb); | ||||||
|     av_free(size_part); |     av_free(size_part); | ||||||
|     av_free(elbg->utility); |     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->cells); | ||||||
|     av_free(elbg->utility_inc); |     av_free(elbg->utility_inc); | ||||||
|     av_free(elbg->scratchbuf); |     av_free(elbg->scratchbuf); | ||||||
|  |     return ret; | ||||||
| } | } | ||||||
|  | |||||||
| @ -36,10 +36,11 @@ | |||||||
|  * @param num_steps The maximum number of steps. One step is already a good compromise between time and quality. |  * @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 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(). |  * @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, |                int numCB, int num_steps, int *closest_cb, | ||||||
|                 AVLFG *rand_state); |                AVLFG *rand_state); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Initialize the **codebook vector for the elbg algorithm. If you have already |  * Initialize the **codebook vector for the elbg algorithm. If you have already | ||||||
| @ -47,9 +48,10 @@ void ff_do_elbg(int *points, int dim, int numpoints, int *codebook, | |||||||
|  * If numpoints < 8*numCB this function fills **codebook with random numbers. |  * 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 |  * 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. |  * **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, |                  int numCB, int num_steps, int *closest_cb, | ||||||
|                   AVLFG *rand_state); |                  AVLFG *rand_state); | ||||||
| 
 | 
 | ||||||
| #endif /* AVCODEC_ELBG_H */ | #endif /* AVCODEC_ELBG_H */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user