shp_decode.cpp 20 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  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 "shp_decode.h"
  17. #include <lzo/lzo1x.h>
  18. #include <virtual_binary.h>
  19. #include "cc_structures.h"
  20. static const char* encode64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  21. static const int decode64_table[256] =
  22. {
  23. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  24. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  25. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
  26. 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
  27. -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
  28. 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
  29. -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
  30. 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1,
  31. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  32. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  33. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  34. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  35. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  36. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  37. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  38. -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
  39. };
  40. static int read_w(const byte*& r)
  41. {
  42. int v = *reinterpret_cast<const unsigned __int16*>(r);
  43. r += 2;
  44. return v;
  45. }
  46. static void write_w(int v, byte*& w)
  47. {
  48. *w++ = v & 0xff;
  49. *w++ = v >> 8;
  50. }
  51. static void write_v40(byte v, int count, byte*& d)
  52. {
  53. while (count)
  54. {
  55. if (v)
  56. {
  57. if (count < 0x100)
  58. {
  59. *d++ = 0x00;
  60. *d++ = count;
  61. *d++ = v;
  62. break;
  63. }
  64. int c_write = min(count, 0x3fff);
  65. *d++ = 0x80;
  66. write_w(0xc000 | c_write, d);
  67. count -= c_write;
  68. *d++ = v;
  69. }
  70. else if (count < 0x80)
  71. {
  72. *d++ = 0x80 | count;
  73. count = 0;
  74. }
  75. else
  76. {
  77. int c_write = count < 0x8000 ? count : 0x7fff;
  78. *d++ = 0x80;
  79. write_w(c_write, d);
  80. count -= c_write;
  81. }
  82. }
  83. }
  84. int get_run_length(const byte* r, const byte* s_end)
  85. {
  86. int count = 1;
  87. int v = *r++;
  88. while (r < s_end && *r++ == v)
  89. count++;
  90. return count;
  91. }
  92. static void write40_c0(byte*& w, int count, int v)
  93. {
  94. *w++ = 0;
  95. *w++ = count;
  96. *w++ = v;
  97. }
  98. static void write40_c1(byte*& w, int count, const byte* r)
  99. {
  100. *w++ = count;
  101. memcpy(w, r, count);
  102. w += count;
  103. }
  104. static void write40_c2(byte*& w, int count)
  105. {
  106. *w++ = 0x80;
  107. write_w(count, w);
  108. }
  109. static void write40_c3(byte*& w, int count, const byte* r)
  110. {
  111. *w++ = 0x80;
  112. write_w(0x8000 | count, w);
  113. memcpy(w, r, count);
  114. w += count;
  115. }
  116. static void write40_c4(byte*& w, int count, int v)
  117. {
  118. *w++ = 0x80;
  119. write_w(0xc000 | count, w);
  120. *w++ = v;
  121. }
  122. static void write40_c5(byte*& w, int count)
  123. {
  124. *w++ = 0x80 | count;
  125. }
  126. static void write40_copy(byte*& w, int count, const byte* r)
  127. {
  128. while (count)
  129. {
  130. if (count < 0x80)
  131. {
  132. write40_c1(w, count, r);
  133. count = 0;
  134. }
  135. else
  136. {
  137. int c_write = count < 0x4000 ? count : 0x3fff;
  138. write40_c3(w, c_write, r);
  139. r += c_write;
  140. count -= c_write;
  141. }
  142. }
  143. }
  144. static void write40_fill(byte*& w, int count, int v)
  145. {
  146. while (count)
  147. {
  148. if (count < 0x100)
  149. {
  150. write40_c0(w, count, v);
  151. count = 0;
  152. }
  153. else
  154. {
  155. int c_write = count < 0x4000 ? count : 0x3fff;
  156. write40_c4(w, c_write, v);
  157. count -= c_write;
  158. }
  159. }
  160. }
  161. static void write40_skip(byte*& w, int count)
  162. {
  163. while (count)
  164. {
  165. if (count < 0x80)
  166. {
  167. write40_c5(w, count);
  168. count = 0;
  169. }
  170. else
  171. {
  172. int c_write = count < 0x8000 ? count : 0x7fff;
  173. write40_c2(w, c_write);
  174. count -= c_write;
  175. }
  176. }
  177. }
  178. static void flush_copy(byte*& w, const byte* r, const byte*& copy_from)
  179. {
  180. if (copy_from)
  181. {
  182. write40_copy(w, r - copy_from, copy_from);
  183. copy_from = NULL;
  184. }
  185. }
  186. int encode40(const byte* last_s, const byte* x, byte* d, int cb_s)
  187. {
  188. // full compression
  189. byte* s = new byte[cb_s];
  190. {
  191. byte* a = s;
  192. int size = cb_s;
  193. while (size--)
  194. *a++ = *last_s++ ^ *x++;
  195. }
  196. const byte* s_end = s + cb_s;
  197. const byte* r = s;
  198. byte* w = d;
  199. const byte* copy_from = NULL;
  200. while (r < s_end)
  201. {
  202. int v = *r;
  203. int t = get_run_length(r, s_end);
  204. if (!v)
  205. {
  206. flush_copy(w, r, copy_from);
  207. write40_skip(w, t);
  208. }
  209. else if (t > 2)
  210. {
  211. flush_copy(w, r, copy_from);
  212. write40_fill(w, t, v);
  213. }
  214. else
  215. {
  216. if (!copy_from)
  217. copy_from = r;
  218. }
  219. r += t;
  220. }
  221. flush_copy(w, r, copy_from);
  222. write40_c2(w, 0);
  223. delete[] s;
  224. return w - d;
  225. }
  226. int encode40_y(const byte* last_r, const byte* r, byte* d, int cb_s)
  227. {
  228. // run length encoding
  229. byte* w = d;
  230. int count = 0;
  231. byte last = ~(*last_r ^ *r);
  232. while (cb_s--)
  233. {
  234. byte v = *last_r++ ^ *r++;
  235. if (last == v)
  236. count++;
  237. else
  238. {
  239. write_v40(last, count, w);
  240. count = 1;
  241. last = v;
  242. }
  243. }
  244. write_v40(last, count, w);
  245. *w++ = 0x80;
  246. write_w(0, w);
  247. return w - d;
  248. }
  249. int encode40_z(const byte* last_s, const byte* s, byte* d, int cb_s)
  250. {
  251. // no compression
  252. const byte* last_r = last_s;
  253. const byte* r = s;
  254. byte* w = d;
  255. while (cb_s)
  256. {
  257. int c_write = cb_s > 0x3fff ? 0x3fff : cb_s;
  258. cb_s -= c_write;
  259. *w++ = 0x80;
  260. *w++ = c_write & 0xff;
  261. *w++ = 0x80 | c_write >> 8;
  262. while (c_write--)
  263. *w++ = *last_r++ ^ *r++;
  264. }
  265. *w++ = 0x80;
  266. *w++ = 0x00;
  267. *w++ = 0x00;
  268. return w - d;
  269. }
  270. int decode40(const byte* s, byte* d)
  271. {
  272. /*
  273. 0 fill 00000000 c v
  274. 1 copy 0ccccccc
  275. 2 skip 10000000 c 0ccccccc
  276. 3 copy 10000000 c 10cccccc
  277. 4 fill 10000000 c 11cccccc v
  278. 5 skip 1ccccccc
  279. */
  280. const byte* r = s;
  281. byte* w = d;
  282. int count;
  283. while (1)
  284. {
  285. int code = *r++;
  286. if (code & 0x80)
  287. {
  288. if (count = code & 0x7f)
  289. {
  290. w += count;
  291. }
  292. else
  293. {
  294. count = *(uint16_t*)r;
  295. r += 2;
  296. code = count >> 8;
  297. if (code & 0x80)
  298. {
  299. count &= 0x3fff;
  300. if (code & 0x40)
  301. {
  302. code = *r++;
  303. while (count--)
  304. *w++ ^= code;
  305. }
  306. else
  307. {
  308. while (count--)
  309. *w++ ^= *r++;
  310. }
  311. }
  312. else
  313. {
  314. if (!count)
  315. break;
  316. w += count;
  317. }
  318. }
  319. }
  320. else if (code)
  321. {
  322. count = code;
  323. while (count--)
  324. *w++ ^= *r++;
  325. }
  326. else
  327. {
  328. count = *r++;
  329. code = *r++;
  330. while (count--)
  331. *w++ ^= code;
  332. }
  333. }
  334. return w - d;
  335. }
  336. static void write_v80(byte v, int count, byte*& d)
  337. {
  338. if (count > 3)
  339. {
  340. *d++ = 0xfe;
  341. write_w(count, d);
  342. *d++ = v;
  343. }
  344. else if (count)
  345. {
  346. *d++ = 0x80 | count;
  347. while (count--)
  348. *d++ = v;
  349. }
  350. }
  351. void get_same(const byte* s, const byte* r, const byte* s_end, byte*& p, int& cb_p)
  352. {
  353. _asm
  354. {
  355. push esi
  356. push edi
  357. mov eax, s_end
  358. mov ebx, s
  359. xor ecx, ecx
  360. mov edi, p
  361. mov [edi], ecx
  362. dec ebx
  363. next_s:
  364. inc ebx
  365. xor edx, edx
  366. mov esi, r
  367. mov edi, ebx
  368. cmp edi, esi
  369. jnb end0
  370. next0:
  371. inc edx
  372. cmp esi, eax
  373. jnb end_line
  374. cmpsb
  375. je next0
  376. end_line:
  377. dec edx
  378. cmp edx, ecx
  379. jl next_s
  380. mov ecx, edx
  381. mov edi, p
  382. mov [edi], ebx
  383. jmp next_s
  384. end0:
  385. mov edi, cb_p
  386. mov [edi], ecx
  387. pop edi
  388. pop esi
  389. }
  390. }
  391. static void write80_c0(byte*& w, int count, int p)
  392. {
  393. *w++ = (count - 3) << 4 | p >> 8;
  394. *w++ = p & 0xff;
  395. }
  396. static void write80_c1(byte*& w, int count, const byte* r)
  397. {
  398. do
  399. {
  400. int c_write = count < 0x40 ? count : 0x3f;
  401. *w++ = 0x80 | c_write;
  402. memcpy(w, r, c_write);
  403. r += c_write;
  404. w += c_write;
  405. count -= c_write;
  406. }
  407. while (count);
  408. }
  409. static void write80_c2(byte*& w, int count, int p)
  410. {
  411. *w++ = 0xc0 | (count - 3);
  412. write_w(p, w);
  413. }
  414. static void write80_c3(byte*& w, int count, int v)
  415. {
  416. *w++ = 0xfe;
  417. write_w(count, w);
  418. *w++ = v;
  419. }
  420. static void write80_c4(byte*& w, int count, int p)
  421. {
  422. *w++ = 0xff;
  423. write_w(count, w);
  424. write_w(p, w);
  425. }
  426. static void flush_c1(byte*& w, const byte* r, const byte*& copy_from)
  427. {
  428. if (copy_from)
  429. {
  430. write80_c1(w, r - copy_from, copy_from);
  431. copy_from = NULL;
  432. }
  433. }
  434. int encode80(const byte* s, byte* d, int cb_s)
  435. {
  436. // full compression
  437. const byte* s_end = s + cb_s;
  438. const byte* r = s;
  439. byte* w = d;
  440. const byte* copy_from = NULL;
  441. while (r < s_end)
  442. {
  443. byte* p;
  444. int cb_p;
  445. int t = get_run_length(r, s_end);
  446. get_same(s, r, s_end, p, cb_p);
  447. if (t < cb_p && cb_p > 2)
  448. {
  449. flush_c1(w, r, copy_from);
  450. if (cb_p - 3 < 8 && r - p < 0x1000)
  451. write80_c0(w, cb_p, r - p);
  452. else if (cb_p - 3 < 0x3e)
  453. write80_c2(w, cb_p, p - s);
  454. else
  455. write80_c4(w, cb_p, p - s);
  456. r += cb_p;
  457. }
  458. else
  459. {
  460. if (t < 3)
  461. {
  462. if (!copy_from)
  463. copy_from = r;
  464. }
  465. else
  466. {
  467. flush_c1(w, r, copy_from);
  468. write80_c3(w, t, *r);
  469. }
  470. r += t;
  471. }
  472. }
  473. flush_c1(w, r, copy_from);
  474. write80_c1(w, 0, NULL);
  475. return w - d;
  476. }
  477. int encode80_y(const byte* s, byte* d, int cb_s)
  478. {
  479. // run length encoding
  480. const byte* r = s;
  481. byte* w = d;
  482. int count = 0;
  483. byte last = ~*r;
  484. while (cb_s--)
  485. {
  486. byte v = *r++;
  487. if (last == v)
  488. count++;
  489. else
  490. {
  491. write_v80(last, count, w);
  492. count = 1;
  493. last = v;
  494. }
  495. }
  496. write_v80(last, count, w);
  497. *w++ = 0x80;
  498. return w - d;
  499. }
  500. int decode80c(const byte image_in[], byte image_out[], int cb_in)
  501. {
  502. /*
  503. 0 copy 0cccpppp p
  504. 1 copy 10cccccc
  505. 2 copy 11cccccc p p
  506. 3 fill 11111110 c c v
  507. 4 copy 11111111 c c p p
  508. */
  509. const byte* copyp;
  510. const byte* r = image_in;
  511. byte* w = image_out;
  512. int code;
  513. int count;
  514. while (1)
  515. {
  516. code = *r++;
  517. if (~code & 0x80)
  518. {
  519. //bit 7 = 0
  520. //command 0 (0cccpppp p): copy
  521. count = (code >> 4) + 3;
  522. copyp = w - (((code & 0xf) << 8) + *r++);
  523. while (count--)
  524. *w++ = *copyp++;
  525. }
  526. else
  527. {
  528. //bit 7 = 1
  529. count = code & 0x3f;
  530. if (~code & 0x40)
  531. {
  532. //bit 6 = 0
  533. if (!count)
  534. //end of image
  535. break;
  536. //command 1 (10cccccc): copy
  537. while (count--)
  538. *w++ = *r++;
  539. }
  540. else
  541. {
  542. //bit 6 = 1
  543. if (count < 0x3e)
  544. {
  545. //command 2 (11cccccc p p): copy
  546. count += 3;
  547. copyp = &image_out[*(unsigned __int16*)r];
  548. r += 2;
  549. while (count--)
  550. *w++ = *copyp++;
  551. }
  552. else
  553. if (count == 0x3e)
  554. {
  555. //command 3 (11111110 c c v): fill
  556. count = *(unsigned __int16*)r;
  557. r += 2;
  558. code = *r++;
  559. while (count--)
  560. *w++ = byte(code);
  561. }
  562. else
  563. {
  564. //command 4 (copy 11111111 c c p p): copy
  565. count = *(unsigned __int16*)r;
  566. r += 2;
  567. copyp = &image_out[*(unsigned __int16*)r];
  568. r += 2;
  569. while (count--)
  570. *w++ = *copyp++;
  571. }
  572. }
  573. }
  574. }
  575. assert(cb_in == r - image_in);
  576. return (w - image_out);
  577. }
  578. int decode80(const byte image_in[], byte image_out[])
  579. {
  580. int cb_out;
  581. /*
  582. 0 copy 0cccpppp p
  583. 1 copy 10cccccc
  584. 2 copy 11cccccc p p
  585. 3 fill 11111110 c c v
  586. 4 copy 11111111 c c p p
  587. */
  588. _asm
  589. {
  590. push esi
  591. push edi
  592. mov ax, ds
  593. mov es, ax
  594. mov esi, image_in
  595. mov edi, image_out
  596. next0:
  597. xor eax, eax
  598. lodsb
  599. mov ecx, eax
  600. test eax, 0x80
  601. jnz c1c
  602. shr ecx, 4
  603. add ecx, 3
  604. and eax, 0xf
  605. shl eax, 8
  606. lodsb
  607. mov edx, esi
  608. mov esi, edi
  609. sub esi, eax
  610. jmp copy_from_destination
  611. c1c:
  612. and ecx, 0x3f
  613. test eax, 0x40
  614. jnz c2c
  615. or ecx, ecx
  616. jz end0
  617. jmp copy_from_source
  618. c2c:
  619. xor eax, eax
  620. lodsw
  621. cmp ecx, 0x3e
  622. je c3
  623. ja c4
  624. mov edx, esi
  625. mov esi, image_out
  626. add esi, eax
  627. add ecx, 3
  628. jmp copy_from_destination
  629. c3:
  630. mov ecx, eax
  631. lodsb
  632. rep stosb
  633. jmp next0
  634. c4:
  635. mov ecx, eax
  636. lodsw
  637. mov edx, esi
  638. mov esi, image_out
  639. add esi, eax
  640. copy_from_destination:
  641. rep movsb
  642. mov esi, edx
  643. jmp next0
  644. copy_from_source:
  645. rep movsb
  646. jmp next0
  647. end0:
  648. sub edi, image_out
  649. mov cb_out, edi
  650. pop edi
  651. pop esi
  652. }
  653. return cb_out;
  654. }
  655. int decode80r(const byte image_in[], byte image_out[])
  656. {
  657. int cb_out;
  658. /*
  659. 0 copy 0cccpppp p
  660. 1 copy 10cccccc
  661. 2 copy 11cccccc p p
  662. 3 fill 11111110 c c v
  663. 4 copy 11111111 c c p p
  664. */
  665. _asm
  666. {
  667. push esi
  668. push edi
  669. mov ax, ds
  670. mov es, ax
  671. mov esi, image_in
  672. mov edi, image_out
  673. next0:
  674. xor eax, eax
  675. lodsb
  676. mov ecx, eax
  677. test eax, 0x80
  678. jnz c1c
  679. shr ecx, 4
  680. add ecx, 3
  681. and eax, 0xf
  682. shl eax, 8
  683. lodsb
  684. mov edx, esi
  685. mov esi, edi
  686. sub esi, eax
  687. jmp copy_from_destination
  688. c1c:
  689. and ecx, 0x3f
  690. test eax, 0x40
  691. jnz c2c
  692. or ecx, ecx
  693. jz end0
  694. jmp copy_from_source
  695. c2c:
  696. xor eax, eax
  697. lodsw
  698. cmp ecx, 0x3e
  699. je c3
  700. ja c4
  701. mov edx, esi
  702. mov esi, edi
  703. sub esi, eax
  704. add ecx, 3
  705. jmp copy_from_destination
  706. c3:
  707. mov ecx, eax
  708. lodsb
  709. rep stosb
  710. jmp next0
  711. c4:
  712. mov ecx, eax
  713. lodsw
  714. mov edx, esi
  715. mov esi, edi
  716. sub esi, eax
  717. copy_from_destination:
  718. rep movsb
  719. mov esi, edx
  720. jmp next0
  721. copy_from_source:
  722. rep movsb
  723. jmp next0
  724. end0:
  725. sub edi, image_out
  726. mov cb_out, edi
  727. pop edi
  728. pop esi
  729. }
  730. return cb_out;
  731. }
  732. int decode2(const byte* s, byte* d, int cb_s, const byte* reference_palet)
  733. {
  734. const byte* r = s;
  735. const byte* r_end = s + cb_s;
  736. byte* w = d;
  737. while (r < r_end)
  738. {
  739. int v = *r++;
  740. if (v)
  741. *w++ = v;
  742. else
  743. {
  744. v = *r++;
  745. memset(w, 0, v);
  746. w += v;
  747. }
  748. }
  749. if (reference_palet)
  750. apply_rp(d, w - d, reference_palet);
  751. return w - d;
  752. }
  753. int decode3(const byte* s, byte* d, int cx, int cy)
  754. {
  755. const byte* r = s;
  756. byte* w = d;
  757. for (int y = 0; y < cy; y++)
  758. {
  759. int count = *reinterpret_cast<const unsigned __int16*>(r) - 2;
  760. r += 2;
  761. int x = 0;
  762. while (count--)
  763. {
  764. int v = *r++;
  765. if (v)
  766. {
  767. x++;
  768. *w++ = v;
  769. }
  770. else
  771. {
  772. count--;
  773. v = *r++;
  774. if (x + v > cx)
  775. v = cx - x;
  776. x += v;
  777. while (v--)
  778. *w++ = 0;
  779. }
  780. }
  781. }
  782. return w - d;
  783. }
  784. int encode3(const byte* s, byte* d, int cx, int cy)
  785. {
  786. const byte* r = s;
  787. byte* w = d;
  788. for (int y = 0; y < cy; y++)
  789. {
  790. const byte* r_end = r + cx;
  791. byte* w_line = w;
  792. w += 2;
  793. while (r < r_end)
  794. {
  795. int v = *r;
  796. *w++ = v;
  797. if (v)
  798. r++;
  799. else
  800. {
  801. int c = get_run_length(r, r_end);
  802. if (c > 0xff)
  803. c = 0xff;
  804. r += c;
  805. *w++ = c;
  806. }
  807. }
  808. *reinterpret_cast<unsigned __int16*>(w_line) = w - w_line;
  809. }
  810. return w - d;
  811. }
  812. Cvirtual_binary encode64(data_ref s)
  813. {
  814. Cvirtual_binary d;
  815. const byte* r = s.data();
  816. int cb_s = s.size();
  817. byte* w = d.write_start(s.size() << 1);
  818. while (cb_s)
  819. {
  820. int c1 = *r++;
  821. *w++ = encode64_table[c1>>2];
  822. int c2 = --cb_s == 0 ? 0 : *r++;
  823. *w++ = encode64_table[((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4)];
  824. if (cb_s == 0)
  825. {
  826. *w++ = '=';
  827. *w++ = '=';
  828. break;
  829. }
  830. int c3 = --cb_s == 0 ? 0 : *r++;
  831. *w++ = encode64_table[((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6)];
  832. if (cb_s == 0)
  833. {
  834. *w++ = '=';
  835. break;
  836. }
  837. --cb_s;
  838. *w++ = encode64_table[c3 & 0x3f];
  839. }
  840. d.set_size(w - d.data());
  841. return d;
  842. }
  843. Cvirtual_binary decode64(data_ref s)
  844. {
  845. Cvirtual_binary d;
  846. const byte* r = s.data();
  847. byte* w = d.write_start(s.size() << 1);
  848. while (*r)
  849. {
  850. int c1 = *r++;
  851. if (decode64_table[c1] == -1)
  852. return Cvirtual_binary();
  853. int c2 = *r++;
  854. if (decode64_table[c2] == -1)
  855. return Cvirtual_binary();
  856. int c3 = *r++;
  857. if (c3 != '=' && decode64_table[c3] == -1)
  858. return Cvirtual_binary();
  859. int c4 = *r++;
  860. if (c4 != '=' && decode64_table[c4] == -1)
  861. return Cvirtual_binary();
  862. *w++ = (decode64_table[c1] << 2) | (decode64_table[c2] >> 4);
  863. if (c3 == '=')
  864. break;
  865. *w++ = ((decode64_table[c2] << 4) & 0xf0) | (decode64_table[c3] >> 2);
  866. if (c4 == '=')
  867. break;
  868. *w++ = ((decode64_table[c3] << 6) & 0xc0) | decode64_table[c4];
  869. }
  870. d.set_size(w - d.data());
  871. return d;
  872. }
  873. static void write5_count(byte*& w, int count)
  874. {
  875. while (count > 255)
  876. {
  877. *w++ = 0;
  878. count -= 255;
  879. }
  880. *w++ = count;
  881. }
  882. static void write5_c0(byte*& w, int count, const byte* r, byte* small_copy)
  883. {
  884. if (count < 4 && !small_copy)
  885. count = count;
  886. if ((count < 4 || count > 7) && small_copy)
  887. {
  888. int small_count = min(count, 3);
  889. *small_copy |= small_count;
  890. memcpy(w, r, small_count);
  891. r += small_count;
  892. w += small_count;
  893. count -= small_count;
  894. }
  895. if (count)
  896. {
  897. assert(count > 3);
  898. if (count > 18)
  899. {
  900. *w++ = 0;
  901. write5_count(w, count - 18);
  902. }
  903. else
  904. *w++ = count - 3;
  905. memcpy(w, r, count);
  906. w += count;
  907. }
  908. }
  909. static void write5_c1(byte*& w, int count, int p)
  910. {
  911. assert(count > 2);
  912. assert(p >= 0);
  913. assert(p < 32768);
  914. count -= 2;
  915. if (count > 7)
  916. {
  917. *w++ = 0x10 | (p >> 11) & 8;
  918. write5_count(w, count - 7);
  919. }
  920. else
  921. *w++ = 0x10 | (p >> 11) & 8 | count;
  922. write_w((p << 2) & 0xfffc, w);
  923. }
  924. static void write5_c2(byte*& w, int count, int p)
  925. {
  926. assert(count > 2);
  927. assert(p > 0);
  928. assert(p <= 16384);
  929. count -= 2;
  930. p--;
  931. if (count > 31)
  932. {
  933. *w++ = 0x20;
  934. write5_count(w, count - 31);
  935. }
  936. else
  937. *w++ = 0x20 | count;
  938. write_w(p << 2, w);
  939. }
  940. static void write5_c3(byte*& w, int count, int p)
  941. {
  942. assert(count > 1);
  943. assert(count < 7);
  944. assert(p > 0);
  945. assert(p <= 2048);
  946. count -= 2;
  947. p--;
  948. *w++ = (count + 1) << 5 | (p & 7) << 2;
  949. *w++ = p >> 3;
  950. }
  951. int get_count(const byte*& r)
  952. {
  953. int count = -255;
  954. int v;
  955. do
  956. {
  957. count += 255;
  958. v = *r++;
  959. }
  960. while (!v);
  961. return count + v;
  962. }
  963. static void flush_c0(byte*& w, const byte* r, const byte*& copy_from, byte* small_copy, bool start)
  964. {
  965. if (copy_from)
  966. {
  967. int count = r - copy_from;
  968. /*
  969. if (start)
  970. {
  971. int small_count = count;
  972. if (count > 241)
  973. small_count = 238;
  974. else if (count > 238)
  975. small_count = count - 4;
  976. *w++ = small_count + 17;
  977. memcpy(w, copy_from, small_count);
  978. copy_from += small_count;
  979. w += small_count;
  980. count -= small_count;
  981. }
  982. */
  983. if (count)
  984. write5_c0(w, count, copy_from, small_copy);
  985. copy_from = NULL;
  986. }
  987. }
  988. int encode5s(const byte* s, byte* d, int cb_s)
  989. {
  990. lzo_init();
  991. static Cvirtual_binary t;
  992. lzo_uint cb_d;
  993. if (LZO_E_OK != lzo1x_1_compress(s, cb_s, d, &cb_d, t.write_start(LZO1X_1_MEM_COMPRESS)))
  994. cb_d = 0;
  995. return cb_d;
  996. }
  997. int encode5s_z(const byte* s, byte* d, int cb_s)
  998. {
  999. // no compression
  1000. const byte* r = s;
  1001. const byte* r_end = s + cb_s;
  1002. byte* w = d;
  1003. write5_c0(w, cb_s, r, NULL);
  1004. r += cb_s;
  1005. write5_c1(w, 3, 0);
  1006. assert(cb_s == r - s);
  1007. return w - d;
  1008. }
  1009. int decode5s(const byte* s, byte* d, int cb_s)
  1010. {
  1011. lzo_init();
  1012. lzo_uint cb_d;
  1013. if (LZO_E_OK != lzo1x_decompress(s, cb_s, d, &cb_d, NULL))
  1014. return 0;
  1015. return cb_d;
  1016. /*
  1017. 0 copy 0000cccc
  1018. 1 copy 0001pccc ppppppzz p
  1019. 2 copy 001ccccc ppppppzz p
  1020. 3 copy cccpppzz p
  1021. */
  1022. const byte* c;
  1023. const byte* r = s;
  1024. byte* w = d;
  1025. int code;
  1026. int count;
  1027. code = *r;
  1028. if (code > 17)
  1029. {
  1030. r++;
  1031. count = code - 17;
  1032. while (count--)
  1033. *w++ = *r++;
  1034. }
  1035. while (1)
  1036. {
  1037. code = *r++;
  1038. if (code & 0xf0)
  1039. {
  1040. if (code & 0xc0)
  1041. {
  1042. count = (code >> 5) - 1;
  1043. c = w - (code >> 2 & 7);
  1044. c -= *r++ << 3;
  1045. c--;
  1046. }
  1047. else if (code & 0x20)
  1048. {
  1049. count = code & 0x1f;
  1050. if (!count)
  1051. count = get_count(r) + 31;
  1052. c = w - (read_w(r) >> 2);
  1053. c--;
  1054. }
  1055. else
  1056. {
  1057. c = w - ((code & 8) << 11);
  1058. count = code & 7;
  1059. if (!count)
  1060. count = get_count(r) + 7;
  1061. c -= read_w(r) >> 2;
  1062. if (c == w)
  1063. break;
  1064. }
  1065. count += 2;
  1066. while (count--)
  1067. {
  1068. if (*w != *c)
  1069. *w = *c;
  1070. w++;
  1071. c++;
  1072. }
  1073. count = *(r - 2) & 3;
  1074. while (count--)
  1075. {
  1076. if (*w != *r)
  1077. *w = *r;
  1078. w++;
  1079. r++;
  1080. }
  1081. }
  1082. else
  1083. {
  1084. count = code ? code + 3: get_count(r) + 18;
  1085. while (count--)
  1086. {
  1087. if (*w != *r)
  1088. *w = *r;
  1089. w++;
  1090. r++;
  1091. }
  1092. }
  1093. }
  1094. assert(cb_s == r - s);
  1095. return w - d;
  1096. }
  1097. int encode5(const byte* s, byte* d, int cb_s, int format)
  1098. {
  1099. const byte* r = s;
  1100. const byte* r_end = s + cb_s;
  1101. byte* w = d;
  1102. while (r < r_end)
  1103. {
  1104. int cb_section = min(r_end - r, 8192);
  1105. t_pack_section_header& header = *reinterpret_cast<t_pack_section_header*>(w);
  1106. w += sizeof(t_pack_section_header);
  1107. w += header.size_in = format == 80 ? encode80(r, w, cb_section) : encode5s(r, w, cb_section);
  1108. r += header.size_out = cb_section;
  1109. }
  1110. return w - d;
  1111. }
  1112. int decode5(const byte* s, byte* d, int cb_s, int format)
  1113. {
  1114. const byte* r = s;
  1115. const byte* r_end = s + cb_s;
  1116. byte* w = d;
  1117. while (r < r_end)
  1118. {
  1119. const t_pack_section_header& header = *reinterpret_cast<const t_pack_section_header*>(r);
  1120. r += sizeof(t_pack_section_header);
  1121. if (format == 80)
  1122. decode80(r, w);
  1123. else
  1124. decode5s(r, w, header.size_in);
  1125. r += header.size_in;
  1126. w += header.size_out;
  1127. }
  1128. return w - d;
  1129. }