amiraReader.asv 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. function data = amiraReader(varargin)
  2. % this m-file skips the header of amira files to give you the straight data
  3. % USEAGE: either type in what you want (valuable for scripting or calling from another program)
  4. % > data = amiraReader('C:\Data\Human\Test_foo.am');
  5. % or
  6. % > data = amiraReadleave the argument blank and use the file selector
  7. %
  8. %%
  9. warning off all;
  10. switch nargin
  11. case 1
  12. filename = varargin{1};
  13. case 0
  14. [file, pathname] = uigetfile({'*.am'},'Please locate Amira file.','Multiselect','off');
  15. filename = [pathname file];
  16. end
  17. fid = fopen(filename,'r','ieee-be');
  18. datachar = char(fread(fid,inf,'char'))';
  19. switch isempty(findstr(datachar,'BINARY-LITTLE-ENDIAN'))
  20. case 1
  21. endianness = 'be';
  22. case 0
  23. endianness = 'le';
  24. end
  25. lattice = findstr(datachar,'define Lattice');
  26. parameter = findstr(datachar,'Parameters');
  27. start_data_position = findstr(datachar,'@1'); % note there will be two @1, so take the second one!
  28. %% Determine if we're dealing with a labelfield or regular data
  29. switch isempty(findstr(datachar,'HxByteRLE'))
  30. case 1 % regular data case
  31. %% blatantly stolen from RTF's geom2am
  32. data_type = char(datachar(findstr(datachar,'Lattice { ')+10:findstr(datachar,'Data } ')-2));
  33. switch data_type
  34. case 'byte'
  35. out_type = 'int8';
  36. case 'short'
  37. out_type = 'int16';
  38. case 'ushort'
  39. out_type = 'uint16';
  40. case 'int32'
  41. out_type = 'int32';
  42. case 'float'
  43. out_type = 'float';
  44. case 'double'
  45. out_type = 'double';
  46. end
  47. %% get the dimensions from the amira header
  48. fseek(fid,lattice+14,'bof');
  49. dimensions = str2num(char(fread(fid,parameter-lattice-15,'char'))');
  50. % get the data from the amira file
  51. fid = fopen(filename,'r',['ieee-' endianness]);
  52. fseek(fid,start_data_position(2)+2,'bof');
  53. data = reshape(fread(fid,dimensions(1)*dimensions(2)*dimensions(3),out_type),dimensions(1),dimensions(2),dimensions(3));
  54. %%
  55. %
  56. %
  57. %
  58. %
  59. %
  60. %
  61. %
  62. %
  63. %
  64. %% Thus begins the label2short code. This will give you a matrix from a labelfield
  65. case 0 % labelfield case
  66. lattice = findstr(datachar,'define Lattice');
  67. parameter = findstr(datachar,'Parameters');
  68. boundingbox = findstr(datachar,'BoundingBox');
  69. CoordType = findstr(datachar,'CoordType');
  70. ByteRLE = findstr(datachar,'HxByteRLE,');
  71. start_data_position = findstr(datachar,'@1'); % note there will be two @1, so take the second one!
  72. DataSection = findstr(datachar,'# Data section follows');
  73. %% get the dimensions from the amira header
  74. fseek(fid,lattice+14,'bof');
  75. dimensions = str2num(char(fread(fid,parameter-lattice-15,'char'))');
  76. fseek(fid,ByteRLE+9,'bof');
  77. byte_length = str2num(char(fread(fid,DataSection - ByteRLE-13,'char'))');
  78. fseek(fid,boundingbox-1,'bof');
  79. BB = char(fread(fid,CoordType - boundingbox-5,'char'))';
  80. %% Switch endianess?
  81. switch endianness
  82. case 'le'
  83. fclose(fid);
  84. fid = fopen(filename,'r',['ieee-' endianness]);
  85. fseek(fid,start_data_position(2)+2,'bof');
  86. data = fread(fid,byte_length,'int8');
  87. case 'be'
  88. fseek(fid,start_data_position(2)+2,'bof');
  89. data = fread(fid,byte_length,'int8');
  90. end
  91. %% This decodes Amira's RLE. I figured this out by trial and error, not
  92. % sure what algorithm they use.
  93. % pre-allocate space for the output
  94. out_line = zeros(dimensions(1)*dimensions(2)*dimensions(3),1);
  95. % pre-compute the final offset due to -#'s
  96. final_offset = sum(data(find(data<0))+127);
  97. net_counter = 0;
  98. offset = 0;
  99. for i = 1:floor((byte_length-final_offset)/2) %
  100. % disp(int2str(i));
  101. data_counter = 2*i+offset;
  102. if ((data(data_counter) == 0) && (data(data_counter-1) > 0))
  103. net_counter = data(data_counter-1)+net_counter;
  104. else
  105. if data(data_counter-1) < 0
  106. for j = 1:128+data(data_counter-1)
  107. out_line(j+net_counter) = data(data_counter+j-1);
  108. % disp(['i = ' int2str(i) ', length = ' int2str(data(data_counter-1)) ', written value = ' int2str(data(data_counter+j-1)) ', offset = ' int2str(offset)]);
  109. end
  110. net_counter = 128+data(data_counter-1)+net_counter;
  111. offset = offset + 127+ data(data_counter-1);
  112. else
  113. for j = 1:data(data_counter-1)
  114. out_line(j+net_counter) = data(data_counter);
  115. % disp(['i = ' int2str(i) ', length = ' int2str(data(data_counter-1)) ', written value = ' int2str(data(data_counter))]);
  116. end
  117. net_counter = data(data_counter-1)+net_counter;
  118. end
  119. end
  120. end
  121. clear data;
  122. data = reshape(out_line,dimensions(1),dimensions(2),dimensions(3));
  123. end