mirror of
				https://git.code.sf.net/p/libpng/code.git
				synced 2025-07-10 18:04:09 +02:00 
			
		
		
		
	[libpng17] Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the
compiled library size. It never worked properly and as far as we can tell, no one uses it. The png_set_filter_heuristics() and png_set_filter_heuristics_fixed() APIs are retained but deprecated.
This commit is contained in:
		
							parent
							
								
									f19f7a6c95
								
							
						
					
					
						commit
						13d83c6948
					
				
							
								
								
									
										4
									
								
								ANNOUNCE
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								ANNOUNCE
									
									
									
									
									
								
							| @ -809,6 +809,10 @@ Version 1.7.0beta61 [May 31, 2015] | |||||||
|     pngwutil.c, introduced in libpng-0.95, March 1997. |     pngwutil.c, introduced in libpng-0.95, March 1997. | ||||||
| 
 | 
 | ||||||
| Version 1.7.0beta62 [May 31, 2015] | Version 1.7.0beta62 [May 31, 2015] | ||||||
|  |   Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the | ||||||
|  |     compiled library size. It never worked properly and as far as we can | ||||||
|  |     tell, no one uses it. The png_set_filter_heuristics() and | ||||||
|  |     png_set_filter_heuristics_fixed(). APIs are retained but deprecated. | ||||||
| 
 | 
 | ||||||
| Send comments/corrections/commendations to png-mng-implement at lists.sf.net | Send comments/corrections/commendations to png-mng-implement at lists.sf.net | ||||||
| (subscription required; visit | (subscription required; visit | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							| @ -5104,6 +5104,10 @@ Version 1.7.0beta61 [May 31, 2015] | |||||||
|     pngwutil.c, introduced in libpng-0.95, March 1997. |     pngwutil.c, introduced in libpng-0.95, March 1997. | ||||||
| 
 | 
 | ||||||
| Version 1.7.0beta62 [May 31, 2015] | Version 1.7.0beta62 [May 31, 2015] | ||||||
|  |   Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the | ||||||
|  |     compiled library size. It never worked properly and as far as we can | ||||||
|  |     tell, no one uses it. The png_set_filter_heuristics() and | ||||||
|  |     png_set_filter_heuristics_fixed(). APIs are retained but deprecated. | ||||||
| 
 | 
 | ||||||
| Send comments/corrections/commendations to png-mng-implement at lists.sf.net | Send comments/corrections/commendations to png-mng-implement at lists.sf.net | ||||||
| (subscription required; visit | (subscription required; visit | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								png.h
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								png.h
									
									
									
									
									
								
							| @ -1747,46 +1747,18 @@ PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, | |||||||
|    PNG_FILTER_AVG | PNG_FILTER_PAETH) |    PNG_FILTER_AVG | PNG_FILTER_PAETH) | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_SUPPORTED | #ifdef PNG_WRITE_SUPPORTED | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */ | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ | ||||||
| /* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
 |  | ||||||
|  * defines, either the default (minimum-sum-of-absolute-differences), or |  | ||||||
|  * the experimental method (weighted-minimum-sum-of-absolute-differences). |  | ||||||
|  * |  | ||||||
|  * Weights are factors >= 1.0, indicating how important it is to keep the |  | ||||||
|  * filter type consistent between rows.  Larger numbers mean the current |  | ||||||
|  * filter is that many times as likely to be the same as the "num_weights" |  | ||||||
|  * previous filters.  This is cumulative for each previous row with a weight. |  | ||||||
|  * There needs to be "num_weights" values in "filter_weights", or it can be |  | ||||||
|  * NULL if the weights aren't being specified.  Weights have no influence on |  | ||||||
|  * the selection of the first row filter.  Well chosen weights can (in theory) |  | ||||||
|  * improve the compression for a given image. |  | ||||||
|  * |  | ||||||
|  * Costs are factors >= 1.0 indicating the relative decoding costs of a |  | ||||||
|  * filter type.  Higher costs indicate more decoding expense, and are |  | ||||||
|  * therefore less likely to be selected over a filter with lower computational |  | ||||||
|  * costs.  There needs to be a value in "filter_costs" for each valid filter |  | ||||||
|  * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't |  | ||||||
|  * setting the costs.  Costs try to improve the speed of decompression without |  | ||||||
|  * unduly increasing the compressed image size. |  | ||||||
|  * |  | ||||||
|  * A negative weight or cost indicates the default value is to be used, and |  | ||||||
|  * values in the range [0.0, 1.0) indicate the value is to remain unchanged. |  | ||||||
|  * The default values for both weights and costs are currently 1.0, but may |  | ||||||
|  * change if good general weighting/cost heuristics can be found.  If both |  | ||||||
|  * the weights and costs are set to 1.0, this degenerates the WEIGHTED method |  | ||||||
|  * to the UNWEIGHTED method, but with added encoding time/computation. |  | ||||||
|  */ |  | ||||||
| PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, | PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, | ||||||
|     int heuristic_method, int num_weights, png_const_doublep filter_weights, |     int heuristic_method, int num_weights, png_const_doublep filter_weights, | ||||||
|     png_const_doublep filter_costs)) |     png_const_doublep filter_costs) PNG_DEPRECATED) | ||||||
| PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, | PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, | ||||||
|     (png_structrp png_ptr, int heuristic_method, int num_weights, |     (png_structrp png_ptr, int heuristic_method, int num_weights, | ||||||
|     png_const_fixed_point_p filter_weights, |     png_const_fixed_point_p filter_weights, | ||||||
|     png_const_fixed_point_p filter_costs)) |     png_const_fixed_point_p filter_costs) PNG_DEPRECATED) | ||||||
| #endif /*  WRITE_WEIGHTED_FILTER */ | #endif /*  WRITE_WEIGHTED_FILTER */ | ||||||
| 
 | 
 | ||||||
