The location of the link is in the About menu under the 'Contacting the IOCCC' and above 'Thanks for the help'. At first I had it at the very bottom, under 'IOCCC markdown guidelines', but it seemed better to have it closer to contacting the IOCCC. This is the same location in the no JavaScript menu (which, for those who do not know or forget, is not a requirement except for some screen sizes). The top level Makefile has a new 'security' rule. Updated make help. Typo fixes in make help. SECURITY.html has had a few updates as well: change the wording of entry code is unsupported (it now says 'ALL CODE IN ALL IOCCC ENTRIES IS UNSUPPORTED!!') and it now links to the mkiocccentry repo and how to report a possible security vulnerability in that repo; as that IS supported - and since there was reference to discussing security concerns is in SECURITY.html - even though the entries will not receive security updates - it seemed a good idea to have a link to report such security issues in the mkiocccentry repo. Perhaps the FAQ needs to be updated for this too.
783 lines
34 KiB
HTML
783 lines
34 KiB
HTML
<!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 -->
|
||
|
||
<!-- END: this line ends content from: inc/top.default.html -->
|
||
<!-- START: this line starts content from: inc/head.default.html -->
|
||
|
||
<head>
|
||
<link rel="stylesheet" href="../../ioccc.css">
|
||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||
<title>2000/bmeyer - Best utility</title>
|
||
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
|
||
<meta name="description" content="2000 IOCCC entry bmeyer - Best utility">
|
||
<meta name="keywords" content="IOCCC, 2000, IOCCC 2000, IOCCC entry, bmeyer, Best utility">
|
||
</head>
|
||
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
<!-- !!! 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/head.default.html -->
|
||
|
||
<!-- -->
|
||
<!-- This web page was formed via the tool: bin/readme2index.sh -->
|
||
<!-- The content of main section of this web page came from: 2000/bmeyer/README.md -->
|
||
<!-- -->
|
||
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2000/bmeyer/README.md !!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2000/bmeyer/README.md !!! -->
|
||
<!-- !!! Do not modify this web page, instead modify the file: 2000/bmeyer/README.md !!! -->
|
||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||
|
||
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
|
||
|
||
<!-- 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/topbar.default.html -->
|
||
|
||
<div class="theader">
|
||
<nav class="topbar">
|
||
<div class="container">
|
||
<div class="logo">
|
||
<a href="../../index.html" class="logo-link">
|
||
IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="topbar-items">
|
||
<div class="item">
|
||
<span class="item-header">
|
||
Entries
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../years.html" class="sub-item-link">
|
||
Winning Entries
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../authors.html" class="sub-item-link">
|
||
Winning Authors
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../location.html" class="sub-item-link">
|
||
Location of winning authors
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../bugs.html" class="sub-item-link">
|
||
Bugs and (mis)features
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
Status
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../news.html" class="sub-item-link">
|
||
IOCCC News
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../status.html" class="sub-item-link">
|
||
Contest status
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../next/index.html" class="sub-item-link">
|
||
Rules and Guidelines
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
FAQ
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../faq.html" class="sub-item-link">
|
||
FAQ
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../faq.html#submit" class="sub-item-link">
|
||
How to enter the IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
|
||
Fixing IOCCC entries
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../faq.html#fix_web_site" class="sub-item-link">
|
||
Fixing the website
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../faq.html#fix_author" class="sub-item-link">
|
||
Updating author info
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="item">
|
||
<span class="item-header">
|
||
About
|
||
</span>
|
||
|
||
<div class="sub-item">
|
||
<div class="outfit-font">
|
||
<a href="../../index.html" class="sub-item-link">
|
||
IOCCC Home
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../judges.html" class="sub-item-link">
|
||
The IOCCC Judges
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../contact.html" class="sub-item-link">
|
||
Contacting the IOCCC
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../SECURITY.html" class="sub-item-link">
|
||
IOCCC Security Policy
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../thanks-for-help.html" class="sub-item-link">
|
||
Thanks for the help
|
||
</a>
|
||
</div>
|
||
|
||
<div class="outfit-font">
|
||
<a href="../../markdown.html" class="sub-item-link">
|
||
IOCCC markdown guidelines
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="header-mobile-menu">
|
||
<noscript>
|
||
<a href="../../nojs-menu.html" class="topbar-js-label">
|
||
Please Enable JavaScript
|
||
</a>
|
||
</noscript>
|
||
|
||
<button id="header-open-menu-button" class="topbar-mobile-menu">
|
||
<img
|
||
src="../../png/hamburger-icon-open.png"
|
||
alt="hamburger style menu icon - open state"
|
||
width=48
|
||
height=48>
|
||
</button>
|
||
|
||
<button id="header-close-menu-button" class="hide-content">
|
||
<img
|
||
src="../../png/hamburger-icon-closed.png"
|
||
alt="hamburger style menu icon - closed state"
|
||
width=48
|
||
height=48>
|
||
</button>
|
||
|
||
<div id="mobile-menu-panel" class="hide-content">
|
||
<div class="mobile-menu-container">
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
Entries
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../years.html">
|
||
Winning Entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../authors.html">
|
||
Authors of winning IOCCC entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../location.html">
|
||
Location of authors
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../bugs.html">
|
||
Bugs and (mis)features
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
|
||
<div class="mobile-menu-item">
|
||
Status
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../status.html">
|
||
Contest status
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../next/index.html">
|
||
Rules and Guidelines
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../news.html">
|
||
IOCCC News
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
FAQ
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../faq.html">
|
||
Frequently Asked Questions
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../faq.html#submit">
|
||
How to enter the IOCCC
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
|
||
Fixing IOCCC entries
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../faq.html#fix_web_site">
|
||
Fixing the website
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
|
||
Fixing author info
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mobile-menu-wrapper">
|
||
<div class="mobile-menu-item">
|
||
About
|
||
</div>
|
||
<div class="mobile-submenu-wrapper">
|
||
|
||
<a class="mobile-submenu-item" href="../../index.html">
|
||
IOCCC Home
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../judges.html">
|
||
The IOCCC Judges
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../contact.html">
|
||
Contacting the IOCCC
|
||
</a>
|
||
|
||
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
|
||
Thanks for the help
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<script>
|
||
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
|
||
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
|
||
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
|
||
|
||
headerOpenMenuButton.addEventListener("click", () => {
|
||
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
|
||
headerOpenMenuButton.classList.add("hide-content");
|
||
|
||
headerCloseMenuButton.classList.remove("hide-content");
|
||
headerCloseMenuButton.classList.add("topbar-mobile-menu");
|
||
|
||
mobileMenuPanel.classList.remove("hide-content");
|
||
mobileMenuPanel.classList.add("topbar-mobile-panel");
|
||
});
|
||
|
||
headerCloseMenuButton.addEventListener("click", () => {
|
||
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
|
||
headerCloseMenuButton.classList.add("hide-content");
|
||
|
||
mobileMenuPanel.classList.add("hide-content");
|
||
mobileMenuPanel.classList.remove("topbar-mobile-panel");
|
||
|
||
headerOpenMenuButton.classList.add("topbar-mobile-menu");
|
||
headerOpenMenuButton.classList.remove("hide-content");
|
||
});
|
||
</script>
|
||
|
||
<!-- END: this line ends content from: inc/topbar.default.html -->
|
||
<!-- START: this line starts content from: inc/header.default.html -->
|
||
|
||
<div class="header">
|
||
<a href="../../2011/zucker/index.html">
|
||
<img src="../../png/ioccc.png"
|
||
alt="IOCCC image by Matt Zucker"
|
||
width=300
|
||
height=110>
|
||
</a>
|
||
<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/navbar.mid.html -->
|
||
|
||
<div class="navbar">
|
||
<a class="Left" href="../bellard/index.html">← bellard</a>
|
||
<a class="Left" href="../index.html">↑ 2000 ↑</a>
|
||
<a class="Left" href="../briddlebane/index.html">briddlebane →</a>
|
||
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/bmeyer.c">C code</a>
|
||
<a class="Right" href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/Makefile">Makefile</a>
|
||
<a class="Right" href="#inventory">Inventory</a>
|
||
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2000%2Fbmeyer%2Findex.html">✓</a>
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/navbar.mid.html -->
|
||
<!-- START: this line starts content from: inc/before-content.default.html -->
|
||
|
||
<div class="content" id="content">
|
||
|
||
<!-- 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">Author:</h2>
|
||
<ul>
|
||
<li>Name: <a href="../../authors.html#Bernd_Meyer">Bernd Meyer</a><br>
|
||
Location: <a href="../../location.html#AU">AU</a> - <em>Commonwealth of Australia</em> (<em>Australia</em>)</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 -->
|
||
|
||
<!-- BEFORE: 1st line of markdown file: 2000/bmeyer/README.md -->
|
||
<h2 id="to-build">To build:</h2>
|
||
<pre><code> make</code></pre>
|
||
<h2 id="to-use">To use:</h2>
|
||
<pre><code> ./bmeyer</code></pre>
|
||
<h2 id="try">Try:</h2>
|
||
<p>In a video window (white text on black background):</p>
|
||
<pre><code> ./try.sh</code></pre>
|
||
<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><code> bmeyer: bmeyer.c
|
||
CC -DY="__setfpucw(0x127f)" -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><code> bmeyer: bmeyer.c
|
||
gcc -DY='int x=0x127f; __asm__ ("fldcw %0" : : "m" (*&x))' $? -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="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/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>
|
||
<pre><code> ./glicbawls < michael.pgm > michael.glic</code></pre>
|
||
<p>and then</p>
|
||
<pre><code> ./glicbawls < michael.glic > michael.decoded.pgm</code></pre>
|
||
<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>
|
||
<pre><code> ./glicbawls 260 <lavabus.pgm >lavabus.glic</code></pre>
|
||
<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>
|
||
<pre><code> ./glicbawls -2 < graph.pgm > graph.2.glic</code></pre>
|
||
<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>
|
||
<pre><code> ./glicbawls -3 180 < graph.pgm >graph.3.glic</code></pre>
|
||
<p>will compress with a maximum error of 3, using a 180 column
|
||
terminal for the progress display, and:</p>
|
||
<pre><code> ./glicbawls -3 180 < graph.3.glic > graph.3maxerr.pgm</code></pre>
|
||
<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="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/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="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/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>
|
||
<!--
|
||
|
||
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
|
||
|
||
You are free to share and adapt this file under the terms of this license:
|
||
|
||
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
|
||
|
||
For more information, see:
|
||
|
||
https://creativecommons.org/licenses/by-sa/4.0/
|
||
|
||
-->
|
||
<!-- AFTER: last line of markdown file: 2000/bmeyer/README.md -->
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<section id="footnotes" class="footnotes footnotes-end-of-document" role="doc-endnotes">
|
||
<h5>Footnotes</h5>
|
||
<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 -->
|
||
|
||
<div id="inventory">
|
||
<h1 id="inventory-for-2000bmeyer">Inventory for 2000/bmeyer</h1>
|
||
</div>
|
||
<h2 id="primary-files">Primary files</h2>
|
||
<ul>
|
||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/bmeyer.c">bmeyer.c</a> - entry source code</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 code</li>
|
||
<li><a href="lavabus.pgm">lavabus.pgm</a> - Kilauea volcano bus trapped in lava</li>
|
||
<li><a href="michael.pgm">michael.pgm</a> - image of 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> - script to try entry</li>
|
||
<li><a href="lenna.glic">lenna.glic</a> - P10 scan of 1972 Playboy centerfold</li>
|
||
</ul>
|
||
<h2 id="secondary-files">Secondary files</h2>
|
||
<ul>
|
||
<li><a href="2000_bmeyer.tar.bz2">2000_bmeyer.tar.bz2</a> - download entry tarball</li>
|
||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/README.md">README.md</a> - markdown source for this web page</li>
|
||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/.entry.json">.entry.json</a> - entry summary and manifest 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="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2000/bmeyer/.path">.path</a> - directory path from top level directory</li>
|
||
<li><a href="index.html">index.html</a> - this web page</li>
|
||
</ul>
|
||
<hr style="width:10%;text-align:left;margin-left:0">
|
||
<h4>
|
||
Jump to: <a href="#">top</a>
|
||
</h4>
|
||
|
||
<!-- 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 -->
|
||
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/after-content.default.html -->
|
||
<!-- START: this line starts content from: inc/footer.inventory.html -->
|
||
|
||
<!--
|
||
|
||
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
|
||
|
||
You are free to share and adapt this file under the terms of this license:
|
||
|
||
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
|
||
|
||
For more information, see:
|
||
|
||
https://creativecommons.org/licenses/by-sa/4.0/
|
||
|
||
-->
|
||
|
||
<div class="footer">
|
||
|
||
<div id="copyright"><h3>Copyright © 1984-2024 by Landon Curt Noll:
|
||
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
|
||
<p>
|
||
This work is <b>licensed by Landon Curt Noll</b> under
|
||
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
|
||
target="_blank"
|
||
rel="license noopener noreferrer"
|
||
style="display:inline-block;">CC BY-SA 4.0</a></b>.
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../png/cc.png"
|
||
alt="cc inside circle symbol">
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../png/by.png"
|
||
alt="person inside circle symbol">
|
||
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
|
||
src="../../png/sa.png"
|
||
alt="arrow looping back on itself inside circle symbol"><br>
|
||
You should <b>carefully review</b> the
|
||
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
|
||
before using the licensed material.<br>
|
||
You may wish to review the
|
||
<b><a href="../../license.html"
|
||
target="_blank"
|
||
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
|
||
of <b>CC BY-SA 4.0</b>.<br>
|
||
</p>
|
||
</div>
|
||
|
||
<div id="coda"><h3>Coda</h3>
|
||
<p>
|
||
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fioccc-src.github.io%2Ftemp-test-ioccc%2F2000%2Fbmeyer%2Findex.html" rel="nofollow">Nu HTML check this web page</a><br>
|
||
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a><br>
|
||
</p>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- END: this line ends content from: inc/footer.inventory.html -->
|
||
<!-- START: this line starts content from: inc/bottom.default.html -->
|
||
|
||
</body>
|
||
</html>
|
||
|
||
<!-- END: this line ends content from: inc/bottom.default.html -->
|