<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://nethackwiki.com/index.php?action=history&amp;feed=atom&amp;title=Tileset%2Ftile2500.py</id>
	<title>Tileset/tile2500.py - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://nethackwiki.com/index.php?action=history&amp;feed=atom&amp;title=Tileset%2Ftile2500.py"/>
	<link rel="alternate" type="text/html" href="https://nethackwiki.com/index.php?title=Tileset/tile2500.py&amp;action=history"/>
	<updated>2026-06-04T01:31:47Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.32.5</generator>
	<entry>
		<id>https://nethackwiki.com/index.php?title=Tileset/tile2500.py&amp;diff=204161&amp;oldid=prev</id>
		<title>Ray Chason: Improve support for 24 bit color images</title>
		<link rel="alternate" type="text/html" href="https://nethackwiki.com/index.php?title=Tileset/tile2500.py&amp;diff=204161&amp;oldid=prev"/>
		<updated>2026-05-19T02:04:17Z</updated>

		<summary type="html">&lt;p&gt;Improve support for 24 bit color images&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Revision as of 02:04, 19 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l91&quot; &gt;Line 91:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 91:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         # Read the header&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         # Read the header&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         fp = open(inpname, &amp;quot;rb&amp;quot;)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         fp = open(inpname, &amp;quot;rb&amp;quot;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;header &lt;/del&gt;= fp.read(&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;54&lt;/del&gt;)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;header1 &lt;/ins&gt;= fp.read(&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;18&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         (magic,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         (magic,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l97&quot; &gt;Line 97:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 97:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         reserved,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         reserved,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.image_offset,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.image_offset,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.header_size,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.header_size&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;) = struct.unpack(&amp;quot;&amp;lt;2s4L&amp;quot;&lt;/ins&gt;, &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;header1)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.width,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;        if magic != b&amp;quot;BM&amp;quot;:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;            raise RuntimeError(&amp;quot;%s is not in .BMP format&amp;quot; % inpname)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;        if self.header_size not in (40, 52, 56, 108, 124):&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;            raise RuntimeError(&amp;quot;%s has an unsupported header type (%d)&amp;quot; % \&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;                    (inpname, self.header_size))&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;        # self.header_size includes its own size of four bytes&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;        header2 = fp.read(self.header_size - 4)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;(&lt;/ins&gt;self.width,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.height,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.height,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_planes,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_planes,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l107&quot; &gt;Line 107:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 118:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.vert_res,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.vert_res,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_colors,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_colors,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_important_colors) = struct.unpack(&amp;quot;&amp;lt;&lt;del class=&quot;diffchange diffchange-inline&quot;&gt;2s6L2H6L&lt;/del&gt;&amp;quot;, &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;header&lt;/del&gt;)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.num_important_colors) = struct.unpack(&amp;quot;&amp;lt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;2L2H6L&lt;/ins&gt;&amp;quot;, &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;header2[0:36]&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;        self.extra = header2[36:]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         # Check various header fields for unsupported stuff&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         # Check various header fields for unsupported stuff&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if magic != b&amp;quot;BM&amp;quot;:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if magic != b&amp;quot;BM&amp;quot;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             raise RuntimeError(&amp;quot;%s is not in .BMP format&amp;quot; % inpname)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             raise RuntimeError(&amp;quot;%s is not in .BMP format&amp;quot; % inpname)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        if self.header_size != 40:&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;            raise RuntimeError(&amp;quot;%s has an unsupported header type (%d)&amp;quot; % \&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                    (inpname, self.header_size))&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if self.num_planes != 1:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if self.num_planes != 1:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l121&quot; &gt;Line 121:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 129:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     (inpname, self.num_planes))&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     (inpname, self.num_planes))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if self.compression &lt;del class=&quot;diffchange diffchange-inline&quot;&gt;!= &lt;/del&gt;0:&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         if self.compression &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;not in (&lt;/ins&gt;0&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;, 3)&lt;/ins&gt;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             raise RuntimeError(&amp;quot;%s is compressed (%d), and not supported&amp;quot; % \&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             raise RuntimeError(&amp;quot;%s is compressed (%d), and not supported&amp;quot; % \&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     (inpname, self.compression))&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     (inpname, self.compression))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l168&quot; &gt;Line 168:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 176:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             for y in range(0, self.height):&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             for y in range(0, self.height):&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row_bytes = fp.read(row_size)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row_bytes = fp.read(row_size)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row_bytes = map(&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row_bytes = &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;list(&lt;/ins&gt;map(&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         lambda x : struct.unpack('&amp;lt;1B', x)[0],&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         lambda x : struct.unpack('&amp;lt;1B', &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;bytearray([&lt;/ins&gt;x&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;])&lt;/ins&gt;)[0],&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         row_bytes)&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         row_bytes&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;)&lt;/ins&gt;)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row = [ None ] * self.width&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 row = [ None ] * self.width&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.image[self.height - 1 - y] = row&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.image[self.height - 1 - y] = row&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l176&quot; &gt;Line 176:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 184:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     x2 = x * bytes_per_pixel&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     x2 = x * bytes_per_pixel&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     row[x] = tuple(row_bytes[x2 : x2 + 3])&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     row[x] = tuple(row_bytes[x2 : x2 + 3])&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        self.compression = 0&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.bits_per_pixel = 24&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;         self.bits_per_pixel = 24&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l666&quot; &gt;Line 666:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 675:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.num_colors,&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.num_colors,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.num_important_colors))&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 self.num_important_colors))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt; &lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;        fp.write(self.extra)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# Convert one bitmap file&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #222; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;# Convert one bitmap file&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Ray Chason</name></author>
		
	</entry>
	<entry>
		<id>https://nethackwiki.com/index.php?title=Tileset/tile2500.py&amp;diff=202712&amp;oldid=prev</id>
		<title>Ray Chason: Upload and describe this program</title>
		<link rel="alternate" type="text/html" href="https://nethackwiki.com/index.php?title=Tileset/tile2500.py&amp;diff=202712&amp;oldid=prev"/>
		<updated>2026-05-03T14:52:12Z</updated>

		<summary type="html">&lt;p&gt;Upload and describe this program&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Here is a [[wikipedia:Python (programming language)|Python]] program that will take a [[NetHack 3.6.7]] [[tileset]] in BMP format and convert it to a form usable with 5.0.0.&lt;br /&gt;
