Code covered by the BSD License  

Highlights from
Reads an IPL (IPLab) file and returns images it contains.

image thumbnail
from Reads an IPL (IPLab) file and returns images it contains. by Tomasz Piech
Reads an IPL (IPLab) file and returns images and meta-data it contains in cell structures.

ipl2tif(file)
function [img_cell, metadata_cell] = ipl2tif(file)

% Reads an IPL (IPLab) file and returns a cell of images that it contains,
% as well as any optional metadata information.
%
% Currently, the following image data type representaions are supported:
%   - uint8
%   - int16
%   - uint16
%   - int32
%   - float32
%   - float64
%
% Data types to add:
%   - Color24
%   - Color48
%
% See comments below for processing of optional and custom tags.

% Tomasz Piech - May 2008

metadata_cell = {};
img_cell = {};

% NOTE: to display debug information in the console, set debug to true
debug = true;

fid = fopen(file, 'r'); % 'r' - read is the default
if fid ~= -1

    try
        
        %% 1st Required TAG, byte order
        tag  = fread(fid, 4, 'uint8=>char');
        size = fread(fid, 1, 'uint32');
        data = fread(fid, 4, 'uint8=>char');

        if debug
            display(sprintf('tag: %s, file version: %s\n', tag, data'));
        end

        
        %% 2nd Required TAG, data set
        tag = fread(fid, 4, 'uint8=>char'); % should be 'data'
        
        if ~strcmpi(tag', 'data')
            return;
        end
        
        size     = fread(fid, 1, 'uint32');
        width    = fread(fid, 1, 'uint32');      % # columns
        height   = fread(fid, 1, 'uint32');      % # rows
        channels = fread(fid, 1, 'uint32');      % 1 = grayscale, 3 = RGB
        zDepth   = fread(fid, 1, 'uint32');
        tDepth   = fread(fid, 1, 'uint32');
        dataType = fread(fid, 1, 'uint32');

        if debug
            display(sprintf('# images: %d, img width: %d, img height: %d\n', tDepth, width, height));
        end

        switch dataType
            case 0
                dt = 'uint8';
            case 1
                dt = 'int16';
            case 2
                dt = 'uint16';
            case 3
                dt = 'int32';
            case 4
                dt = 'float32';
            case 5
                dt = 'Color24';
            case 6
                dt = 'Color48';
            case 7
                dt = '(reserved)';
            case 8
                dt = '(reserved)';
            case 9
                dt = '(reserved)';
            case 10
                dt = 'float64';
            otherwise
                dt = 'unknown';
        end

        img_cell = cell(1, tDepth);

        %% read images - source and destination data types are the same
        % TODO: add processing for remaining formats: Color24 & Color48

        % precision, e.g. '*uint16' is equivalent to 'uint16=>uint16'
        if dataType == 0 || dataType == 1 || dataType == 2 || ...
           dataType == 3 || dataType == 4 || dataType == 10
            precision = sprintf('*%s', dt);
        else
            if debug
                display(sprintf('Data type %s (%d) is not supported.', dt, dataType));
            end
            
            return;
        end
        
        for t=1:tDepth
            for z=1:zDepth
                for c=1:channels
                    % read, reshape then transform
                    img = fread(fid, width * height, precision);
                    img = reshape(img, width, height)';
                    img_cell(1, t) = {img};
                end
            end
        end

        clear img;

        %% Optional TAGS before last required TAG ('fini')
        tag = fread(fid, 4, 'uint8=>char');
        tag = tag';
        size = fread(fid, 1, 'uint32');

        while strcmp(tag, 'fini') == 0

            switch tag

                % add processing of optional/custom tags here
                % for example, a custom tag might store a string 
                % representation of the software version of the application
                % used to acquire your images, such as 'soft'
                %
                % case 'soft'
                %     data = fread(fid, size, 'uint8=>char');
                %     data = data';
                %     metadata_cell = [metadata_cell; { tag, data }];
                %
                % or, some IPL files include segmentation information in
                % the 'mask' tag
                %
                % case 'mask'
                %     data = fread(fid, size, 'uint8');
                %     metadata_cell = [metadata_cell; { tag, data }];
                %
                % see IPLab SDK documentation for more information
                
                otherwise
                    if debug
                        % read as char data
                        data = fread(fid, size, 'uint8=>char');
                        data = data';
                    else
                        fseek(fid, size, 'cof');
                    end
            end

            if debug
                display(sprintf('Tag name %s, size %d, data %s\n', tag, size, data));
            end
            
            % read next tag and its data size
            tag = fread(fid, 4, 'uint8=>char');
            tag = tag';
            size = fread(fid, 1, 'uint32');
        end

    catch ME
        
        %% finally, close the file
        fclose(fid);
        rethrow(ME);
    end

    fclose(fid);

end

Contact us at files@mathworks.com