168 строки
4.0 KiB
Plaintext
168 строки
4.0 KiB
Plaintext
% Copyright (C) 2012-2017,2018 John E. Davis
|
|
%
|
|
% This file is part of the S-Lang Library and may be distributed under the
|
|
% terms of the GNU General Public License. See the file COPYING for
|
|
% more information.
|
|
%---------------------------------------------------------------------------
|
|
autoload ("glob", "glob");
|
|
import ("png");
|
|
|
|
% Colormap functions
|
|
|
|
private define linear_range (a, b, xa, xb)
|
|
{
|
|
return typecast (xa + ([0:b-a] * (xb-xa)/double(b-a)), UChar_Type);
|
|
}
|
|
|
|
private define build_colormap_channel (ranges)
|
|
{
|
|
variable r = UChar_Type[256];
|
|
variable i = 0;
|
|
loop (length(ranges)/4)
|
|
{
|
|
variable a = ranges[i];
|
|
variable b = ranges[i+1];
|
|
variable xa = ranges[i+2];
|
|
variable xb = ranges[i+3];
|
|
r[[a:b]] = linear_range (a, b, xa, xb);
|
|
i += 4;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
define png_build_colormap (r_ranges, g_ranges, b_ranges)
|
|
{
|
|
return ((build_colormap_channel (r_ranges) shl 16)
|
|
+ (build_colormap_channel (g_ranges) shl 8)
|
|
+ (build_colormap_channel (b_ranges)));
|
|
}
|
|
|
|
private variable Color_Maps = Assoc_Type[Array_Type];
|
|
private variable Color_Map_Dir = path_concat (path_dirname (__FILE__), "cmaps");
|
|
private variable Png_Namespace = current_namespace ();
|
|
|
|
define png_add_colormap (name, map)
|
|
{
|
|
Color_Maps[name] = map;
|
|
}
|
|
|
|
define png_get_colormap (name)
|
|
{
|
|
if (assoc_key_exists (Color_Maps, name))
|
|
return Color_Maps[name];
|
|
|
|
variable mapfile = strcat (name, ".map");
|
|
variable file = path_concat (Color_Map_Dir, mapfile);
|
|
if (stat_file (file) == NULL)
|
|
throw OpenError, "Unable to load colormap $mapfile"$;
|
|
|
|
() = evalfile (file, Png_Namespace);
|
|
|
|
if (assoc_key_exists (Color_Maps, name))
|
|
return Color_Maps[name];
|
|
|
|
throw DataError, "$file does not contain the $name color map"$;
|
|
}
|
|
|
|
define png_get_colormap_names ()
|
|
{
|
|
variable maps = glob (path_concat (Color_Map_Dir, "*.map"));
|
|
maps = array_map (String_Type, &path_basename_sans_extname, maps);
|
|
variable n = length (maps);
|
|
variable idx = Char_Type[n];
|
|
_for (0, n-1, 1)
|
|
{
|
|
variable i = ();
|
|
!if (assoc_key_exists (Color_Maps, maps[i]))
|
|
idx[i] = 1;
|
|
}
|
|
return [maps[where(idx)], assoc_get_keys (Color_Maps)];
|
|
|
|
}
|
|
|
|
define png_rgb_to_gray (rgb)
|
|
{
|
|
variable gray = ((rgb&0xFF) + ((rgb&0xFF00)shr 8) + ((rgb&0xFF0000)shr 16));
|
|
return typecast ((__tmp(gray)/3.0), UChar_Type);
|
|
}
|
|
|
|
private define normalize_gray (gray, nlevels)
|
|
{
|
|
variable g0 = qualifier ("gmin");
|
|
variable g1 = qualifier ("gmax");
|
|
|
|
if ((typeof (gray) == UChar_Type) && (nlevels == 256)
|
|
&& (g0 == NULL) && (g1 == NULL))
|
|
return gray;
|
|
|
|
variable is_bad = isnan(gray) or isinf(gray);
|
|
variable any_is_bad = any(is_bad);
|
|
if (any_is_bad)
|
|
{
|
|
variable good_gray = gray [where(is_bad == 0)];
|
|
if (g0 == NULL) g0 = min (good_gray);
|
|
if (g1 == NULL) g1 = max (good_gray);
|
|
}
|
|
else
|
|
{
|
|
if (g0 == NULL) g0 = min(gray);
|
|
if (g1 == NULL) g1 = max(gray);
|
|
}
|
|
if (g0 > g1) (g0, g1) = (g1, g0);
|
|
|
|
if (g0 != g1)
|
|
{
|
|
variable factor = nlevels/double(g1-g0);
|
|
gray = typecast ((gray-g0)*factor, Int_Type);
|
|
gray[where (gray<0)] = 0;
|
|
gray[where (gray>=nlevels)] = (nlevels-1);
|
|
}
|
|
else
|
|
gray = typecast (gray * 0 + 127, Int_Type);
|
|
|
|
variable bad_level = 0;
|
|
if (any_is_bad)
|
|
gray[where(is_bad)] = bad_level;
|
|
|
|
return gray;
|
|
}
|
|
|
|
private define gray_to_rgb_with_cmap (gray, cmap)
|
|
{
|
|
if (typeof (cmap) == String_Type)
|
|
cmap = png_get_colormap (cmap);
|
|
|
|
gray = normalize_gray (gray, length(cmap);;__qualifiers());
|
|
return cmap[gray];
|
|
}
|
|
|
|
define png_gray_to_rgb ()
|
|
{
|
|
variable gray;
|
|
if (_NARGS == 2)
|
|
return gray_to_rgb_with_cmap (;;__qualifiers ());
|
|
|
|
gray = ();
|
|
gray = normalize_gray (gray, 256;;__qualifiers ());
|
|
return gray + (gray shl 8) + (gray shl 16);
|
|
}
|
|
|
|
define png_rgb_get_r (rgb)
|
|
{
|
|
return typecast ((rgb shr 16) & 0xFF, UChar_Type);
|
|
}
|
|
define png_rgb_get_g (rgb)
|
|
{
|
|
return typecast ((rgb shr 8) & 0xFF, UChar_Type);
|
|
}
|
|
define png_rgb_get_b (rgb)
|
|
{
|
|
return typecast (rgb & 0xFF, UChar_Type);
|
|
}
|
|
|
|
$1 = path_concat (path_dirname (__FILE__), "help/pngfuns.hlp");
|
|
if (NULL != stat_file ($1))
|
|
add_doc_file ($1);
|
|
|
|
provide("png");
|