&lt;br /&gt;
If you have a [[Mac]] or [[Linux]], you probably already have Python (or can install it with your package manager). Windows users can run this with [https://www.activestate.com/activepython ActiveState Python].&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;./tile2500.py -h&amp;lt;/code&amp;gt; for a complete list of options. Most tilesets convert without needing any options; the program assumes that the image contains 40 tiles per row and that tiles are square, unless the tile size is given. The output file name just adds &amp;quot;-500&amp;quot; before the &amp;quot;.bmp&amp;quot; suffix, unless the command line specifies a different name.&lt;br /&gt;
&lt;br /&gt;
New tiles are created as follows:&lt;br /&gt;
&lt;br /&gt;
* Monsters now have separate tiles for male and female forms. This includes single-gender monsters. If separate tiles are not available in the 3.6.7 tileset, the single tile is duplicated.&lt;br /&gt;
* The wooden shield tile is duplicated to make shields of drain resistance and shock resistance. This duplication should likely be left alone.&lt;br /&gt;
* Tiles for stairs and ladders are duplicated to make branch stairs and branch ladders.&lt;br /&gt;
* The single [[altar]] tile is duplicated to make unaligned, chaotic, neutral, lawful and &amp;quot;other&amp;quot; altars.&lt;br /&gt;
* The [[molten lava]] tile is duplicated to make a tile for the [[wall of lava]].&lt;br /&gt;
* The positions for &amp;quot;unexplored&amp;quot; and &amp;quot;nothing&amp;quot; use the &amp;quot;stone&amp;quot; tile.&lt;br /&gt;
&lt;br /&gt;
The following tiles are replaced with a red X box as a placeholder; for monsters, this applies to the male and female forms and also the statues:&lt;br /&gt;
* displacer beast&lt;br /&gt;
* baby gold dragon&lt;br /&gt;
* gold dragon&lt;br /&gt;
* genetic engineer&lt;br /&gt;
* generic strange&lt;br /&gt;
* generic weapon&lt;br /&gt;
* generic armor&lt;br /&gt;
* generic ring&lt;br /&gt;
* generic amulet&lt;br /&gt;
* generic tool&lt;br /&gt;
* generic food&lt;br /&gt;
* generic potion&lt;br /&gt;
* generic scroll&lt;br /&gt;
* generic spellbook&lt;br /&gt;
* generic wand&lt;br /&gt;
* generic coin&lt;br /&gt;
* generic gem&lt;br /&gt;
* generic large rock&lt;br /&gt;
* generic iron ball&lt;br /&gt;
* generic iron chain&lt;br /&gt;
* generic venom&lt;br /&gt;
* silver mace&lt;br /&gt;
* crystal helmet&lt;br /&gt;
* gold dragon scale mail&lt;br /&gt;
* gold dragon scales&lt;br /&gt;
* perforated amulet&lt;br /&gt;
* cubical amulet&lt;br /&gt;
* checkered spellbook&lt;br /&gt;
* redwood wand&lt;br /&gt;
* engraving in a room&lt;br /&gt;
* engraving in a corridor&lt;br /&gt;
* trapped door&lt;br /&gt;
* trapped chest&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
# tile2500.py -- convert NetHack 3.6.x tile sets most of the way to 5.0.0&lt;br /&gt;
#&lt;br /&gt;
# Copyright (c) 2026, Ray Chason&lt;br /&gt;
# All rights reserved.&lt;br /&gt;
#&lt;br /&gt;
# Redistribution and use in source and binary forms, with or without&lt;br /&gt;
# modification, are permitted provided that the following conditions are met:&lt;br /&gt;
#&lt;br /&gt;
# 1. Redistributions of source code must retain the above copyright notice, this&lt;br /&gt;
#    list of conditions and the following disclaimer.&lt;br /&gt;
#&lt;br /&gt;
# 2. Redistributions in binary form must reproduce the above copyright notice,&lt;br /&gt;
#    this list of conditions and the following disclaimer in the documentation&lt;br /&gt;
#    and/or other materials provided with the distribution.&lt;br /&gt;
#&lt;br /&gt;
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &amp;quot;AS IS&amp;quot;&lt;br /&gt;
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&lt;br /&gt;
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE&lt;br /&gt;
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE&lt;br /&gt;
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR&lt;br /&gt;
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF&lt;br /&gt;
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS&lt;br /&gt;
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN&lt;br /&gt;
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)&lt;br /&gt;
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE&lt;br /&gt;
# POSSIBILITY OF SUCH DAMAGE.&lt;br /&gt;
&lt;br /&gt;
import argparse&lt;br /&gt;
import os.path&lt;br /&gt;
import struct&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
# A Bitmap image, with some extra methods for tile mapping&lt;br /&gt;
class Bitmap(object):&lt;br /&gt;
    def __init__(self, inpname):&lt;br /&gt;
        # TODO: This assumes the BITMAPINFOHEADER structure. Add support for&lt;br /&gt;
        # other bitmap formats.&lt;br /&gt;
&lt;br /&gt;
        # Read the header&lt;br /&gt;
        fp = open(inpname, &amp;quot;rb&amp;quot;)&lt;br /&gt;
        header = fp.read(54)&lt;br /&gt;
&lt;br /&gt;
        (magic,&lt;br /&gt;
        self.bmp_size,&lt;br /&gt;
        reserved,&lt;br /&gt;
        self.image_offset,&lt;br /&gt;
        self.header_size,&lt;br /&gt;
        self.width,&lt;br /&gt;
        self.height,&lt;br /&gt;
        self.num_planes,&lt;br /&gt;
        self.bits_per_pixel,&lt;br /&gt;
        self.compression,&lt;br /&gt;
        self.image_size,&lt;br /&gt;
        self.horiz_res,&lt;br /&gt;
        self.vert_res,&lt;br /&gt;
        self.num_colors,&lt;br /&gt;
        self.num_important_colors) = struct.unpack(&amp;quot;&amp;lt;2s6L2H6L&amp;quot;, header)&lt;br /&gt;
&lt;br /&gt;
        # Check various header fields for unsupported stuff&lt;br /&gt;
        if magic != b&amp;quot;BM&amp;quot;:&lt;br /&gt;
            raise RuntimeError(&amp;quot;%s is not in .BMP format&amp;quot; % inpname)&lt;br /&gt;
&lt;br /&gt;
        if self.header_size != 40:&lt;br /&gt;
            raise RuntimeError(&amp;quot;%s has an unsupported header type (%d)&amp;quot; % \&lt;br /&gt;
                    (inpname, self.header_size))&lt;br /&gt;
&lt;br /&gt;
        if self.num_planes != 1:&lt;br /&gt;
            raise RuntimeError(&amp;quot;%s has %d planes, not supported&amp;quot; % \&lt;br /&gt;
                    (inpname, self.num_planes))&lt;br /&gt;
&lt;br /&gt;
        if self.compression != 0:&lt;br /&gt;
            raise RuntimeError(&amp;quot;%s is compressed (%d), and not supported&amp;quot; % \&lt;br /&gt;
                    (inpname, self.compression))&lt;br /&gt;
