function niiheader = niiformat(format)
%
%    niiheader=niiformat(format)
%
%    Return a NIfTI header format descriptor as an Nx3 cell array
%
%    author: Qianqian Fang (q.fang <at> neu.edu)
%
%    input:
%        format:'nifti1' - return the header descriptor for NIfTI-1 format
%               'nifti2' - return the header descriptor for NIfTI-2 format
%
%    output:
%        niiheader: an Nx3 cell array in the format similar to the 'Format'
%             specifier of the memmapfile.m function in MATLAB
%             It has the following structure:
%
%             column 1: data type string, it can be one of the following
%                'int8','int16','int32','int64',
%                'uint8','uint16','uint32','uint64',
%                'single','double'
%             column 2: an integer vector denoting the size of the data
%             column 3: a string denoting the fieldname in the output struct
%
%    this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifty
%
%    License: Apache 2.0, see https://github.com/NeuroJSON/jnifty for details
%

header.nifti1 = {                            ...
                 'int32'   [1 1]  'sizeof_hdr'      % !< MUST be 348           %  % int sizeof_hdr;       %  ...
                 'int8'    [1 10] 'data_type'       % !< ++UNUSED++            %  % char data_type[10];   %  ...
                 'int8'    [1 18] 'db_name'         % !< ++UNUSED++            %  % char db_name[18];     %  ...
                 'int32'   [1 1]  'extents'         % !< ++UNUSED++            %  % int extents;          %  ...
                 'int16'   [1 1]  'session_error'   % !< ++UNUSED++            %  % short session_error;  %  ...
                 'int8'    [1 1]  'regular'         % !< ++UNUSED++            %  % char regular;         %  ...
                 'int8'    [1 1]  'dim_info'        % !< MRI slice ordering.   %  % char hkey_un0;        %  ...
                 'uint16'  [1 8]  'dim'             % !< Data array dimensions.%  % short dim[8];         %  ...
                 'single'  [1 1]  'intent_p1'       % !< 1st intent parameter. %  % short unused8/9;      %  ...
                 'single'  [1 1]  'intent_p2'       % !< 2nd intent parameter. %  % short unused10/11;    %  ...
                 'single'  [1 1]  'intent_p3'       % !< 3rd intent parameter. %  % short unused12/13;    %  ...
                 'int16'   [1 1]  'intent_code'     % !< NIFTI_INTENT_* code.  %  % short unused14;       %  ...
                 'int16'   [1 1]  'datatype'        % !< Defines data type!    %  % short datatype;       %  ...
                 'int16'   [1 1]  'bitpix'          % !< Number bits/voxel.    %  % short bitpix;         %  ...
                 'int16'   [1 1]  'slice_start'     % !< First slice index.    %  % short dim_un0;        %  ...
                 'single'  [1 8]  'pixdim'          % !< Grid spacings.        %  % float pixdim[8];      %  ...
                 'single'  [1 1]  'vox_offset'      % !< Offset into .nii file %  % float vox_offset;     %  ...
                 'single'  [1 1]  'scl_slope'       % !< Data scaling: slope.  %  % float funused1;       %  ...
                 'single'  [1 1]  'scl_inter'       % !< Data scaling: offset. %  % float funused2;       %  ...
                 'int16'   [1 1]  'slice_end'       % !< Last slice index.     %  % float funused3;       %  ...
                 'int8'    [1 1]  'slice_code'      % !< Slice timing order.   %                             ...
                 'int8'    [1 1]  'xyzt_units'      % !< Units of pixdim[1..4] %                             ...
                 'single'  [1 1]  'cal_max'         % !< Max display intensity %  % float cal_max;        %  ...
                 'single'  [1 1]  'cal_min'         % !< Min display intensity %  % float cal_min;        %  ...
                 'single'  [1 1]  'slice_duration'  % !< Time for 1 slice.     %  % float compressed;     %  ...
                 'single'  [1 1]  'toffset'         % !< Time axis shift.      %  % float verified;       %  ...
                 'int32'   [1 1]  'glmax'           % !< ++UNUSED++            %  % int glmax;            %  ...
                 'int32'   [1 1]  'glmin'           % !< ++UNUSED++            %  % int glmin;            %  ...
                 'int8'    [1 80] 'descrip'         % !< any text you like.    %  % char descrip[80];     %  ...
                 'int8'    [1 24] 'aux_file'        % !< auxiliary filename.   %  % char aux_file[24];    %  ...
                 'int16'   [1 1]  'qform_code'      % !< NIFTI_XFORM_* code.   %  %-- all ANALYZE 7.5 --- %  ...
                 'int16'   [1 1]  'sform_code'      % !< NIFTI_XFORM_* code.   %  %below here are replaced%  ...
                 'single'  [1 1]  'quatern_b'       % !< Quaternion b param.   %             ...
                 'single'  [1 1]  'quatern_c'       % !< Quaternion c param.   %             ...
                 'single'  [1 1]  'quatern_d'       % !< Quaternion d param.   %             ...
                 'single'  [1 1]  'qoffset_x'       % !< Quaternion x shift.   %             ...
                 'single'  [1 1]  'qoffset_y'       % !< Quaternion y shift.   %             ...
                 'single'  [1 1]  'qoffset_z'       % !< Quaternion z shift.   %             ...
                 'single'  [1 4]  'srow_x'          % !< 1st row affine transform.   %           ...
                 'single'  [1 4]  'srow_y'          % !< 2nd row affine transform.   %           ...
                 'single'  [1 4]  'srow_z'          % !< 3rd row affine transform.   %           ...
                 'int8'    [1 16] 'intent_name'     % !< 'name' or meaning of data.  %           ...
                 'int8'    [1 4]  'magic'           % !< MUST be "ni1\0" or "n+1\0". %           ...
                 'int8'    [1 4]  'extension'       % !< header extension      %             ...
                };

