END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Visit the official fractalforums.com Youtube Channel
 
*
Welcome, Guest. Please login or register. March 28, 2024, 01:53:00 PM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: [1]   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: KFB to MMIT converter  (Read 4341 times)
0 Members and 1 Guest are viewing this topic.
Dinkydau
Fractal Senior
******
Posts: 1616



WWW
« on: February 02, 2017, 05:26:19 PM »

I made a program to convert KFB maps from Kalles Fraktaler to the Mandel Machine MMIT format that can be loaded in Mandel Machine. My motivation was to use Mandel Machine to save renders as PNG (Kalles Fraktaler only saves as JPEG) and to use the coloring methods available in Mandel Machine. KFB files from fractal types other than the Mandelbrot set (burning ship and others) also work but of course you can't continue zooming in Mandel Machine.

Download it here:
https://mega.nz/#!M40BBQLA!vAeotI2-0_kaWBMoDqyGs_wDMTIAGe1tn0yqBt_CIqU

Information:
It's a commandline program.

The MMIT and KFB file formats only have iteration data in common which has consequences for the other relevant data.
If you want to load the gradient in Mandel Machine, save both a KFB and KFR file. Mandel Machine can read the KFR file and load the gradient from there.
Because KFB doesn't have location information, I designed the program to write some arbitrary location information to the MMIT file. Otherwise Mandel Machine doesn't understand the file. If you want the correct location information (for example to continue zooming) you will also need to load the KFR file or just copy and paste it from Kalles Fraktaler, but make sure to deselect location information when you load the MMIT.

The MMIT file format was designed to allow for efficient storage of iteration data. My program generates very inefficient MMIT files because I'm too lazy to figure out how to do zlib compression and use a smaller datatype for the iteration counts when possible.

This program makes use of source code from Claude's kf-extras to read KFB files and extract iteration counts from them. Claude also helped me to find the relevant source code in Mandel Machine. Thanks for the help.