| /* Heuristic used for row filter selection.  These defines should NOT be
 | /* Heuristic used for row filter selection.  These defines should NOT be
 | ||||||
|  * changed. |  * changed.  As of libpng-1.7.0beta62, these are no longer used. | ||||||
|  */ |  */ | ||||||
| #define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */ | #define PNG_FILTER_HEURISTIC_DEFAULT    0  /* Currently "UNWEIGHTED" */ | ||||||
| #define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */ | #define PNG_FILTER_HEURISTIC_UNWEIGHTED 1  /* Used by libpng < 0.95 */ | ||||||
|  | |||||||
							
								
								
									
										269
									
								
								pngwrite.c
									
									
									
									
									
								
							
							
						
						
									
										269
									
								
								pngwrite.c
									
									
									
									
									
								
							| @ -929,10 +929,6 @@ png_write_flush(png_structrp png_ptr) | |||||||
| } | } | ||||||
| #endif /* WRITE_FLUSH */ | #endif /* WRITE_FLUSH */ | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
| static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */ |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| /* Free any memory used in png_ptr struct without freeing the struct itself. */ | /* Free any memory used in png_ptr struct without freeing the struct itself. */ | ||||||
| static void | static void | ||||||
| png_write_destroy(png_structrp png_ptr) | png_write_destroy(png_structrp png_ptr) | ||||||
| @ -956,15 +952,6 @@ png_write_destroy(png_structrp png_ptr) | |||||||
|    png_ptr->tst_row = NULL; |    png_ptr->tst_row = NULL; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|    /* Use this to save a little code space, it doesn't free the filter_costs */ |  | ||||||
|    png_reset_filter_heuristics(png_ptr); |  | ||||||
|    png_free(png_ptr, png_ptr->filter_costs); |  | ||||||
|    png_free(png_ptr, png_ptr->inv_filter_costs); |  | ||||||
|    png_ptr->filter_costs = NULL; |  | ||||||
|    png_ptr->inv_filter_costs = NULL; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED | #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED | ||||||
|    png_free(png_ptr, png_ptr->chunk_list); |    png_free(png_ptr, png_ptr->chunk_list); | ||||||
|    png_ptr->chunk_list = NULL; |    png_ptr->chunk_list = NULL; | ||||||
| @ -1119,255 +1106,31 @@ png_set_filter(png_structrp png_ptr, int method, int filters) | |||||||
|  * better compression. |  * better compression. | ||||||
|  */ |  */ | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */ | #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED      /* GRR 970116 */ | ||||||
| /* Convenience reset API. */ |  | ||||||
| static void |  | ||||||
| png_reset_filter_heuristics(png_structrp png_ptr) |  | ||||||
| { |  | ||||||
|    /* Clear out any old values in the 'weights' - this must be done because if
 |  | ||||||
|     * the app calls set_filter_heuristics multiple times with different |  | ||||||
|     * 'num_weights' values we would otherwise potentially have wrong sized |  | ||||||
|     * arrays. |  | ||||||
|     */ |  | ||||||
|    png_ptr->num_prev_filters = 0; |  | ||||||
|    png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; |  | ||||||
|    if (png_ptr->prev_filters != NULL) |  | ||||||
|    { |  | ||||||
|       png_bytep old = png_ptr->prev_filters; |  | ||||||
|       png_ptr->prev_filters = NULL; |  | ||||||
|       png_free(png_ptr, old); |  | ||||||
|    } |  | ||||||
|    if (png_ptr->filter_weights != NULL) |  | ||||||
|    { |  | ||||||
|       png_uint_16p old = png_ptr->filter_weights; |  | ||||||
|       png_ptr->filter_weights = NULL; |  | ||||||
|       png_free(png_ptr, old); |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    if (png_ptr->inv_filter_weights != NULL) |  | ||||||
|    { |  | ||||||
|       png_uint_16p old = png_ptr->inv_filter_weights; |  | ||||||
|       png_ptr->inv_filter_weights = NULL; |  | ||||||
|       png_free(png_ptr, old); |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    /* Leave the filter_costs - this array is fixed size. */ |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int |  | ||||||
| png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method, |  | ||||||
|    int num_weights) |  | ||||||
| { |  | ||||||
|    if (png_ptr == NULL) |  | ||||||
|       return 0; |  | ||||||
| 
 |  | ||||||
|    /* Clear out the arrays */ |  | ||||||
|    png_reset_filter_heuristics(png_ptr); |  | ||||||
| 
 |  | ||||||
|    /* Check arguments; the 'reset' function makes the correct settings for the
 |  | ||||||
|     * unweighted case, but we must handle the weight case by initializing the |  | ||||||
|     * arrays for the caller. |  | ||||||
|     */ |  | ||||||
|    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|    { |  | ||||||
|       int i; |  | ||||||
| 
 |  | ||||||
|       if (num_weights > 0) |  | ||||||
|       { |  | ||||||
|          png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, |  | ||||||
|              (png_uint_32)((sizeof (png_byte)) * num_weights)); |  | ||||||
| 
 |  | ||||||
|          /* To make sure that the weighting starts out fairly */ |  | ||||||
|          for (i = 0; i < num_weights; i++) |  | ||||||
|          { |  | ||||||
|             png_ptr->prev_filters[i] = 255; |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, |  | ||||||
|              (png_uint_32)((sizeof (png_uint_16)) * num_weights)); |  | ||||||
| 
 |  | ||||||
|          png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, |  | ||||||
|              (png_uint_32)((sizeof (png_uint_16)) * num_weights)); |  | ||||||
| 
 |  | ||||||
|          for (i = 0; i < num_weights; i++) |  | ||||||
|          { |  | ||||||
|             png_ptr->inv_filter_weights[i] = |  | ||||||
|             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          /* Safe to set this now */ |  | ||||||
|          png_ptr->num_prev_filters = png_check_byte(png_ptr, num_weights); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       /* If, in the future, there are other filter methods, this would
 |  | ||||||
|        * need to be based on png_ptr->filter. |  | ||||||
|        */ |  | ||||||
|       if (png_ptr->filter_costs == NULL) |  | ||||||
|       { |  | ||||||
|          png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, |  | ||||||
|              (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); |  | ||||||
| 
 |  | ||||||
|          png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, |  | ||||||
|              (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST)); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) |  | ||||||
|       { |  | ||||||
|          png_ptr->inv_filter_costs[i] = |  | ||||||
|          png_ptr->filter_costs[i] = PNG_COST_FACTOR; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       /* All the arrays are inited, safe to set this: */ |  | ||||||
|       png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; |  | ||||||
| 
 |  | ||||||
|       /* Return the 'ok' code. */ |  | ||||||
|       return 1; |  | ||||||
|    } |  | ||||||
|    else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || |  | ||||||
|       heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) |  | ||||||
|    { |  | ||||||
|       return 1; |  | ||||||
|    } |  | ||||||
|    else |  | ||||||
|    { |  | ||||||
|       png_warning(png_ptr, "Unknown filter heuristic method"); |  | ||||||
|       return 0; |  | ||||||
|    } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Provide floating and fixed point APIs */ |  | ||||||
| #ifdef PNG_FLOATING_POINT_SUPPORTED | #ifdef PNG_FLOATING_POINT_SUPPORTED | ||||||
| static png_uint_16 | PNG_FUNCTION(void,PNGAPI | ||||||
| u16_from_fp(png_const_structrp png_ptr, int position, double fp) | png_set_filter_heuristics,(png_structrp png_ptr, int heuristic_method, | ||||||
| { |  | ||||||
|     /* Utility: given a double make sure it fits into a PNG 16-bit unsigned
 |  | ||||||
|      * value. |  | ||||||
|      */ |  | ||||||
|     if (fp >= 0 && fp < 65536) |  | ||||||
|         return (png_uint_16)/*SAFE*/fp; |  | ||||||
| 
 |  | ||||||
|     png_affirm(png_ptr, param_deb("fp to u16 overflow") position); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #define u16_from_fp(pp, fp) (u16_from_fp((pp), PNG_SRC_LINE, (fp))) |  | ||||||
| 
 |  | ||||||
| void PNGAPI |  | ||||||
| png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, |  | ||||||
|     int num_weights, png_const_doublep filter_weights, |     int num_weights, png_const_doublep filter_weights, | ||||||
|     png_const_doublep filter_costs) |     png_const_doublep filter_costs),PNG_DEPRECATED) | ||||||
| { | { | ||||||
|    png_debug(1, "in png_set_filter_heuristics"); |    PNG_UNUSED(png_ptr) | ||||||
| 
 |    PNG_UNUSED(heuristic_method) | ||||||
|    /* The internal API allocates all the arrays and ensures that the elements of
 |    PNG_UNUSED(num_weights) | ||||||
|     * those arrays are set to the default value. |    PNG_UNUSED(filter_weights) | ||||||
|     */ |    PNG_UNUSED(filter_costs) | ||||||
|    if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) |  | ||||||
|       return; |  | ||||||
| 
 |  | ||||||
|    /* If using the weighted method copy in the weights. */ |  | ||||||
|    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|    { |  | ||||||
|       int i; |  | ||||||
|       for (i = 0; i < num_weights; i++) |  | ||||||
|       { |  | ||||||
|          if (filter_weights[i] <= 0.0) |  | ||||||
|          { |  | ||||||
|             png_ptr->inv_filter_weights[i] = |  | ||||||
|             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             png_ptr->inv_filter_weights[i] = |  | ||||||
|                 u16_from_fp(png_ptr, PNG_WEIGHT_FACTOR*filter_weights[i]+.5); |  | ||||||
| 
 |  | ||||||
|             png_ptr->filter_weights[i] = |  | ||||||
|                 u16_from_fp(png_ptr, PNG_WEIGHT_FACTOR/filter_weights[i]+.5); |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       /* Here is where we set the relative costs of the different filters.  We
 |  | ||||||
|        * should take the desired compression level into account when setting |  | ||||||
|        * the costs, so that Paeth, for instance, has a high relative cost at low |  | ||||||
|        * compression levels, while it has a lower relative cost at higher |  | ||||||
|        * compression settings.  The filter types are in order of increasing |  | ||||||
|        * relative cost, so it would be possible to do this with an algorithm. |  | ||||||
|        */ |  | ||||||
|       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) |  | ||||||
|       { |  | ||||||
|          png_ptr->inv_filter_costs[i] = |  | ||||||
|              u16_from_fp(png_ptr, PNG_COST_FACTOR / filter_costs[i] + .5); |  | ||||||
| 
 |  | ||||||
|          png_ptr->filter_costs[i] = |  | ||||||
|              u16_from_fp(png_ptr, PNG_COST_FACTOR * filter_costs[i] + .5); |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
| } | } | ||||||
| #endif /* FLOATING_POINT */ | #endif /* FLOATING_POINT */ | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_FIXED_POINT_SUPPORTED | #ifdef PNG_FIXED_POINT_SUPPORTED | ||||||
| void PNGAPI | PNG_FUNCTION(void,PNGAPI | ||||||
| png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, | png_set_filter_heuristics_fixed,(png_structrp png_ptr, int heuristic_method, | ||||||
|     int num_weights, png_const_fixed_point_p filter_weights, |     int num_weights, png_const_fixed_point_p filter_weights, | ||||||
|     png_const_fixed_point_p filter_costs) |     png_const_fixed_point_p filter_costs),PNG_DEPRECATED) | ||||||
| { | { | ||||||
|    png_debug(1, "in png_set_filter_heuristics_fixed"); |    PNG_UNUSED(png_ptr) | ||||||
| 
 |    PNG_UNUSED(heuristic_method) | ||||||
|    /* The internal API allocates all the arrays and ensures that the elements of
 |    PNG_UNUSED(num_weights) | ||||||
|     * those arrays are set to the default value. |    PNG_UNUSED(filter_weights) | ||||||
|     */ |    PNG_UNUSED(filter_costs) | ||||||
|    if (png_init_filter_heuristics(png_ptr, heuristic_method, num_weights) == 0) |  | ||||||
|       return; |  | ||||||
| 
 |  | ||||||
|    /* If using the weighted method copy in the weights. */ |  | ||||||
|    if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|    { |  | ||||||
|       int i; |  | ||||||
|       for (i = 0; i < num_weights; i++) |  | ||||||
|       { |  | ||||||
|          if (filter_weights[i] <= 0) |  | ||||||
|          { |  | ||||||
|             png_ptr->inv_filter_weights[i] = |  | ||||||
|             png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             png_ptr->inv_filter_weights[i] = png_check_u16(png_ptr, |  | ||||||
|                (PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); |  | ||||||
| 
 |  | ||||||
|             png_ptr->filter_weights[i] = png_check_u16(png_ptr, |  | ||||||
|                (PNG_WEIGHT_FACTOR*PNG_FP_1+(filter_weights[i]/2))/ |  | ||||||
|                   filter_weights[i]); |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       /* Here is where we set the relative costs of the different filters.  We
 |  | ||||||
|        * should take the desired compression level into account when setting |  | ||||||
|        * the costs, so that Paeth, for instance, has a high relative cost at low |  | ||||||
|        * compression levels, while it has a lower relative cost at higher |  | ||||||
|        * compression settings.  The filter types are in order of increasing |  | ||||||
|        * relative cost, so it would be possible to do this with an algorithm. |  | ||||||
|        */ |  | ||||||
|       for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) |  | ||||||
|          if (filter_costs[i] >= PNG_FP_1) |  | ||||||
|       { |  | ||||||
|          png_uint_32 tmp; |  | ||||||
| 
 |  | ||||||
|          /* Use a 32 bit unsigned temporary here because otherwise the
 |  | ||||||
|           * intermediate value will be a 32 bit *signed* integer (ANSI rules) |  | ||||||
|           * and this will get the wrong answer on division. |  | ||||||
|           */ |  | ||||||
|          tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); |  | ||||||
|          tmp /= filter_costs[i]; |  | ||||||
| 
 |  | ||||||
|          png_ptr->inv_filter_costs[i] = png_check_u16(png_ptr, tmp); |  | ||||||
| 
 |  | ||||||
|          tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; |  | ||||||
|          tmp /= PNG_FP_1; |  | ||||||
| 
 |  | ||||||
|          png_ptr->filter_costs[i] = png_check_u16(png_ptr, tmp); |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
| } | } | ||||||
| #endif /* FIXED_POINT */ | #endif /* FIXED_POINT */ | ||||||
| #endif /* WRITE_WEIGHTED_FILTER */ | #endif /* WRITE_WEIGHTED_FILTER */ | ||||||
|  | |||||||
							
								
								
									
										271
									
								
								pngwutil.c
									
									
									
									
									
								
							
							
						
						
									
										271
									
								
								pngwutil.c
									
									
									
									
									
								
							| @ -2497,54 +2497,6 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, | |||||||
|    return (sum); |    return (sum); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
| 
 |  | ||||||
| #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) |  | ||||||
| #define PNG_HISHIFT 10 |  | ||||||
| #define PNG_LOMASK ((png_uint_32)0xffffL) |  | ||||||
| #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) |  | ||||||
| 
 |  | ||||||
| static png_size_t /* PRIVATE */ |  | ||||||
| png_increase_lmins(png_structrp png_ptr, png_size_t lmins) |  | ||||||
| { |  | ||||||
|    /* We temporarily increase the "minimum sum" by the factor we
 |  | ||||||
|     * would reduce the sum of this filter, so that we can do the |  | ||||||
|     * early exit comparison without scaling the sum each time. |  | ||||||
|     */ |  | ||||||
|    int j; |  | ||||||
|    png_uint_32 lmhi, lmlo; |  | ||||||
|    lmlo = lmins & PNG_LOMASK; |  | ||||||
|    lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK; |  | ||||||
| 
 |  | ||||||
|    for (j = 0; j < png_ptr->num_prev_filters; j++) |  | ||||||
|    { |  | ||||||
|       if (png_ptr->prev_filters[j] == png_ptr->try_row[0]) |  | ||||||
|       { |  | ||||||
|          lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> |  | ||||||
|              PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|          lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> |  | ||||||
|              PNG_WEIGHT_SHIFT; |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
| 
 |  | ||||||
|    lmlo = (lmlo * png_ptr->inv_filter_costs[png_ptr->try_row[0]]) >> |  | ||||||
|        PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|    lmhi = (lmhi * png_ptr->inv_filter_costs[png_ptr->try_row[0]]) >> |  | ||||||
|        PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|    if (lmhi > PNG_HIMASK) |  | ||||||
|       lmins = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|    else |  | ||||||
|       lmins = (lmhi << PNG_HISHIFT) + lmlo; |  | ||||||
| 
 |  | ||||||
|    return (lmins); |  | ||||||
| } |  | ||||||
| #endif /* WRITE_WEIGHTED_FILTER */ |  | ||||||
| 
 |  | ||||||
| #endif /* WRITE_FILTER */ | #endif /* WRITE_FILTER */ | ||||||
| 
 | 
 | ||||||
| void /* PRIVATE */ | void /* PRIVATE */ | ||||||
| @ -2557,22 +2509,11 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|    png_bytep row_buf; |    png_bytep row_buf; | ||||||
|    png_bytep best_row; |    png_bytep best_row; | ||||||
|    png_uint_32 bpp; |    png_uint_32 bpp; | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|    int num_p_filters = png_ptr->num_prev_filters; |  | ||||||
| #endif |  | ||||||
|    png_size_t mins; |    png_size_t mins; | ||||||
|    png_size_t row_bytes = row_info->rowbytes; |    png_size_t row_bytes = row_info->rowbytes; | ||||||
| 
 | 
 | ||||||
|    png_debug(1, "in png_write_find_filter"); |    png_debug(1, "in png_write_find_filter"); | ||||||
| 
 | 
 | ||||||
| #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|    if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) |  | ||||||
|    { |  | ||||||
|      /* These will never be selected so we need not test them. */ |  | ||||||
|      filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); |  | ||||||
|    } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|    /* Find out how many bytes offset each pixel is */ |    /* Find out how many bytes offset each pixel is */ | ||||||
|    bpp = (row_info->pixel_depth + 7) >> 3; |    bpp = (row_info->pixel_depth + 7) >> 3; | ||||||
| 
 | 
 | ||||||
| @ -2618,45 +2559,6 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|       png_size_t i; |       png_size_t i; | ||||||
|       int v; |       int v; | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|       { |  | ||||||
|          png_uint_32 sumhi, sumlo; |  | ||||||
|          int j; |  | ||||||
|          sumlo = sum & PNG_LOMASK; |  | ||||||
|          sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */ |  | ||||||
| 
 |  | ||||||
|          /* Reduce the sum if we match any of the previous rows */ |  | ||||||
|          for (j = 0; j < num_p_filters; j++) |  | ||||||
|          { |  | ||||||
|             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) |  | ||||||
|             { |  | ||||||
|                sumlo = (sumlo * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|                sumhi = (sumhi * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          /* Factor in the cost of this filter (this is here for completeness,
 |  | ||||||
|           * but it makes no sense to have a "cost" for the NONE filter, as |  | ||||||
|           * it has the minimum possible computational cost - none). |  | ||||||
|           */ |  | ||||||
|          sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          if (sumhi > PNG_HIMASK) |  | ||||||
|             sum = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|             sum = (sumhi << PNG_HISHIFT) + sumlo; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       if (PNG_SIZE_MAX/128 <= row_bytes) |       if (PNG_SIZE_MAX/128 <= row_bytes) | ||||||
|       { |       { | ||||||
|          for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) |          for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) | ||||||
| @ -2693,48 +2595,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|    { |    { | ||||||
|       png_size_t sum; |       png_size_t sum; | ||||||
|       png_size_t lmins = mins; |       png_size_t lmins = mins; | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|          lmins = png_increase_lmins(png_ptr, lmins); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);  |       sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);  | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|       { |  | ||||||
|          int j; |  | ||||||
|          png_uint_32 sumhi, sumlo; |  | ||||||
|          sumlo = sum & PNG_LOMASK; |  | ||||||
|          sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; |  | ||||||
| 
 |  | ||||||
|          for (j = 0; j < num_p_filters; j++) |  | ||||||
|          { |  | ||||||
|             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) |  | ||||||
|             { |  | ||||||
|                sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|                sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          if (sumhi > PNG_HIMASK) |  | ||||||
|             sum = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|             sum = (sumhi << PNG_HISHIFT) + sumlo; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       if (sum < mins) |       if (sum < mins) | ||||||
|       { |       { | ||||||
|          mins = sum; |          mins = sum; | ||||||
| @ -2758,48 +2620,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|    { |    { | ||||||
|       png_size_t sum; |       png_size_t sum; | ||||||
|       png_size_t lmins = mins; |       png_size_t lmins = mins; | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|          lmins = png_increase_lmins(png_ptr, lmins); |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       sum = png_setup_up_row(png_ptr, row_bytes, lmins);  |       sum = png_setup_up_row(png_ptr, row_bytes, lmins);  | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|       { |  | ||||||
|          int j; |  | ||||||
|          png_uint_32 sumhi, sumlo; |  | ||||||
|          sumlo = sum & PNG_LOMASK; |  | ||||||
|          sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; |  | ||||||
| 
 |  | ||||||
|          for (j = 0; j < num_p_filters; j++) |  | ||||||
|          { |  | ||||||
|             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) |  | ||||||
|             { |  | ||||||
|                sumlo = (sumlo * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|                sumhi = (sumhi * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          if (sumhi > PNG_HIMASK) |  | ||||||
|             sum = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|             sum = (sumhi << PNG_HISHIFT) + sumlo; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       if (sum < mins) |       if (sum < mins) | ||||||
|       { |       { | ||||||
|          mins = sum; |          mins = sum; | ||||||
| @ -2823,48 +2645,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|    { |    { | ||||||
|       png_size_t sum; |       png_size_t sum; | ||||||
|       png_size_t lmins = mins; |       png_size_t lmins = mins; | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|          lmins = png_increase_lmins(png_ptr, lmins); |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|       sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); |       sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|       { |  | ||||||
|          int j; |  | ||||||
|          png_uint_32 sumhi, sumlo; |  | ||||||
|          sumlo = sum & PNG_LOMASK; |  | ||||||
|          sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; |  | ||||||
| 
 |  | ||||||
|          for (j = 0; j < num_p_filters; j++) |  | ||||||
|          { |  | ||||||
|             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) |  | ||||||
|             { |  | ||||||
|                sumlo = (sumlo * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|                sumhi = (sumhi * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          if (sumhi > PNG_HIMASK) |  | ||||||
|             sum = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|             sum = (sumhi << PNG_HISHIFT) + sumlo; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       if (sum < mins) |       if (sum < mins) | ||||||
|       { |       { | ||||||
|          mins = sum; |          mins = sum; | ||||||
| @ -2888,48 +2671,9 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
|    { |    { | ||||||
|       png_size_t sum; |       png_size_t sum; | ||||||
|       png_size_t lmins = mins; |       png_size_t lmins = mins; | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|          lmins = png_increase_lmins(png_ptr, lmins); |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|       sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); |       sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); | ||||||
| 
 | 
 | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|       if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) |  | ||||||
|       { |  | ||||||
|          int j; |  | ||||||
|          png_uint_32 sumhi, sumlo; |  | ||||||
|          sumlo = sum & PNG_LOMASK; |  | ||||||
|          sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; |  | ||||||
| 
 |  | ||||||
|          for (j = 0; j < num_p_filters; j++) |  | ||||||
|          { |  | ||||||
|             if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) |  | ||||||
|             { |  | ||||||
|                sumlo = (sumlo * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
| 
 |  | ||||||
|                sumhi = (sumhi * png_ptr->filter_weights[j]) >> |  | ||||||
|                    PNG_WEIGHT_SHIFT; |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
| 
 |  | ||||||
|          sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> |  | ||||||
|              PNG_COST_SHIFT; |  | ||||||
| 
 |  | ||||||
|          if (sumhi > PNG_HIMASK) |  | ||||||
|             sum = PNG_MAXSUM; |  | ||||||
| 
 |  | ||||||
|          else |  | ||||||
|             sum = (sumhi << PNG_HISHIFT) + sumlo; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|       if (sum < mins) |       if (sum < mins) | ||||||
|       { |       { | ||||||
|          mins = sum; |          mins = sum; | ||||||
| @ -2944,21 +2688,6 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | |||||||
| 
 | 
 | ||||||
|    /* Do the actual writing of the filtered row data from the chosen filter. */ |    /* Do the actual writing of the filtered row data from the chosen filter. */ | ||||||
|    png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); |    png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); | ||||||
| 
 |  | ||||||
| #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED |  | ||||||
|    /* Save the type of filter we picked this time for future calculations */ |  | ||||||
|    if (png_ptr->num_prev_filters > 0) |  | ||||||
|    { |  | ||||||
|       int j; |  | ||||||
| 
 |  | ||||||
|       for (j = 1; j < num_p_filters; j++) |  | ||||||
|       { |  | ||||||
|          png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       png_ptr->prev_filters[j] = best_row[0]; |  | ||||||
|    } |  | ||||||
| #endif /* WRITE_WEIGHTED_FILTER */ |  | ||||||
| #endif /* WRITE_FILTER */ | #endif /* WRITE_FILTER */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| /* Libpng version 1.7.0beta62 - May 31, 2015 */ | /* Libpng version 1.7.0beta62 - May 31, 2015 */ | ||||||
| 
 | 
 | ||||||
| /* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ | /* Copyright (c) 1998-2015 Glenn Randers-Pehrson */ | ||||||
| 
 | 
 | ||||||
| /* This code is released under the libpng license. */ | /* This code is released under the libpng license. */ | ||||||
| /* For conditions of distribution and use, see the disclaimer */ | /* For conditions of distribution and use, see the disclaimer */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Glenn Randers-Pehrson
						Glenn Randers-Pehrson