header.nifti2 = {                            ...
                 'int32'   [1 1]  'sizeof_hdr'      % !< MUST be 540           %  % int sizeof_hdr;       %  ...
                 'int8'    [1 8]  'magic'           % !< MUST be "ni2\0" or "n+2\0". %           ...
                 'int16'   [1 1]  'datatype'        % !< Defines data type!    %  % short datatype;       %  ...
                 'int16'   [1 1]  'bitpix'          % !< Number bits/voxel.    %  % short bitpix;         %  ...
                 'int64'   [1 8]  'dim'             % !< Data array dimensions.%  % short dim[8];         %  ...
                 'double'  [1 1]  'intent_p1'       % !< 1st intent parameter. %  % short unused8/9;      %  ...
                 'double'  [1 1]  'intent_p2'       % !< 2nd intent parameter. %  % short unused10/11;    %  ...
                 'double'  [1 1]  'intent_p3'       % !< 3rd intent parameter. %  % short unused12/13;    %  ...
                 'double'  [1 8]  'pixdim'          % !< Grid spacings.        %  % float pixdim[8];      %  ...
                 'int64'   [1 1]  'vox_offset'      % !< Offset into .nii file %  % float vox_offset;     %  ...
                 'double'  [1 1]  'scl_slope'       % !< Data scaling: slope.  %  % float funused1;       %  ...
                 'double'  [1 1]  'scl_inter'       % !< Data scaling: offset. %  % float funused2;       %  ...
                 'double'  [1 1]  'cal_max'         % !< Max display intensity %  % float cal_max;        %  ...
                 'double'  [1 1]  'cal_min'         % !< Min display intensity %  % float cal_min;        %  ...
                 'double'  [1 1]  'slice_duration'  % !< Time for 1 slice.     %  % float compressed;     %  ...
                 'double'  [1 1]  'toffset'         % !< Time axis shift.      %  % float verified;       %  ...
                 'int64'   [1 1]  'slice_start'     % !< First slice index.    %  % short dim_un0;        %  ...
                 'int64'   [1 1]  'slice_end'       % !< Last slice index.     %  % float funused3;       %  ...
                 'int8'    [1 80] 'descrip'         % !< any text you like.    %  % char descrip[80];     %  ...
                 'int8'    [1 24] 'aux_file'        % !< auxiliary filename.   %  % char aux_file[24];    %  ...
                 'int32'   [1 1]  'qform_code'      % !< NIFTI_XFORM_* code.   %  %-- all ANALYZE 7.5 --- %  ...
                 'int32'   [1 1]  'sform_code'      % !< NIFTI_XFORM_* code.   %  %below here are replaced%  ...
                 'double'  [1 1]  'quatern_b'       % !< Quaternion b param.   %             ...
                 'double'  [1 1]  'quatern_c'       % !< Quaternion c param.   %             ...
                 'double'  [1 1]  'quatern_d'       % !< Quaternion d param.   %             ...
                 'double'  [1 1]  'qoffset_x'       % !< Quaternion x shift.   %             ...
                 'double'  [1 1]  'qoffset_y'       % !< Quaternion y shift.   %             ...
                 'double'  [1 1]  'qoffset_z'       % !< Quaternion z shift.   %             ...
                 'double'  [1 4]  'srow_x'          % !< 1st row affine transform.   %           ...
                 'double'  [1 4]  'srow_y'          % !< 2nd row affine transform.   %           ...
                 'double'  [1 4]  'srow_z'          % !< 3rd row affine transform.   %           ...
                 'int32'   [1 1]  'slice_code'      % !< Slice timing order.   %                             ...
                 'int32'   [1 1]  'xyzt_units'      % !< Units of pixdim[1..4] %                             ...
                 'int32'   [1 1]  'intent_code'     % !< NIFTI_INTENT_* code.  %  % short unused14;       %  ...
                 'int8'    [1 16] 'intent_name'     % !< 'name' or meaning of data.  %           ...
                 'int8'    [1 1]  'dim_info'        % !< MRI slice ordering.   %  % char hkey_un0;        %  ...
                 'int8'    [1 15] 'reserved'        % !< unused buffer     %             ...
                 'int8'    [1 4]  'extension'       % !< header extension      %             ...
                };

if (nargin < 1)
    format = 'nifti1';
end

format = lower(format);

if (isfield(header, format))
    niiheader = header.(format);
else
    error('format must be either nifti1 or nifti2');
end
