Return to Level1Techs.com

[Devember 2021] Picture converter for MKS-TFT

MKS-TFT are a series of touchscreens used by 3d printers.
The interface icons / pictures can be changed by loading .bin files from an sd-card.
The .bin files contain picture data.

The firmware used by MKS-TFT is partially open source.
Unfortunately, the picture implementation is non-free / proprietary.

In this project I’ll try to reverse engineer the .bin format and implement a simple commandline picture converter.

RegularRoadmap™ :

(1) Reverse engineer the .bin format:

  • Procure sample .bin files (note: make sure they are open source / free, so that we don’t violate anything)
  • Analyze the .bin file:
    • Header
    • Picture data, raw or compressed? (note: Because MKS-TFT is an embedded system, the pixel data is probably stored in some RAW format.)
  • If anything fails, abandon ship and pick a new project.

(2) Implement a simple picture converter from some standard picture format:

  • Depending on the .bin format, pick:
    • license(s), language
    • picture format & library (unless I write my own parser/writer)
  • Github page, main and build
  • picture read & write
  • bin read & write
  • commandline parameters
  • refactoring
  • documentation
3 Likes

Sample .bin files:

License: Creative Commons - Attribution - Share Alike

Here are some visualizations of the binary files:
(made with binvis.io)

(1)


(2)

(3)

They don’t seem to have a header.

1 Like

Filesizes:


logo.bin is 153600 bytes.

The rest .bin files are 16224 bytes. If the bin files contained compressed data, they would probably have different filesizes.

Another bit of information from: Bin · Issue #10 · majurca/MKS-TFT28-NEW-PICTURES · GitHub
The display has a resolution of 320x240 (76800 pixels)
The buttons have a resolution of 78x204 (8112 pixels)
There is also a mention of 16-bit color.

153600 bytes / 76800 pixels = 2 bytes/pixel
16224 bytes / 8112 pixels = 2 bytes/pixel
(Almost always 2 bytes are 16 bits)

What a coincidence.

Here is my current theory:
The .bin files don’t have a header.
If true, the OS relies on the filename/filesize to determine the resolution.

The picture is stored in a raw format:
RGB in a 555 or 565 bit layout
Or if there is a transparency channel:
RGBA5551

It’s also entirely possible that they are using a different subpixel order, like BGR, GRB, … .

1 Like

If the .bin files contain raw pixel data, I may be able to concatenate a header and get a usable picture.

For this experiment, I’ll be using about.bin and about.svg from the source pictures.

A filetype that supports 16-bit color and RAW is bmp.

To first aquire a bmp header:
I used GIMP to convert about.svg to a bmp.

There are three ways to store 16-bit color in bmp:
-BMP565
-BMPA1555
-BMPX1555

So we have 3 headers to try out:

dd if=about.bmp of=header.bin ibs=1 count=138

(note: 138 bytes was the bmp header)

For each of them I did:

cat header.bin about.bin > aboutpic.bmp

It worked!
Screenshot from 2021-10-13 14-26-02

The picture is upside down, but we can conclude that the .bin format is RGB565.

2 Likes
1 Like

After ~700 lines of code (sloccount), It’s still pre-alpha, but It can now read and write bmp565 images:

It can also complain about bad input files and provide some error info.

There is a chance it might partially work in unusual CPUs that have 16-bit bytes.

2 Likes

Very impressive so far. Bravo.

1 Like

Update:

  • Added support for commandline parameters
  • Made an icon for README
  • Various fixes and improvements

It is now in alpha phase.

Over the next months I’ll refactor and test the code, and write documentation.
I’ll test it in various linux distros, non-glibc void, FreeBSD, HaikuOS, OpenIndiana and RedoxOS.
I also want to try out input fuzzing with AFLplusplus.

1 Like