⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileguessendian.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
字号:
function isle = fileguessendian(filename, wordsize, iooff, iosize)
% fileguessendian  - guess endian type of (partial) file content
%
% FORMAT:       isle = fileguessendian(filename [, ws [, iooff [, iosize]]])
%
% Input fields:
%
%       filename    filename
%       ws          endian wordsize, either of [2, 4, 8, 16]
%       iooff       1x1 value, default 0
%       iosize      1x1 value, default til end of file
%
% Output fields:
%
%       isle        true if content was guessed as little endian
%                   false if content was guessed as big endian
%                   NaN if content could not be guessed as either
%
% Note: - if wordsize is not given, the file will be scanned from 40%
%         of it's size onwards for the usual wordsizes 4 and 8

% Version:  v0.7a
% Build:    7080811
% Date:     Aug-08 2007, 11:17 AM CEST
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin < 1 || ...
   ~ischar(filename) || ...
    isempty(filename) || ...
    exist(filename(:)', 'file') ~= 2
    error( ...
        'BVQXtools:BadArgument', ...
        'Bad or missing argument.' ...
    );
end
filename = filename(:)';
filedir = dir(filename);
filesiz = filedir.bytes;

% detect completely automatic
isle = NaN;
if nargin < 3 || ...
   ~isa(wordsize, 'double') || ...
    numel(wordsize) ~= 1 || ...
   ~any([2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64] == wordsize)

    % check iopos and iosize
    if nargin < 3
        iooff = floor(0.4 * filesiz);
    end
    if nargin < 4
        iosize = Inf;
    end
    
    % repeat this at different positions
    for k = 1:6
        islev = zeros(1, 13);
        if nargin > 2
            islev(1) = fileguessendian(filename, 2, iooff, iosize);
        else
            islev(1) = NaN;
        end
        for c = 1:4
            islev(c + 1) = fileguessendian(filename, 4, iooff + c - 1, iosize);
        end
        for c = 1:8
            islev(c + 5) = fileguessendian(filename, 8, iooff + c - 1, iosize);
        end
        isled = (~isnan(islev));
        isles = sum(isled);
        if isles > 0
            islew = sum(islev(isled));
            if islew >= (0.75 * isles)
                isle = true;
            elseif islew <= (0.25 * isles)
                isle = false;
            end
        end
        if ~isnan(isle) && ...
            nargin > 2
            return;
        end

        % if file large enough get new IOPos
        if filesiz > 65536
            iooff = floor(rand(1) * filesiz);
            
        % otherwise give up
        else
            return;
        end
    end
    return;
end

% wordsize is known
if nargin < 3
    iooff = 0;
end
if nargin < 4
    iosize = Inf;
end
if ~isa(iooff, 'double') || ...
    numel(iooff) ~= 1 || ...
    isinf(iooff) || ...
    isnan(iooff) || ...
    iooff < 0 || ...
    iooff ~= fix(iooff) || ...
   ~isa(iosize, 'double') || ...
    numel(iosize) ~= 1 || ...
    isnan(iosize) || ...
    iosize < wordsize || ...
    (iosize / wordsize) ~= fix(iosize / wordsize) || ...
    (~isinf(iosize) && ...
     (iooff + iosize) > filesiz)
    error( ...
        'BVQXtools:BadArgument', ...
        'Invalid argument combination.' ...
    );
end

% open file for read access
try
    fid = fopen(filename, 'r', 'ieee-le');
    if fid < 1
        error('BAD_FILE_ID');
    end
    fseek(fid, iooff, -1);
    if ftell(fid) ~= iooff
        error('SEEK_FAILED');
    end
    
    % look for first byte deviating from zero
    ciooff = iooff + 32768;
    iszero = 16;
    while iszero > 0
        if ciooff <= filesiz
            ftr = fread(fid, [32768, 1], '*uint8');
        else
            ftr = fread(fid, [1, Inf], '*uint8');
            iszero = 0;
        end
        ftn = find(ftr > 0);
        if ~isempty(ftn)
            iszero = 0;
            iooff = (ftell(fid) - numel(ftr)) + ...
                wordsize * floor((ftn(1) - 1) / wordsize);
            if iooff < 0
                iooff = 0;
            end
        elseif iszero == 0
            fclose(fid);
            return;
        end
        iszero = iszero - 1;
    end
catch
    error( ...
        'BVQXtools:FileReadError', ...
        'Error opening/seeking file.' ...
    );
end
if isinf(iosize)
    iosize = filesiz - iooff;
end
ioend = iooff + wordsize * floor(iosize / wordsize);

% create a loop to allow working on large files
guesses = 0;
ilrgread = 1536 / wordsize;
lrgread = ilrgread;
lrgth = ceil(lrgread / 5 + 1);
for cpos = iooff:1536:ioend
    
    % seek to position
    fseek(fid, cpos, -1);
    
    % for smaller chunks
    if (cpos + 1536) > ioend

        % re-calc number of elements
        lrgread = (ioend - cpos) / wordsize;
        lrgth = ceil(lrgread / 4 + 1);
        
        % check number
        if lrgread ~= fix(lrgread)
            fclose(fid);
            warning( ...
                'BVQXtools:InternalError', ...
                'Error accessing file.' ...
            );
            return;
        end
    end
    
    % read content
    bytecont = fread(fid, [wordsize, lrgread], '*uint8');

    % check some larger wordsize things first
    if any([4, 8] == wordsize)
        
        % small floats start with hex 0x3f
        fldet = sum(bytecont == 63, 2);
        nulsum = sum(bytecont == 0, 2);
        
        % check for float 1's
        if wordsize == 4
            if all([fldet(4), sum(bytecont(3, :) == 128), nulsum(1)] > lrgth)
                isle = true;
                break;
            elseif all([fldet(1), sum(bytecont(2, :) == 128), nulsum(end)] > lrgth)
                isle = false;
                break;
            end
        else
            if all([fldet(8), sum(bytecont(7, :) == 255)] > lrgth)
                isle = true;
                break;
            elseif all([fldet(1), sum(bytecont(2, :) == 255)] > lrgth)
                isle = false;
                break;
            end
        end
        
        % calc difference in meaningful range
        lhdiff = sum(bytecont(1, :) > 59 & bytecont(1, :) < 73) - ...
            sum(bytecont(end, :) > 59 & bytecont(end, :) < 73);
        fldmed = double(median(bytecont, 2));
        fldmed(fldmed == 0) = NaN;
        fldsum = sum(bytecont == repmat(fldmed, [1, lrgread]), 2);
        
        % check difference, LE?
        if wordsize == 4
            if fldsum(4) > lrgth && ...
                lhdiff < -lrgth

                % make sure it's in the right direction
                if fldsum(3) > (lrgth / 2)
                    isle = true;
                    break;
                elseif fldsum(1) > (lrgth / 2)
                    isle = false;
                    break;
                end
            elseif fldsum(1) > lrgth && ...
                lhdiff > lrgth

                % make sure it's in the right direction
                if fldsum(2) > (lrgth / 2)
                    isle = false;
                    break;
                elseif fldsum(4) > (lrgth / 2)
                    isle = true;
                    break;
                end
            end
        else
            if fldsum(8) > lrgth && ...
                lhdiff < -lrgth

                % make sure it's in the right direction
                isle = true;
                if fldsum(1) > (lrgth / 2)
                    isle = false;
                end
                break;
            elseif fldsum(1) > lrgth && ...
                lhdiff > lrgth

                % make sure it's in the right direction
                isle = false;
                if fldsum(2) > (lrgth / 2)
                    isle = true;
                end
                break;
            end
        end
        
        % for larger integrals
        if nulsum(end) == lrgread && ...
            nulsum(end - 1) > (0.75 * lrgread) && ...
            nulsum(end - 2) > 0 && ...
            nulsum(1) < (0.1 * lrgread)
            isle = true;
            break;
        elseif nulsum(1) == lrgread && ...
            nulsum(2) > (0.75 * lrgread) && ...
            nulsum(3) > 0 && ...
            nulsum(end) < (0.1 * lrgread)
            isle = false;
            break;
        end
    end

    % look for intresting entries
    lowon = (bytecont(1, :) > 3 & bytecont(1, :) < 252);
    highon = (bytecont(end, :) > 3 & bytecont(end, :) < 252);
    
    % check simple difference
    lhdiff = sum(highon(~lowon)) - sum(lowon(~highon));
    if lhdiff < -lrgth
        isle = true;
        break;
    elseif lhdiff > lrgth
        isle = false;
        break;
    end
    
    % some last resort
    if any([4, 8] == wordsize)
        if fldsum(end) > (0.8 * lrgread + 1) && ...
            all(fldsum(1:end-1) < lrgth)
            isle = true;
            break;
        elseif fldsum(1) > (0.8 * lrgread + 1) && ...
            all(fldsum(2:end) < lrgth)
            isle = false;
            break;
        end
    end
    
    % increase and check number of guesses
    guesses = guesses + 1;
    if guesses > 3 || ...
        lrgread ~= ilrgread
        break;
    end
end

% close file
fclose(fid);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -