vxl_file.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. XCC Utilities and Library
  3. Copyright (C) 2000 Olaf van der Spek <[email protected]>
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "stdafx.h"
  16. #include "vxl_file.h"
  17. #include "file32.h"
  18. #include "image_file.h"
  19. #ifndef XCC_MINIMAL_BUILD
  20. #include "multi_line.h"
  21. #include "pcx_decode.h"
  22. #include "pcx_file_write.h"
  23. #endif
  24. #include "string_conversion.h"
  25. bool Cvxl_file::is_valid() const
  26. {
  27. int size = get_size();
  28. const t_vxl_header& h = header();
  29. if (sizeof(t_vxl_header) > size ||
  30. strcmp(h.id, vxl_id) ||
  31. h.one != 1 ||
  32. h.c_section_headers != h.c_section_tailers ||
  33. h.size != size - sizeof(t_vxl_header) - h.c_section_headers * sizeof(t_vxl_section_header) - h.c_section_tailers * sizeof(t_vxl_section_tailer) ||
  34. h.unknown != 0x1f10)
  35. return false;
  36. /*
  37. for (int i = 0; i < header.c_section_headers; i++)
  38. {
  39. const t_vxl_section_header& section_header = *get_section_header(i);
  40. const t_vxl_section_tailer& section_tailer = *get_section_tailer(i);
  41. if (section_header.one != 1 ||
  42. section_header.zero ||
  43. section_tailer.span_end_ofs - section_tailer.span_start_ofs != section_tailer.span_data_ofs - section_tailer.span_end_ofs)
  44. return false;
  45. }
  46. */
  47. return true;
  48. }
  49. #ifndef XCC_MINIMAL_BUILD
  50. int Cvxl_file::extract_as_pcx(const Cfname& name, t_file_type ft, const t_palet _palet) const
  51. {
  52. t_palet palet;
  53. memcpy(palet, _palet, sizeof(t_palet));
  54. convert_palet_18_to_24(palet);
  55. const t_vxl_section_tailer& section_tailer = *get_section_tailer(0);
  56. const int cx = section_tailer.cx;
  57. const int cy = section_tailer.cy;
  58. const int cz = section_tailer.cz;
  59. Cvirtual_binary s;
  60. for (int i = 0; i < cz; i++)
  61. {
  62. memset(s.write_start(cx * cy), 0, cx * cy);
  63. int j = 0;
  64. for (int y = 0; y < cy; y++)
  65. {
  66. for (int x = 0; x < cx; x++)
  67. {
  68. const byte* r = get_span_data(0, j);
  69. if (r)
  70. {
  71. int z = 0;
  72. while (z < cz)
  73. {
  74. z += *r++;
  75. int c = *r++;
  76. while (c--)
  77. {
  78. if (i == z)
  79. s.data_edit()[x + cx * y] = *r;
  80. r += 2;
  81. z++;
  82. }
  83. r++;
  84. }
  85. }
  86. j++;
  87. }
  88. }
  89. Cfname t = name;
  90. t.set_title(name.get_ftitle() + " " + nwzl(4, i));
  91. int error = image_file_write(t, ft, s.data(), palet, cx, cy);
  92. if (error)
  93. return error;
  94. }
  95. return 0;
  96. }
  97. #endif
  98. ostream& Cvxl_file::extract_as_text(ostream& os) const
  99. {
  100. for (int i = 0; i < get_c_section_headers(); i++)
  101. {
  102. const t_vxl_section_tailer& section_tailer = *get_section_tailer(i);
  103. const int cx = section_tailer.cx;
  104. const int cy = section_tailer.cy;
  105. const int cz = section_tailer.cz;
  106. int j = 0;
  107. for (int y = 0; y < cy; y++)
  108. {
  109. for (int x = 0; x < cx; x++)
  110. {
  111. const byte* r = get_span_data(i, j);
  112. if (r)
  113. {
  114. int z = 0;
  115. while (z < cz)
  116. {
  117. z += *r++;
  118. int c = *r++;
  119. while (c--)
  120. {
  121. os << i << ',' << x << ',' << y << ',' << z << ',' << static_cast<int>(*r++) << ',' << static_cast<int>(*r++) << endl;
  122. z++;
  123. }
  124. r++;
  125. }
  126. }
  127. j++;
  128. }
  129. }
  130. }
  131. return os;
  132. }
  133. enum
  134. {
  135. vi_header,
  136. vi_body,
  137. vi_tailer,
  138. vi_palet,
  139. vi_color,
  140. vi_surface_normal,
  141. vi_x,
  142. vi_y,
  143. vi_z,
  144. vi_cx,
  145. vi_cy,
  146. vi_cz,
  147. vi_id,
  148. vi_red,
  149. vi_green,
  150. vi_blue,
  151. vi_x_min,
  152. vi_y_min,
  153. vi_z_min,
  154. vi_x_max,
  155. vi_y_max,
  156. vi_z_max
  157. };
  158. #ifndef XCC_MINIMAL_BUILD
  159. int Cvxl_file::extract_as_xif(const string& name) const
  160. {
  161. Cxif_key k;
  162. Cxif_key& header = k.open_key_write(vi_header);
  163. Cxif_key& palet = header.open_key_write(vi_palet);
  164. int i;
  165. for (i = 0; i < 256; i++)
  166. {
  167. Cxif_key& palet_entry = palet.open_key_write(i);
  168. palet_entry.set_value_int(vi_red, get_palet()[i].r);
  169. palet_entry.set_value_int(vi_green, get_palet()[i].g);
  170. palet_entry.set_value_int(vi_blue, get_palet()[i].b);
  171. }
  172. Cxif_key& body = k.open_key_write(vi_body);
  173. for (i = 0; i < get_c_section_headers(); i++)
  174. {
  175. const t_vxl_section_header& section_header = *get_section_header(i);
  176. const t_vxl_section_tailer& section_tailer = *get_section_tailer(i);
  177. const int cx = section_tailer.cx;
  178. const int cy = section_tailer.cy;
  179. const int cz = section_tailer.cz;
  180. Cxif_key& section = body.open_key_write(i);
  181. Cxif_key& header = section.open_key_write(vi_header);
  182. header.set_value_string(vi_id, section_header.id);
  183. Cxif_key& body = section.open_key_write(vi_body);
  184. int j = 0;
  185. for (int y = 0; y < cy; y++)
  186. {
  187. Cxif_key& yi = body.open_key_write(y);
  188. for (int x = 0; x < cx; x++)
  189. {
  190. Cxif_key& xi = yi.open_key_write(x);
  191. const byte* r = get_span_data(i, j);
  192. if (r)
  193. {
  194. int z = 0;
  195. while (z < cz)
  196. {
  197. z += *r++;
  198. int c = *r++;
  199. while (c--)
  200. {
  201. Cxif_key& zi = xi.open_key_write(z);
  202. zi.set_value_int(vi_color, *r++);
  203. zi.set_value_int(vi_surface_normal, *r++);
  204. z++;
  205. }
  206. r++;
  207. }
  208. }
  209. j++;
  210. }
  211. }
  212. Cxif_key& tailer = section.open_key_write(vi_tailer);
  213. tailer.set_value_int(vi_x_min, section_tailer.x_min_scale * 1000000);
  214. tailer.set_value_int(vi_y_min, section_tailer.y_min_scale * 1000000);
  215. tailer.set_value_int(vi_z_min, section_tailer.z_min_scale * 1000000);
  216. tailer.set_value_int(vi_x_max, section_tailer.x_max_scale * 1000000);
  217. tailer.set_value_int(vi_y_max, section_tailer.y_max_scale * 1000000);
  218. tailer.set_value_int(vi_z_max, section_tailer.z_max_scale * 1000000);
  219. tailer.set_value_int(vi_cx, cx);
  220. tailer.set_value_int(vi_cy, cy);
  221. tailer.set_value_int(vi_cz, cz);
  222. }
  223. return k.vdata().save(name);
  224. }
  225. Cvirtual_binary vxl_file_write(const Cxif_key& s)
  226. {
  227. Cvirtual_binary d;
  228. byte* w = d.write_start(1 << 20);
  229. const Cxif_key& header_key = s.open_key_read(vi_header);
  230. const Cxif_key& body_key = s.open_key_read(vi_body);
  231. int c_sections = body_key.c_keys();
  232. int* span_start_list_ofs = new int[c_sections];
  233. int* span_end_list_ofs = new int[c_sections];
  234. int* span_data_ofs = new int[c_sections];
  235. t_vxl_header& header = *reinterpret_cast<t_vxl_header*>(w);
  236. strcpy(header.id, vxl_id);
  237. header.one = 1;
  238. header.c_section_headers = c_sections;
  239. header.c_section_tailers = c_sections;
  240. header.unknown = 0x1f10;
  241. const Cxif_key& palet_key = header_key.open_key_read(vi_palet);
  242. int i;
  243. for (i = 0; i < 256; i++)
  244. {
  245. const Cxif_key& palet_entry_key = palet_key.open_key_read(i);
  246. header.palet[i].r = palet_entry_key.get_value_int(vi_red);
  247. header.palet[i].g = palet_entry_key.get_value_int(vi_green);
  248. header.palet[i].b = palet_entry_key.get_value_int(vi_blue);
  249. }
  250. w += sizeof(t_vxl_header);
  251. for (i = 0; i < c_sections; i++)
  252. {
  253. const Cxif_key& section_key = body_key.open_key_read(i);
  254. const Cxif_key& section_header_key = section_key.open_key_read(vi_header);
  255. t_vxl_section_header& section_header = *reinterpret_cast<t_vxl_section_header*>(w);
  256. strcpy(section_header.id, section_header_key.get_value_string(vi_id).c_str());
  257. section_header.section_i = i;
  258. section_header.one = 1;
  259. section_header.zero = 0;
  260. w += sizeof(t_vxl_section_header);
  261. }
  262. byte* body_start = w;
  263. for (i = 0; i < c_sections; i++)
  264. {
  265. const Cxif_key& section_key = body_key.open_key_read(i);
  266. const Cxif_key& section_body_key = section_key.open_key_read(vi_body);
  267. const Cxif_key& section_tailer_key = section_key.open_key_read(vi_tailer);
  268. const int cx = section_tailer_key.get_value_int(vi_cx);
  269. const int cy = section_tailer_key.get_value_int(vi_cy);
  270. const int cz = section_tailer_key.get_value_int(vi_cz);
  271. __int32* span_start_list = reinterpret_cast<__int32*>(w);
  272. span_start_list_ofs[i] = w - body_start;
  273. w += 4 * cx * cy;
  274. __int32* span_end_list = reinterpret_cast<__int32*>(w);
  275. span_end_list_ofs[i] = w - body_start;
  276. w += 4 * cx * cy;
  277. byte* span_data_start = w;
  278. span_data_ofs[i] = w - body_start;
  279. int span_i = 0;
  280. for (int y = 0; y < cy; y++)
  281. {
  282. const Cxif_key& yi = section_body_key.open_key_read(y);
  283. for (int x = 0; x < cx; x++)
  284. {
  285. byte* span_start = w;
  286. const Cxif_key& xi = yi.open_key_read(x);
  287. int z = 0;
  288. for (auto& i : xi.m_keys)
  289. {
  290. int z_inc = i.first - z;
  291. z = i.first + 1;
  292. *w++ = z_inc;
  293. *w++ = 1;
  294. *w++ = i.second.get_value_int(vi_color);
  295. *w++ = i.second.get_value_int(vi_surface_normal);
  296. *w++ = 1;
  297. }
  298. if (span_start == w)
  299. {
  300. span_start_list[span_i] = -1;
  301. span_end_list[span_i] = -1;
  302. }
  303. else
  304. {
  305. if (z != cz)
  306. {
  307. *w++ = cz - z;
  308. *w++ = 0;
  309. *w++ = 0;
  310. }
  311. span_start_list[span_i] = span_start - span_data_start;
  312. span_end_list[span_i] = w - span_data_start - 1;
  313. }
  314. span_i++;
  315. }
  316. }
  317. }
  318. header.size = w - body_start;
  319. for (i = 0; i < c_sections; i++)
  320. {
  321. const Cxif_key& section_key = body_key.open_key_read(i);
  322. const Cxif_key& section_tailer_key = section_key.open_key_read(vi_tailer);
  323. t_vxl_section_tailer& section_tailer = *reinterpret_cast<t_vxl_section_tailer*>(w);
  324. section_tailer.span_start_ofs = span_start_list_ofs[i];
  325. section_tailer.span_end_ofs = span_end_list_ofs[i];
  326. section_tailer.span_data_ofs = span_data_ofs[i];
  327. section_tailer.scale = 0;
  328. for (int ty = 0; ty < 3; ty++)
  329. {
  330. for (int tx = 0; tx < 4; tx++)
  331. section_tailer.transform[ty][tx] = 0;
  332. }
  333. section_tailer.x_min_scale = section_tailer_key.get_value_int(vi_x_min) / 1000000.0;
  334. section_tailer.y_min_scale = section_tailer_key.get_value_int(vi_y_min) / 1000000.0;
  335. section_tailer.z_min_scale = section_tailer_key.get_value_int(vi_z_min) / 1000000.0;
  336. section_tailer.x_max_scale = section_tailer_key.get_value_int(vi_x_max) / 1000000.0;
  337. section_tailer.y_max_scale = section_tailer_key.get_value_int(vi_y_max) / 1000000.0;
  338. section_tailer.z_max_scale = section_tailer_key.get_value_int(vi_z_max) / 1000000.0;
  339. section_tailer.cx = section_tailer_key.get_value_int(vi_cx);
  340. section_tailer.cy = section_tailer_key.get_value_int(vi_cy);
  341. section_tailer.cz = section_tailer_key.get_value_int(vi_cz);
  342. section_tailer.unknown = 2;
  343. w += sizeof(t_vxl_section_tailer);
  344. }
  345. delete[] span_data_ofs;
  346. delete[] span_end_list_ofs;
  347. delete[] span_start_list_ofs;
  348. d.set_size(w - d.data());
  349. return d;
  350. }
  351. Cvirtual_binary vxl_file_write(const byte* s, const byte* s_normals, int cx, int cy, int cz)
  352. {
  353. Cxif_key k;
  354. Cxif_key& header = k.open_key_write(vi_header);
  355. Cxif_key& palet = header.open_key_write(vi_palet);
  356. for (int i = 0; i < 256; i++)
  357. {
  358. Cxif_key& palet_entry = palet.open_key_write(i);
  359. palet_entry.set_value_int(vi_red, i);
  360. palet_entry.set_value_int(vi_green, i);
  361. palet_entry.set_value_int(vi_blue, i);
  362. }
  363. Cxif_key& body = k.open_key_write(vi_body);
  364. {
  365. Cxif_key& section = body.open_key_write(0);
  366. Cxif_key& header = section.open_key_write(vi_header);
  367. header.set_value_string(vi_id, "NONE");
  368. Cxif_key& body = section.open_key_write(vi_body);
  369. for (int y = 0; y < cy; y++)
  370. {
  371. Cxif_key& yi = body.open_key_write(y);
  372. for (int x = 0; x < cx; x++)
  373. {
  374. Cxif_key& xi = yi.open_key_write(x);
  375. const byte* r = s + x + cx * y;
  376. for (int z = 0; z < cz; z++)
  377. {
  378. int v = *r;
  379. if (v)
  380. {
  381. Cxif_key& zi = xi.open_key_write(z);
  382. zi.set_value_int(vi_color, v);
  383. zi.set_value_int(vi_surface_normal, s_normals ? s_normals[r - s]: -1);
  384. }
  385. r += cx * cy;
  386. }
  387. }
  388. }
  389. Cxif_key& tailer = section.open_key_write(vi_tailer);
  390. tailer.set_value_int(vi_x_min, cx * -1000000 / 2);
  391. tailer.set_value_int(vi_y_min, cy * -1000000 / 2);
  392. tailer.set_value_int(vi_z_min, cz * -1000000 / 2);
  393. tailer.set_value_int(vi_x_max, cx * +1000000 / 2);
  394. tailer.set_value_int(vi_y_max, cy * +1000000 / 2);
  395. tailer.set_value_int(vi_z_max, cz * +1000000 / 2);
  396. tailer.set_value_int(vi_cx, cx);
  397. tailer.set_value_int(vi_cy, cy);
  398. tailer.set_value_int(vi_cz, cz);
  399. }
  400. return vxl_file_write(k);
  401. }
  402. struct t_voxel
  403. {
  404. int x;
  405. int y;
  406. int z;
  407. int color;
  408. int normal;
  409. };
  410. Cvirtual_binary vxl_file_write(Cvirtual_tfile s)
  411. {
  412. using t_list = list<t_voxel>;
  413. t_list list;
  414. int cs = 0;
  415. int cx = 0;
  416. int cy = 0;
  417. int cz = 0;
  418. while (!s.eof())
  419. {
  420. Cmulti_line l = s.read_line();
  421. t_voxel e;
  422. int s = l.get_next_int(',');
  423. e.x = l.get_next_int(',');
  424. e.y = l.get_next_int(',');
  425. e.z = l.get_next_int(',');
  426. e.normal = l.get_next_int(',');
  427. e.color = l.get_next_int(',');
  428. if (!s)
  429. list.push_back(e);
  430. cs = max(cs, s + 1);
  431. cx = max(cx, e.x + 1);
  432. cy = max(cy, e.y + 1);
  433. cz = max(cz, e.z + 1);
  434. }
  435. Cvirtual_binary colors(NULL, cx * cy * cz);
  436. Cvirtual_binary normals(NULL, cx * cy * cz);
  437. colors.memset(0);
  438. normals.memset(0);
  439. for (auto& e : list)
  440. {
  441. int o = e.x + cx * (e.y + cy * e.z);
  442. colors.data_edit()[o] = e.color;
  443. normals.data_edit()[o] = e.normal;
  444. }
  445. return vxl_file_write(colors.data(), normals.data(), cx, cy, cz);
  446. }
  447. #endif
  448. struct t_vxl4_header
  449. {
  450. unsigned __int32 c_sections;
  451. };
  452. struct t_vxl4_section_header
  453. {
  454. char id[16];
  455. __int32 section_i;
  456. float scale;
  457. float x_min_scale;
  458. float y_min_scale;
  459. float z_min_scale;
  460. float x_max_scale;
  461. float y_max_scale;
  462. float z_max_scale;
  463. unsigned __int8 cx;
  464. unsigned __int8 cy;
  465. unsigned __int8 cz;
  466. __int8 unknown;
  467. };
  468. int vxl_encode4(const Cvxl_file& f, byte* d)
  469. {
  470. const int c_sections = f.get_c_section_headers();
  471. byte* w = d;
  472. t_vxl4_header& header = *reinterpret_cast<t_vxl4_header*>(w);
  473. header.c_sections = c_sections;
  474. w += sizeof(t_vxl4_header);
  475. for (int i = 0; i < c_sections; i++)
  476. {
  477. const t_vxl_section_header& s_section_header = *f.get_section_header(i);
  478. const t_vxl_section_tailer& section_tailer = *f.get_section_tailer(i);
  479. const int cx = section_tailer.cx;
  480. const int cy = section_tailer.cy;
  481. const int cz = section_tailer.cz;
  482. t_vxl4_section_header& section_header = *reinterpret_cast<t_vxl4_section_header*>(w);
  483. strcpy(section_header.id, s_section_header.id);
  484. section_header.section_i = s_section_header.section_i;
  485. assert(s_section_header.section_i == i);
  486. section_header.scale = section_tailer.scale;
  487. section_header.x_min_scale = section_tailer.x_min_scale;
  488. section_header.y_min_scale = section_tailer.y_min_scale;
  489. section_header.z_min_scale = section_tailer.z_min_scale;
  490. section_header.x_max_scale = section_tailer.x_max_scale;
  491. section_header.y_max_scale = section_tailer.y_max_scale;
  492. section_header.z_max_scale = section_tailer.z_max_scale;
  493. section_header.cx = section_tailer.cx;
  494. section_header.cy = section_tailer.cy;
  495. section_header.cz = section_tailer.cz;
  496. section_header.unknown = section_tailer.unknown;
  497. w += sizeof(t_vxl4_section_header);
  498. for (int j = 0; j < f.get_c_spans(i); j++)
  499. {
  500. const byte* r = f.get_span_data(i, j);
  501. if (r)
  502. {
  503. int z = 0;
  504. while (z < cz)
  505. {
  506. int z_inc = *w++ = *r++;
  507. if (z_inc == cz)
  508. break;
  509. z += z_inc;
  510. int c = *w++ = *r++;
  511. while (c--)
  512. {
  513. *w++ = *r++;
  514. *w++ = *r++;
  515. z++;
  516. }
  517. r++;
  518. }
  519. }
  520. else
  521. *w++ = cz;
  522. }
  523. }
  524. return w - d;
  525. }
  526. int vxl_decode4_size(const byte* s)
  527. {
  528. const byte* r = s;
  529. const t_vxl4_header& s_header = *reinterpret_cast<const t_vxl4_header*>(r);
  530. const int c_sections = s_header.c_sections;
  531. r += sizeof(t_vxl4_header);
  532. int w = 0;
  533. for (int i = 0; i < c_sections; i++)
  534. {
  535. const t_vxl4_section_header& section_header = *reinterpret_cast<const t_vxl4_section_header*>(r);
  536. const int cx = section_header.cx;
  537. const int cy = section_header.cy;
  538. const int cz = section_header.cz;
  539. w += 8 * cx * cy;
  540. r += sizeof(t_vxl4_section_header);
  541. for (int j = 0; j < cx * cy; j++)
  542. {
  543. int z = 0;
  544. while (z < cz)
  545. {
  546. int z_inc = *r++;
  547. if (z_inc == cz)
  548. break;
  549. z += z_inc;
  550. int count = *r++;
  551. r += 2 * count;
  552. w += 2 * count + 3;
  553. z += count;
  554. }
  555. }
  556. }
  557. return w
  558. + sizeof(t_vxl_header)
  559. + (sizeof(t_vxl_section_header) + sizeof(t_vxl_section_tailer)) * c_sections;
  560. }
  561. Cvirtual_binary vxl_decode4(const byte* s, int cb_d)
  562. {
  563. Cvirtual_binary d;
  564. const byte* r = s;
  565. const t_vxl4_header& s_header = *reinterpret_cast<const t_vxl4_header*>(r);
  566. const int c_sections = s_header.c_sections;
  567. r += sizeof(t_vxl4_header);
  568. byte* w = d.write_start(cb_d ? cb_d : 1 << 20);
  569. t_vxl_header& header = *reinterpret_cast<t_vxl_header*>(w);
  570. strcpy(header.id, vxl_id);
  571. header.one = 1;
  572. header.c_section_headers = c_sections;
  573. header.c_section_tailers = c_sections;
  574. header.unknown = 0x1f10;
  575. w += sizeof(t_vxl_header);
  576. t_vxl_section_header* d_section_header = reinterpret_cast<t_vxl_section_header*>(w);
  577. t_vxl_section_tailer* section_tailer = new t_vxl_section_tailer[c_sections];
  578. w += sizeof(t_vxl_section_header) * c_sections;
  579. byte* body_start = w;
  580. for (int i = 0; i < c_sections; i++)
  581. {
  582. const t_vxl4_section_header& section_header = *reinterpret_cast<const t_vxl4_section_header*>(r);
  583. const int cx = section_header.cx;
  584. const int cy = section_header.cy;
  585. const int cz = section_header.cz;
  586. strcpy(d_section_header->id, section_header.id);
  587. d_section_header->section_i = section_header.section_i;
  588. d_section_header->one = 1;
  589. d_section_header->zero = 0;
  590. d_section_header++;
  591. __int32* span_start_list = reinterpret_cast<__int32*>(w);
  592. section_tailer[i].span_start_ofs = w - body_start;
  593. w += 4 * cx * cy;
  594. __int32* span_end_list = reinterpret_cast<__int32*>(w);
  595. section_tailer[i].span_end_ofs = w - body_start;
  596. w += 4 * cx * cy;
  597. section_tailer[i].span_data_ofs = w - body_start;
  598. section_tailer[i].scale = section_header.scale;
  599. section_tailer[i].x_min_scale = section_header.x_min_scale;
  600. section_tailer[i].y_min_scale = section_header.y_min_scale;
  601. section_tailer[i].z_min_scale = section_header.z_min_scale;
  602. section_tailer[i].x_max_scale = section_header.x_max_scale;
  603. section_tailer[i].y_max_scale = section_header.y_max_scale;
  604. section_tailer[i].z_max_scale = section_header.z_max_scale;
  605. section_tailer[i].cx = section_header.cx;
  606. section_tailer[i].cy = section_header.cy;
  607. section_tailer[i].cz = section_header.cz;
  608. section_tailer[i].unknown = section_header.unknown;
  609. r += sizeof(t_vxl4_section_header);
  610. byte* span_data_start = w;
  611. for (int j = 0; j < cx * cy; j++)
  612. {
  613. byte* span_start = w;
  614. int z = 0;
  615. while (z < cz)
  616. {
  617. int z_inc = *r++;
  618. if (z_inc == cz)
  619. break;
  620. z += *w++ = z_inc;
  621. int count = *w++ = *r++;
  622. int c = count;
  623. while (c--)
  624. {
  625. *w++ = *r++;
  626. *w++ = *r++;
  627. z++;
  628. }
  629. *w++ = count;
  630. }
  631. if (span_start == w)
  632. {
  633. span_start_list[j] = -1;
  634. span_end_list[j] = -1;
  635. }
  636. else
  637. {
  638. span_start_list[j] = span_start - span_data_start;
  639. span_end_list[j] = w - span_data_start - 1;
  640. }
  641. }
  642. }
  643. header.size = w - body_start;
  644. memcpy(w, section_tailer, sizeof(t_vxl_section_tailer) * c_sections);
  645. delete[] section_tailer;
  646. w += sizeof(t_vxl_section_tailer) * c_sections;
  647. assert(!cb_d || d.size() == w - d.data());
  648. return cb_d ? d : Cvirtual_binary(d.data(), w - d.data());
  649. }