ham_convert is a freeware (also free for commercial use) graphic converter written by Sebastian Sieczko that can convert a normal jpg/gif/png image to one of the graphic modes of the Commodore Amiga. Its main use is to produce high-quality hold-and-modify (HAM) images using brute-force search.
It can produce ILBM IFF files (Amiga graphic modes: EHB, HAM6, HAM8, 2/4/8/16/32/64/128/256-color indexed, PCHG – 4/8/16/32/EHB modes).
This program requires java and should work on any operating system supported by JRE8 or newer (JRE8 is recommended due to JRE11 ui rendering changes).
WSL normally only supports pure command line applications. It is still possible to run ham_convert in cli mode under WSL by installing Xvfb:
sudo apt install xvfb. Running ham_convert under WSL:
xvfb-run -a java -Xms500m -Xmx2g -jar ham_convert_1.7.0.jar [image/txt file list] [options]. Alternative Xvfb configuration. Version 1.7.0 was confirmed working under WSL with Xvfb. To run gui version you need to install full X Server like VcXsrv or XMing.
There are two program versions: stable, and a more frequently updated beta version containing most recent fixes and improvements. Beta version is released to allow users to test newly added features that aren’t yet fully polished to be included in the stable release. This mostly means improved conversion so beta version is recommended for best image quality.
If you found an issue while using stable version, try the latest beta. If the problem still exist please report it here.
Example HAM6 images are available here.
Contact info (also available in the program – click on the copyright note at the bottom-left of the main window). Please report missing features, incompatibilities, regressions, image quality issues, visual glitches, bugs and any undesired or simply weird behavior. Inclusion of your test pictures and conversion settings will also be really helpful. If you don’t get an answer (your e-mail was probably classified as spam by gmail) write a comment below.
I send thanks to the following people who helped me with testing and gave some interesting ideas:
Tomasz Rachwal, cholok
- ILBM IFF file generation (HAM6, HAM8, EHB, 2/4/8/16/32/64/128/256-color modes, DynamicHires-like modes with 2-6 planes as PCHG IFF) with optional lossless compression. Hires and lace flag control is also available.
- Dithering modes: Bayer, Atkinson, Floyd–Steinberg, Jarvis, Judice, and Ninke, Sierra Lite, 2-row Sierra, 3-row Sierra, Checks (default mode, includes special “lines” and “lines-mixed” versions for HAM6, recommended for interlaced images).
- Dithering propagation factor selection (5%-100%, most used values: 75%, 85%, 100%, no effect for Bayer and Checks because of lack of error propagation).
- Dual mode – dual pixel HAM error calculation. This feature exploits dependence of possible set/modify operations of the next pixel on the choice made in current pixel in the same line. Supported in all HAM modes. Testing showed that a two-pixel sequence testing is not enough to react on the coming rapid color change so a more efficient “triple mode” was implemented.
- Triple mode (HAM6, HAM8) – extension of dual mode with three pixels instead of two. That makes it slower, but much more efficient.
The principle is to check all possible 3-pixel combinations of HAM operations to better reproduce the source image. Because up to 3 pixels with modify operations are needed to reproduce the source color if all 3 color components differ from the previous pixel in the same line there is a varying “lag” that results in undesired intermediate colors. This lag causes the image to appear slightly blurry horizontally sometimes with garbage pixels at edges called artefacts. Triple mode attempts to better organize set and modify operations to reduce this lag and make resulting image sharper. Use this option for HAM6. Enabled by default since 1.2.2.
Improved in 1.3.1 beta – added more aggressive variant distributing error more evenly across 3 consecutive pixels (requires LAB error calculation mode).
Experimental HAM8 version added in 1.4.0.
- Build-in palette generator using Java Advanced Imaging library. NeuQuant Neural-Net image quantization algorithm is used by default. There are several modes. Mode 0 is a fast single-pass mode for slower computers. Multi-pass modes: 1-safest that doesn’t look great but always gives acceptable result with no side-effects. Other modes eliminate some very similar colors from a bigger palette to make palette more diverse and make room for colors of smaller details that wouldn’t normally appear. Mode 9 is the most aggressive and should be used with caution because it eliminates more colors than other mores and it can make the resulting picture look unnatural.
Alternative Wu’s color quantizer by Xiaolin Wu is available since 1.3.2 beta. It’s recommended in batch mode, due to faster calculation.
- Color reduction is performed only when a source image contains more colors that is allowed in the selected Amiga mode. In OCS modes these colors still need to be converted to 12-bit RGB colorspace, so an image won’t look identical but very close. This allows the user to perform color reduction in a different program and use ham_convert to just save as an iff image.
- Parallel HAM6/HAM8/HAM10 conversion (experimental, since 1.4.0). Image is divided vertically into slices processed on separate CPU cores. Number of CPU threads can be adjusted in the extra options tab.
- Optional multithreaded HAM6 palette optimization. Attempts to minimize average error by inserting colors from the source image. Unlike previous methods this one performs HAM6 conversion each time to measure how palette modification affects average error. Warning: it might take a long time depending on a number of optimization cycles (1-2 seems to be enough for decent quality).
- Batch conversion.
- Importing a palette from a PAL file (JASC palette file format) or ILBM IFF file.
- HAM6 conversion supports more accurrate LAB error calculation mode using CIELAB colorspace instead of RGB. Often produces better results than the old RGB version but is much slower.
Experimental HAM8 version since 1.4.0.
- Color mapping in non-HAM indexed modes is performed optionally using a CIEDE2000-based color difference function operating in the CIELAB colorspace.
- HAM map generation. It’s an image that illustrates what type of operation was used on every pixel of the HAM image. Legend: red – modify red, green – modify green, blue – modify blue, black – set.
- Error map generation (saved together with the ham map). Brightness represents the color distance between a source color and a calculated color of a ham pixel (normalized to 0-255). Greater distance=brighter pixel.
- Image scaling (incremental bicubic). New size can be specified in pixels or as a percentage.
- Command line mode:
java -jar ham_convert.jar file_path mode optional_parameters (example: java -jar ham_convert.jar C:\img\test.png ham6 norle).
If you start the program without “java -jar” it will be launched in the background.
Ham6 and ham8 modes support multiple conversion profiles – normal which offers good best compromise between speed and quality, fast – faster but still producing decent picture quality, fastest – lower quality than and faster than fast, slow – best quality when speed is not important.
- Parameter 1 – source file path (mandatory): jpg/png/gif image or txt file with one image path per line for bath conversion (unicode console required for diacritic characters).
- Parameter 2 – mode (mandatory): ham6, ham6_slow, ham6_slowest, ham6_fast, ham6_faster, ham6_fastest, ham6_ludicrous, ham6_sliced (experimental, since 1.7.0), ham8, ham8_fast, ham8_fastest, ham8_slow, ocs2, ocs4, ocs8, ocs16, ocs32, ehb, ehb_animation (for batch conversion of animation/video frames – more consistent palette across frames), aga64, aga128, aga256, dhires (dynamic hires 16-color per line).
Program will be terminated if mode parameter is missing/incorrect or any of the other parameters is incorrect.
- Parameter 3+ – optional settings:
- dither – enable Bayer dithering for most modes, Checks for DynamicHires, Checks lines-mixed for ham6.
- dither_fs – enable Floyd-Steinberg dithering for most modes, constrained Sierra Lite for DynamicHires. Adds additional noise to ham6 that can increase the number of artefacts.
- dither_masked – reduced visibility “masked” checks-line mixed dithering to make dithering pattern less visible. Requires batch mode (.txt source file list) and ham6. Designed to convert animations in cli batch mode.
- dither_temporal – experimental temporal checks-line mixed dithering to increase the number of simulated color levels in ham6 batch mode to 61 (slighly below rgb666). Requires batch mode (.txt source file list) and ham6. Designed to convert animations in cli batch mode with at least 30 fps.
- norle – disable lossless iff rle compression.
- nopng – disable output png saving (save only iff).
- normalize – stretch contrast (normalize range to 0-255),
- black_bkd – force black background color (always set palette color 0 to black).
- fixed_pal – use fixed palette: 16-level grayscale on ocs, rgb453level+6level grayscale on aga.
- quant_wu – use Wu’s color quantizer instead of NeuQuant. Recommended in batch mode due to faster calculation.
- diversity_X – similar color removal strength (X=0-6 for ehb, X=0-9 for other modes). Not supported in ham8 and dhires.
- propagation_X – error propagation factor, requires dither_fs, X=0-100.
- threads_X – CPU threads, X=1 to available CPU threads.
- Command line ham6 conversion profiles (from highest to lowest quality):
- ham6_slowest (ham6 with slower palette optimizer, for still image conversion),
- ham6_slow (ham6 with normal palette optimizer, for still image conversion),
- ham6 (same as default gui settings, optimal speed/quality),
- ham6_fast (decent quality),
- ham6_fastest (possible fringing),
- ham6_ludicrous (visible fringing).
- Command line ham8 conversion profiles (from highest to lowest quality):
- ham8 (same as default gui settings, optimal speed/quality),
- ham8_fast (decent quality),
- Sample palette files of the various vintage home computers from the 80s like Commodore 64 and Atari 800xl. Use them with the 256-color mode.
- Notes – fonts may look worse on Linux with OpenJDK, high DPI scaling on Windows 10 requires JRE9 or newer and is not guaranteed to display fully correctly.
- HAM6 mode – 2 control bits+4 bits of data, 16-color palette, 12-bit color space (Amiga OCS/ECS), multiple dithering methods, checks lines-mixed by default. Note: the most common way to minimize fringing in HAM modes is to oversaturate and overbright the pictures so there are few dark tones close to each other and few tones close to grayscale.
Recommended options: triple mode, LAB error calculation (CIE94), dithering: checks lines-mixed for 15-bit bitdepth simulation (a dithering method optimized for HAM, Floyd-Steinberg introduces too much HAM fringing due to increased rapid color variability).
- HAM8 mode – 2 control bits+6 bits of data, 64 color palette, 24-bit color space (Amiga AGA). The only mode supported in the earliest versions of the program. Later work moved into HAM6 and that mode is best supported.
Recommended options: dual mode.
- HAM10 mode – 2 control bits+8 bits of data, 256 color palette, 24-bit color space (unfinished Amiga AAA).
- HAM5 mode – 1 control bit (and 1 hardwired to zero)+4 bits of data, 12-bit color space (Amiga OCS/ECS). Experimental support in 1.3.1 beta. Differences from ham6: red and modify green operations are unavailable resulting in worse quality.
- 64-color EHB (Extra Half-Brite) mode – 32 colors+the same 32, but with halved brightness, 12-bit color space (Amiga OCS/ECS).
- OCS/ECS indexed modes – 4-32 colors, 12-bit color space.
- AGA indexed modes – 64-256 colors, 24-bit color space.
- Dynamic HiRes – 4/8/16-color palette in hires, 4/8/16/32/64 (EHB) in lores. On pre-AGA Amigas this software mode allowed displaying more than 16 colors in high resolution modes that didn’t support HAM and more than 16 colors at once. PCHG IFF saving is available since 1.3.0 beta (tested viewers: Paint.net – Windows, Visage – Amiga). In 16-color hires mode only max. 7 color changes are supported on real hardware.
Checks dithering was improved in 1.3.2 beta. New version turned out to be best suited for dynamichires per-line palette changes and is now performs much better that all other dithering types, but is not yet optimized and slow with more than 8 colors per line. It’s recommended for the best quality. Constrained sierra lite is second best in terms of quality.
- Color bit depth reducer for RGB bit depth reduction (every combination of 1-8 bits per channel).
- ZX Spectrum mode – 15 colors divided into two palettes: bright1 and bright0. Two colors for every 8×8 pixel block, both from bright1 or both from bright0.
- ZX Spectrum 8×1 mode available in some ZX Spectrum clones like Timex Sinclair, Pentagon. This mode uses a 8×1 pixel block size to improve the color resolution. The rest is the same as in normal mode.
- C64 hires and multicolor modes.
- Commodore Plus/4 hires and multicolor modes.
- MSX screen 2 – 2 colors out of 15 every 8×1 block.
- MSX 2+/TurboR screen 12 – 19268-color YJK (since 1.4.1 beta, experimental).
- VGA fakemode: fake 18-bit hicolor mode used to simulate more than 256 colors at once on a normal VGA card.
- Sliced variants of HAM and indexed modes – different palette every horizontal line for better color reproduction. Replaced with higher quality DynamicHires modes.
- Converting source image to 12-bit RGB
- Iterational color reduction using Neuquant and similar color removal with configurable strength (pal. gener. mode 0-9, 5 recommended). Starts from 64-color palette, decreases palette size until there are only 16 unique colors.
- Optional palette optimization.
- Calculating HAM operation type for each pixel using brute force search with configurable search sequence length (dual mode-2 pixels, triple mode-3 pixels).
Triple mode (HAM6) – checking 2116 combinations of horizontal 3-pixel groups staring with the current coordinate (out of the 262144-64*64*64 possible combinations only 2116-23*23*4 were determined experimentally to be relevant, out of 23 16 are sets 0-15, modify r-1, r, r+1, g, b-1, b, b+1, where r, g, b are source quantized channel values). Third pixel only needs 4 operations – set closest color, modify r, g, b.
Finding the lowest error by calculating err(x,y)2+err(x+1,y)2+err(x+2)2 for every combination. Plotting pixel x, y then repeating the same calculation from pixel x+1, y. Effectively results in backward error propagation – err(x+2) is reduced by slightly increasing err(x+1,y) and err(x,y), and err(x+1) is reduced by slightly increasing err(x,y).
- Optional dithering (checks lines-mixed simulates 15-bit color depth, other types more noticeable and less optimized for HAM).
- Optional error map and ham operation map saving.
- Optional IFF image output with lossless compression.
- PNG image output with lossless compression (all images are saved in the same location as the source image).
- Examples thanks to Trachu – HAM6 with checks (lines-mixed) dithering
- Examples thanks to Z-UNIT – HAM6
- Examples thanks to Trachu – DynamicHires (8 colors per line) with checks dithering
- No Man’s Sky HAM6 slideshow by Blake Patterson on the Amiga 1000.
- HAM6 CDXL videos encoded by AGABlaster+ham_convert.
- Real hardware screenshots by retronav.
- Test image – Mielno, Poland (54°15’44.0″N 16°03’06.8″E). Testing platform: WinUAE 3.0.0., emulated Amiga 1200 with 4 MB fast ram, clean installation of Workbench 3.1, no RTG.