mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:32:44 +00:00 
			
		
		
		
	LibGfx/ICC: Add a one-element cache for CLUT conversions
Our current CLUT code is pretty slow. A one-element cache can make it quite a bit faster for images that have long runs of a single color, such as illustrations. It also seems to help with photos some (in `0000711.pdf` page 1) -- I suppose even them have enough repeating pixels for it to be worth it. Some numbers, with `pdf --render-bench`: `0000711.pdf --page 1` (high-res photo) before: 2.9s after: 2.43s `0000277.pdf --page 19` (my nemesis PDF, large-ish illustration) before: 2.17s after: 0.58s (!) `0000502.pdf --page 2` (wat hoe dat) before: 0.66s after: 0.27s `0000521.pdf --page 10 ` (japanese) before: 0.52s after: 0.29s `0000364.pdf --page 1` (4 min test case) before: 0.48s after: 0.19s Thanks to that last one, reduces the time for `time Meta/test_pdf.py ~/Downloads/0000` from 4m22s to 1m28s. Helps quite a bit with #23157 (but high-res photos are still too slow).
This commit is contained in:
		
							parent
							
								
									6a8e418e40
								
							
						
					
					
						commit
						27e369cd19
					
				
					 2 changed files with 26 additions and 4 deletions
				
			
		|  | @ -1219,14 +1219,21 @@ ErrorOr<FloatVector3> Profile::to_pcs_a_to_b(TagData const& tag_data, ReadonlyBy | |||
|     // Assumes a "normal" device_class() (i.e. not DeviceLink).
 | ||||
|     VERIFY(number_of_components_in_color_space(connection_space()) == 3); | ||||
| 
 | ||||
|     if (m_to_pcs_clut_cache.has_value() && m_to_pcs_clut_cache->key == color) | ||||
|         return m_to_pcs_clut_cache->value; | ||||
| 
 | ||||
|     FloatVector3 result; | ||||
| 
 | ||||
|     switch (tag_data.type()) { | ||||
|     case Lut16TagData::Type: { | ||||
|         auto const& a_to_b = static_cast<Lut16TagData const&>(tag_data); | ||||
|         return a_to_b.evaluate(data_color_space(), connection_space(), color); | ||||
|         result = TRY(a_to_b.evaluate(data_color_space(), connection_space(), color)); | ||||
|         break; | ||||
|     } | ||||
|     case Lut8TagData::Type: { | ||||
|         auto const& a_to_b = static_cast<Lut8TagData const&>(tag_data); | ||||
|         return a_to_b.evaluate(data_color_space(), connection_space(), color); | ||||
|         result = TRY(a_to_b.evaluate(data_color_space(), connection_space(), color)); | ||||
|         break; | ||||
|     } | ||||
|     case LutAToBTagData::Type: { | ||||
|         auto const& a_to_b = static_cast<LutAToBTagData const&>(tag_data); | ||||
|  | @ -1236,10 +1243,19 @@ ErrorOr<FloatVector3> Profile::to_pcs_a_to_b(TagData const& tag_data, ReadonlyBy | |||
|         if (a_to_b.number_of_output_channels() != number_of_components_in_color_space(connection_space())) | ||||
|             return Error::from_string_literal("ICC::Profile::to_pcs_a_to_b: mAB output channel count does not match profile connection space size"); | ||||
| 
 | ||||
|         return a_to_b.evaluate(connection_space(), color); | ||||
|         result = TRY(a_to_b.evaluate(connection_space(), color)); | ||||
|         break; | ||||
|     } | ||||
|     default: | ||||
|         VERIFY_NOT_REACHED(); | ||||
|     } | ||||
|     VERIFY_NOT_REACHED(); | ||||
| 
 | ||||
|     if (!m_to_pcs_clut_cache.has_value()) | ||||
|         m_to_pcs_clut_cache = OneElementCLUTCache {}; | ||||
|     m_to_pcs_clut_cache->key = Vector<u8, 4>(color); | ||||
|     m_to_pcs_clut_cache->value = result; | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| ErrorOr<FloatVector3> Profile::to_pcs(ReadonlyBytes color) const | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nico Weber
						Nico Weber