https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: 1b4f44aecd6542d197c3cf349a8f83dad91291bd authored by danne on 09 August 2019, 10:06:33 UTC
crop_rec.c:(EOSM highlight issue in blown highlight cmos4 has to be on default. Todo, anoly add the fix for higher iso maybe. From here https://www.magiclantern.fm/forum/index.php?topic=20025.msg219647#msg219647)
Tip revision: 1b4f44a
mlv.c
/*
 * Copyright (C) 2013 Magic Lantern Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include <dryos.h>
#include <module.h>
#include <stdint.h>
#include <lens.h>
#include <property.h>
#include <propvalues.h>
#include <picstyle.h>
#include <raw.h>
#include <fps.h>

#include "mlv.h"
#include "../trace/trace.h"

extern uint32_t raw_rec_trace_ctx;

extern uint64_t get_us_clock();
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, int n);
extern const char* get_picstyle_name(int raw_picstyle);

extern struct prop_picstyle_settings picstyle_settings[];

void mlv_fill_lens(mlv_lens_hdr_t *hdr, uint64_t start_timestamp)
{
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "LENS");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_lens_hdr_t);

    hdr->focalLength = lens_info.focal_len;
    hdr->focalDist = lens_info.focus_dist;
    hdr->aperture = lens_info.aperture * 10;
    hdr->stabilizerMode = lens_info.IS;
    hdr->lensID = lens_info.lens_id;
    hdr->autofocusMode = af_mode;
    hdr->flags = 0;

    char buf[33];
    snprintf(buf, sizeof(buf), "%X%08X", (uint32_t) (lens_info.lens_serial >> 32), (uint32_t)(lens_info.lens_serial & 0xFFFFFFFF));
    
    strncpy((char *)hdr->lensName, lens_info.name, 32);
    strncpy((char *)hdr->lensSerial, buf, 32);
}

void mlv_fill_wbal(mlv_wbal_hdr_t *hdr, uint64_t start_timestamp)
{
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "WBAL");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_wbal_hdr_t);

    hdr->wb_mode = lens_info.wb_mode;
    hdr->kelvin = lens_info.kelvin;
    hdr->wbgain_r = lens_info.WBGain_R;
    hdr->wbgain_g = lens_info.WBGain_G;
    hdr->wbgain_b = lens_info.WBGain_B;
    hdr->wbs_gm = lens_info.wbs_gm;
    hdr->wbs_ba = lens_info.wbs_ba;
}

void mlv_fill_styl(mlv_styl_hdr_t *hdr, uint64_t start_timestamp)
{
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "STYL");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_styl_hdr_t);

    hdr->picStyleId = lens_info.raw_picstyle;
    hdr->contrast = lens_get_contrast();
    hdr->sharpness = lens_get_sharpness();
    hdr->saturation = lens_get_saturation();
    hdr->colortone = lens_get_color_tone();

    strncpy((char *)hdr->picStyleName, get_picstyle_name(lens_info.raw_picstyle), sizeof(hdr->picStyleName));
}

void mlv_fill_expo(mlv_expo_hdr_t *hdr, uint64_t start_timestamp)
{
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "EXPO");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_expo_hdr_t);

    /* iso is zero when auto-iso is enabled */
    if(lens_info.iso == 0)
    {
        hdr->isoMode = 1;
        hdr->isoValue = lens_info.iso_auto;
    }
    else
    {
        hdr->isoMode = 0;
        hdr->isoValue = lens_info.iso;
    }
    hdr->isoAnalog = lens_info.iso_analog_raw;
    hdr->digitalGain = lens_info.iso_digital_ev;
    hdr->shutterValue = (uint32_t)(1000.0f * (1000000.0f / (float)get_current_shutter_reciprocal_x1000()));
}

void mlv_fill_rtci(mlv_rtci_hdr_t *hdr, uint64_t start_timestamp)
{
    struct tm now;
    memset(&now, 0x00, sizeof(struct tm));

    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "RTCI");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_rtci_hdr_t);

    /* get calendar time from real time clock */
    LoadCalendarFromRTC(&now);

    hdr->tm_sec = now.tm_sec;
    hdr->tm_min = now.tm_min;
    hdr->tm_hour = now.tm_hour;
    hdr->tm_mday = now.tm_mday;
    hdr->tm_mon = now.tm_mon;
    hdr->tm_year = now.tm_year;
    hdr->tm_wday = now.tm_wday;
    hdr->tm_yday = now.tm_yday;
    hdr->tm_isdst = now.tm_isdst;
    hdr->tm_gmtoff = now.tm_gmtoff;

    memset(hdr->tm_zone, 0x00, 8);
    strncpy((char *)hdr->tm_zone, now.tm_zone, 8);
}