If you find a location that causes problems please let me know. I will try to improve the program if I can. (I'm not an experienced programmer.)

Source code (written in C) that depends on kfb.h and kfb.c from kf-extras:
Code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include "kfb.h"

void asserts(){
    assert(sizeof(char)==1);
    assert(sizeof(short)==2);
    assert(sizeof(int)==4);
    assert(sizeof(float)==4);
    assert(sizeof(double)==8);
    assert(sizeof(long)==4);
    assert(sizeof(long long)==8);
    return;
}

//data_size counts how large the mmit data is before zlib formatting
int data_size = 0;
const char one = 1;

union DoubleBytes {//to interpret double as char array and inverse byte order
   double d;
   char b[8];
};

union IntBytes {//to interpret int as char array
   int i;
   char b[4];
};

//functions to write data in big endian notation

int le_to_be_int(int input){
    int num = input;
    int b0,b1,b2,b3;
    int res;
    b0 = (num & 0x000000ff) << 24u;
    b1 = (num & 0x0000ff00) << 8u;
    b2 = (num & 0x00ff0000) >> 8u;
    b3 = (num & 0xff000000) >> 24u;
    res = b0 | b1 | b2 | b3;
    return res;
}

void write_be_int(int input, FILE *outfile){
    int res = le_to_be_int(input);
    fwrite(&res, 4, 1, outfile);
    data_size += 4;
}

void write_be_char(char input, FILE *outfile){
fwrite(&input, 1, 1, outfile);
data_size += 1;
}

void write_be_double(double input, FILE *outfile){
union DoubleBytes doublebytes;
doublebytes.d = input;
for(int i=0; i<4; i++){//reverse byte order in the double with char array interpretation
char temp = doublebytes.b[i];
doublebytes.b[i] = doublebytes.b[7-i];
doublebytes.b[7-i] = temp;
}
fwrite(&doublebytes.d, 8, 1, outfile);
data_size += 8;
}

int main(int argc, char **argv) {
    //Check and load KFB file-----------------------------------------------------------------------------------
    asserts();
    if (argc < 2)
    {
      printf("This program converts a given KFB file to MMIT. Program version: 1.0
");
      printf("Usage: "); printf(argv[0]); printf(" path_to_KFB [path_to_MMIT]
");
      printf("Default for path_to_MMIT: MMIT-convert.mmit
");
        return 1;
    }
    printf("Loading KFB file...
");
    kfb *in = kfb_load(argv[1]);
    if (! in) { printf("Loading KFB file failed.
"); return 1; }
    int width = kfb_width(in);
    int height = kfb_height(in);
  
    //Writing all relevant mmit data to tempoutfile without zlib format--------------------------------------------

    FILE *tempoutfile;
    tempoutfile=fopen("tempoutfile", "wb");
    
    //Get min and max iteration values present in KFB
double max_iters = 0;
double min_iters = 800100100;
for(int i=0; i<height; i++){
     for(int j=0; j<width; j++){
     double ij = kfb_get(in, j, i);
     if(ij<min_iters) min_iters = ij;
     if(ij>max_iters) max_iters = ij;
     }
    }
    printf("Lowest iteration count: %lf
", min_iters);
    printf("Highest iteration count: %lf
", max_iters);
    
    //Parameters and settings
    write_be_int(one, tempoutfile); //Program version
    write_be_int(width, tempoutfile); //Canvas width
    write_be_int(height, tempoutfile); //Canvas height
    char supersampling = 0; write_be_char(supersampling, tempoutfile); //Supersampling (Always 0 for no supersampling)
    double magnification = 512; write_be_double(magnification, tempoutfile); //Fake magnification default to arbitrary value;
    double rotation = 256; write_be_double(rotation, tempoutfile); //Fake rotation default to arbitrary value;
    int coord_digits = 11; write_be_int(coord_digits, tempoutfile); //Fake number of coordinate digits
    int coords[44] = {-1, -1, -1, -1, -1768346623, 1239184185, -1450836726, -1610156628, -1160793342, 1122682978, 1750969101, 1468815386, -86691575, -319241320, -141699069, 731720154, -1302511102, 2092147506, 1358717447, -121412270, -362838523, 1906712988, 218032387, 147395776, 1528659973, -1874890155, 1817790991, 431114295, 1763611407, -389200653, 1363516937, 1455562147, 707986444, -847133922, 1130970381, 1568324293, 1567881485, -580086891, 1843248142, 1016614712, 1950251523, -75377623, -1674907892, 1914116203};
    for(int i=0; i<44; i++){ //Fake array of coordinate digits
   fwrite(&coords[i], 4, 1, tempoutfile);
data_size += 4;
}
    
int iteration_limit = 799999999; write_be_int(iteration_limit, tempoutfile); //default one below MM's 800M limit, seems safe
char bytesPerSample = 4; write_be_char(bytesPerSample, tempoutfile); //always 4 (the max) for simplicity
write_be_double(min_iters, tempoutfile); //minimum number of iterations in the data
double granularity = (799999999 - min_iters)/4294967290; write_be_double(granularity, tempoutfile); //(equal to iterRange / 4294967290, where iterRange is maxIt - minIt)

printf("Writing iteration data...
");
//Iteration data
    double granRec = 0; if(granularity != 0) granRec = 1/granularity;
    long long prevEncoded = 0;
    char buffer[width*4];
    union IntBytes intbytes;
    for(int row=0; row<height; row++){
     for(int col=0; col<width; col++){
     double it = kfb_get(in, col, row);
     long long encoded;
     if (it == max_iters) encoded = 3; //Point inside minibrot
     else encoded = round((it-min_iters)*granRec) + 5; //encodeSample
     int diff = encoded - prevEncoded;
     //writeSample:
     intbytes.i = diff;
     buffer[col+3*width] = intbytes.b[3];
buffer[col+2*width] = intbytes.b[2];
buffer[col+width] = intbytes.b[1];
buffer[col] = intbytes.b[0];
//
     prevEncoded = encoded;
     }
     fwrite(&buffer, width*4, 1, tempoutfile);
     data_size += width*4;
    }
  
    fclose(tempoutfile);
    kfb_free(in);
    
    printf ("Total data size: %d
", data_size);

    //read uncompressed MMIT data into array a---------------------------------------------------------------------
    char* a = malloc(data_size);
    if(a==NULL){ printf ("Allocation of memory failed.
"); return 1;}
    FILE *readbackfile;
    readbackfile=fopen("tempoutfile", "rb");
    fread(a, data_size, 1, readbackfile);
  
    printf("Writing zlib format...
");
    //Convert to zlib format and write to file---------------------------------------------------------------------
    FILE *outfile;
    if(argc > 2) outfile=fopen(argv[2], "wb");
    else outfile=fopen("MMIT-convert.mmit", "wb");
  
    int bytes_written = 0;
char header_more[] = {0, 86, 129, 169, 126}; // hardcoded zlib header for a block size of 33110;
    while(bytes_written<data_size)
    {
     if(data_size - bytes_written > 33110)
      { //not the last block header
      fwrite(&header_more, 5, 1, outfile);
      for(int j=0; j<33110; j++)
      {
      fwrite(&a[bytes_written+j], 1, 1, outfile);
      }
      bytes_written += 33110;
   }
   else
   { //the last block header
   short to_go = data_size - bytes_written;
      short complement = 65535 - to_go;
      fwrite(&one, 1, 1, outfile);
      fwrite(&to_go, 2, 1, outfile);
      fwrite(&complement, 2, 1, outfile);
      for(int j=0; j<to_go; j++)
      {
      fwrite(&a[bytes_written+j], 1, 1, outfile);
      }
      bytes_written += to_go;
   }
    }
  
    //-----------------------------------------------------------------------------------
  
    fclose(readbackfile);
    if(remove("tempoutfile") != 0) printf("Deleting the temporary file failed.");

    printf ("Done");

    return 0;
}

The Mandel Machine MMIT compressed iteration data file format:

Code:
Every datatype needs to be written in big endian notation.

The following streamed through a Deflater (raw zlib format):

<int 4 bytes> Program Version
<int 4 bytes> Canvas Width
<int 4 bytes> Canvas Height
<byte> Supersampling
<double> Magnification
<double> Rotation
<int 4 bytes> Number of coordinate digits represented by long ints
<long long array> array 2 times as long as the above int
<int 4 bytes> Iteration limit
<byte> Bytes per sample
<double> minimum iteration count
<double> granularity (equal to iterRange / (2^(bytes_per_sample*8) - 6), where iterRange is maxIt - minIt)
<int array> row by row encoded samples (one int value per pixel)
« Last Edit: February 11, 2017, 09:46:09 PM by Dinkydau » Logged

Adam Majewski
Fractal Lover
**
Posts: 221


WWW
« Reply #1 on: February 03, 2017, 04:35:21 PM »

Thx. What is the licence of your program ?
Logged
Dinkydau
Fractal Senior
******
Posts: 1616



WWW
« Reply #2 on: February 04, 2017, 12:28:26 AM »

There is no license. Please don't sell it for money, claim it as your own creation etc. You can use it and make changes to it as you wish. When appropriate, giving credit is appreciated (if you publish an edited version for example). The same thing goes for my images and videos. I just hope that everyone who uses this is reasonable and honest.
Logged

lycium
Fractal Supremo
*****
Posts: 1158



WWW
« Reply #3 on: February 04, 2017, 03:34:35 AM »

Kalles Fraktaler only saves as JPEG

Whaaaaat... that's just unbelievable. Especially in this day of public domain single-header PNG writer libraries: https://github.com/nothings/stb/blob/master/stb_image_write.h
Logged

Adam Majewski
Fractal Lover
**
Posts: 221


WWW
« Reply #4 on: February 04, 2017, 12:01:02 PM »

There is no license. Please don't sell it for money, claim it as your own creation etc. You can use it and make changes to it as you wish. When appropriate, giving credit is appreciated (if you publish an edited version for example). The same thing goes for my images and videos. I just hope that everyone who uses this is reasonable and honest.

I have asked because kf-extras  has :
 
  "kf-extras -- extras for manipulating output from Kalles Fraktaler 2
  (C) 2014 Claude Heiland-Allen, partially based on work by Karl Runmo
  License: attribution, with any modified source made available (no warranty)"

Can I put you code here ? 

https://en.wikibooks.org/wiki/Fractals/MandelMachine#data_format




Logged
Kalles Fraktaler
Fractal Senior
******
Posts: 1458



kallesfraktaler
WWW
« Reply #5 on: February 04, 2017, 01:46:36 PM »

I think it would be cool to be able to do the other way, from MMIT to KFB or MMY.
But I cannot run MM anyway because java is blocked on my machine  sad
Logged

Want to create DEEP Mandelbrot fractals 100 times faster than the commercial programs, for FREE? One hour or one minute? Three months or one day? Try Kalles Fraktaler http://www.chillheimer.de/kallesfraktaler
http://www.facebook.com/kallesfraktaler
Dinkydau
Fractal Senior
******
Posts: 1616



WWW
« Reply #6 on: February 05, 2017, 08:06:08 PM »

I have asked because kf-extras  has :
 
  "kf-extras -- extras for manipulating output from Kalles Fraktaler 2
  (C) 2014 Claude Heiland-Allen, partially based on work by Karl Runmo
  License: attribution, with any modified source made available (no warranty)"

Can I put you code here ? 

https://en.wikibooks.org/wiki/Fractals/MandelMachine#data_format
That's okay but if I make changes the updated version will be in this thread.

Let me make some changes to the MMIT format specification by the way. Outside of the context of this program bytes per sample doesn't have to be always 4.

I think it would be cool to be able to do the other way, from MMIT to KFB or MMY.
But I cannot run MM anyway because java is blocked on my machine  sad
How can java be "blocked"? I assume you have full control over your machine.
Logged

Pages: [1]   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Ultra Fractal Coloring Converter Help & Support fractalwizz 9 1562 Last post October 22, 2008, 03:41:00 PM
by David Makin
OS X converter for MDB sequential renders to movie format Help & Support DavidMac 7 547 Last post April 28, 2012, 01:43:44 PM
by DavidMac
Gamma Ray Converter Images Showcase (Rate My Fractal) JoeFRAQ 0 776 Last post January 03, 2014, 04:27:36 PM
by JoeFRAQ
WAV -> MIDI converter? Fractal Music audiofractalman 11 4908 Last post December 10, 2015, 12:51:16 AM
by audiofractalman
Chaotic Converter Mandelbulber Gallery mclarekin 0 513 Last post August 10, 2015, 02:19:54 AM
by mclarekin

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.215 seconds with 28 queries. (Pretty URLs adds 0.012s, 2q)