mirror of
				https://git.code.sf.net/p/libpng/code.git
				synced 2025-07-10 18:04:09 +02:00 
			
		
		
		
	[libpng16] Avoid filter-selection heuristic sum calculations in cases where
only one filter is a candidate for selection. This trades off code size (added png_setup_*_row_only() functions) for speed.
This commit is contained in:
		
							parent
							
								
									9c04f57cab
								
							
						
					
					
						commit
						29135161d7
					
				
							
								
								
									
										3
									
								
								ANNOUNCE
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								ANNOUNCE
									
									
									
									
									
								
							| @ -45,6 +45,9 @@ Version 1.6.24beta02 [June 19, 2016] | ||||
|     implemented in 1.7), however a simple safe fix here is to chose the lowest | ||||
|     numbered filter in the list from png_set_filter (this only works if the | ||||
|     first problem is also fixed) (John Bowler). | ||||
|   Avoid filter-selection heuristic sum calculations in cases where only one | ||||
|     filter is a candidate for selection. This trades off code size (added | ||||
|     png_setup_*_row_only() functions) for speed. | ||||
| 
 | ||||
| Send comments/corrections/commendations to png-mng-implement at lists.sf.net | ||||
| (subscription required; visit | ||||
|  | ||||
							
								
								
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							| @ -5616,6 +5616,9 @@ Version 1.6.24beta02 [June 19, 2016] | ||||
|     implemented in 1.7), however a simple safe fix here is to chose the lowest | ||||
|     numbered filter in the list from png_set_filter (this only works if the | ||||
|     first problem is also fixed) (John Bowler). | ||||
|   Avoid filter-selection heuristic sum calculations in cases where only one | ||||
|     filter is a candidate for selection. This trades off code size (added | ||||
|     png_setup_*_row_only() functions) for speed. | ||||
| 
 | ||||
| Send comments/corrections/commendations to png-mng-implement at lists.sf.net | ||||
| (subscription required; visit | ||||
|  | ||||
							
								
								
									
										111
									
								
								pngwutil.c
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								pngwutil.c
									
									
									
									
									
								
							| @ -2278,6 +2278,28 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, | ||||
|    return (sum); | ||||
| } | ||||
| 
 | ||||
| static void /* PRIVATE */ | ||||
| png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, | ||||
|     const png_size_t row_bytes) | ||||
| { | ||||
|    png_bytep rp, dp, lp; | ||||
|    png_size_t i; | ||||
| 
 | ||||
|    png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; | ||||
| 
 | ||||
|    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; | ||||
|         i++, rp++, dp++) | ||||
|    { | ||||
|       *dp = *rp; | ||||
|    } | ||||
| 
 | ||||
|    for (lp = png_ptr->row_buf + 1; i < row_bytes; | ||||
|       i++, rp++, lp++, dp++) | ||||
|    { | ||||
|       *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| static png_size_t /* PRIVATE */ | ||||
| png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, | ||||
|     const png_size_t lmins) | ||||
| @ -2302,6 +2324,21 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, | ||||
| 
 | ||||
|    return (sum); | ||||
| } | ||||
| static void /* PRIVATE */ | ||||
| png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes) | ||||
| { | ||||
|    png_bytep rp, dp, pp; | ||||
|    png_size_t i; | ||||
| 
 | ||||
|    png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; | ||||
| 
 | ||||
|    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, | ||||
|        pp = png_ptr->prev_row + 1; i < row_bytes; | ||||
|        i++, rp++, pp++, dp++) | ||||
|    { | ||||
|       *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| static png_size_t /* PRIVATE */ | ||||
| png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, | ||||
| @ -2335,6 +2372,27 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, | ||||
| 
 | ||||
|    return (sum); | ||||
| } | ||||
| static void /* PRIVATE */ | ||||
| png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, | ||||
|       const png_size_t row_bytes) | ||||
| { | ||||
|    png_bytep rp, dp, pp, lp; | ||||
|    png_uint_32 i; | ||||
| 
 | ||||
|    png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; | ||||
| 
 | ||||
|    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, | ||||
|         pp = png_ptr->prev_row + 1; i < bpp; i++) | ||||
|    { | ||||
|       *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); | ||||
|    } | ||||
| 
 | ||||