void mlv_fill_idnt(mlv_idnt_hdr_t *hdr, uint64_t start_timestamp)
{
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)hdr, "IDNT");
    mlv_set_timestamp((mlv_hdr_t *)hdr, start_timestamp);
    hdr->blockSize = sizeof(mlv_idnt_hdr_t);
    
    hdr->cameraModel = camera_model_id;
    memcpy(hdr->cameraName, camera_model, 32);
    memcpy(hdr->cameraSerial, camera_serial, 32);

    trace_write(raw_rec_trace_ctx, "[IDNT] cameraName: '%s' cameraModel: 0x%08X cameraSerial: '%s'", hdr->cameraName, hdr->cameraModel, hdr->cameraSerial);
}

void mlv_build_vers(mlv_vers_hdr_t **hdr, uint64_t start_timestamp, const char *version_string)
{
    int block_length = (strlen(version_string) + sizeof(mlv_vers_hdr_t) + 1 + 3) & ~3;
    mlv_vers_hdr_t *header = malloc(block_length);
    
    /* prepare header */
    mlv_set_type((mlv_hdr_t *)header, "VERS");
    mlv_set_timestamp((mlv_hdr_t *)header, start_timestamp);
    header->blockSize = block_length;
    header->length = strlen(version_string);
    
    char *vers_hdr_payload = (char *)&header[1];
    strcpy(vers_hdr_payload, version_string);
    
    *hdr = header;
}

uint64_t mlv_prng_lfsr(uint64_t value)
{
    uint64_t lfsr = value;
    int max_clocks = 512;

    for(int clocks = 0; clocks < max_clocks; clocks++)
    {
        /* maximum length LFSR according to http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf */
        int bit = ((lfsr >> 63) ^ (lfsr >> 62) ^ (lfsr >> 60) ^ (lfsr >> 59)) & 1;
        lfsr = (lfsr << 1) | bit;
    }

    return lfsr;
}

uint64_t mlv_generate_guid()
{
    struct tm now;
    uint64_t guid = get_us_clock();
    LoadCalendarFromRTC(&now);

    /* now run through prng once to shuffle bits */
    guid = mlv_prng_lfsr(guid);

    /* then seed shuffled bits with rtc time */
    guid ^= now.tm_sec;
    guid ^= now.tm_min << 7;
    guid ^= now.tm_hour << 12;
    guid ^= now.tm_yday << 17;
    guid ^= now.tm_year << 26;
    guid ^= get_us_clock() << 37;

    /* now run through final prng pass */
    return mlv_prng_lfsr(guid);
}

void mlv_init_fileheader(mlv_file_hdr_t *hdr)
{
    mlv_set_type((mlv_hdr_t*)hdr, "MLVI");
    hdr->blockSize = sizeof(mlv_file_hdr_t);
    strncpy((char*)hdr->versionString, MLV_VERSION_STRING, sizeof(hdr->versionString));
}

void mlv_set_type(mlv_hdr_t *hdr, char *type)
{
    memcpy(hdr->blockType, type, 4);
}

uint64_t mlv_set_timestamp(mlv_hdr_t *hdr, uint64_t start)
{
    uint64_t timestamp = get_us_clock();

    if(hdr)
    {
        hdr->timestamp = timestamp - start;
    }
    return timestamp;
}

int mlv_write_vers_blocks(FILE *f, uint64_t mlv_start_timestamp)
{
    int mod = -1;
    int error = 0;
    
    do
    {
        /* get next loaded module id */
        mod = module_get_next_loaded(mod);
        
        /* make sure thats a valid one */
        if(mod >= 0)
        {
            /* fetch information from module loader */
            const char *mod_name = module_get_name(mod);
            const char *mod_build_date = module_get_string(mod, "Build date");
            const char *mod_last_update = module_get_string(mod, "Last update");
            
            if(mod_name != NULL)
            {
                /* just in case that ever happens */
                if(mod_build_date == NULL)
                {
                    mod_build_date = "(no build date)";
                }
                if(mod_last_update == NULL)
                {
                    mod_last_update = "(no version)";
                }
                
                /* separating the format string allows us to measure its length for malloc */
                const char *fmt_string = "%s built %s; commit %s";
                int buf_length = strlen(fmt_string) + strlen(mod_name) + strlen(mod_build_date) + strlen(mod_last_update) + 1;
                char *version_string = malloc(buf_length);
                
                /* now build the string */
                snprintf(version_string, buf_length, fmt_string, mod_name, mod_build_date, mod_last_update);
                
                /* and finally remove any newlines, they are annoying */
                for(unsigned int pos = 0; pos < strlen(version_string); pos++)
                {
                    if(version_string[pos] == '\n')
                    {
                        version_string[pos] = ' ';
                    }
                }
                
                /* let the mlv helpers build the block for us */
                mlv_vers_hdr_t *hdr = NULL;
                mlv_build_vers(&hdr, mlv_start_timestamp, version_string);
                
                /* try to write to output file */
                if(FIO_WriteFile(f, hdr, hdr->blockSize) != (int)hdr->blockSize)
                {
                    error = 1;
                }
                
                /* free both temporary string and allocated mlv block */
                free(version_string);
                free(hdr);
            }
        }
    } while(mod >= 0 && !error);
    
    return error;
}
back to top