123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- function out_data = label2short(varargin)
- %%%%%%%%%
- %
- % The more non-zero elements your labelfield has, the longer this
- % function will take to run!!!
- %
- % USAGE: (1) >> data = label2short; <Enter>
- % (2) >> label2short('C:\Data\SU00x\Foo_label-field.am'); <Enter>
- %
- % Uncomment the last lines of text if you want to write new files!
- % Creates an additional file called xxx_short.am
- %
- % Multi-file select works!!
- %
- % This m-file decodes Amira's Run-Length Encoding that they use to save
- % space in their LabelFields. As per usual, no documentation on their
- % compression algorithm, so I figured it out on my own.
- %
- % 0 to 127 --> Copy the next value n times
- % -127 to -1 --> Copy the next n values VERBATIM
- %
- % The string:
- % 00001111111000001010000001000
- % Saved in Amira's RLE as:
- % 4 0 7 1 5 0 -125 1 0 1 6 0 -127 1 3 0
- %
- % I never knew about RLE, this guy's site was fairly useful. His name is
- % dipperstein, I mean, come on!
- % http://michael.dipperstein.com/rle/index.html
- % last updated June 8, 2008 - viewed 3/18/09
- %
- % DLB 3/18/09
- %
- %% multi file selector
- switch nargin
- case 1
- filename = varargin{1};
- leng = 1;
- case 0
- [file, pathname] = uigetfile({'*.am'},'Please locate Amira LabelField(s).','Multiselect','on');
- if isequal(file,0)
- disp('User selected Cancel');
- fclose all;
- return
- else
- if isa(file,'cell')
- for k = 1:length(file)
- filename{k} = fullfile(pathname,file{k});
- disp(['User selected ' filename{k}]);
- end
- leng = length(file);
- else
- filename = [pathname file];
- disp(['User selected ', fullfile(pathname, filename)]);
- leng = 1;
- end
- end
- end
- for n = 1:leng
- if isa(filename,'cell')
- fil = filename{n};
- else
- fil = filename;
- end
- fid = fopen(fil,'r','ieee-be');
- datachar = char(fread(fid,inf,'char'))';
- switch isempty(findstr(datachar,'BINARY-LITTLE-ENDIAN'))
- case 1
- endianness = 'be';
- case 0
- endianness = 'le';
- end
- lattice = findstr(datachar,'define Lattice');
- parameter = findstr(datachar,'Parameters');
- boundingbox = findstr(datachar,'BoundingBox');
- CoordType = findstr(datachar,'CoordType');
- ByteRLE = findstr(datachar,'HxByteRLE,');
- start_data_position = findstr(datachar,'@1'); % note there will be two @1, so take the second one!
- DataSection = findstr(datachar,'# Data section follows');
- %% get the dimensions from the amira header
- fseek(fid,lattice+14,'bof');
- dimensions = str2num(char(fread(fid,parameter-lattice-15,'char'))');
- fseek(fid,ByteRLE+9,'bof');
- byte_length = str2num(char(fread(fid,DataSection - ByteRLE-13,'char'))');
- fseek(fid,boundingbox-1,'bof');
- BB = char(fread(fid,CoordType - boundingbox-5,'char'))';
- %% Switch endianess?
- switch endianness
- case 'le'
- fclose(fid);
- fid = fopen(fil,'r',['ieee-' endianness]);
- fseek(fid,start_data_position(2)+2,'bof');
- data = fread(fid,byte_length,'int8');
- case 'be'
- fseek(fid,start_data_position(2)+2,'bof');
- data = fread(fid,byte_length,'int8');
- end
- %% This decodes Amira's RLE. I figured this out by trial and error, not
- % sure what algorithm they use.
-
- % pre-allocate space for the output
- out_line = zeros(dimensions(1)*dimensions(2)*dimensions(3),1);
- % pre-compute the final offset due to -#'s
- final_offset = sum(data(find(data<0))+127);
- net_counter = 0;
- offset = 0;
- for i = 1:floor((byte_length-final_offset)/2) %
- % disp(int2str(i));
- data_counter = 2*i+offset;
- if ((data(data_counter) == 0) && (data(data_counter-1) > 0))
- net_counter = data(data_counter-1)+net_counter;
- else
- if data(data_counter-1) < 0
- for j = 1:128+data(data_counter-1)
- out_line(j+net_counter) = data(data_counter+j-1);
- % disp(['i = ' int2str(i) ', length = ' int2str(data(data_counter-1)) ', written value = ' int2str(data(data_counter+j-1)) ', offset = ' int2str(offset)]);
- end
- net_counter = 128+data(data_counter-1)+net_counter;
- offset = offset + 127+ data(data_counter-1);
- else
- for j = 1:data(data_counter-1)
- out_line(j+net_counter) = data(data_counter);
- % disp(['i = ' int2str(i) ', length = ' int2str(data(data_counter-1)) ', written value = ' int2str(data(data_counter))]);
- end
- net_counter = data(data_counter-1)+net_counter;
- end
- end
- end
- out_data = reshape(out_line,dimensions(1),dimensions(2),dimensions(3));
- %% this is from my amiraCTWriter.m
- % fid = fopen(strrep(fil,'.am','_short.am'),'w');
- % switch endianness
- % case 'be'
- % fprintf(fid,'# AmiraMesh 3D BINARY 2.0\n\n');
- % fprintf(fid,['# CreationDate: ' datestr(now,'ddd mmm') datestr(now,' dd HH:MM:SS yyyy') '\n\n']);
- % case 'le'
- % fprintf(fid,'# AmiraMesh BINARY-LITTLE-ENDIAN 2.1\n\n');
- % end
- % fprintf(fid,'define Lattice %g %g %g\n\n',dimensions(1),dimensions(2),dimensions(3));
- % fprintf(fid,'Parameters {\n');
- % fprintf(fid,' Content "%gx%gx%g %s, uniform coordinates",\n',dimensions(1),dimensions(2),dimensions(3),'short');
- % fprintf(fid,' %s\n',BB);
- % fprintf(fid,' CoordType "uniform"\n');
- % fprintf(fid,'}\n\n');
- % fprintf(fid,'Lattice { %s Data } @1\n\n','short');
- % fprintf(fid,'# Data section follows\n');
- % fprintf(fid,'@1\n');
- % fclose(fid); % close the text part of the file
- % fid = fopen(strrep(fil,'.am','_short.am'),'ab',['ieee-' endianness]);
- % fwrite(fid,out_data(:,:,:),'short');
- % fclose(fid);
- end
|