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

📄 dcmio.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
📖 第 1 页 / 共 2 页
字号:

                    % number of objects
                    switch (ddt)
                        case {'double'}
                            dvl = round(dvl / 8);
                        case {'int32', 'single', 'uint32'}
                            dvl = round(dvl / 4);
                        case {'int16', 'uint16'}
                            dvl = dvl / 2;
                    end
                    dval = fread(rfid, [1, dvl], ['*' ddt]);
                    if ischar(dval) && ...
                        isempty(dval)
                        dval = '';
                    end
                    if DataVR.deblank
                        dval = deblank(dval);
                    end
                else
                    dval = [];
                end
                MetaStr(MetaKeyCount).Value = dval;
                MetaKeyCount = MetaKeyCount + 1;

            end

            % put meta back
            dcmcont.Meta = MetaStr;
            mkey = cell(length(MetaStr), 1);
            mkys = struct;
            for c = 1:length(mkey)
                mky = sprintf('k_%04X_%04X', MetaStr(c).Key);
                mkey{c} = mky;
                mkys.(mky) = c;
            end
            dcmcont.MetaKeys = mkey;
            dcmcont.MetaKeyLookup = mkys;
        end

        % initialize data struct
        dstr = dcmcont.Data;
        DataLEndian = true;

        % check implicit/explicit TS for data part
        vrcheck = fc_uint8(fpos+4:fpos+5);
        dcmcont.DataTSExplicit = all(vrcheck > 64 & vrcheck < 91);
        dvs = dcmcont.DataTSExplicit;

        % check endian only on explicit VR syntax
        if dcmcont.DataTSExplicit
            lecheck = fc_uint8(fpos:fpos+4);
            if lecheck(1) < lecheck(2)
                dcmcont.DataLittleEndian = false;
            elseif lecheck(1) == lecheck(2)
                if lecheck(3) < lecheck(4)
                    dcmcont.DataLittleEndian = false;
                elseif lecheck(3) == lecheck(4)
                    warning( ...
                        'BVQXtools:FileDetectionFailed', ...
                        'Error detecting Endian type in Data part, assuming LE.' ...
                    );
                    dcmcont.DataLittleEndian = true;
                end
            end
            DataLEndian = dcmcont.DataLittleEndian;
        end
        if DataLEndian
            rfid = fid;
        else
            rfid = fidbe;
        end

        % data part until fpos > flenmin
        DStrKeyCount = numel(dstr);
        while fpos <= flenmin

            % get correct key format
            DataKeyCount = DataKeyCount + 1;
            fposh = round(fpos/2);
            if DataLEndian
                DicomKey = double([fc_uint16_le(fposh), fc_uint16_le(fposh+1)]);
            else
                DicomKey = double([fc_uint16_be(fposh), fc_uint16_be(fposh+1)]);
            end
            if DataKeyCount > DStrKeyCount
                if DStrKeyCount < 128
                    DStrKeyCount = 128;
                end
                dstr(2 * DStrKeyCount).Key = [];
                DStrKeyCount = numel(dstr);
            end
            dstr(DataKeyCount).Key = DicomKey;
            fpos = fpos + 4;

            % sequence ?
            if DicomKey(1) > 65533
                DataSequence = true;
                DataVR = vrSQ;
            else
                DataSequence = false;
            end

            % VR ?
            if ~DataSequence && ...
                dvs
                DataVR = upper(char(fc_uint8(fpos:fpos+1)));
                fpos = fpos + 2;
                if ~isfield(my_dicom_vr, DataVR)
                    error( ...
                        'BVQXtools:InvalidToken', ...
                        'Invalid VR found: %s.', ...
                        DataVR ...
                    );
                end
                DataVR = my_dicom_vr.(DataVR);
            elseif ~dvs
                tkey = sprintf('k_%04X_%04X', DicomKey(1), DicomKey(2));
                try
                    DataVR = my_dicom_vr.(upper(my_dicom_dic.Dictionary.(tkey).vr));
                catch
                    DataVR = vrUN;
                end
            elseif ~DataSequence
                DataVR = vrUN;
            end
            dstr(DataKeyCount).VR = DataVR.tag;
            if DataVR.length(2) > 32767
                DataShortVLength = false;
            else
                DataShortVLength = true;
            end

            % length
            fposh = round(fpos/2);
            if DataLEndian
                DataVLengthShort = double(fc_uint16_le(fposh));
            else
                DataVLengthShort = double(fc_uint16_be(fposh));
            end
            if ~DataShortVLength && ...
               ~DataSequence && ...
                dvs && ...
                DataVLengthShort > 0
                error( ...
                    'BVQXtools:InvalidFileContent', ...
                    'Invalid 16-bit VL for given VR.' ...
                );
            elseif DataSequence && ...
                any([57357, 57565] == DicomKey(2)) && ...
                all(fc_uint16_le(fposh:fposh+1) == 0)
                fpos = fpos - 2;
                fposh = fposh - 1;
            end
            if ~DataShortVLength || ...
                 ~dvs
                if DataVLengthShort == 0 && ...
                    dvs
                    if DataLEndian
                        DataVLengthLong = 65536 * ...
                            double(fc_uint16_le(fposh+2)) + ...
                            double(fc_uint16_le(fposh+1));
                    else
                        DataVLengthLong = 65536 * ...
                            double(fc_uint16_le(fposh+1)) + ...
                            double(fc_uint16_le(fposh+2));
                    end
                    fpos = fpos + 6;
                else
                    if DataLEndian
                        DataVLengthLong = 65536 * ...
                            double(fc_uint16_le(fposh+1)) + ...
                            double(fc_uint16_le(fpos));
                    else
                        DataVLengthLong = 65536 * ...
                            double(fc_uint16_le(fposh)) + ...
                            double(fc_uint16_le(fposh+1));
                    end
                    fpos = fpos + 4;
                end
                dvl = DataVLengthLong;
            else
                fpos = fpos + 2;
                DataVLengthLong = NaN;
                dvl = DataVLengthShort;
            end
            dstr(DataKeyCount).VLShort = DataVLengthShort;
            dstr(DataKeyCount).VLLong  = DataVLengthLong;
            dvl = 2 * round(dvl/2);

            % get value according to type
            ddt = lower(DataVR.datatype);
            if ~strcmp(ddt, 'sequence')

                % go to and update position
                fseek(rfid, fpos - 1, -1);
                fpos = fpos + dvl;

                % number of objects
                switch (ddt)
                    case {'double'}
                        dvl = round(dvl / 8);
                    case {'int32', 'single', 'uint32'}
                        dvl = round(dvl / 4);
                    case {'int16', 'uint16'}
                        dvl = dvl / 2;
                end
                dval = fread(rfid, [1, dvl], ['*' ddt]);
                if ischar(dval) && ...
                    isempty(dval)
                    dval = '';
                end
                if DataVR.deblank
                    dval = deblank(dval);
                end
            else
                dval = [];
            end
            dstr(DataKeyCount).Value = dval;

        end

        % put meta back
        dcmcont.Data = dstr(1:DataKeyCount);
        DicomKey = cell(numel(dcmcont.Data), 1);
        dkys = struct;
        for c = 1:length(DicomKey)
            dky = dcmiofmtkey(dstr(c).Key);
            DicomKey{c} = dky;
            dkys.(dky) = c;
        end
        dcmcont.DataKeys = DicomKey;
        dcmcont.DataKeyLookup = dkys;

    % writing
    else

        % not yet implemented

    end

catch
    % do nothing here...
end % try forcemode

% close main file
fclose(fid);

% create good object
hfile = bless(BVQXfile('new:dcm'), 1);
setcont(hfile, dcmcont);

% close big-endian file
if ~writemode
    fclose(fidbe);
end

% give correct output
varargout = [{hfile}, cell(1, max(0, nargout - 1))];


% format a dicom key
function dfk = dcmiofmtkey(k)
persistent dfkc;
if isempty(dfkc)
    dfkc = '0123456789ABCDEF';
end
fkr = min(65535, max(0, floor(real(k))));
fk1 = '0000';
fc = 4;
fk = fkr(1);
while fk > 0
    fk1(fc) = dfkc(mod(fk, 16) + 1);
    fk = floor(fk/16);
    fc = fc - 1;
end
fk2 = '0000';
fc = 4;
fk = fkr(2);
while fk > 0
    fk2(fc) = dfkc(mod(fk, 16) + 1);
    fk = floor(fk/16);
    fc = fc - 1;
end
dfk = ['k_' fk1 '_' fk2];

⌨️ 快捷键说明

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