[This is a not very good translation from Japanese, I am deeply sorry] --------------------------------------------------------------------- ======================================================================== #### MAKI format specificaton #### By Woody RINN (MAKIchanNET #03) ======================================================================== - Naming MAKI is a 640x400 pixel analog 16-color image format developed at MAKIchanNET. The official name is "MAKI format". It is also casually known as the "Maki-chan format". In this case, "Maki-chan" refers to Maki-chan from MAKIchanNET, which is written in hiragana. - Overview First, vertical similarities are removed using XOR filtering, then the image is divided into squares, and only squares with differing pixels are stored. Each pair of horizontal pixels are grouped in single bytes. This yields a virtual screen resolution of 320x400. One pixel can be represented by one byte. It consists of two color codes. MSB LSB I1 G1 R1 B1 I2 G2 R2 B2 - Data 1) Section layout Data is divided in five sections. Header (48 bytes) Analog palette (48 bytes) Flag A (1000 bytes) Flag B Pixel data 2) Header layout The header consists of 48 bytes. The data uses the Motorola storage type. Actually, the prototype was first written on the X86K, but for some reason it's never been changed (^^;) Offset Content Size Explanation ------- --------------------- ----- ----------------------------- 0 'MAKI01A ' 8 Check these 8 bytes 8 'PC98' + %USER% + EOF 23+1 Model, env. var. USER, etc 32 (0 - 16000) 2 Size of Flag B 34 (0 - 64000) 2 Size of Pixel Data A 36 (0 - 64000) 2 Size of Pixel Data B 38 0 2 Extension flags 40 0 2 Display start position X 42 0 2 Display start position Y 44 640 2 Display end position X+1 46 400 2 Display end position Y+1 Firstly, the first 8 bytes are check data. Currently, two types are defined: "MAKI01A " and "MAKI01B ". (Don't forget the space at the end) After that is the model code. Please try to keep it to four characters, so it looks good when searching with GREP etc. (Examples: PC98, PC88, ESEQ, X68K, MSX2) Next is the user name. The contents of the environment variable USER are saved here. Originally, this string was to store the encoder version and other information. The character length limit is too tight. I should have made it more flexible (^^;). I see a lot of image data from users who have not set up their USER variable. Please encourage them to write their names. :) The text ends with EOF ($1A). This is 32 bytes. You can examine this data by using TYPE etc. After that, size and other such data is recorded. Display coordinates are reserved for when partial compression is supported in the future. Currently partial compression is not supported. The values are always 0, 0, 640, 400. Words are stored in Motorola format, upper byte first, then lower. Sorry :) Example: 640, 400 == $02, $80, $01, $90 3) Extension flags The two bytes from offset 38 are used as extension flags. For now, only bits 0 and 1 of byte 39 are used. MSB LSB xxxx xxxx xxxx xxBA A: 200-row flag (bit 0) Set this to 1 when saving at 200 rows. This means the aspect ratio is 1:2 (vertically), not that the data only goes for 200 rows. In the case of MSX, 212 rows are saved. If you look at an image using 200-row mode in a conventional loader, it will appear squashed by half. B: Digital 8-color flag (bit 1) If this is set, it uses digital 8-color data. When viewed on a digital 88 or 98, the image should be displayed as is, and error diffusion is not done. This does not apply to analog color models. 4) Palette data The palette data is 1 byte each in the order GRB, for a total of 48 bytes. If the value is not 0, expand it to 8 bits by filling the lower bits with 1's. 0 ... %00000000 1 ... %00011111 2 ... %00101111 Example: 16-color case 3 ... %00111111 4 ... %01001111 : : 15 ... %11111111 - How to decompress Now let's explain the basic image decompression algorithm. 1) Virtual screen deployment First, create a 320x400 pixel black and white virtual screen in memory. Check flag A one bit at a time. If the bit is 0, clear the 4x4 square. If the bit is set, read 2 bytes from flag B and use them as the data for that 4x4 square. In this way, 4x4 pixel squares are set one at a time, starting from the upper left corner, and ending when 320x400 pixels are finished. The pixel data offset is saved in the header, but in this case it is the same as starting to read pixel data from the next byte after the last flag B byte. 2) Extracting pixel data There is a 320x400 pixel black and white virtual screen in memory. Now let's examine the virtual screen one bit at a time. If the bit is 0, clear 2 pixels on the actual screen. If the bit is set, read 1 byte from pixel data and display 2 pixels on the actual screen. Additionally, pixel data A has the top 200 rows, and B the bottom 200 rows. Segment boundary countermeasures :) 3) Image reconstruction In the case of "MAKI01A ", 400 minus 2 rows are XOR'ed with the row two rows above. for(y=2;y<400;y++){ for(x=0;x<640;x++){ pset(x,y,(point(x,y)^point(x,y-2)); /* XOR it */ } } In the case of "MAKI01B ", it is 4 rows above. - Compression method Follow the decompression method in reverse. 1) Take the vertical difference for(y=399;y>1;y++){ for(x=0;x<640;x++){ pset(x,y,(point(x,y)^point(x,y-2)); /* XOR it */ } } Compare the result from XOR'ing 400 minus 2 with 2 rows above with the result from XOR'ing 400 minus 4 with 4 rows above, and select the one that has fewer non-zero pixels. If it is the 2 rows one, that is "MAKI01A ", and if it is the 4 rows one, that is "MAKI01B ". 2) Set up a virtual screen Check each pixel on the screen, and if it is 0, set the corresponding bit on the virtual screen to 0. If it is not 0, set the corresponding bit on the virtual screen to 1, and write the pixel value to the buffer. The top 200 rows are written in pixel data A, and the bottom 200 rows are written in pixel data B. 3) Create flag A Check each 4x4 pixel square on the virtual screen, and if it is all 0, set the corresponding flag A bit to 0. If it is not all 0, set the corresponding flag A bit to 1, and write the virtual screen data to flag B. 4) Save The header, palette, flags A and B, and pixel data are saved to the file in this order. - Future prospects At first, the MAKI format was released with the expectation that it would be improved and expanded in the future, like "Well, we're just testing the format for now." But it has spread wide unexpectedly :) Making poorly thought-out modifications would just cause confusion, and recently high-performing high-compression formats like Yanagisawa-san's PI have been announced, so if a new format was to be announced, it will not be an improvement to MAKI, but something completely different. Various experiments have already been done, and the new format is near. A lot of progress is being made behind the scenes, so please look forward to it. When the announcement will be is not decided yet, but I do not intend to release it until I am satisfied with it. Ah, I'm looking for collaborators who could help port the format to various platforms. Same for MAKI, please. - Rights and rules This format is completely free to use without any restrictions. However, the right to use a loader/saver etc belongs to the creator of that program. The rights to any images saved in this format belong to the creators of those images. Please follow the terms set by each of them. If there is any trouble as a result of using this format, MAKIchanNET and the members involved in making this format are in no way responsible. Support for this format is available on MAKIchanNET and on any BBS that has MAKIchanNET members. You are free to create and publish tools like loaders/savers. If you are interested in a port, please contact MAKIchanNET or one of its members as soon as possible. - Conclusion This specification can be freely distributed. Questions, bug reports, requests, comments etc are welcome. I would be happy if you send me an e-mail. Glad to be useful to CG enthusiasts. That's it. RINN