|    for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) | ||||
|    { | ||||
|       *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) | ||||
|           & 0xff); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| static png_size_t /* PRIVATE */ | ||||
| png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, | ||||
| @ -2389,6 +2447,48 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, | ||||
| 
 | ||||
|    return (sum); | ||||
| } | ||||
| static void /* PRIVATE */ | ||||
| png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp, | ||||
|     const png_size_t row_bytes) | ||||
| { | ||||
|    png_bytep rp, dp, pp, cp, lp; | ||||
|    png_size_t i; | ||||
| 
 | ||||
|    png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; | ||||
| 
 | ||||
|    for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, | ||||
|        pp = png_ptr->prev_row + 1; i < bpp; i++) | ||||
|    { | ||||
|       *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); | ||||
|    } | ||||
| 
 | ||||
|    for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; | ||||
|         i++) | ||||
|    { | ||||
|       int a, b, c, pa, pb, pc, p; | ||||
| 
 | ||||
|       b = *pp++; | ||||
|       c = *cp++; | ||||
|       a = *lp++; | ||||
| 
 | ||||
|       p = b - c; | ||||
|       pc = a - c; | ||||
| 
 | ||||
| #ifdef PNG_USE_ABS | ||||
|       pa = abs(p); | ||||
|       pb = abs(pc); | ||||
|       pc = abs(p + pc); | ||||
| #else | ||||
|       pa = p < 0 ? -p : p; | ||||
|       pb = pc < 0 ? -pc : pc; | ||||
|       pc = (p + pc) < 0 ? -(p + pc) : p + pc; | ||||
| #endif | ||||
| 
 | ||||
|       p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; | ||||
| 
 | ||||
|       *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); | ||||
|    } | ||||
| } | ||||
| #endif /* WRITE_FILTER */ | ||||
| 
 | ||||
| void /* PRIVATE */ | ||||
| @ -2476,10 +2576,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | ||||
|    if (filter_to_do == PNG_FILTER_SUB) | ||||
|    /* It's the only filter so no testing is needed */ | ||||
|    { | ||||
|       /* Passing PNG_SIZE_MAX here and below prevents the 'setup' function
 | ||||
|        * breaking out of the loop when lmins is exceeded. | ||||
|        */ | ||||
|       (void) png_setup_sub_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX); | ||||
|       png_setup_sub_row_only(png_ptr, bpp, row_bytes); | ||||
|       best_row = png_ptr->try_row; | ||||
|    } | ||||
| 
 | ||||
| @ -2505,7 +2602,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | ||||
|    /* Up filter */ | ||||
|    if (filter_to_do == PNG_FILTER_UP) | ||||
|    { | ||||
|       (void) png_setup_up_row(png_ptr, row_bytes, PNG_SIZE_MAX); | ||||
|       png_setup_up_row_only(png_ptr, row_bytes); | ||||
|       best_row = png_ptr->try_row; | ||||
|    } | ||||
| 
 | ||||
| @ -2531,7 +2628,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | ||||
|    /* Avg filter */ | ||||
|    if (filter_to_do == PNG_FILTER_AVG) | ||||
|    { | ||||
|       (void) png_setup_avg_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX); | ||||
|       png_setup_avg_row_only(png_ptr, bpp, row_bytes); | ||||
|       best_row = png_ptr->try_row; | ||||
|    } | ||||
| 
 | ||||
| @ -2557,7 +2654,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) | ||||
|    /* Paeth filter */ | ||||
|    if ((filter_to_do == PNG_FILTER_PAETH) != 0) | ||||
|    { | ||||
|       (void) png_setup_paeth_row(png_ptr, bpp, row_bytes, PNG_SIZE_MAX); | ||||
|       png_setup_paeth_row_only(png_ptr, bpp, row_bytes); | ||||
|       best_row = png_ptr->try_row; | ||||
|    } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Glenn Randers-Pehrson
						Glenn Randers-Pehrson