&lt;br /&gt;
        if self.bits_per_pixel not in (1, 2, 4, 8, 24, 32):&lt;br /&gt;
            raise RuntimeError(&amp;quot;%s has %d bits per pixel, not supported&amp;quot; % \&lt;br /&gt;
                    (inpname, self.bits_per_pixel))&lt;br /&gt;
&lt;br /&gt;
        # Read the palette&lt;br /&gt;
        if self.bits_per_pixel &amp;lt;= 8:&lt;br /&gt;
            if self.num_colors == 0:&lt;br /&gt;
                self.num_colors = 1 &amp;lt;&amp;lt; self.bits_per_pixel&lt;br /&gt;
            self.palette = [ None ] * self.num_colors&lt;br /&gt;
            for i in range(0, self.num_colors):&lt;br /&gt;
                b, g, r, z = struct.unpack(&amp;quot;&amp;lt;4B&amp;quot;, fp.read(4))&lt;br /&gt;
                self.palette[i] = (b, g, r)&lt;br /&gt;
        else:&lt;br /&gt;
            self.palette = None&lt;br /&gt;
&lt;br /&gt;
        # Read the pixels&lt;br /&gt;
        fp.seek(self.image_offset)&lt;br /&gt;
        self.image = [ None ] * self.height&lt;br /&gt;
        row_size = ((self.bits_per_pixel * self.width + 31) // 32) * 4&lt;br /&gt;
        if self.bits_per_pixel &amp;lt;= 8:&lt;br /&gt;
            # Palettized image; convert to 24 bit&lt;br /&gt;
            pixels_per_byte = 8 // self.bits_per_pixel&lt;br /&gt;
            mask = (1 &amp;lt;&amp;lt; self.bits_per_pixel) - 1&lt;br /&gt;
            for y in range(0, self.height):&lt;br /&gt;
                row_bytes = fp.read(row_size)&lt;br /&gt;
                row_bytes = list(map(&lt;br /&gt;
                        lambda x : struct.unpack('&amp;lt;1B', bytearray([x]))[0],&lt;br /&gt;
                        row_bytes))&lt;br /&gt;
                row = [ None ] * self.width&lt;br /&gt;
                self.image[self.height - 1 - y] = row&lt;br /&gt;
                shift = 8&lt;br /&gt;
                for x in range(0, self.width):&lt;br /&gt;
                    if shift &amp;lt;= 0:&lt;br /&gt;
                        shift = 8&lt;br /&gt;
                    shift -= self.bits_per_pixel&lt;br /&gt;
                    x_hi = x // pixels_per_byte&lt;br /&gt;
                    i = (row_bytes[x_hi] &amp;gt;&amp;gt; shift) &amp;amp; mask&lt;br /&gt;
                    row[x] = self.palette[i]&lt;br /&gt;
        else:&lt;br /&gt;
            # 24 or 32 bits per pixel&lt;br /&gt;
            bytes_per_pixel = self.bits_per_pixel // 8&lt;br /&gt;
            for y in range(0, self.height):&lt;br /&gt;
                row_bytes = fp.read(row_size)&lt;br /&gt;
                row_bytes = map(&lt;br /&gt;
                        lambda x : struct.unpack('&amp;lt;1B', x)[0],&lt;br /&gt;
                        row_bytes)&lt;br /&gt;
                row = [ None ] * self.width&lt;br /&gt;
                self.image[self.height - 1 - y] = row&lt;br /&gt;
                for x in range(0, self.width):&lt;br /&gt;
                    x2 = x * bytes_per_pixel&lt;br /&gt;
                    row[x] = tuple(row_bytes[x2 : x2 + 3])&lt;br /&gt;
        self.bits_per_pixel = 24&lt;br /&gt;
&lt;br /&gt;
        # These are yet unknown&lt;br /&gt;
        self.tile_width = None&lt;br /&gt;
        self.tile_height = None&lt;br /&gt;
        self.tiles_per_row = None&lt;br /&gt;
        self.tile_rows = None&lt;br /&gt;
        self.tiles = None&lt;br /&gt;
&lt;br /&gt;
    # Split the image into tiles&lt;br /&gt;
    def split(self, tile_width, tile_height):&lt;br /&gt;
        self.tile_width = tile_width&lt;br /&gt;
        self.tile_height = tile_height&lt;br /&gt;
        self.tiles_per_row = self.width // tile_width&lt;br /&gt;
        self.tile_rows = self.height // tile_height&lt;br /&gt;
        num_tiles = self.tiles_per_row * self.tile_rows&lt;br /&gt;
        self.tiles = [ None ] * num_tiles&lt;br /&gt;
&lt;br /&gt;
        for t in range(0, num_tiles):&lt;br /&gt;
            tile = [ None ] * tile_height&lt;br /&gt;
            self.tiles[t] = tile&lt;br /&gt;
            t_col = t % self.tiles_per_row&lt;br /&gt;
            t_row = t // self.tiles_per_row&lt;br /&gt;
            t_x = t_col * tile_width&lt;br /&gt;
            t_y = t_row * tile_height&lt;br /&gt;
            for y in range(0, tile_height):&lt;br /&gt;
                tile[y] = self.image[t_y + y][t_x : t_x + tile_width]&lt;br /&gt;
&lt;br /&gt;
    # Rearrange the tiles to match the NetHack 5.0.0 order&lt;br /&gt;
    def remap(self):&lt;br /&gt;
        # Monster map. This is used for monsters themselves, and also for&lt;br /&gt;
        # statues.&lt;br /&gt;
        # Each position in the array stands for two tiles. Where 3.6.x uses&lt;br /&gt;
        # a single tile for male and female monsters (or the monster is single&lt;br /&gt;
        # gender), here we use a single number.&lt;br /&gt;
        # A tuple of two elements maps separate 3.6.x tiles for male and female&lt;br /&gt;
        # monsters.&lt;br /&gt;
        # If the element is None, use the placeholder tile.&lt;br /&gt;
        # The invisible monster marker is ungendered and is placed in tile_map.&lt;br /&gt;
        monster_map = [&lt;br /&gt;
            # giant ant through tiger&lt;br /&gt;
              0,   1,   2,   3,   4,   5,   6,   7,   8,   9,&lt;br /&gt;
             10,  11,  12,  13,  14,  15,  16,  17,  18,  19,&lt;br /&gt;
             20,  21,  22,  23,  24,  25,  26,  27,  28,  29,&lt;br /&gt;
             30,  31,  32,  33,  34,  35,  36,  37,  38,  39,&lt;br /&gt;
             40,&lt;br /&gt;
            # New monster: displacer beast&lt;br /&gt;
            None,&lt;br /&gt;
            # gremlin through baby gray dragon&lt;br /&gt;
             41,  42,  43,  44,  45,  46,  47,  48,  49,  50,&lt;br /&gt;
             51,  52,  53,  54,  55,  56,  57,  58,  59,  60,&lt;br /&gt;
             61,  62,  63,  64,  65,  66,  67,  68,  69,  70,&lt;br /&gt;
             71,  72,  73,  74,  75,  76,  77,  78,  79,  80,&lt;br /&gt;
             81,  82,  83,  84,  85,  86,  87,  88,  89,  90,&lt;br /&gt;
             91,  92,  93,  94,  95,  96,  97,  98,  99, 100,&lt;br /&gt;
            101, 102, 103, 104, 105, 106, 107, 108, 109, 110,&lt;br /&gt;
            111, 112, 113, 114, 115, 116, 117, 118, 119, 120,&lt;br /&gt;
            121, 122, 123, 124, 125, 126, 127, 128, 129, 130,&lt;br /&gt;
            131, 132, 133, 134,&lt;br /&gt;
            # New monster: baby gold dragon&lt;br /&gt;
            None,&lt;br /&gt;
            # baby silver dragon through gray dragon&lt;br /&gt;
            135, 136, 137, 138, 139, 140, 141, 142, 143, 144,&lt;br /&gt;
            # New monster: gold dragon&lt;br /&gt;
            None,&lt;br /&gt;
            # silver dragon through quantum mechanic&lt;br /&gt;
            145, 146, 147, 148, 149, 150, 151, 152, 153, 154,&lt;br /&gt;
            155, 156, 157, 158, 159, 160, 161, 162, 163, 164,&lt;br /&gt;
            165, 166, 167, 168, 169, 170, 171, 172, 173, 174,&lt;br /&gt;
            175, 176, 177, 178, 179, 180, 181, 182, 183, 184,&lt;br /&gt;
            185, 186, 187, 188, 189, 190, 191, 192, 193, 194,&lt;br /&gt;
            195, 196, 197, 198, 199, 200, 201, 202, 203, 204,&lt;br /&gt;
            205, 206, 207, 208, 209, 210, 211, 212,&lt;br /&gt;
            # New monster: genetic engineer&lt;br /&gt;
            None,&lt;br /&gt;
            # rust monster through water demon&lt;br /&gt;
            213, 214, 215, 216, 217, 218, 219, 220, 221, 222,&lt;br /&gt;
            223, 224, 225, 226, 227, 228, 229, 230, 231, 232,&lt;br /&gt;
            233, 234, 235, 236, 237, 238, 239, 240, 241, 242,&lt;br /&gt;
            243, 244, 245, 246, 247, 248, 249, 250, 251, 252,&lt;br /&gt;
            253, 254, 255, 256, 257, 258, 259, 260, 261, 262,&lt;br /&gt;
            263, 264, 265, 266, 267, 268, 269, 270, 271, 272,&lt;br /&gt;
            273, 274, 275, 276, 277, 278, 279, 280, 281, 282,&lt;br /&gt;
            283, 284, 285, 286, 287, 288, 289, 290, 291, 292,&lt;br /&gt;
            # incubus and succubus map to amorous demon&lt;br /&gt;
            (295, 293),&lt;br /&gt;
            # horned devil is reordered&lt;br /&gt;
            294,&lt;br /&gt;
            # erinys through barbarian&lt;br /&gt;
            296, 297, 298, 299, 300, 301, 302, 303, 304, 305,&lt;br /&gt;
            306, 307, 308, 309, 310, 311, 312, 313, 314, 315,&lt;br /&gt;
            316, 317, 318, 319, 320, 321, 322, 323, 324, 325,&lt;br /&gt;
            326, 327, 328, 329, 330, 331, 332, 333, 334, 335,&lt;br /&gt;
            336,&lt;br /&gt;
            # caveman and cavewoman map to cave dweller&lt;br /&gt;
            (337, 338),&lt;br /&gt;
            # healer through monk&lt;br /&gt;
            339, 340, 341,&lt;br /&gt;
            # priest and priestess map to cleric&lt;br /&gt;
            (342, 343),&lt;br /&gt;
            # ranger through apprentice&lt;br /&gt;
            344, 345, 346, 347, 348, 349, 350, 351, 352, 353,&lt;br /&gt;
            354, 355, 356, 357, 358, 359, 360, 361, 362, 363,&lt;br /&gt;
            364, 365, 366, 367, 368, 369, 370, 371, 372, 373,&lt;br /&gt;
            374, 375, 376, 377, 378, 379, 380, 381, 382, 383,&lt;br /&gt;
            384, 385, 386, 387, 388, 389, 390, 391, 392&lt;br /&gt;
        ]&lt;br /&gt;
        # Place the tile_map tiles starting here&lt;br /&gt;
        tile_map_begin = len(monster_map) * 2&lt;br /&gt;
        # Map for things other than monsters.&lt;br /&gt;
        # Each position in the array stands for one tile, and indexes the tile&lt;br /&gt;
        # position in the 3.6.x tileset.&lt;br /&gt;
        # If the element is None, use the placeholder tile.&lt;br /&gt;
        tile_map = [&lt;br /&gt;
            # invisible monster&lt;br /&gt;
            393,&lt;br /&gt;
            # strange object&lt;br /&gt;
            394+0,&lt;br /&gt;
            # New tiles for generic unseen objects&lt;br /&gt;
            None, # generic strange&lt;br /&gt;
            None, # generic weapon&lt;br /&gt;
            None, # generic armor&lt;br /&gt;
            None, # generic ring&lt;br /&gt;
            None, # generic amulet&lt;br /&gt;
            None, # generic tool&lt;br /&gt;
            None, # generic food&lt;br /&gt;
            None, # generic potion&lt;br /&gt;
            None, # generic scroll&lt;br /&gt;
            None, # generic spellbook&lt;br /&gt;
            None, # generic wand&lt;br /&gt;
            None, # generic coin&lt;br /&gt;
            None, # generic gem&lt;br /&gt;
            None, # generic large rock&lt;br /&gt;
            None, # generic iron ball&lt;br /&gt;
            None, # generic iron chain&lt;br /&gt;
            None, # generic venom&lt;br /&gt;
            # arrow through glaive&lt;br /&gt;
            395, 396, 397, 398, 399,&lt;br /&gt;
            400, 401, 402, 403, 404, 405, 406, 407, 408, 409,&lt;br /&gt;
            410, 411, 412, 413, 414, 415, 416, 417, 418, 419,&lt;br /&gt;
            420, 421, 422, 423, 424, 425, 426, 427, 428, 429,&lt;br /&gt;
            430, 431, 432, 433, 434, 435, 436, 437, 438, 439,&lt;br /&gt;
            # lance and mace are reordered&lt;br /&gt;
            441, 442, 443,&lt;br /&gt;
            445, 446, 447, 448, 449,&lt;br /&gt;
            444,&lt;br /&gt;
            440,&lt;br /&gt;
            450,&lt;br /&gt;
            # New tile for silver mace&lt;br /&gt;
            None,&lt;br /&gt;
            # morning star through dented pot&lt;br /&gt;
            451, 452, 453, 454, 455, 456, 457, 458, 459,&lt;br /&gt;
            460, 461, 462, 463, 464, 465, 466, 467, 468, 469,&lt;br /&gt;
            470, 471,&lt;br /&gt;
            # Helm of brilliance becomes a crystal helmet at this position&lt;br /&gt;
            None,&lt;br /&gt;
            # plumed helmet through gray dragon scale mail&lt;br /&gt;
            472, 473, 474, 475, 476,&lt;br /&gt;
            # New tile for gold dragon scale mail&lt;br /&gt;
            None,&lt;br /&gt;
            # silver dragon scale mail through gray dragon scales&lt;br /&gt;
            477, 478, 479, 480, 481, 482, 483, 484, 485, 486,&lt;br /&gt;
            # New tile for gold dragon scales&lt;br /&gt;
            None,&lt;br /&gt;
            # silver dragon scales through wooden shield&lt;br /&gt;
            487, 488, 489,&lt;br /&gt;
            490, 491, 492, 493, 494, 495, 496, 497, 498, 499,&lt;br /&gt;
            500, 501, 502, 503, 504, 505, 506, 507, 508, 509,&lt;br /&gt;
            510, 511, 512, 513, 514, 515, 516, 517, 518, 519,&lt;br /&gt;
            520, 521, 522, 523, 524, 525,&lt;br /&gt;
            # wooden shield duplicated to make shields of drain and shock&lt;br /&gt;
            # resistance&lt;br /&gt;
            525, 525,&lt;br /&gt;
            # blue and green shield through octagonal amulet&lt;br /&gt;
            526, 527, 528, 529,&lt;br /&gt;
            530, 531, 532, 533, 534, 535, 536, 537, 538, 539,&lt;br /&gt;
            540, 541, 542, 543, 544, 545, 546, 547, 548, 549,&lt;br /&gt;
            550, 551, 552, 553, 554, 555, 556, 557, 558, 559,&lt;br /&gt;
            560, 561, 562, 563, 564, 565, 566, 567, 568, 569,&lt;br /&gt;
            570, 571, 572, 573, 574, 575, 576, 577, 578, 579,&lt;br /&gt;
            580, 581, 582,&lt;br /&gt;
            # New tile for perforated amulet&lt;br /&gt;
            None,&lt;br /&gt;
            # New tile for cubical amulet&lt;br /&gt;
            None,&lt;br /&gt;
            # Fake AoY through thick spellbook&lt;br /&gt;
            583, 584, 585, 586, 587, 588, 589,&lt;br /&gt;
            590, 591, 592, 593, 594, 595, 596, 597, 598, 599,&lt;br /&gt;
            600, 601, 602, 603, 604, 605, 606, 607, 608, 609,&lt;br /&gt;
            610, 611, 612, 613, 614, 615, 616, 617, 618, 619,&lt;br /&gt;
            620, 621, 622, 623, 624, 625, 626, 627, 628, 629,&lt;br /&gt;
            630, 631, 632, 633, 634, 635, 636, 637, 638, 639,&lt;br /&gt;
            640, 641, 642, 643, 644, 645, 646, 647, 648, 649,&lt;br /&gt;
            650, 651, 652, 653, 654, 655, 656, 657, 658, 659,&lt;br /&gt;
            660, 661, 662, 663, 664, 665, 666, 667, 668, 669,&lt;br /&gt;
            670, 671, 672, 673, 674, 675, 676, 677, 678, 679,&lt;br /&gt;
            680, 681, 682, 683, 684, 685, 686, 687, 688, 689,&lt;br /&gt;
            690, 691, 692, 693, 694, 695, 696, 697, 698, 699,&lt;br /&gt;
            700, 701, 702, 703, 704, 705, 706, 707, 708, 709,&lt;br /&gt;
            710, 711, 712, 713, 714, 715, 716, 717, 718, 719,&lt;br /&gt;
            720, 721, 722, 723, 724, 725, 726, 727, 728, 729,&lt;br /&gt;
            730, 731, 732, 733, 734, 735, 736, 737, 738, 739,&lt;br /&gt;
            740, 741, 742, 743, 744, 745, 746, 747, 748, 749,&lt;br /&gt;
            750, 751, 752, 753, 754, 755, 756, 757, 758, 759,&lt;br /&gt;
            760, 761, 762, 763, 764, 765, 766, 767, 768, 769,&lt;br /&gt;
            770, 771, 772, 773, 774, 775, 776,&lt;br /&gt;
            # New tile for checkered spellbook&lt;br /&gt;
            None,&lt;br /&gt;
            # plain spellbook through pine wand&lt;br /&gt;
            777, 778, 779, 780, 781, 782, 783, 784,&lt;br /&gt;
            # New tile for redwood wand&lt;br /&gt;
            None,&lt;br /&gt;
            # Oak wand through acid venom&lt;br /&gt;
            785, 786, 787, 788, 789,&lt;br /&gt;
            790, 791, 792, 793, 794, 795, 796, 797, 798, 799,&lt;br /&gt;
            800, 801, 802, 803, 804, 805, 806, 807, 808, 809,&lt;br /&gt;
            810, 811, 812, 813, 814, 815, 816, 817, 818, 819,&lt;br /&gt;
            820, 821, 822, 823, 824, 825, 826, 827, 828, 829,&lt;br /&gt;
            830, 831, 832, 833, 834, 835, 836, 837, 838, 839,&lt;br /&gt;
            840, 841, 842, 843, 844, 845, 846, 847, 848, 849,&lt;br /&gt;
&lt;br /&gt;
            # Dungeon features&lt;br /&gt;
            # stone through dark part of a room&lt;br /&gt;
            850, 851, 852, 853, 854, 855, 856, 857, 858, 859,&lt;br /&gt;
            860, 861, 862, 863, 864, 865, 866, 867, 868, 869,&lt;br /&gt;
            870,&lt;br /&gt;
            # New tile for engraving in a room&lt;br /&gt;
            None,&lt;br /&gt;
            # corridor and lit corridor&lt;br /&gt;
            871, 872,&lt;br /&gt;
            # New tile for engraving in a corridor&lt;br /&gt;
            None,&lt;br /&gt;
            # staircase up through ladder down&lt;br /&gt;
            873, 874, 875, 876,&lt;br /&gt;
            # staircases and ladders duplicated for branch stairs and ladders&lt;br /&gt;
            873, 874, 875, 876,&lt;br /&gt;
            # altar duplicated: unaligned, chaotic, neutral, lawful, other&lt;br /&gt;
            877, 877, 877, 877, 877,&lt;br /&gt;
            # grave through molten lava&lt;br /&gt;
            878, 879, 880, 881, 882, 883, 884,&lt;br /&gt;
            # molten lava duplicated for wall of lava&lt;br /&gt;
            884,&lt;br /&gt;
            # vertical open drawbridge through vibrating square&lt;br /&gt;
            885, 886, 887, 888, 889,&lt;br /&gt;
            890, 891, 892, 893, 894, 895, 896, 897, 898, 899,&lt;br /&gt;
            900, 901, 902, 903, 904, 905, 906, 907, 908, 909,&lt;br /&gt;
            910, 911, 912, 913, 914,&lt;br /&gt;
            # New tile for trapped door&lt;br /&gt;
            None,&lt;br /&gt;
            # New tile for trapped chest&lt;br /&gt;
            None,&lt;br /&gt;
            # missile zaps through acid zaps (reordered)&lt;br /&gt;
            1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009,&lt;br /&gt;
            1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019,&lt;br /&gt;
            1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029,&lt;br /&gt;
            1030, 1031,&lt;br /&gt;
            # dig beam through explosion frosty bottom right&lt;br /&gt;
            # Tiles 915 through 918 are unused and are deleted&lt;br /&gt;
            919,&lt;br /&gt;
            920, 921, 922, 923, 924, 925, 926, 927, 928, 929,&lt;br /&gt;
            930, 931, 932, 933, 934, 935, 936, 937, 938, 939,&lt;br /&gt;
            940, 941, 942, 943, 944, 945, 946, 947, 948, 949,&lt;br /&gt;
            950, 951, 952, 953, 954, 955, 956, 957, 958, 959,&lt;br /&gt;
            960, 961, 962, 963, 964, 965, 966, 967, 968, 969,&lt;br /&gt;
            970, 971, 972, 973, 974, 975, 976, 977, 978, 979,&lt;br /&gt;
            980, 981, 982, 983, 984, 985, 986, 987, 988, 989,&lt;br /&gt;
            990, 991, 992, 993, 994, 995, 996, 997, 998, 999,&lt;br /&gt;
            # warnings&lt;br /&gt;
            1032, 1033, 1034, 1035, 1036, 1037,&lt;br /&gt;
            # unexplored and nothing reuse the tile for stone&lt;br /&gt;
            850, 850,&lt;br /&gt;
            # mines walls through sokoban walls&lt;br /&gt;
            1038, 1039,&lt;br /&gt;
            1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049,&lt;br /&gt;
            1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059,&lt;br /&gt;
            1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069,&lt;br /&gt;
            1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079,&lt;br /&gt;
            1080, 1081&lt;br /&gt;
        ]&lt;br /&gt;
        # Place the statues starting here&lt;br /&gt;
        statues_begin = tile_map_begin + len(tile_map)&lt;br /&gt;
        # First statue tile in the 3.6.x map&lt;br /&gt;
        statues_begin_36 = 1082&lt;br /&gt;
        # Place the invisible monster statue here&lt;br /&gt;
        invis_monster_statue = statues_begin + len(monster_map) * 2&lt;br /&gt;
        invis_monster_statue_36 = statues_begin_36 + tile_map[0]&lt;br /&gt;
&lt;br /&gt;
        # The new tile map&lt;br /&gt;
        map_size = invis_monster_statue + 1&lt;br /&gt;
        new_tiles = [ None ] * map_size&lt;br /&gt;
&lt;br /&gt;
        # Map the monsters and the statues&lt;br /&gt;
        for i in range(0, len(monster_map)):&lt;br /&gt;
            i_m = i*2 + 0   # male&lt;br /&gt;
            i_f = i*2 + 1   # female&lt;br /&gt;
            m = monster_map[i]&lt;br /&gt;
            if m is None:&lt;br /&gt;
                new_tiles[i_m] = self.placeHolderTile()&lt;br /&gt;
                new_tiles[i_f] = self.placeHolderTile()&lt;br /&gt;
                new_tiles[i_m+statues_begin] = self.placeHolderTile()&lt;br /&gt;
                new_tiles[i_f+statues_begin] = self.placeHolderTile()&lt;br /&gt;
            elif isinstance(m, tuple):&lt;br /&gt;
                new_tiles[i_m] = self.tiles[m[0]]&lt;br /&gt;
                new_tiles[i_f] = self.tiles[m[1]]&lt;br /&gt;
                new_tiles[i_m+statues_begin] = self.tiles[m[0]+statues_begin_36]&lt;br /&gt;
                new_tiles[i_f+statues_begin] = self.tiles[m[1]+statues_begin_36]&lt;br /&gt;
            else:&lt;br /&gt;
                new_tiles[i_m] = self.tiles[m]&lt;br /&gt;
                new_tiles[i_f] = self.tiles[m]&lt;br /&gt;
                new_tiles[i_m+statues_begin] = self.tiles[m+statues_begin_36]&lt;br /&gt;
                new_tiles[i_f+statues_begin] = self.tiles[m+statues_begin_36]&lt;br /&gt;
&lt;br /&gt;
        # Map the invisible monster, the objects and the dungeon features&lt;br /&gt;
        for i in range(0, len(tile_map)):&lt;br /&gt;
            m = tile_map[i]&lt;br /&gt;
            if m is None:&lt;br /&gt;
                new_tiles[i+tile_map_begin] = self.placeHolderTile()&lt;br /&gt;
            else:&lt;br /&gt;
                new_tiles[i+tile_map_begin] = self.tiles[m]&lt;br /&gt;
&lt;br /&gt;
        # Place the invisible monster statue&lt;br /&gt;
        new_tiles[invis_monster_statue] = self.tiles[invis_monster_statue_36]&lt;br /&gt;
&lt;br /&gt;
        # Update the number of tile rows&lt;br /&gt;
        self.tile_rows = (len(new_tiles) + self.tiles_per_row - 1) \&lt;br /&gt;
                // self.tiles_per_row&lt;br /&gt;
&lt;br /&gt;
        # Add some blank tiles to fill out the last row&lt;br /&gt;
        num_tiles = self.tile_rows * self.tiles_per_row&lt;br /&gt;
        if len(new_tiles) &amp;lt; num_tiles:&lt;br /&gt;
            blank_tile = self.blankTile()&lt;br /&gt;
            while len(new_tiles) &amp;lt; num_tiles:&lt;br /&gt;
                new_tiles.append(blank_tile)&lt;br /&gt;
        self.tiles = new_tiles&lt;br /&gt;
&lt;br /&gt;
    # Rejoin the tiles into a new image&lt;br /&gt;
    def join(self):&lt;br /&gt;
        # New image dimensions; normally width will be unchanged&lt;br /&gt;
        self.width = self.tiles_per_row * self.tile_width&lt;br /&gt;
        self.height = self.tile_rows * self.tile_height&lt;br /&gt;
&lt;br /&gt;
        # Create blank image&lt;br /&gt;
        self.image = [ None ] * self.height&lt;br /&gt;
        for i in range(0, self.height):&lt;br /&gt;
            self.image[i] = []&lt;br /&gt;
&lt;br /&gt;
        # Add each tile to the end of its row&lt;br /&gt;
        for i in range(0, len(self.tiles)):&lt;br /&gt;
            t_row = i // self.tiles_per_row&lt;br /&gt;
            t_y = t_row * self.tile_height&lt;br /&gt;
            tile = self.tiles[i]&lt;br /&gt;
            for j in range(0, self.tile_height):&lt;br /&gt;
                self.image[t_y + j].extend(tile[j])&lt;br /&gt;
&lt;br /&gt;
    # Write the image to the output file&lt;br /&gt;
    def write(self, outname):&lt;br /&gt;
        fp = open(outname, &amp;quot;wb&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        # Write a palettized image if possible without degradation&lt;br /&gt;
        self.buildPalette()&lt;br /&gt;
        palette_map = {}&lt;br /&gt;
        if self.bits_per_pixel &amp;lt;= 8:&lt;br /&gt;
            for i in range(0, len(self.palette)):&lt;br /&gt;
                palette_map[self.palette[i]] = i&lt;br /&gt;
&lt;br /&gt;
        # Write the header, with placeholders for some fields&lt;br /&gt;
        self.writeHeader(fp)&lt;br /&gt;
&lt;br /&gt;
        # Write the palette if any&lt;br /&gt;
        if self.bits_per_pixel &amp;lt;= 8:&lt;br /&gt;
            for i in range(0, self.num_colors):&lt;br /&gt;
                fp.write(struct.pack(&amp;quot;&amp;lt;4B&amp;quot;,&lt;br /&gt;
                        self.palette[i][0],&lt;br /&gt;
                        self.palette[i][1],&lt;br /&gt;
                        self.palette[i][2],&lt;br /&gt;
                        0))&lt;br /&gt;
        self.image_offset = fp.tell()&lt;br /&gt;
&lt;br /&gt;
        # Write the pixels&lt;br /&gt;
        row_size = ((self.bits_per_pixel * self.width + 31) // 32) * 4&lt;br /&gt;
        if self.bits_per_pixel &amp;lt;= 8:&lt;br /&gt;
            for y in range(0, self.height):&lt;br /&gt;
                row = self.image[self.height - 1 - y]&lt;br /&gt;
                bits = 0&lt;br /&gt;
                byte = 0&lt;br /&gt;
                count = 0&lt;br /&gt;
                for x in range(0, self.width):&lt;br /&gt;
                    index = palette_map[row[x]]&lt;br /&gt;
                    byte = (byte &amp;lt;&amp;lt; self.bits_per_pixel) | index&lt;br /&gt;
                    bits += self.bits_per_pixel&lt;br /&gt;
                    if bits &amp;gt;= 8:&lt;br /&gt;
                        fp.write(struct.pack(&amp;quot;&amp;lt;1B&amp;quot;, byte))&lt;br /&gt;
                        byte = 0&lt;br /&gt;
                        bits = 0&lt;br /&gt;
                        count += 1&lt;br /&gt;
                if bits != 0:&lt;br /&gt;
                    byte &amp;lt;&amp;lt;= 8 - bits&lt;br /&gt;
                    fp.write(struct.pack(&amp;quot;&amp;lt;1B&amp;quot;, byte))&lt;br /&gt;
                    count += 1&lt;br /&gt;
                while count &amp;lt; row_size:&lt;br /&gt;
                    fp.write(struct.pack(&amp;quot;&amp;lt;1B&amp;quot;, 0))&lt;br /&gt;
                    count += 1&lt;br /&gt;
        else:&lt;br /&gt;
            for y in range(0, self.height):&lt;br /&gt;
                row = self.image[self.height - 1 - y]&lt;br /&gt;
                for x in range(0, self.width):&lt;br /&gt;
                    for byte in row[x]:&lt;br /&gt;
                        fp.write(struct.pack(&amp;quot;&amp;lt;1B&amp;quot;, byte))&lt;br /&gt;
                count = len(row) * len(row[0])&lt;br /&gt;
                while count &amp;lt; row_size:&lt;br /&gt;
                    fp.write(struct.pack(&amp;quot;&amp;lt;1B&amp;quot;, 0))&lt;br /&gt;
                    count += 1&lt;br /&gt;
&lt;br /&gt;
        # Write the header with the correct offsets&lt;br /&gt;
        self.bmp_size = fp.tell()&lt;br /&gt;
        fp.seek(0)&lt;br /&gt;
        self.writeHeader(fp)&lt;br /&gt;
&lt;br /&gt;
    # Given the existing image, build a palette if possible&lt;br /&gt;
    # If there are more than 256 unique colors, build no palette; we will&lt;br /&gt;
    # write a 24 bit bitmap&lt;br /&gt;
    def buildPalette(self):&lt;br /&gt;
        # Collect all colors present in the image&lt;br /&gt;
        color_count = {}&lt;br /&gt;
        for row in self.image:&lt;br /&gt;
            for pixel in row:&lt;br /&gt;
                if pixel not in color_count:&lt;br /&gt;
                    color_count[pixel] = 0&lt;br /&gt;
                color_count[pixel] += 1&lt;br /&gt;
&lt;br /&gt;
        # Get the list of unique colors; this will be the palette&lt;br /&gt;
        palette = list(color_count.keys())&lt;br /&gt;
        self.num_colors = len(palette)&lt;br /&gt;
        if self.num_colors &amp;gt; 256:&lt;br /&gt;
            # We will write a 24 bit bitmap&lt;br /&gt;
            self.bits_per_pixel = 24&lt;br /&gt;
            self.palette = None&lt;br /&gt;
            return&lt;br /&gt;
&lt;br /&gt;
        # Arrange in descending order of occurrence&lt;br /&gt;
        palette.sort(key=lambda a : -color_count[a])&lt;br /&gt;
&lt;br /&gt;
        # Set a valid bit-per-pixel count, with the fewest bits that will&lt;br /&gt;
        # encompass the palette&lt;br /&gt;
        self.palette = palette&lt;br /&gt;
        if self.num_colors &amp;lt; 2:&lt;br /&gt;
            self.bits_per_pixel = 1&lt;br /&gt;
        elif self.num_colors &amp;lt; 4:&lt;br /&gt;
            self.bits_per_pixel = 2&lt;br /&gt;
        elif self.num_colors &amp;lt; 16:&lt;br /&gt;
            self.bits_per_pixel = 4&lt;br /&gt;
        else:&lt;br /&gt;
            self.bits_per_pixel = 8&lt;br /&gt;
&lt;br /&gt;
    # A black tile, to fill the last row&lt;br /&gt;
    def blankTile(self):&lt;br /&gt;
        return [ [ (0, 0, 0) ] * self.tile_width ] * self.tile_height&lt;br /&gt;
&lt;br /&gt;
    # A placeholder tile, for the tiles that cannot otherwise be derived&lt;br /&gt;
    # This will appear as a red block with a black X through it&lt;br /&gt;
    def placeHolderTile(self):&lt;br /&gt;
        red   = ( 0x00, 0x00, 0xFF )&lt;br /&gt;
        black = ( 0x00, 0x00, 0x00 )&lt;br /&gt;
        tile = [ None ] * self.tile_height&lt;br /&gt;
        for y in range(0, self.tile_height):&lt;br /&gt;
            tile[y] = [ red ] * self.tile_width&lt;br /&gt;
        m = min(self.tile_width, self.tile_height)&lt;br /&gt;
        for x in range(0, m):&lt;br /&gt;
            tile[x][x] = black&lt;br /&gt;
            tile[x][m - 1 - x] = black&lt;br /&gt;
        return tile&lt;br /&gt;
&lt;br /&gt;
    # Write a BITMAPINFOHEADER-type header for a BMP file&lt;br /&gt;
    def writeHeader(self, fp):&lt;br /&gt;
        fp.write(struct.pack(&amp;quot;&amp;lt;2s6L2H6L&amp;quot;,&lt;br /&gt;
                b&amp;quot;BM&amp;quot;,&lt;br /&gt;
                self.bmp_size,&lt;br /&gt;
                0,&lt;br /&gt;
                self.image_offset,&lt;br /&gt;
                self.header_size,&lt;br /&gt;
                self.width,&lt;br /&gt;
                self.height,&lt;br /&gt;
                self.num_planes,&lt;br /&gt;
                self.bits_per_pixel,&lt;br /&gt;
                self.compression,&lt;br /&gt;
                self.image_size,&lt;br /&gt;
                self.horiz_res,&lt;br /&gt;
                self.vert_res,&lt;br /&gt;
                self.num_colors,&lt;br /&gt;
                self.num_important_colors))&lt;br /&gt;
&lt;br /&gt;
# Convert one bitmap file&lt;br /&gt;
# inpname is the name of the file to be converted; args contains the arguments&lt;br /&gt;
# as parsed by the ArgumentParser object&lt;br /&gt;
def convertBitmap(inpname, args):&lt;br /&gt;
    # Collect arguments from args&lt;br /&gt;
    tile_width = args.tile_width&lt;br /&gt;
    tile_height = args.tile_height&lt;br /&gt;
    outname = args.output&lt;br /&gt;
&lt;br /&gt;
    # Provide default output file name&lt;br /&gt;
    if outname is None:&lt;br /&gt;
        d, n = os.path.split(inpname)&lt;br /&gt;
        dot = n.rfind('.')&lt;br /&gt;
        if dot != -1:&lt;br /&gt;
            n = n[:dot]&lt;br /&gt;
        n += '-500.bmp'&lt;br /&gt;
        outname = os.path.join(d, n)&lt;br /&gt;
&lt;br /&gt;
    # Read the bitmap image&lt;br /&gt;
    bmp = Bitmap(inpname)&lt;br /&gt;
&lt;br /&gt;
    # Provide default tile dimensions&lt;br /&gt;
    if tile_width is None:&lt;br /&gt;
        tile_width = bmp.width // 40&lt;br /&gt;
    if tile_height is None:&lt;br /&gt;
        tile_height = tile_width&lt;br /&gt;
&lt;br /&gt;
    # Split the bitmap into tiles&lt;br /&gt;
    bmp.split(tile_width, tile_height)&lt;br /&gt;
&lt;br /&gt;
    # Remap into 5.0.0 arrangement&lt;br /&gt;
    bmp.remap()&lt;br /&gt;
&lt;br /&gt;
    # Rejoin into a single image&lt;br /&gt;
    bmp.join()&lt;br /&gt;
&lt;br /&gt;
    # Write to disk&lt;br /&gt;
    bmp.write(outname)&lt;br /&gt;
&lt;br /&gt;
# Define command line arguments for this program&lt;br /&gt;
parser = argparse.ArgumentParser(&lt;br /&gt;
            formatter_class=argparse.RawDescriptionHelpFormatter,&lt;br /&gt;
            description='Convert NetHack 3.6.x tile sets for use with 5.0.0',&lt;br /&gt;
            epilog=&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
If --tile-width is not specified, it is the image width divided by 40.&lt;br /&gt;
If --tile-height is not specified, it is equal to the tile width.&lt;br /&gt;
If --no-statues is specified, statue glyphs are copied from the 3.6.x statue&lt;br /&gt;
   glyph; if not, statue glyphs are generated by converting the monster glyphs&lt;br /&gt;
   to grayscale.&lt;br /&gt;
&lt;br /&gt;
Images must be in BMP format.&lt;br /&gt;
&lt;br /&gt;
If --output is not specified, the output file name is &amp;lt;input-name&amp;gt;-500.bmp.&lt;br /&gt;
Multiple images can be converted, but only if --output is not specified.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;)&lt;br /&gt;
parser.add_argument('images', metavar='image', type=str, nargs='+',&lt;br /&gt;
            help='Name of a tile set image for NetHack 3.6.x')&lt;br /&gt;
parser.add_argument('--tile-width', '-x', dest='tile_width', type=int,&lt;br /&gt;
            help='Width of a single tile in pixels')&lt;br /&gt;
parser.add_argument('--tile-height', '-y', dest='tile_height', type=int,&lt;br /&gt;
            help='Height of a single tile in pixels')&lt;br /&gt;
parser.add_argument('--output', '-o', dest='output', type=str,&lt;br /&gt;
            help='Name of output image')&lt;br /&gt;
&lt;br /&gt;
args = parser.parse_args()&lt;br /&gt;
if len(args.images) &amp;gt; 1 and args.output is not None:&lt;br /&gt;
    sys.stderr.write(&amp;quot;Cannot specify --output with more than one image name\n&amp;quot;)&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
# Process each image in turn&lt;br /&gt;
rc = 0&lt;br /&gt;
for image in args.images:&lt;br /&gt;
    if not convertBitmap(image, args):&lt;br /&gt;
        rc = 1&lt;br /&gt;
sys.exit(rc)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Ray Chason</name></author>
		
	</entry>
</feed>