Enhanced decoding of YJK images

Page 5/5
1 | 2 | 3 | 4 |

By KdL

Paragon (1429)

KdL's picture

24-08-2017, 10:18

Yes hit9918, the converter is yours and it is great, thank you for your work! Running Naked in a Field of Flowers

Some details:
- over the final pictures at the borders I have masked the artifacts with two black columns of sprites;
- the aspect ratio of the original picture has been manually edited, similarly to the JUST mode of a Panasonic TV.

The final result with blueMSX 50Hz "streched mode" is this:

Original image: 1024x768
Optimal resize: 240x212 (by paint.net)
Editing: 40 pixels of the left and right sides are stretched to 48 pixels (by paint.net)
Output image: 256x212 (PNG by paint.net)
Finally: the hit9918's Java Converter

By Grauw

Ascended (10561)

Grauw's picture

05-05-2020, 03:42

I’ve been doing research into YJK and I’m writing an article about it for the MSX Assembly Page.

One of the things I think I may have found an explanation for is why the V9958 uses YJK where blue is given the highest weight and green the lowest, as opposed to YUV where green is given the highest weight and blue the lowest. As such Y expresses luma much better in YUV. Separating luma (light intensity) from chroma (colour) is very useful because our eyes are more sensitive to intensity than to colour changes. Ricardo Cancho Niemietz has written an excellent article about this: Issues on YJK colour model implemented in Yamaha V9958 VDP chip.

So this leaves us mystified. Why did the Yamaha designers choose YJK when they could’ve gone for YUV by just swapping some weights? Clearly their engineers were very smart and they wouldn’t make a colour model inspired by YUV but deviate in such an important detail without reason.

I think the explanation is as follows: there are six bits for J and K, but only five for Y. Due to this YJK can only represent half of the RGB colours, 2^14 instead of the 2^15 that 15-bit RGB can produce. Ideally Y would have 6 bits as well to get the full range, but this didn’t fit in the byte encoding (and certainly not in YJK+YAE).

So if you want to reduce the resolution of one of the RGB colour components by one bit, which would you choose? The answer is blue, just like in screen 8, because our eyes are the least perceptive of blue, so we won’t notice it so much. And this is indeed what the Yamaha designers did; in YJK mode blue is effectively only 4-bit, and in YJK+YAE mode effectively 3-bit.

Had the Yamaha designers gone for YUV and given the largest weight to green instead of blue, green would have gotten the least resolution, the most visible colour of all! Especially in YUV+YAE mode this would’ve been quite noticeable. This is probably also what you will see if you use the additional YUV mode on the V9990. Although at first sight the YUV mode is the better choice it may actually give worse results, with perhaps more accurate colour reproduction, but also much more visible banding.

By Pac

Scribe (6649)

Pac's picture

06-05-2020, 01:23

Interesting, so if I have understood correctly, that unintentional mistake that Yamaha made according to the Ricardo's article, was in fact something intentional?

By Grauw

Ascended (10561)

Grauw's picture

03-01-2021, 19:29

Hi all, I’ve just published a new article on the MSX Assembly Page:

The YJK screen modes

An exploration of the YJK screen modes of the MSX2+.

If you have any feedback let me know! I’m also working on a part 2 on image conversion to YJK.

By sd_snatcher

Prophet (3500)

sd_snatcher's picture

04-01-2021, 00:12

Excellent article!

Here's one contribution: What you called "color clipping" has a specific technical term in the color space nomenclature. It's called "Out of gamut colors".

The biggest trick about to draw pixel art on YJK while getting around the color bleed is to learn how to use these out of gamut colors similar to how the black color was used on the ZX-Spectrum to disguise the color bleed.

This is a quick list of the repertory of tricks I used to maximize the results:

  • Use the out of gamut colors to disguise the color bleed, similar to what's done with the black color on the ZX-Spectrum, or the shared background color on the C64
  • Careful cell management/alignment, much like used on good screen-2 graphics
  • Misguiding pixels, to disguise square block corners and fool the brain that the bleed isn't there (IOW, deblock the color bleed, since our brain is trained to quickly detect and hate it)
  • Cheat a lot with pseudo color perception (aka color illusion), like on C64 graphics (and some recent screen-2 graphics), when you can't use the exact color you need given the restrictions
  • Dithering might be a good friend to help to disguise the color bleed and to add details where otherwise the restrictions wouldn't permit. Do not be afraid to use it when necessary

These tricks are used in the majority of impressive pixel art for all platforms that have color bleed, including: MSX/SCR2, ZX-Spectrum, C64 and even the NES.

Using them is possible to produce normal pixel art on YJK like this:

And even lineart-styled pixel art like these:

And even allows much higher quality and colorful image conversions like this:

By Grauw

Ascended (10561)

Grauw's picture

04-01-2021, 20:36

Thanks! I’ll incorporate those ideas.

By sd_snatcher

Prophet (3500)

sd_snatcher's picture

04-01-2021, 21:20


AFAIK none of the current image converters take advantage of the out-of-gamut colors. All of them just use by-the-book conversion/clipping formulas.

Yes, a human artist can take much more advantage of those colors, since he will create new contours that an automatic converter never will (much like screen-2), but even that considered, the out-of-gamut colors can still help automatic image converters.

By asiga

Rookie (21)

asiga's picture

23-08-2021, 23:54

If I'm looking at the right functions in the Java code by hit9918 (btw, the link seems to be broken, but found a backup at atariage, not sure if it's the latest version though), I assume that his algorithm is a brute force optimization by iterating over all possible YJK values for the 4 pixels, and finding which solution has the minimum least squares error in the group of 4 pixels (considering a combination of r,g,b errors and luminance error).

Is that correct? Or maybe the latest version was using another algorithm?

If it's correct, that approach is obviously going to provide the best result, because you are actually getting the solution with the smallest possible error. However... the cost is high, as with every brute-force optimization technique...

Has anybody developed any alternative formula that is not expensive as iterating over all the possible YJK values, and that at the same time provides a better result than getting the JK from the RGB average of the 4 pixels (which generates the very noticeable luminance artifacts in a lot of MSX2+ pictures out there) ?

BTW, Grauw, GREAT ARTICLE!!! Smile

Page 5/5
1 | 2 | 3 | 4 |