2
0

parser_blend.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. // .blend file parser
  2. // Reference:
  3. // https://github.com/fschutt/mystery-of-the-blend-backup
  4. // https://web.archive.org/web/20170630054951/http://www.atmind.nl/blender/mystery_ot_blend.html
  5. // Usage:
  6. // let bl: blend_t = parser_blend_init(blob: buffer_view_t);
  7. // krom_log(parser_blend_dir(bl, "Scene"));
  8. // let scenes: any = parser_blend_get(bl, "Scene");
  9. // krom_log(get(get(scenes[0], "id"), "name"));
  10. type blend_t = {
  11. pos?: i32;
  12. view?: buffer_view_t;
  13. // Header
  14. version?: string;
  15. pointer_size?: i32;
  16. little_endian?: bool;
  17. // Data
  18. blocks?: block_t[];
  19. dna?: dna_t;
  20. map?: map_t<any, block_t>; // Map blocks by memory address
  21. };
  22. function parser_blend_init(buffer: buffer_t): blend_t {
  23. let raw: blend_t = {};
  24. raw.blocks = [];
  25. raw.map = map_create();
  26. raw.view = buffer_view_create(buffer);
  27. raw.pos = 0;
  28. if (parser_blend_read_chars(raw, 7) != "BLENDER") {
  29. raw.view = buffer_view_create(krom_inflate(buffer, false));
  30. raw.pos = 0;
  31. if (parser_blend_read_chars(raw, 7) != "BLENDER") {
  32. return null;
  33. }
  34. }
  35. parser_blend_parse(raw);
  36. return raw;
  37. }
  38. function parser_blend_dir(raw: blend_t, type: string): string[] {
  39. // Return structure fields
  40. let type_index: i32 = parser_blend_get_type_index(raw.dna, type);
  41. if (type_index == -1) {
  42. return null;
  43. }
  44. let ds: dna_struct_t = parser_blend_get_struct(raw.dna, type_index);
  45. let fields: string[] = [];
  46. for (let i: i32 = 0; i < ds.field_names.length; ++i) {
  47. let name_index: i32 = ds.field_names[i];
  48. let type_index: i32 = ds.field_types[i];
  49. array_push(fields, raw.dna.types[type_index] + " " + raw.dna.names[name_index]);
  50. }
  51. return fields;
  52. }
  53. function parser_blend_get(raw: blend_t, type: string): bl_handle_t[] {
  54. if (raw.dna == null) {
  55. return null;
  56. }
  57. // Return all structures of type
  58. let type_index: i32 = parser_blend_get_type_index(raw.dna, type);
  59. if (type_index == -1) {
  60. return null;
  61. }
  62. let ds: dna_struct_t = parser_blend_get_struct(raw.dna, type_index);
  63. let handles: bl_handle_t[] = [];
  64. for (let i: i32 = 0; i < raw.blocks.length; ++i) {
  65. let b: block_t = raw.blocks[i];
  66. if (raw.dna.structs[b.sdna_index].type == type_index) {
  67. let h: bl_handle_t = {};
  68. h.offset = 0;
  69. array_push(handles, h);
  70. h.block = b;
  71. h.ds = ds;
  72. }
  73. }
  74. return handles;
  75. }
  76. function parser_blend_get_struct(dna: dna_t, type_index: i32): dna_struct_t {
  77. for (let i: i32 = 0; i < dna.structs.length; ++i) {
  78. let ds: dna_struct_t = dna.structs[i];
  79. if (ds.type == type_index) {
  80. return ds;
  81. }
  82. }
  83. return null;
  84. }
  85. function parser_blend_get_type_index(dna: dna_t, type: string): i32 {
  86. for (let i: i32 = 0; i < dna.types.length; ++i) {
  87. if (type == dna.types[i]) {
  88. return i;
  89. }
  90. }
  91. return -1;
  92. }
  93. function parser_blend_parse(raw: blend_t) {
  94. // Pointer size: _ 32bit, - 64bit
  95. raw.pointer_size = parser_blend_read_char(raw) == "_" ? 4 : 8;
  96. // v - little endian, V - big endian
  97. raw.little_endian = parser_blend_read_char(raw) == "v";
  98. raw.version = parser_blend_read_chars(raw, 3);
  99. // Reading file blocks
  100. // Header - data
  101. while (raw.pos < buffer_view_size(raw.view)) {
  102. parser_blend_align(raw);
  103. let b: block_t = {};
  104. // Block type
  105. b.code = parser_blend_read_chars(raw, 4);
  106. if (b.code == "ENDB") {
  107. break;
  108. }
  109. array_push(raw.blocks, b);
  110. b.blend = raw;
  111. // Total block length
  112. b.size = parser_blend_read_i32(raw);
  113. // Memory address
  114. let addr: any = parser_blend_read_pointer(raw);
  115. if (map_get(raw.map, addr) == null) {
  116. map_set(raw.map, addr, b);
  117. }
  118. // Index of dna struct contained in this block
  119. b.sdna_index = parser_blend_read_i32(raw);
  120. // Number of dna structs in this block
  121. b.count = parser_blend_read_i32(raw);
  122. b.pos = raw.pos;
  123. // This block stores dna structures
  124. if (b.code == "DNA1") {
  125. raw.dna = {};
  126. raw.dna.names = [];
  127. raw.dna.types = [];
  128. raw.dna.types_length = [];
  129. raw.dna.structs = [];
  130. parser_blend_read_chars(raw, 4); // SDNA
  131. parser_blend_read_chars(raw, 4); // NAME
  132. let names_count: i32 = parser_blend_read_i32(raw);
  133. for (let i: i32 = 0; i < names_count; ++i) {
  134. array_push(raw.dna.names, parser_blend_read_string(raw));
  135. }
  136. parser_blend_align(raw);
  137. parser_blend_read_chars(raw, 4); // TYPE
  138. let types_count: i32 = parser_blend_read_i32(raw);
  139. for (let i: i32 = 0; i < types_count; ++i) {
  140. array_push(raw.dna.types, parser_blend_read_string(raw));
  141. }
  142. parser_blend_align(raw);
  143. parser_blend_read_chars(raw, 4); // TLEN
  144. for (let i: i32 = 0; i < types_count; ++i) {
  145. array_push(raw.dna.types_length, parser_blend_read_i16(raw));
  146. }
  147. parser_blend_align(raw);
  148. parser_blend_read_chars(raw, 4); // STRC
  149. let struct_count: i32 = parser_blend_read_i32(raw);
  150. for (let i: i32 = 0; i < struct_count; ++i) {
  151. let ds: dna_struct_t = {};
  152. array_push(raw.dna.structs, ds);
  153. ds.dna = raw.dna;
  154. ds.type = parser_blend_read_i16(raw);
  155. let field_count: i32 = parser_blend_read_i16(raw);
  156. if (field_count > 0) {
  157. ds.field_types = [];
  158. ds.field_names = [];
  159. for (let j: i32 = 0; j < field_count; ++j) {
  160. array_push(ds.field_types, parser_blend_read_i16(raw));
  161. array_push(ds.field_names, parser_blend_read_i16(raw));
  162. }
  163. }
  164. }
  165. }
  166. else {
  167. raw.pos += b.size;
  168. }
  169. }
  170. }
  171. function parser_blend_align(raw: blend_t) {
  172. // 4 bytes aligned
  173. let mod: i32 = raw.pos % 4;
  174. if (mod > 0) {
  175. raw.pos += 4 - mod;
  176. }
  177. }
  178. function parser_blend_read_i8(raw: blend_t): i32 {
  179. let i: i32 = buffer_view_get_u8(raw.view, raw.pos);
  180. raw.pos += 1;
  181. return i;
  182. }
  183. function parser_blend_read_i16(raw: blend_t): i32 {
  184. let i: i32 = buffer_view_get_i16(raw.view, raw.pos); //, raw.little_endian
  185. raw.pos += 2;
  186. return i;
  187. }
  188. function parser_blend_read_i32(raw: blend_t): i32 {
  189. let i: i32 = buffer_view_get_i32(raw.view, raw.pos); //, raw.little_endian
  190. raw.pos += 4;
  191. return i;
  192. }
  193. function parser_blend_read_i64(raw: blend_t): any {
  194. let aview: any = raw.view;
  195. let i: i32 = aview.getBigInt64(raw.pos, raw.little_endian);
  196. raw.pos += 8;
  197. return i;
  198. }
  199. function parser_blend_read_f32(raw: blend_t): f32 {
  200. let f: f32 = buffer_view_get_f32(raw.view, raw.pos); //, raw.little_endian
  201. raw.pos += 4;
  202. return f;
  203. }
  204. function parser_blend_read_i8array(raw: blend_t, len: i32): i32_array_t {
  205. let ar: i32_array_t = i32_array_create(len);
  206. for (let i: i32 = 0; i < len; ++i) {
  207. ar[i] = parser_blend_read_i8(raw);
  208. }
  209. return ar;
  210. }
  211. function parser_blend_read_i16array(raw: blend_t, len: i32): i32_array_t {
  212. let ar: i32_array_t = i32_array_create(len);
  213. for (let i: i32 = 0; i < len; ++i) {
  214. ar[i] = parser_blend_read_i16(raw);
  215. }
  216. return ar;
  217. }
  218. function parser_blend_read_i32array(raw: blend_t, len: i32): i32_array_t {
  219. let ar: i32_array_t = i32_array_create(len);
  220. for (let i: i32 = 0; i < len; ++i) {
  221. ar[i] = parser_blend_read_i32(raw);
  222. }
  223. return ar;
  224. }
  225. function parser_blend_read_f32array(raw: blend_t, len: i32): f32_array_t {
  226. let ar: f32_array_t = f32_array_create(len);
  227. for (let i: i32 = 0; i < len; ++i) {
  228. ar[i] = parser_blend_read_f32(raw);
  229. }
  230. return ar;
  231. }
  232. function parser_blend_read_string(raw: blend_t): string {
  233. let s: string = "";
  234. while (true) {
  235. let ch: i32 = parser_blend_read_i8(raw);
  236. if (ch == 0) {
  237. break;
  238. }
  239. s += string_from_char_code(ch);
  240. }
  241. return s;
  242. }
  243. function parser_blend_read_chars(raw: blend_t, len: i32): string {
  244. let s: string = "";
  245. for (let i: i32 = 0; i < len; ++i) {
  246. s += parser_blend_read_char(raw);
  247. }
  248. return s;
  249. }
  250. function parser_blend_read_char(raw: blend_t): string {
  251. return string_from_char_code(parser_blend_read_i8(raw));
  252. }
  253. function parser_blend_read_pointer(raw: blend_t): any {
  254. return raw.pointer_size == 4 ? parser_blend_read_i32(raw) : parser_blend_read_i64(raw);
  255. }
  256. type block_t = {
  257. blend?: blend_t;
  258. code?: string;
  259. size?: i32;
  260. sdna_index?: i32;
  261. count?: i32;
  262. pos?: i32; // Byte pos of data start in blob
  263. };
  264. type dna_t = {
  265. names?: string[];
  266. types?: string[];
  267. types_length?: i32[];
  268. structs?: dna_struct_t[];
  269. };
  270. type dna_struct_t = {
  271. dna?: dna_t;
  272. type?: i32; // Index in dna.types
  273. field_types?: i32[]; // Index in dna.types
  274. field_names?: i32[]; // Index in dna.names
  275. };
  276. type bl_handle_t = {
  277. block?: block_t;
  278. offset?: i32; // Block data bytes offset
  279. ds?: dna_struct_t;
  280. };
  281. function bl_handle_get_size(raw: bl_handle_t, index: i32): i32 {
  282. let name_index: i32 = raw.ds.field_names[index];
  283. let type_index: i32 = raw.ds.field_types[index];
  284. let dna: dna_t = raw.ds.dna;
  285. let n: string = dna.names[name_index];
  286. let size: i32 = 0;
  287. if (string_index_of(n, "*") >= 0) {
  288. size = raw.block.blend.pointer_size;
  289. }
  290. else {
  291. size = dna.types_length[type_index];
  292. }
  293. if (string_index_of(n, "[") > 0) {
  294. size *= bl_handle_get_array_len(n);
  295. }
  296. return size;
  297. }
  298. function bl_handle_base_name(s: string): string {
  299. while (char_at(s, 0) == "*") {
  300. s = substring(s, 1, s.length);
  301. }
  302. if (char_at(s, s.length - 1) == "]") {
  303. s = substring(s, 0, string_index_of(s, "["));
  304. }
  305. return s;
  306. }
  307. function bl_handle_get_array_len(s: string): i32 {
  308. return parse_int(substring(s, string_index_of(s, "[") + 1, string_index_of(s, "]")));
  309. }
  310. function bl_handle_get(raw: bl_handle_t, name: string, index: i32 = 0, as_type: string = null, array_len: i32 = 0): any {
  311. // Return raw type or structure
  312. let dna: dna_t = raw.ds.dna;
  313. for (let i: i32 = 0; i < raw.ds.field_names.length; ++i) {
  314. let name_index: i32 = raw.ds.field_names[i];
  315. let dna_name: string = dna.names[name_index];
  316. if (name == bl_handle_base_name(dna_name)) {
  317. let type_index: i32 = raw.ds.field_types[i];
  318. let type: string = dna.types[type_index];
  319. let new_offset: i32 = raw.offset;
  320. for (let j: i32 = 0; j < i; ++j) {
  321. new_offset += bl_handle_get_size(raw, j);
  322. }
  323. // Cast void * to type
  324. if (as_type != null) {
  325. for (let i: i32 = 0; i < dna.types.length; ++i) {
  326. if (dna.types[i] == as_type) {
  327. type_index = i;
  328. break;
  329. }
  330. }
  331. }
  332. // Raw type
  333. if (type_index < 12) {
  334. let blend: blend_t = raw.block.blend;
  335. blend.pos = raw.block.pos + new_offset;
  336. let is_array: bool = char_at(dna_name, dna_name.length - 1) == "]";
  337. let len: i32 = is_array ? (array_len > 0 ? array_len : bl_handle_get_array_len(dna_name)) : 1;
  338. if (type == "int") {
  339. return is_array ? parser_blend_read_i32array(blend, len) : parser_blend_read_i32(blend);
  340. }
  341. else if (type == "char") {
  342. return is_array ? parser_blend_read_string(blend) : parser_blend_read_i8(blend);
  343. }
  344. else if (type == "uchar") {
  345. return is_array ? parser_blend_read_i8array(blend, len) : parser_blend_read_i8(blend);
  346. }
  347. else if (type == "short") {
  348. return is_array ? parser_blend_read_i16array(blend, len) : parser_blend_read_i16(blend);
  349. }
  350. else if (type == "ushort") {
  351. return is_array ? parser_blend_read_i16array(blend, len) : parser_blend_read_i16(blend);
  352. }
  353. else if (type == "float") {
  354. return is_array ? parser_blend_read_f32array(blend, len) : parser_blend_read_f32(blend);
  355. }
  356. else if (type == "double") {
  357. return 0; //readf64(blend);
  358. }
  359. else if (type == "long") {
  360. return is_array ? parser_blend_read_i32array(blend, len) : parser_blend_read_i32(blend);
  361. }
  362. else if (type == "ulong") {
  363. return is_array ? parser_blend_read_i32array(blend, len) : parser_blend_read_i32(blend);
  364. }
  365. else if (type == "int64_t") {
  366. return parser_blend_read_i64(blend);
  367. }
  368. else if (type == "uint64_t") {
  369. return parser_blend_read_i64(blend);
  370. }
  371. else if (type == "void") {
  372. if (char_at(dna_name, 0) == "*") {
  373. return parser_blend_read_i64(blend);
  374. }
  375. }
  376. }
  377. // Structure
  378. let h: bl_handle_t = {};
  379. h.offset = 0;
  380. h.ds = parser_blend_get_struct(dna, type_index);
  381. let is_pointer: bool = char_at(dna_name, 0) == "*";
  382. if (is_pointer) {
  383. raw.block.blend.pos = raw.block.pos + new_offset;
  384. let addr: any = parser_blend_read_pointer(raw.block.blend);
  385. if (map_get(raw.block.blend.map, addr) != null) {
  386. h.block = map_get(raw.block.blend.map, addr);
  387. }
  388. else h.block = raw.block;
  389. h.offset = 0;
  390. }
  391. else {
  392. h.block = raw.block;
  393. h.offset = new_offset;
  394. }
  395. h.offset += dna.types_length[type_index] * index;
  396. return h;
  397. }
  398. }
  399. return null;
  400. }