<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MlyOjl</id>
	<title>MultimediaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=MlyOjl"/>
	<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php/Special:Contributions/MlyOjl"/>
	<updated>2026-04-30T14:07:53Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=HNM4&amp;diff=7650</id>
		<title>HNM4</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=HNM4&amp;diff=7650"/>
		<updated>2007-04-11T04:37:24Z</updated>

		<summary type="html">&lt;p&gt;MlyOjl: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;HNM4 is the third generation of the Cryo HNM video format. At least two decoder-incompatible variation of this format is known. Main version, operates in 320x200x256 resolution and simplified 640x480x256 spin-off, used in ALIENS game. Both formats share same container structure.&lt;br /&gt;
&lt;br /&gt;
== File Format ==&lt;br /&gt;
File header:&lt;br /&gt;
  dword signature     - file signature, &amp;quot;HNM4&amp;quot;&lt;br /&gt;
  dword unknown1      - probably format version&lt;br /&gt;
  word  width         - width of the frame&lt;br /&gt;
  word  height        - height of the frame&lt;br /&gt;
  dword filesize      - size of the entrie hnm file&lt;br /&gt;
  dword frames        - number of frames&lt;br /&gt;
  dword taboffset     - offset of the TAB chunk&lt;br /&gt;
  word  bits          - sound sample resolution&lt;br /&gt;
  word  channels      - number of sound channels&lt;br /&gt;
  dword framesize     - frame allocation size (width * height)&lt;br /&gt;
  byte  unknown2[16]  - seems to be unused&lt;br /&gt;
  byte  copyright[16] - &amp;quot;-Copyright CRYO-&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The rest of the file organized on manner similar to [[HNM (1)]] format. All single-frame related chunks combined to superchunks, where each superchunk starts with 32-bit value, lower 24 bits of it indicates superchunk size and highest 8 bits - flags (unknown). Each chunk starts with another 24 8 bits length header followed by 4 bytes of chunk ID (where only 2 bytes can be actually used), and chunk data. Near the end of file usually TAB chunk located, it doesn't have an upper-level superchunk.&lt;br /&gt;
&lt;br /&gt;
=== PL Chunk ===&lt;br /&gt;
Palette. Stored in same format as used in [[HNM (1)]].&lt;br /&gt;
* ALIENS: However, non-zero bit 23 of ChunkId indicates that palette stored in complete 8-bits-per-component format, unlike regular 6-bits otherwise.&lt;br /&gt;
&lt;br /&gt;
=== IZ Chunk ===&lt;br /&gt;
Keyframe. See video decompression below.&lt;br /&gt;
&lt;br /&gt;
=== IU Chunk ===&lt;br /&gt;
Interframe. See video decompression below.&lt;br /&gt;
&lt;br /&gt;
=== SD Chunk ===&lt;br /&gt;
Sound data. [[PCM#Differential_PCM|DPCM]]-encoded sound fragment.&lt;br /&gt;
&lt;br /&gt;
== Decoding Video ==&lt;br /&gt;
=== Intraframes ===&lt;br /&gt;
Intraframe decompression is simialar to [[HNM (1)]] 0xFE frames. But with a few changes. Chunk data starts with small 4-bytes header:&lt;br /&gt;
  word width  - width of the frame&lt;br /&gt;
  byte height - height of the frame (only lower byte of it)&lt;br /&gt;
  byte mode   - rendering mode (always 0xFE ?)&lt;br /&gt;
&lt;br /&gt;
Then immediately followed by LZ-packed raster (without 6-byte compression header as was used before). LZ decompression algorithm remains the same, but bitreader use 32-bits queue and processing bits from highest to lowest.&lt;br /&gt;
&lt;br /&gt;
* You can safely ignore width/height/mode fields of the frame header as original decoder always renders whole frame regardless specified values.&lt;br /&gt;
&lt;br /&gt;
=== Interframes ===&lt;br /&gt;
==== HNM4 Interframe ====&lt;br /&gt;
Packed interframe consist of one or more compression codes. Depending on the code's count field following cases possible:&lt;br /&gt;
&lt;br /&gt;
  bits&lt;br /&gt;
    0..4 : count = 0&lt;br /&gt;
    5..7 : tag:&lt;br /&gt;
            0: copy next two bytes of input to the output&lt;br /&gt;
            1: skip (next byte of input) * 2 bytes of output&lt;br /&gt;
            2: skip (next word of input) * 2 bytes of output&lt;br /&gt;
            3: fill (next byte of input) * 2 of output with (next byte of input)&lt;br /&gt;
         else: finish the unpacking&lt;br /&gt;
 &lt;br /&gt;
   - or -&lt;br /&gt;
 &lt;br /&gt;
    0..4 : count &amp;lt;&amp;gt; 0&lt;br /&gt;
       5 : previous&lt;br /&gt;
       6 : backline&lt;br /&gt;
       7 : backward&lt;br /&gt;
       8 : swap&lt;br /&gt;
   9..23 : offset&lt;br /&gt;
&lt;br /&gt;
In this case for (count) pixel pairs, copy them from the (output   offset * 2 - 32768) of the current frame to the output. Flag bits modify various parameters of this scheme (multiple flags can be used):&lt;br /&gt;
* previous - copy pairs from the previous frame&lt;br /&gt;
* backline - first pixel located 2 lines above   (swap)&lt;br /&gt;
* backward - advance source pixel pairs in backward order&lt;br /&gt;
* swap     - swap pair's pixels&lt;br /&gt;
&lt;br /&gt;
==== HNM4A Interframe ====&lt;br /&gt;
HNM4A interframe is a simplified version of the HNM4 interframe. Code format:&lt;br /&gt;
  bits&lt;br /&gt;
    0..5 : count = 0&lt;br /&gt;
    6..7 : tag:&lt;br /&gt;
            0: skip (next byte of input) bytes of output&lt;br /&gt;
            1: draw 1x2 column of the output with next 2 bytes of input&lt;br /&gt;
            2: advance to the next line of output (but keep current x position)&lt;br /&gt;
            3: finish the unpacking&lt;br /&gt;
 &lt;br /&gt;
   - or -&lt;br /&gt;
 &lt;br /&gt;
    0..5 : count &amp;lt;&amp;gt; 0&lt;br /&gt;
       6 : previous&lt;br /&gt;
       7 : delta&lt;br /&gt;
   8..23 : offset&lt;br /&gt;
&lt;br /&gt;
For (count) 1x2 columns copy them from the (output   offset) to the output.&lt;br /&gt;
* previous - copy column from the previous frame&lt;br /&gt;
* delta    - copy column from (output   offset - 65536)&lt;br /&gt;
&lt;br /&gt;
=== Postprocessing ===&lt;br /&gt;
For HNM4 (but not HNM4A movies) you need to perform extra frame postprocessing by swapping pixels using following self-explaining example (assuming 4xN image):&lt;br /&gt;
&lt;br /&gt;
  Just unpacked frame       Final frame&lt;br /&gt;
      p0 p1 p2 p3    ==&amp;gt;    p0 p2 p4 p6&lt;br /&gt;
      p4 p5 p6 p7           p1 p3 p5 p7&lt;br /&gt;
          ...                   ...&lt;br /&gt;
&lt;br /&gt;
== Decoding Audio ==&lt;br /&gt;
'''TODO'''&lt;br /&gt;
&lt;br /&gt;
== Games Using HNM4 ==&lt;br /&gt;
* Lost Eden&lt;br /&gt;
* Hardline&lt;br /&gt;
* Aliens&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Formats]]&lt;/div&gt;</summary>
		<author><name>MlyOjl</name></author>
	</entry>
</feed>