--------------------------------------------------------------------- --------------------------------------------------------------------- -- PNG_IO -- Ada95 Portable Network Graphics Input/Output Package -- -- -- -- Copyright (©) 2003 Dr Stephen J. Sangwine (S.Sangwine@IEEE.org) -- -- -- -- This software was created by Stephen J. Sangwine. He hereby -- -- asserts his Moral Right to be identified as author of this -- -- software. -- --------------------------------------------------------------------- --------------------------------------------------------------------- -- PNG_IO is free software; you can redistribute it and/or modify -- -- it under the terms of the GNU General Public License as -- -- published by the Free Software Foundation; either version 2 of -- -- the License, or (at your option) any later version. -- -- -- -- PNG_IO is distributed in the hope that it will be useful, but -- -- WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- -- GNU General Public License for more details. -- -- -- -- You should have received a copy of the GNU General Public -- -- License along with this software (in the file gpl.txt); if not, -- -- contact the Free Software Foundation, or access www.fsf.org. -- --------------------------------------------------------------------- --------------------------------------------------------------------- -- Released: 1 July 2004 -- -- Edited: 13 August 2006 to refer to the ISO standard. -- -- 13 August 2006 to implement the changed from modular -- -- to discrete input and output samples: -- -- requiring use of 'Pos and 'Val to -- -- handle non-integer types. -- --------------------------------------------------------------------- --------------------------------------------------------------------- with Ada.Numerics.Elementary_Functions; package body PNG_IO.Gamma_Encoding is pragma Assert( Input_Sample'Pos( Input_Sample'First) = 0); pragma Assert(Output_Sample'Pos(Output_Sample'First) = 0); -- The gamma lookup table (below) handles a double conversion, from the -- input gamma to linearized pixels, and then to the output gamma. Either -- (or indeed both!) of the gamma values may be unity (i.e. 100_000). The -- two stage calculation is merged here into one stage. The ISO standard -- Sections 12.2 and 13.13 explains how the conversion is done. Simply -- put, the pixel values from the input file are converted to floats in the -- range 0.0 .. 1.0, the two gamma exponents are applied, and the result is -- then scaled into the output range. type Lookup_Table is array(Input_Sample) of Output_Sample; LUT : Lookup_Table; -- This is initialised below during elaboration. function To_Output_Gamma(I : Input_Sample) return Output_Sample is begin return LUT(I); end To_Output_Gamma; begin Initialise_LUT : declare IG : constant Float := 1.0e5/Float( Input_Gamma); OG : constant Float := 1.0e5/Float(Output_Gamma); Exponent : constant Float := Float(IG)/Float(OG); use Ada.Numerics.Elementary_Functions; -- For the ** operator. IL : constant Float := Float( Input_Sample'Pos( Input_Sample'Last)); OL : constant Float := Float(Output_Sample'Pos(Output_Sample'Last)); begin for P in LUT'Range loop LUT(P) := Output_Sample'Val(Integer(((Float(Input_Sample'Pos(P))/IL) ** Exponent) * OL)); end loop; end Initialise_LUT; end PNG_IO.Gamma_Encoding;