ham_convert is a freeware (also free for commercial use) graphic converter written by Sebastian Sieczko that can convert a normal jpg/gif/png/tiff/jpeg2000 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 has two interfaces: normal gui interface and a command line interface, that can be used by other applications.
This program requires java and should work on any operating system supported by JRE9 or newer (latest jre version recommended, on version 8 may suffer from low performance if started without start_jre8.bat). For best performance start using the included startup scripts or type “java -Xms500m -Xmx2g -jar ham_convert_1.10.3.jar” in the the command line.
If you get an error message when starting the program with the included start script or have 4 GB or less of RAM try to run ham_convert jar file directly by double-clicking on it (there is no exe file, java uses jar files instead).
You can use JRE portable if you can’t use the normal version. Use jPortable Launcher to run ham_convert jar file.
To launch ham_convert manually using JRE portable (not recommended): install JRE portable into C:\PortableApps\CommonFiles\OpenJDKJRE64
where C is your drive letter, and create a text file named start_portable.bat containing the following line (or edit this sample file):
C:\PortableApps\CommonFiles\OpenJDKJRE64\bin\java.exe -Xms500m -Xmx2g -jar ham_convert_1.10.3.jar
again replacing X with your drive letter. Place start_portable.bat in the same folder as ham_convert jar and double click on it to run ham_convert. If it doesn’t work check if the path to the java.exe is correct and the name of the ham_convert jar file is the same as on your hard drive. Installing non-portable version of java is recommended.
ham_convert (and any other java app) can be run on Steam Deck. Download Java runtime directly from Oracle: https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.tar.gz. Extract this file to another folder, for example /home/deck/java/. Inside this folder you should see a bin folder (which contains all the needed Java binaries). We now have a portable Java environment that we can use for any Java applications. Now you need to run a command in the terminal to start ham_convert:
/home/deck/java/bin/java -Xms500m -Xmx2g -jar path_to_the_ham_convert_jar
You can modify the included start.sh. This script needs to have executable permissions in order for Steam to launch it.
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.9.4.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 or upgrade to Windows 11. WSL2 on Windows 11 supports ham_convert both in gui and command-line mode.
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 send bug report 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). You’re welcome to send you’re ideas how to improve HAM conversion quality. Please report missing features, incompatibilities, regressions, image quality issues, visual glitches, bugs and any undesired or simply weird behavior. If the conversion stalls it could be the result if an error. Try starting the program from command line using “java -jar ham_convert_executable_file_name.jar” and repeat the conversion. If you get an error message in the command line, send it to a contact e-mail to help fixing the problem. 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 don’t accept donations, but if you really want you can send me a postcard.
I send thanks to the following people who helped me with testing and gave some interesting ideas:
Tomasz Rachwal, cholok
ham_convert 1.10.0
ham_convert 1.10.0 – extra options
ham_convert 1.10.0 – preview
ham_convert 1.10.0 – resize
Features
- 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. In command line mode you can skip png generation and save only iff by adding nopng parameter (command line mode is described here).
- Newtronic Video DAC 18 iff saving (experimental) – select mode=”HAM8″, palette source=”Video DAC 18 – fixed 6-bit grayscale”, triple/turbo triple mode, enable iff saving, selecting cie94 uses din99 instead of lab. Info: https://amiga.resource.cx/exp/videodac18
- 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 using brute force seach. This feature exploits dependence of possible set/modify operations of the next pixel on the choice made in the 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) – triple pixel HAM error calculation using brute force seach. An 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 similar color removal modes (labeled pal. diversity). 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. Adjusting these modes have no effect in HAM8.
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.
In HAM8 internal palette generator may generate palette with a background color slightly different from the source image due to the lower color bit-depth used internally by NeuQuant and Wu. This problem also appears in other programs like IrfanView. It’s recommended to perform a manual adjustment in palette editor if necessary.
- 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. If your image has slightly more colors than the target OCS colormode (not AGA) try converting to RGB444 first using color bit depth reducer and check the number of used colors. If it fits in the limit convert the image produced by the color bit depth reducer to the target colormode. If you need conversion to AGA mode with less than 64 colors select AGA 64-color more and adjust the number of used colors in the extra options tab.
- 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 using brute force search. Attempts to minimize average error by inserting colors from the source image or every possible color from RGB444, if extensive search is enabled. 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). Distributed2 variant produces best results. Some images may still require manual palette adjustment depending on what image areas you want to have fewest artefacts.
- Batch conversion. For best performance start ham_convert using the included startup scripts or type “java -Xms500m -Xmx2g -jar ham_convert_1.9.1.jar” in the the command line and install newest available version of java.
- Importing a palette from a PAL file (JASC palette file format) or ILBM IFF file.
- HAM6/HAM8 conversion supports more accurate 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.
- In HAM modes line can optionally start with modify operation (modifies border color instead of previous pixel) for better quality.
- 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. Resizing in external image editing software might produce better quality.
- Stretch contrast (normalize color range to 0-255, leave this option disabled unless you really want the colors of the source image to be altered, including the background color).
- Command line mode:
java -Xms500m -Xmx2g -jar ham_convert.jar file_path mode optional_parameters (example: java -Xms500m -Xmx2g -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, ham10, 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_bayer8x8 – enable Bayer 8×8 dithering for all modes including 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.
- rgbg_pal – use fixed RGBG ham pattern (HAM6 mode only).
- write_pal – save the calculated palette to a separate JASC pal file (from 1.10.1).
- 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.
- color_rgb – RGB (non-lab) color distance (ham6/ham8).
- color_lab_cie76 – LAB colorspace, CIE76 color distance (ham6/ham8).
- color_lab_cie94 – LAB colorspace, CIE94 color distance (ham6/ham8).
- color_ictcp – ICtCp colorspace and color distance (ham6/ham8).
- Command line ham6 conversion profiles (from highest to lowest quality, can be accessed using multiple names):
- ham6_q7 / ham6_slowest (ham6 with triple mode and slower palette optimizer, for still image conversion, cie94),
- ham6_q6 / ham6_slow (ham6 with triple mode and normal palette optimizer, for still image conversion, cie94),
- ham6_q5 / ham6 / ham6_normal (same as default gui settings, optimal speed/quality, triple mode, cie94),
- ham6_q4 / ham6_tt / ham6_normal_turbo (faster variant of ham6 with similar quality, turbo triple mode, cie94),
- ham6_q3 / ham6_fast (decent quality, dual mode, cie94),
- ham6_q2 / ham6_faster (dual mode, cie76),
- ham6_q1 / ham6_fastest (possible fringing, dual mode, rgb),
- ham6_q0 / ham6_ludicrous (visible fringing, single mode, rgb).
- Command line ham8 conversion profiles (from highest to lowest quality, can be accessed using multiple names):
- ham8_q3 / ham8_slow,
- ham8_q2 / ham8 (same as default gui settings, optimal speed/quality),
- ham8_q1 / ham8_fast (decent quality),
- ham8_q0 / ham8_fastest,
- 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.
- The following formats may not be decoded correctly: animated gif, transparent png (fixed in 1.8.7).
Supported modes
- 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.
You can also prepare source inage so that it is already within the limited colorspace of the HAM6 (RGB444) by making sure that all colors have all components that are only multiples of 17 (0, 17, 34, …, 221, 238, 255). If you don’t plan to use dithering during the conversion this step will help the converter better recreate source colors.
Recommended options: triple mode, LAB error calculation (CIE78/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). CIE78 usually produces more glitch-free output, but CIE94 reduces other artefacts. It is recommended to try both variants.
- 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). The specs description on wikipedia is incomplete and not 100% reliable but it was useful for debugging other HAM modes.
- 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).
EHB animation option can be used to improve palette consistency across animation frames in batch conversion of animation frames.
Optional extra OCS palette optimization uses brute force search to improve image quality.
- OCS/ECS indexed modes – 4-32 colors, 12-bit color space.
- AGA indexed modes – 64-256 colors, 24-bit color space.
- Dynamic HiRes OCS – 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).
For maximum quality enable accurate mode, disable turbo accurate mode in the extra options tab and optionally enable bayer 8×8 dithering.
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. Checks/bayer 4×4/bayer 8×8 are recommended for the best quality. Constrained sierra lite is second best in terms of quality.
- DynamicHires AGA – like DynamicHires OCS, but with palette colors being selected from RGB888 instead of RGB444.
- 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).
- Oric – 2 colors out of 8 every 6×1 block.
- Robotron KC85/4 – 2 colors per 8×1 block, 1 of 16 foreground and 1 of 8 background colors.
- Atari 8-bit 5-color and 4-color modes per line (experimental, based on DynamicHires).
- Acorn Archimedes VIDC1 256-color mode (out of 4096). 256-color mode is implemented using only 16 color registers. User can only define lower bits of each channel, for a total of 8 bits out of 12. Higher bits (4 total) are filled by the video chip.
- 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.
HAM6 conversion steps executed by the program
- Converting source image to 12-bit RGB
- Iterational color reduction using Neuquant and similar color removal with configurable strength (palette generation 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).
- 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
Mielno – original image
Mielno – ham8 iff image (Deluxe Paint 5)
Mielno – ham map (ham8)
Really Nice. Thax a lot!
How can I view the pics on amiga in ham8?
You need an iff picture viewer. I use Deluxe Paint 5 for testing. Amiga can read a 720KB (not 1.44MB) PC-formatted floppy disk (instruction: http://goo.gl/ryk71d).
IIRC, my AGA Amigas had no trouble with 1.44MB PC floppy disks. I had an external Hi-Density Amiga drive and used the DiskSpare.device (free software) to get 1.96MB out of floppies. I seem to also recall using 1.44MB PC HiDen floppies with it. That was on an A1000 IIRC. You would need a Hi-Density floppy drive to get 1.44MB PC drive support from any Amiga.
I seem to recall that only the A4000 came with Hi-Density floppies, but my A1200 has a HiDensity drive in it. Odd.
TRSE is probably a good practical environment to play with actually using Amiga imagery. Even just or slideshows and demos. (I don’t know if it supports SHAM more or Dynamic HiRes though. Ask the developer- he seems to be a literal genius.) I will paste that URL in below.
https://lemonspawn.com/turbo-rascal-syntax-error-expected-but-begin/
Any chance for Gameboy Color support? It uses 8 palettes, 4 colors per each. Each palette is applied to 8*8 pixel block (tile). Kind of Speccy on steroids since you can have 4 colors per tile and twice as much to choose from. 🙂
I can’t promise anything. I will do some research but currently I’m concentrating my work on Amiga modes. Non-Amiga modes aren’t fully implemented and they use an almost brute-force approach to palette generation. Game Boy Color has a palette of 32,768 colors so the number of combinations it too high to check them all. NeuQuant algorithm which I use for color reduction doesn’t work well with less than 16 colors.
Oh, I see. I’m not familiar with this stuff so I just asked seeing that there’s support for other 8bit platforms. No problem!
Nice converter! I’ve noticed the IFF saving option being disabled by modes that change the palette on a line by line basis. Would it be hard to implement writing the palette changes as PCHG chunk? Or at least as another simple text format file so it’s possible to convert it to a program/copperlist for the real machine!?
I’ve never had time to finish coding the sliced modes. There aren’t fully Amiga-compatible because in reality in 16-color mode not all 16 can be changed and with more colors it gets even worse. According to this document: http://wiki.amigaos.net/wiki/ILBM_IFF_Interleaved_Bitmap#ILBM.PCHG “in laced pictures the changes can only happen on even lines”.
Number of color changes per line line can be selected in the DynamicHires mode, and in the latest beta version palettes are written to a png image (it was used for debugging but I’ve enabled it in the beta version).
PCHG IFF support will be added after the current 1.2.0 release.
PCHG IFF export is available in 1.3.0 beta (in DynamicHires mode).
Sliced HAM6 PCHG IFF export is available in 1.7.0.
I have coded a colorcycling effect using palette changes per line starting from a 256 color base palette. I still have problems with horizontal artefacts when the palette changes from one line to the next. I saw in your images there are no such horizontal artefacts. What’s your strategy on minimizing these?
The effect can be seen here: http://www.pvv.org/~espenamo/11colorchanges256basepal.MOV
The only mode with color changes between lines supported by ham_convert is DynamicHires. Other modes including HAM use single palette. ham_convert is mostly optimized for HAM conversion, DynamicHires conversion still needs more work.
Color changes calculation (DynamicHires mode):
-16 unique colors per line.
-Color changes only every 2 lines (2 successive lines have the same palette).
for(j=0:number_of_lines-1)
{
for(i=0:number_of_changes_per_line-1)
{
0.if(j==0)calculate 16-color palette from the source image, else copy palette from line j-2,
1.prepare 16 palettes with color i,1,...,15 removed (remove 1 color from each one), convert lines j,j+1 of the source image to a new palette and calculate an average color distance between original pixel and converted pixel,
2.select palette with the lowest average color distance,
3.swap added color with color at index i,
3.convert lines j,j+1 of the source image to rgb444 and populate the array with all unique colors,
4.check all items in the array by putting each one in the empty space of the palette from (2.), convert lines j,j+1 of the source image to a new palette and calculate an average color distance between original pixel and converted pixel,
5.select palette with the lowest average color distance,
6.select palette with the lowest error,
7.convert line to a new palette.
8.j=j+2
}
i=i+1
}
More advanced color changes calculation was developed by Trachu for his converter which produces DynamicHires images with less artefacts than ham_convert: https://www.ppa.pl/forum/scena/38042/dynamic-hires-czyli-nowe-otwarcie-mocy-amiga-500
Thanks for the detailed explanation! I’ll try it out for future demo projects 🙂 for this particular demo release I ended up skipping the per line color changes as the artefacts were too dirty and the deadline was coming fast.
Ham converter it’s a very beautyful software for project a bitmap graphic.
I have work for my personal graphics.
Great program, thanks a lot!
Would it be possible to add yet another feature? Namely to limit the number of actually used base-colors by having an edit field to tell the program to only use e.g. the first 55 of the 64 available base-colors for HAM8 and to ignore the remaining 9. My idea is to have some base-colors available for color cycle effects and such.
What do you think?
I can add this feature in the next version.
That’s fantastic news, thanks in advance!
Added to the latest beta version. HAM6: 2-16 colors, HAM8: 2-64 colors.
Thanks, man, that’s great news! Just saw the update, fantastic work!
Yo man! Great update, as always. The triple-speedup works quite well.
I have one idea for further improvement:
the converter tends to use HAM modification-commands even if it could use a base-color instead.
For example, here I have a logo with large patches of some greenish color (RGB 24,132,48) which ends up in base-color #24 (essentially this green is the main background color).
But instead of using 24,24,24,24,… for a solid green horizontal line, hamconvert generates something like this instead:
24, 225, 76, 134, 134, 134, …
which means
1. base-color #24
2. change green to 132 (which it already is)
3. change blue to 48 (which it already is)
4. change red to 24 (which it already is)
5. dito
6. dito
…
While the resulting HAM8 picture is technically correct, not using the base-color whereever possible needlessly produces HAM artefacts when trying to do something with the picture beyond just displaying it.
In my case I wanted to use DIWSTRT / DIWSTOP with a cover sprite to build a curtain effect.
But because of the above this becomes impossible, the HAM artefacts are too severe.
I added a patcher to my own HAM-to-proprietary-format converter to fix this by simply going over all pixels and checking for useless color-modification commands in respect to the last base-color command.
Probably something like this would be a nice addon for hamconvert too.
Cheers!
Thanks for the bug report. I will investigate this problem and I will try to fix it in the next release.
I’ve implemented a fix in the current beta version and it works in ham6 where the original image is converted to rgb444 first. It doesn’t make much difference in ham8 if the exact background color isn’t present in the generated palette. It happens quite often, because both NeuQuant and Wu frequently can’t faithfully retain background color. For example they generate 27,135,51 instead of 28,136,52. It’s often very close, but with all 3 components slightly different from the original it will be used once and then updated with modify until it reaches the exact value. If the program kept repeating the set it will never reach the exact value.
Stretch contrast option alters the background color, so that you don’t know what color has to be present in the palette to generate consistent set pixels.
NeuQuant, Wu, Scolorq can’t reliably retain background color when reducing palette to 64 colors. I’ve added Median Cut, which often retains background color, but generates worse palette overall. I’ve tested color reduction in IrfanView and it also generates slightly different background color. I think most other programs do that below certain number of colors. For now the user will have to manually modify palette using build-in palette editor or edit the calculated pal file in text editor to ensure the exact background color is present or select Median Cut, which degrades the quality. I’ll continue working on this.
Hi there, will it possible to add ‘Cancel’ or ‘Abort’ feature – for very slow conversions (like dynamic palette) it is common that results are not acceptable but there is no possibility to interrupt processing – we need to wait to the end or quit and close application. It could be nice to have opportunity to stop processing so different options can be verified.
Hello, I can try but it will be difficult to do safely on most Amiga modes.
Thx, you just triggered my curiosity – why aborting conversion and restoring initial state can be unsafe on most Amiga modes? ‘Exit’ button works great but it means you need relaunch ham_convert and set all options from scratch.
Also this seem there is no repeatable behavior as computed palette seem to be different each time when conversion is started? It is correct observation (or i’m just confused?).
For today i usually use GIMP with XiMagic Quantizer plugin to generate optimal 16 color palette for HAM6 (SColorQ method) then apply Gimp ‘Dither’ to restrict RGB 4:4:4 uniformly sampled (so OCS/AGA nibbles are matched) after this use GIMP ‘Index’ to convert true color into 16 color (after this step i can also rearrange colors in palette so they can be more functional like dark on index 0 and bright on index 1 or opposite for OS2 color scheme) then extracting JASC palette (trough IrfanView) as separate file so it can be used in ham_convert. As you see this is quite complex process.
Btw i have few ideas to share – not sure if they are good or not – glad to hear your opinion.
First – for HAM images horizontal edge detection may be helpful to take decision about using color from index or HAM – HAM fringing can be avoided by using index color so computing CLUT is important for edge areas – never tried to do this in GIMP or similar editor so perhaps building index palette focused on edge pixels can be good way to avoid HAM fringing.
Second at least in theory resize, dithering should be done in linear light space (so remove gamma – dither – reapply gamma).
Recall from slow computer times that trick to avoid costly processing in linear light space was performing all operations on inverted (negated) image – of course after processing there is need to negate negated result. Not sure it this work but some algorithms not focused on subjective quality (like median cut) can build different palette if this approach is used.
Third is Ulichney dithering (blue noise) – can be useful for image sequences with animation target – i know some Ulichney precomputed tables are available. It looks like FS dither but it is stationary similarly to Bayer so no error propagation.
Fourth is “standard”, precomputed OCS 16 color palette – not sure if there is possibility to embed such “standardized” OCS palette (it can be downloaded as external one but having possibility to select it from option can be faster than manually selecting it trough external file).
Thx once again, returning quite regularly to check ham_convert, great work.
Generated palette is the same each time you run the conversion.
I’m currently working on Oric Atmos conversion. Meanwhile I’m evaluating CIELAB alternatives like ICtCp, CAM02, CAM16.
As for the dithering, I’ve already added Ostromoukhov variable-coefficient error dithering with coefficient tables generated from noise.
16-color grayscale OCS palette can be selected using the pal. source – fixed 4-bit grayscale OCS. It produces quite ok HAM6 quality.
I don’t know if adding edge detection will make much difference, because now when I calculate set/modify operation for the current pixel in triple mode I actually calculate a sequence of 3 pixels – current and next 2, so that the choice in the current pixel will produce better possible colors in the next pixels. In ham6 I think it’s more important to check how many color components are different from the previous pixel, because it determines how many modify operations are required. With a 3-pixel sequence modify operations can start before the edge to better reproduce color transition and reduce the lag between source color component values and actual ham6 values. Most edges can’t be reproduced using the limited 16-color palette.
Dynamic Hires conversion cancel option was added in http://mrsebe2.bplaced.net/ham_convert/ham_convert_1.9.3_beta_12-12-2023.zip
Thx for Cancel/Abort – this will for sure improve possibility to quickly verify various settings (if i see that conversion results are NOK then i can try different settings).
Edge detection – my opinion was related to fact that HAM6 is sensitive for something called “overload” – normal thing in delta modulation/compression (as HAM is delta compression). If edge (i.e. rapid change) of signal occurs then fringing is outcome – using horizontal edge information may narrow intensive search for lowest error in surrounding pixels. Of course this my naive interpretation.
Blue noise (Ulichney) noise mask generator can be found for example here:https://github.com/jdupuy/BlueNoiseDitherMaskTiles
Hi, this converter is amazing, thanks for developing it!
I am trying to find the best combinations to convert some videos to CDXL (via agaconv), but I am not sure if the options used are the best. I extended agaconv to support different color schemes (like lab_cie94), but I am not sure if I am missing something.
The generated command looks like this:
java -Xms500m -Xmx2g -jar ham_convert_1.10.0.jar tmp-agaconv-video-ham6-320-20948/ham_convert_batch_file.txt ham6_q5 norle nopng dither_masked color_lab_cie94
Not sure how to activate the triple mode or if there are better dither options – masked atm produces a sort of “colour-interlace” effect that makes the video look *a lot* better than FS!
Another thing I noticed: the software runs faster on a 2012 i5@2.5GHZ (Mac Mini) than it does on an M3 Pro (2023)… any idea what could be the root cause? I can think either of an excessive number of threads (maybe I need to optimise via command-line), lack of memory, or unsupported math functions that need more operations on ARM.
I’ve added a more precise description of command line ham6 conversion profiles. Triple mode is activated in ham6_q4 – ham6_q7.
Dither and dither_masked option use dithering more appropriate for ham6 that avoid adding additional noise. Second variant flips pattern on even lines to make it less visible.
There is a new color space option in 1.10.0 that you can try instead of color_lab_cie94: color_ictcp.
On ARM cpu you should install native ARM build of java: https://adoptium.net/temurin/releases/?os=mac&arch=aarch64. Otherwise it will use slower Intel emulation (there is an articlecomparing java 11 and 17 on arm mac: https://bitrise.io/blog/post/building-android-apps-on-apple-silicon). M1, M2, M3 have different types of cores – performance and efficiency. It’s possible that the installed version of java incorrectly assigns cores. There is a command line parameter to adjust number of used threads manually – threads_X – CPU threads, X=1 to available CPU threads.