Files
ioccc/2000/bmeyer/index.html
T
Landon Curt Noll 86b8c91b0d change winner to author in HTML left sidebar
Also moved building of entry compressed tarballs
to last in the `make www` and `make quick_www`
top level Makefile rules.
2024-02-13 15:37:28 -08:00

487 lines
26 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- START: two lines up starts content from: inc/top.default.html -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- -->
<!-- The original markdown content was formed by the tool: bin/readme2index.sh -->
<!-- The HTML was converted from markdown by the tool: bin/md2html.sh -->
<!-- -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2000/bmeyer - Best Utility</title>
<meta name="description" content="2000 IOCCC entry bmeyer - Best Utility">
<meta name="keywords" content="IOCCC, 2000, IOCCC 2000, IOCCC entry, bmeyer, Best Utility">
</head>
<!-- END: this line ends content from: inc/head.default.html -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<img src="../../png/ioccc.png" alt="IOCCC image by Matt Zucker" width=300 height=110>
<h1>The International Obfuscated C Code Contest</h1>
<h2>2000/bmeyer - Best Utility</h2>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/topnav.mid.html -->
<div class="topnav">
<a class="Left" href="../bellard/index.html">&larr; bellard</a>
<a class="Left" href="../index.html">&uarr; 2000 &uarr;</a>
<a class="Left" href="../briddlebane/index.html">briddlebane &rarr;</a>
<a class="Right" href="#inventory">Inventory</a>
</div>
<!-- END: this line ends content from: inc/topnav.mid.html -->
<!-- START: this line starts content from: inc/begin-row.default.html -->
<div class="row">
<!-- END: this line ends content from: inc/begin-row.default.html -->
<!-- START: this line starts content from: inc/begin-leftcolumn.default.html -->
<div class="leftcolumn">
<!-- END: this line ends content from: inc/begin-leftcolumn.default.html -->
<!-- START: this line starts content from: inc/sidenav.default.html -->
<div class="sidenav">
<a href="#content">Jump to contents</a>
</div>
<hr>
<div class="sidenav">
<a href="../../index.html">IOCCC Home</a>
<a href="../../years.html">Winning Entries</a>
<a href="../../authors.html">People who have won</a>
</div>
<hr>
<div class="sidenav">
<a href="../../news.html">IOCCC News</a>
<a href="../../faq.html#submit">How to enter the IOCCC</a>
<a href="../../faq.html">FAQ</a>
</div>
<hr>
<div class="sidenav">
<a href="../../bugs.html">Bugs &amp; (mis)features</a>
<a href="../../faq.html#fix_an_entry">Fixing IOCCC entries</a>
<a href="../../faq.html#fix_web_site">Fixing the web site</a>
<a href="../../faq.html#fix_author">Fixing author info</a>
<a href="../../thanks-for-help.html">Thanks for the help</a>
</div>
<hr>
<div class="sidenav">
<a href="../../judges.html">The IOCCC Judges</a>
<a href="../../contact.html">Contacting the IOCCC</a>
</div>
<hr>
<div class="sidenav">
<a href="#top">Jump to top</a>
</div>
<!-- END: this line ends content from: inc/sidenav.default.html -->
<!-- START: this line starts content from: inc/end-leftcolumn.default.html -->
</div>
<!-- END: this line ends content from: inc/end-leftcolumn.default.html -->
<!-- START: this line starts content from: inc/begin-rightcolumn.default.html -->
<div class="rightcolumn">
<!-- END: this line ends content from: inc/begin-rightcolumn.default.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<a name="content"></a>
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-author.sh -->
<h2 id="author"><a name="author"></a>Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#Bernd_Meyer">Bernd Meyer</a><br>
Location: <a href="../../location.html#AU">AU</a> <br><br></li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
<!-- END: this line ends content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h2 id="to-build">To build:</h2>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span></span></code></pre></div>
<h2 id="to-use">To use:</h2>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./bmeyer</span></span></code></pre></div>
<h2 id="try">Try:</h2>
<p>In a video window (white text on black background):</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./try.sh</span></span></code></pre></div>
<p>The script will suggest you compare the output of the program with
images, prompting you to press any key to continue so that you may do
so.</p>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>Don’t even think of supplying different compression factors (the
dashed argument) for compression and decompression! You’ve been
warned.</p>
<p>The author recommended on linux/x86, glibc 2.0, libc4/5:</p>
<pre class="make"><code>bmeyer: bmeyer.c
CC -DY=&quot;__setfpucw(0x127f)&quot; -O6 $? -o $@ -lm</code></pre>
<p>However many compilers use <code>-O3</code> as the maximum level for
<code>-O</code> optimization.</p>
<p>And on linux/x86, glibc 2.1:</p>
<pre class="make"><code>bmeyer: bmeyer.c
gcc -DY=&#39;int x=0x127f; __asm__ (&quot;fldcw %0&quot; : : &quot;m&quot; (*&amp;x))&#39; $? -o $@ -lm</code></pre>
<p>Compile with the maximum possible optimization on your system. If
your system has 80-bit internal representation of floating point values
(x86, some Motorola processors) and you want the compressed format to be
portable across platforms, you need to set your FPU to use 64 bit mode.
Read the author’s remarks below for more details.</p>
<p>If you cannot work out how to get into 64 bit mode, you can try using
<code>-ffloat-store</code> if you compile with GCC (this may have a
performance penalty). The resulting binary will have a good chance to
produce portable files, but due to the resulting double-rounding (first
internally set to 80 bit, then to 64 bit on writing the value to
memory), there is a small but very real chance any given file produced
might not be portable.</p>
<p>The <a href="Makefile">Makefile</a> defaults to <code>-O3</code> and
no <code>asm()</code> call.</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<p>This program is called <code>GLICBAWLS</code></p>
<h4 id="function">Function</h4>
<p><code>GLICBAWLS</code> stands for “Grey Level Image Compression By
Adaptive Weighted Least Squares”.</p>
<p>And that’s exactly what this program does — feed it a .PGM file
(either raw [i.e. P5] or ASCII [i.e. P2]) on stdin, and it will output a
compressed version to stdout. Feed it a compressed file on stdin, and it
will decompress it to stdout — as either raw or ASCII .PGM, depending on
what format it was compressed from. For example:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> <span class="op">&lt;</span> michael.pgm <span class="op">&gt;</span> michael.glic</span></code></pre></div>
<p>and then</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> <span class="op">&lt;</span> michael.glic <span class="op">&gt;</span> michael.decoded.pgm</span></code></pre></div>
<p>As it turns out, <code>glicbawls</code> compresses greyscale images
(or, more precisely, “natural” greyscale images) better than any other
program I am aware of (with the exception of the not-yet-published
program developed for my PhD thesis). Of course, this might take some
time, so a progress indicator is provided. To make things more
interesting, instead of a boring bar or percentage display, an ASCII
rendition of the image being compressed/decompressed is output to
<code>stderr</code> (assuming white text on black background). If you
have trouble recognizing the image, try squinting at it ;-).</p>
<p>If you still have trouble, simply use a terminal or xterm with more
than 80 columns, and tell <code>glicbawls</code> about it by giving the
number of columns as an argument. For example</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> 260 <span class="op">&lt;</span>lavabus.pgm <span class="op">&gt;</span>lavabus.glic</span></code></pre></div>
<p>will allow <code>glicbawls</code> to use up to 260 columns, which
makes things much more recognizable.</p>
<p>Still running out of space? Need to compress those images just a tad
more? And maybe you can handle some loss due to the compression? If so,
you can use <code>glicbawls</code>’ “near lossless” compression mode. In
that mode, the decoded pixel values are allowed to differ from the
originals, but there is an upper limit on the magnitude of the
difference. For example, if a maximum error of 2 is allowed, an original
pixel value of 37 could be decoded as 35, 36, 37, 38 or 39. In order to
use this mode, simply give the maximum allowed error as an argument,
with a dash (<code>-</code>) before it. For example:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> <span class="at">-2</span> <span class="op">&lt;</span> graph.pgm <span class="op">&gt;</span> graph.2.glic</span></code></pre></div>
<p>will compress in a way that allows decompression with a maximum error
of two. You can combine both types of arguments, i.e.:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> <span class="at">-3</span> 180 <span class="op">&lt;</span> graph.pgm <span class="op">&gt;</span>graph.3.glic</span></code></pre></div>
<p>will compress with a maximum error of 3, using a 180 column terminal
for the progress display, and:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./glicbawls</span> <span class="at">-3</span> 180 <span class="op">&lt;</span> graph.3.glic <span class="op">&gt;</span> graph.3maxerr.pgm</span></code></pre></div>
<p>will decompress the result on such a terminal.</p>
<p>But wait, there is more — you can also feed <code>glicbawls</code>
.PPM files (i.e. colour images), raw or ASCII, your choice.
<code>glicbawls</code> will compress and decompress them just fine.
However, it only does “reasonably well” on them; It beats PNG easily,
but there are certainly programs out there that can compress colour
images considerably better. And don’t even <em>think</em> about using it
for so-called “artistic” images (i.e. anything that wasn’t scanned from
a photo or camera)….</p>
<h3 id="warning">WARNING</h3>
<p><code>glicball</code> is rather CPU and FPU intensive. Don’t run it
on anything slow. Things start to be usable around 300+MHz, with 600+
being highly desirable.</p>
<h3 id="compile-instructions">Compile Instructions</h3>
<p>Unlike most compression program, <code>glicbawls</code> makes heavy
use of floating point maths — and not all FPUs are created equal. Most
importantly, the x86 and 68k FPUs use 80 bit floating point formats
internally, while most other processors use IEEE 64 bit formats by
default. If not taken care of, this means that a <code>glicbawls</code>
file compressed on one CPU cannot generally be decompressed on
another.</p>
<p>Fortunately, just about all current FPUs can be put into IEEE 64 bit
mode (or at least something close enough for <code>glicbawls</code>).
Unfortunately, there is no standard way of doing so. For this reason,
the build file contains <em>three</em> compile lines; one for machines
that already use 64 bit mode by default (most RISC processors), one for
linux/x86 machines using libc4, libc5 or glibc2.0, and one for linux/x86
machines using glibc2.1 (glibc2.1 no longer exports the
<code>__setfpucw()</code> function, necessitating the use of gcc inline
assembly. *Grumble*).</p>
<p>So, if you are building on a machine that does not, by default, use
IEEE 64 bit floating point doubles, you’ll have to define <code>Y</code>
to be a command that switches it into that mode. If you fail to do so,
your <code>glicbawls</code> executable will still be able to decompress
its own compressed files, but you may be unable to exchange files with
<code>glicbawls</code> on other machines.</p>
<h3 id="obfuscation">Obfuscation</h3>
<p>Most of the obfuscation of this program was driven by the desperate
struggle to fit all of <code>glicbawls</code>’ features into code that
fits the IOCCC’s size limits. All identifiers’ names are
single-character, which was only possible by ruthless exploitation of
scope. There is a function <code>M()</code> that handles nearly all
input from <code>stdin</code>, handles all output to
<code>stdout</code>, and also recursively calculates one of the
mathematical expressions needed for error modelling. There is a function
that calculates <code>(A^(-1)*b)*x</code> with <code>A</code> being a
matrix and <code>b</code> and <code>x</code> being vectors, and does so
in a very efficient way — but one would be hard pressed to find it.
There is an arithmetic coder that is even less recognizable. A lot of
loop variables don’t get initialized, but instead the code is arranged
in such a way that they just happen to have the right value when control
flow reaches the loops. Lots of functions use the same two global
scratch variables. Variables change their meaning all the time, and the
differences between compressing and decompressing are handled in rather
subtle ways all over the program. The string that holds the ASCII values
for displaying the progress image doubles as a description on how to
find a pixel’s causal neighbours. And then there are a few
<code>#define</code>s that really are just in there to save a few
characters, but as an added “benefit” make the source ever more
unreadable.</p>
<p>In short — running it through the preprocessor and the pretty-printer
will give you something that looks slightly less like line noise and
slightly more like a C program, but unless you are a true wizard, it is
unlikely to gain you any insights into what is actually going on….<a
href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a></p>
<h3 id="bugs-assumptions-and-todo">Bugs, Assumptions and TODO</h3>
<p><code>glicbawls</code> assumes that characters are 8 bit wide, and
that the character set used is ASCII. If one of these isn’t true, all
hell will break loose.</p>
<p>The .PGM headers are not checked very thoroughly —
<code>glicbawls</code> will happily try to encode lots of files that it
shouldn’t touch. The old adage of “garbage in, garbage out” holds in
that case. Furthermore, even if <code>glicbawls</code> detects an
incorrect input, it fails to provide a meaningful error message, and
instead simply aborts.</p>
<p>When decompressing a near-lossless encoded image, the maximum allowed
error is required as a command line parameter. This should really be
saved in the compressed file!</p>
<p><code>glicbawls</code> relies on the decimal representation of all
integers having less than 255 digits. While ANSI C does not guarantee
this, it seems rather unlikely that anyone in the foreseeable future
would use images with <code>10^255</code> rows, columns or different
levels of grey. Also, it is assumed that any integer used can be cast to
a <code>double</code> and back without loss of precision. This limits
the number of rows, columns and grey levels to 9 quintillion, which
should also be sufficient for the next few years.</p>
<p>There is a theoretical chance that you might get a division by zero
error. You have a MUCH better chance of getting hit by lightning the
very second you realize that you just won a few million in a lottery.
But if it happens to you, don’t say I didn’t warn you! Instead, go out
and buy a lightning rod and a lottery ticket ;-)</p>
<p>At one point, a pointer to <code>int</code> is used as the target of
a <code>"%1[#]"</code> conversion in a <code>scanf(3)</code>, which
makes gcc rather unhappy, but shouldn’t really cause anyone any trouble.
The same goes for a couple of assignments which are used as truth
values.</p>
<h3 id="algorithm">Algorithm</h3>
<p>An exhaustive explanation of the algorithm used would go beyond the
scope of an info file, and would also be quite difficult in pure ASCII,
so the following is just a rough outline, and contains some
compression-speak…</p>
<p>The image is handled in <a
href="https://en.wikipedia.org/wiki/Scan_line">scanline</a> ordering.
For each pixel, an expected value is calculated by creating a least
squares predictor of order 12 based on all of the previously
encoded/decoded pixels. However, the contribution of each pixel is
weighted according to its <a
href="https://en.wikipedia.org/wiki/Taxicab_geometry">Manhattan-distance</a>
from the current pixel, <code>D</code>. That weight used is
<code>pow(0.8,D)</code>. <a href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a> <a href="#fn3" class="footnote-ref"
id="fnref3" role="doc-noteref"><sup>3</sup></a> <a href="#fn4"
class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a></p>
<p>In a similar way, the prediction <em>errors</em> for all previous
pixels are combined — a weighted average (with weight
<code>pow(0.7,D)</code>) of the squares of all previous prediction
errors is taken, and the square root of the (appropriately scaled)
result is called sigma.</p>
<p>The predicted value and sigma are then used as the parameters of a <a
href="https://en.wikipedia.org/wiki/Student%27s_t-distribution">Student
or t-distribution</a> (which is similar to a <a
href="https://en.wikipedia.org/wiki/Normal_distribution">normal
distribution</a>, but has more weight in the tails), providing a <a
href="https://en.wikipedia.org/wiki/Probability_distribution">probability
distribution</a> for the current pixel.</p>
<p>Next, the possible interval of values for the current pixel is
halved, and through integration of the probability distribution, a
probability is calculated for the pixel value being in the lower half.
During encoding, the actual value is examined, and the result encoded
using an arithmetic coder. During decoding, the arithmetic decoder
provides the information which half the actual value is in. In both
cases, the interval borders are adjusted accordingly, the arithmetic
coder/decoder updated, and the interval halving repeated until the
precise value has been en/decoded<a href="#fn5" class="footnote-ref"
id="fnref5" role="doc-noteref"><sup>5</sup></a>.</p>
<h3 id="photo-credit">Photo Credit:</h3>
<p><a href="lavabus.pgm">Lavabus</a> was taken by the judge, Landon Curt
Noll. <a href="michael.pgm">Michael</a> was provided by the author. <a
href="lenna.glic">Lenna</a> is a 1972 Playboy centerfold (doesn’t show
very much).</p>
<ul>
<li><p><a href="michael.pgm">michael.pgm</a></p>
<p>The author’s Godchild and nephew.</p></li>
<li><p><a href="lavabus.pgm">lavabus.pgm</a></p>
<p>A bus that was trapped by lava from <a
href="https://en.wikipedia.org/wiki/Kīlauea">Kilauea volcano</a> in
Hawaii, US. Nobody was in the bus at the time, BTW. Photo date:
1981.</p></li>
<li><p><a href="lenna.glic">lenna.glic</a></p>
<p>A November 1972 Playboy centerfold was scanned in long ago and has
been used for image compression research since then. Playboy originally
threatened to prosecute unauthorized use, but eventually granted that,
having been in use for image compression testing for so long, it was now
a useful benchmark. (Note: This picture doesn’t show very
much.)</p></li>
</ul>
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
License:</h2>
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
Reserved. You are free to share and adapt this file under the terms of
this license:</p>
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
<p>For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/</p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Yes, this could be seen as a challenge….<a
href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Actually, the weight is <code>pow(0.8,D)/s</code>, where
<code>s</code> is the sigma used for encoding/decoding the particular
previous pixel. Dividing by <code>s</code> is a rather arbitrary action
justified only by the improvement in results. Mathematically, I can only
justify dividing by <code>s^2</code>, or not dividing at all….<a
href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>Obviously, these least squares predictors are not
calculated from scratch for each pixel. Some clever reuse of earlier
results allows <code>O(1)</code> calculation, rather than the
<code>O(previous_rows*columns)</code> this description would suggest.<a
href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>As anyone who has ever tried local least squares knows
from bitter experience, there is a lot of numerical instability
associated with them. So <code>glicbawls</code> adds a bias towards an
averaging predictor to the equation system the least squares predictor
is calculated from. The weight that is given to this bias is constantly
adjusted throughout coding/decoding, thus justifying the ‘a’ in
<code>glicbawls</code>.<a href="#fnref4" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn5"><p>In the case of near-lossless coding, the interval is not
necessarily <em>halved</em>, but rather split at a convenient point (the
split points are chosen in such a way as to minimise the expected number
of bits needed for coding). Also, the iteration ends as soon as the
interval is small enough to guarantee decoding within the requested
maximum error.<a href="#fnref5" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
<h1 id="inventory-for-2000bmeyer"><a name="inventory"></a>Inventory for
2000/bmeyer</h1>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a href="index.html">index.html</a> - entry home page</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/bmeyer.c">bmeyer.c</a>
- winning source</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/Makefile">Makefile</a>
- entry Makefile</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/bmeyer.orig.c">bmeyer.orig.c</a>
- original source</li>
<li><a href="lavabus.pgm">lavabus.pgm</a> - Kilauea volcano bus trapped
in lava</li>
<li><a href="michael.pgm">michael.pgm</a> - author’s Godchild and
Nephew</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/try.sh">try.sh</a>
- how to run</li>
<li><a href="lenna.glic">lenna.glic</a> - P10 scan of 1972 Playboy
centerfold</li>
<li><a href="2000_bmeyer.tar.bz2">2000_bmeyer.tar.bz2</a> - download
winning source</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/.entry.json">.entry.json</a>
- description of entry in JSON</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/.gitignore">.gitignore</a>
- list of files that should not be committed under git</li>
<li><a href=".path">.path</a> - directory path from top directory</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/README.md">README.md</a>
- markdown source for index.html</li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
<!-- END: this line ends content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/end-rightcolumn.default.html -->
</div>
<!-- END: this line ends content from: inc/end-rightcolumn.default.html -->
<!-- START: this line starts content from: inc/end-row.default.html -->
</div>
<!-- END: this line ends content from: inc/end-row.default.html -->
<!-- START: this line starts content from: inc/footer.default.html -->
<div class="footer">
<hr>
<h2>Coda</h2>
<p><a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2000%2Fbmeyer%2Findex.html">Nu HTML check this web page</a></p>
<p><a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a></p>
</div>
<!-- END: this line ends content from: inc/footer.default.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->