% Fletcher16.m
% computes a Fletcher 16-bit checksum on argument
% Compatible with MATLAB and GNU Octave

function chksum = Fletcher16(fname)
    
    % Open file and read 8 bits at a time
    fid     = fopen(fname, 'r');
    data    = fread(fid,inf,'uint8');
    fclose(fid);
    
    % Initialize variables
    sum1 = 255;
    sum2 = 255;
    bytes = length(data);   % Number of bytes to sum
    k = 1;
        
    % Perform checksum
    while(bytes)
        % Do 20 sums before modular reduction
        if(bytes >= 20)
            tlen = 20;
        else
            tlen = bytes;
        end
        
        bytes = bytes - tlen;   % Decrement number of bytes left
        
            % Calculate checksum
        sum1 = sum1 + data(k);
        sum2 = sum2 + sum1;
        tlen = tlen - 1;
        
        while(tlen)
            sum1 = sum1 + data(k);
            sum2 = sum2 + sum1;
            tlen = tlen - 1;
        end
        
            % Special handling if running GNU octave
        if(exist('OCTAVE_VERSION', 'builtin') ~= 0)
            arg3 = 16;
        else
            arg3 = 'uint16';
        end
        
        sum1 = bitand(sum1,255) + bitshift(sum1,-8,arg3);
        sum2 = bitand(sum2,255) + bitshift(sum2,-8,arg3);
        
        k = k + 1;
        
    end
    
    sum1 = bitand(sum1,255) + bitshift(sum1,-8,arg3);
    sum2 = bitand(sum2,255) + bitshift(sum2,-8,arg3);
    
    chksum = bitor(bitshift(sum2,8,arg3), sum1);

end