summaryrefslogtreecommitdiffstats
path: root/src/pixman/pixman/make-srgb.pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pixman/pixman/make-srgb.pl')
-rw-r--r--src/pixman/pixman/make-srgb.pl115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/pixman/pixman/make-srgb.pl b/src/pixman/pixman/make-srgb.pl
new file mode 100644
index 0000000..cdaa80b
--- /dev/null
+++ b/src/pixman/pixman/make-srgb.pl
@@ -0,0 +1,115 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+sub linear_to_srgb
+{
+ my ($c) = @_;
+
+ if ($c < 0.0031308)
+ {
+ return $c * 12.92;
+ }
+ else
+ {
+ return 1.055 * $c ** (1.0/2.4) - 0.055;
+ }
+}
+
+sub srgb_to_linear
+{
+ my ($c) = @_;
+
+ if ($c < 0.04045)
+ {
+ return $c / 12.92;
+ }
+ else
+ {
+ return (($c + 0.055) / 1.055) ** 2.4
+ }
+}
+
+my @linear_to_srgb;
+for my $linear (0 .. 4095)
+{
+ my $srgb = int(linear_to_srgb($linear / 4095.0) * 255.0 + 0.5);
+ push @linear_to_srgb, $srgb;
+}
+
+my @srgb_to_linear;
+for my $srgb (0 .. 255)
+{
+ my $linear = int(srgb_to_linear($srgb / 255.0) * 65535.0 + 0.5);
+ push @srgb_to_linear, $linear;
+}
+
+# Ensure that we have a lossless sRGB and back conversion loop.
+# some of the darkest shades need a little bias -- maximum is just
+# 5 increments out of 16. This gives us useful property with
+# least amount of error in the sRGB-to-linear table, and keeps the actual
+# table lookup in the other direction as simple as possible.
+for my $srgb (0 .. $#srgb_to_linear)
+{
+ my $add = 0;
+ while (1)
+ {
+ my $linear = $srgb_to_linear[$srgb];
+ my $srgb_lossy = $linear_to_srgb[$linear >> 4];
+ last if $srgb == $srgb_lossy;
+
+ # Add slight bias to this component until it rounds correctly
+ $srgb_to_linear[$srgb] ++;
+ $add ++;
+ }
+ die "Too many adds at $srgb" if $add > 5;
+}
+
+print <<"PROLOG";
+/* WARNING: This file is generated by $0.
+ * Please edit that file instead of this one.
+ */
+
+#include <stdint.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+PROLOG
+
+print "const uint8_t linear_to_srgb[" . @linear_to_srgb . "] =\n";
+print "{\n";
+for my $linear (0 .. $#linear_to_srgb)
+{
+ if (($linear % 10) == 0)
+ {
+ print "\t";
+ }
+ print sprintf("%d, ", $linear_to_srgb[$linear]);
+ if (($linear % 10) == 9)
+ {
+ print "\n";
+ }
+}
+print "\n};\n";
+print "\n";
+
+print "const uint16_t srgb_to_linear[" . @srgb_to_linear . "] =\n";
+print "{\n";
+for my $srgb (0 .. $#srgb_to_linear)
+{
+ if (($srgb % 10) == 0)
+ {
+ print "\t";
+ }
+ print sprintf("%d, ", $srgb_to_linear[$srgb]);
+ if (($srgb % 10) == 9)
+ {
+ print "\n";
+ }
+}
+print "\n};\n";
+
OpenPOWER on IntegriCloud