patch.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Engine Application
  4. //
  5. //////////////////////////////////////////////////////////////////////////////
  6. #include "pch.h"
  7. //////////////////////////////////////////////////////////////////////////////
  8. //
  9. // The main entry point
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12. #include "main.h"
  13. //////////////////////////////////////////////////////////////////////////////
  14. //
  15. //
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. typedef unsigned int uint;
  19. //////////////////////////////////////////////////////////////////////////////
  20. //
  21. //
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. class Span {
  25. public:
  26. BYTE* m_pbyte;
  27. int m_length;
  28. Span(BYTE* pbyte, int length) :
  29. m_pbyte(pbyte),
  30. m_length(length)
  31. {
  32. }
  33. };
  34. class AllocSpan : public Span {
  35. public:
  36. AllocSpan(int length) :
  37. Span(new BYTE[length], length)
  38. {
  39. }
  40. ~AllocSpan()
  41. {
  42. delete m_pbyte;
  43. }
  44. };
  45. //////////////////////////////////////////////////////////////////////////////
  46. //
  47. //
  48. //
  49. //////////////////////////////////////////////////////////////////////////////
  50. class Stream : public IObject {
  51. public:
  52. virtual void Write(const void* p, uint length) = 0;
  53. template<class Type>
  54. void Write(const Type& value)
  55. {
  56. Write(&value, sizeof(Type));
  57. }
  58. template<class Type>
  59. void WriteMultiple(const Type& value, uint length)
  60. {
  61. for (uint index = 0; index < length; index++) {
  62. Write(value);
  63. }
  64. }
  65. };
  66. //////////////////////////////////////////////////////////////////////////////
  67. //
  68. //
  69. //
  70. //////////////////////////////////////////////////////////////////////////////
  71. class MemoryStream : public Stream {
  72. private:
  73. TVector<BYTE> m_vb;
  74. public:
  75. MemoryStream()
  76. {
  77. }
  78. void Write(const void* p, uint length)
  79. {
  80. int count = m_vb.GetCount();
  81. m_vb.SetCount(count + length);
  82. memcpy(&(m_vb.Get(count)), p, length);
  83. }
  84. template<class Type>
  85. void Write(const Type& value)
  86. {
  87. Write(&value, sizeof(Type));
  88. }
  89. Span GetSpan()
  90. {
  91. return Span((BYTE*)&(m_vb[0]), m_vb.GetCount());
  92. }
  93. };
  94. //////////////////////////////////////////////////////////////////////////////
  95. //
  96. //
  97. //
  98. //////////////////////////////////////////////////////////////////////////////
  99. template<class Type>
  100. void Extract(BYTE*& pbyte, Type& value)
  101. {
  102. value = *((Type*)pbyte);
  103. pbyte += sizeof(Type);
  104. }
  105. //////////////////////////////////////////////////////////////////////////////
  106. //
  107. // RLECompessor
  108. //
  109. //////////////////////////////////////////////////////////////////////////////
  110. namespace RLECompressor {
  111. //////////////////////////////////////////////////////////////////////////////
  112. //
  113. //
  114. //
  115. //////////////////////////////////////////////////////////////////////////////
  116. const WORD RLEMask = 0xc000;
  117. const WORD RLEMaskFill = 0x0000;
  118. const WORD RLEMaskBYTE = 0x4000;
  119. const WORD RLEMaskWORD = 0x8000;
  120. const WORD RLEMaskDWORD = 0xc000;
  121. const WORD RLELengthMask = 0x3fff;
  122. //////////////////////////////////////////////////////////////////////////////
  123. //
  124. //
  125. //
  126. //////////////////////////////////////////////////////////////////////////////
  127. template<class Type>
  128. void DoStoreSpan(Type** ppd, Stream* pstream, WORD code, WORD count)
  129. {
  130. pstream->Write(WORD(code | count));
  131. pstream->Write((*ppd)[0]);
  132. (*ppd) += count;
  133. }
  134. //////////////////////////////////////////////////////////////////////////////
  135. //
  136. //
  137. //
  138. //////////////////////////////////////////////////////////////////////////////
  139. void DoRawStoreSpan(BYTE* pstart, BYTE*& pd, Stream* pstream)
  140. {
  141. WORD length = pd - pstart;
  142. if (length > 0) {
  143. pstream->Write(WORD(RLEMaskFill | length));
  144. pstream->Write(pstart, length);
  145. }
  146. }
  147. //////////////////////////////////////////////////////////////////////////////
  148. //
  149. //
  150. //
  151. //////////////////////////////////////////////////////////////////////////////
  152. template<class Type>
  153. WORD CouldStoreSpan(Type** ppd, Type* pend)
  154. {
  155. if ((*ppd) + 1 < pend) {
  156. Type value = (*ppd)[0];
  157. WORD count = 0;
  158. while (
  159. ((*ppd) + count + 1 < pend)
  160. && (*ppd)[count] == value
  161. ) {
  162. count++;
  163. }
  164. if (count * sizeof(Type) > 2 + sizeof(Type)) {
  165. return min(count, RLELengthMask);
  166. }
  167. }
  168. return 0;
  169. }
  170. //////////////////////////////////////////////////////////////////////////////
  171. //
  172. //
  173. //
  174. //////////////////////////////////////////////////////////////////////////////
  175. TRef<MemoryStream> Compress(const Span& span)
  176. {
  177. TRef<MemoryStream> pstream = new MemoryStream();
  178. BYTE* pend = span.m_pbyte + span.m_length;
  179. BYTE* pstart = span.m_pbyte;
  180. BYTE* pd = span.m_pbyte;
  181. while (pd < pend) {
  182. WORD count;
  183. if (count = CouldStoreSpan((DWORD**)&pd, (DWORD*)pend)) {
  184. DoRawStoreSpan(pstart, pd, pstream);
  185. DoStoreSpan((DWORD**)&pd, pstream, RLEMaskDWORD, count);
  186. pstart = pd;
  187. } else if (count = CouldStoreSpan((WORD**)&pd, (WORD*)pend)) {
  188. DoRawStoreSpan(pstart, pd, pstream);
  189. DoStoreSpan((WORD**)&pd, pstream, RLEMaskWORD, count);
  190. pstart = pd;
  191. } else if (count = CouldStoreSpan((BYTE**)&pd, (BYTE*)pend)) {
  192. DoRawStoreSpan(pstart, pd, pstream);
  193. DoStoreSpan((BYTE**)&pd, pstream, RLEMaskBYTE, count);
  194. pstart = pd;
  195. }
  196. pd++;
  197. }
  198. DoRawStoreSpan(pstart, pd, pstream);
  199. return pstream;
  200. }
  201. //////////////////////////////////////////////////////////////////////////////
  202. //
  203. //
  204. //
  205. //////////////////////////////////////////////////////////////////////////////
  206. TRef<MemoryStream> Decompress(const Span& span)
  207. {
  208. TRef<MemoryStream> pstream = new MemoryStream();
  209. BYTE* prle = span.m_pbyte;
  210. BYTE* pend = span.m_pbyte + span.m_length;
  211. while (prle < pend) {
  212. WORD word; Extract(prle, word);
  213. int length = word & RLELengthMask;
  214. switch (word & RLEMask) {
  215. case RLEMaskFill:
  216. {
  217. pstream->Write(prle, length);
  218. prle += length;
  219. }
  220. break;
  221. case RLEMaskBYTE:
  222. {
  223. BYTE byte; Extract(prle, byte);
  224. pstream->WriteMultiple(byte, length);
  225. }
  226. break;
  227. case RLEMaskWORD:
  228. {
  229. WORD word; Extract(prle, word);
  230. pstream->WriteMultiple(word, length);
  231. }
  232. break;
  233. case RLEMaskDWORD:
  234. {
  235. DWORD dword; Extract(prle, dword);
  236. pstream->WriteMultiple(dword, length);
  237. }
  238. break;
  239. }
  240. }
  241. return pstream;
  242. }
  243. };
  244. //////////////////////////////////////////////////////////////////////////////
  245. //
  246. // DictionaryCompressor
  247. //
  248. //////////////////////////////////////////////////////////////////////////////
  249. namespace DifferentialCompressor {
  250. #if 1
  251. typedef char LengthType;
  252. #define LengthMax 128
  253. #else
  254. typedef short LengthType;
  255. #define LengthMax 32768
  256. #endif
  257. const int m_lengthLargestMatch = LengthMax - 1;
  258. const int m_lengthLargestNoMatch = LengthMax;
  259. //////////////////////////////////////////////////////////////////////////////
  260. //
  261. //
  262. //
  263. //////////////////////////////////////////////////////////////////////////////
  264. class Dictionary {
  265. //////////////////////////////////////////////////////////////////////////////
  266. //
  267. //
  268. //
  269. //////////////////////////////////////////////////////////////////////////////
  270. AllocSpan m_span;
  271. BYTE* m_pbyteValid;
  272. BYTE** m_ppbyte;
  273. int m_length;
  274. float m_dtime;
  275. int m_maxLength;
  276. //////////////////////////////////////////////////////////////////////////////
  277. //
  278. //
  279. //
  280. //////////////////////////////////////////////////////////////////////////////
  281. public:
  282. Dictionary(
  283. const Span& spanOld,
  284. const Span& spanNew,
  285. int maxLength
  286. ) :
  287. m_span(spanOld.m_length + spanNew.m_length),
  288. m_maxLength(maxLength)
  289. {
  290. Time timeStart = Time::Now();
  291. //
  292. // Make a big dictionary that includes both files
  293. //
  294. memcpy(m_span.m_pbyte, spanOld.m_pbyte, spanOld.m_length);
  295. memcpy(m_span.m_pbyte + spanOld.m_length, spanNew.m_pbyte, spanNew.m_length);
  296. //
  297. // Only allow use of the parts of the dictionary that the decompressor will
  298. // have access to.
  299. //
  300. m_pbyteValid = m_span.m_pbyte + spanOld.m_length;
  301. //
  302. // Make a sorted list of all the substrings.
  303. //
  304. m_ppbyte = new BYTE*[m_span.m_length];
  305. for (int index = 0; index < m_span.m_length; index++) {
  306. m_ppbyte[index] = m_span.m_pbyte + index;
  307. }
  308. printf("Dictionary contains %d strings.\n", m_span.m_length);
  309. m_length = Sort(0, m_span.m_length);
  310. printf("Dictionary contains %d Unique Strings\n", m_length);
  311. m_dtime = Time::Now() - timeStart;
  312. }
  313. ~Dictionary()
  314. {
  315. delete m_ppbyte;
  316. }
  317. //////////////////////////////////////////////////////////////////////////////
  318. //
  319. //
  320. //
  321. //////////////////////////////////////////////////////////////////////////////
  322. float GetDTime()
  323. {
  324. return m_dtime;
  325. }
  326. void IncreaseValidSize(int length)
  327. {
  328. m_pbyteValid += length;
  329. }
  330. int GetIndex(BYTE* pbyte)
  331. {
  332. return pbyte - m_span.m_pbyte;
  333. }
  334. int GetLength(BYTE* pbyte)
  335. {
  336. return (m_span.m_pbyte + m_span.m_length) - pbyte;
  337. }
  338. int GetSortLength(BYTE* pbyte)
  339. {
  340. return min(m_maxLength, (m_span.m_pbyte + m_span.m_length) - pbyte);
  341. }
  342. int GetValidLength(BYTE* pbyte)
  343. {
  344. return max(0, m_pbyteValid - pbyte);
  345. }
  346. //////////////////////////////////////////////////////////////////////////////
  347. //
  348. // 0 strings are the same
  349. // -1 string is less that string2
  350. // 1 string is greater than string2
  351. //
  352. //////////////////////////////////////////////////////////////////////////////
  353. int CompareString(
  354. BYTE* pbyte1,
  355. int length1,
  356. BYTE* pbyte2,
  357. int length2,
  358. int& lengthMatch
  359. ) {
  360. int lengthMax = min(length1, length2);
  361. for (lengthMatch = 0; lengthMatch < lengthMax; lengthMatch++) {
  362. BYTE b1 = pbyte1[lengthMatch];
  363. BYTE b2 = pbyte2[lengthMatch];
  364. if (b1 > b2) {
  365. return 1;
  366. } else if (b1 < b2) {
  367. return -1;
  368. }
  369. }
  370. if (length1 > lengthMax) {
  371. return 1;
  372. } else if (length2 > lengthMax) {
  373. return -1;
  374. }
  375. return 0;
  376. }
  377. //////////////////////////////////////////////////////////////////////////////
  378. //
  379. //
  380. //
  381. //////////////////////////////////////////////////////////////////////////////
  382. int Sort(int min, int max)
  383. {
  384. if (max - min <= 1) {
  385. return max;
  386. }
  387. if (max - min > 10000) {
  388. printf("Sorting %d to %d \r", min, max);
  389. }
  390. int indexMiddle = (min + max) / 2;
  391. BYTE* pbyteMiddle = m_ppbyte[indexMiddle];
  392. int lengthMiddle = GetSortLength(pbyteMiddle);
  393. int left = min;
  394. int right = max - 1;
  395. int leftWrite = left;
  396. int rightWrite = right;
  397. while (left <= right) {
  398. //
  399. // Find the next left entry that needs to be swapped
  400. //
  401. while (left <= right) {
  402. int length;
  403. int result =
  404. CompareString(
  405. m_ppbyte[left],
  406. GetSortLength(m_ppbyte[left]),
  407. pbyteMiddle,
  408. lengthMiddle,
  409. length
  410. );
  411. if (result == 0) {
  412. pbyteMiddle = min(pbyteMiddle, m_ppbyte[left]);
  413. left++;
  414. } else if (result == -1) {
  415. m_ppbyte[leftWrite] = m_ppbyte[left];
  416. leftWrite++;
  417. left++;
  418. } else {
  419. break;
  420. }
  421. }
  422. //
  423. // Find the next right entry that needs to be swapped
  424. //
  425. while (left <= right) {
  426. int length;
  427. int result =
  428. CompareString(
  429. m_ppbyte[right],
  430. GetSortLength(m_ppbyte[right]),
  431. pbyteMiddle,
  432. lengthMiddle,
  433. length
  434. );
  435. if (result == 0) {
  436. pbyteMiddle = min(pbyteMiddle, m_ppbyte[right]);
  437. right--;
  438. } else if (result == 1) {
  439. m_ppbyte[rightWrite] = m_ppbyte[right];
  440. rightWrite--;
  441. right--;
  442. } else {
  443. break;
  444. }
  445. }
  446. //
  447. // Swap them
  448. //
  449. if (left < right) {
  450. BYTE* pbyte = m_ppbyte[left];
  451. m_ppbyte[ leftWrite] = m_ppbyte[right];
  452. m_ppbyte[rightWrite] = pbyte;
  453. leftWrite++;
  454. left++;
  455. rightWrite--;
  456. right--;
  457. }
  458. }
  459. //
  460. // Sort the left
  461. //
  462. int leftMax = Sort(min, leftWrite);
  463. //
  464. // Insert the middle
  465. //
  466. m_ppbyte[leftMax] = pbyteMiddle;
  467. //
  468. // Move the right
  469. //
  470. int rightSize = max - (rightWrite + 1);
  471. for (int index = 0; index < rightSize; index++) {
  472. m_ppbyte[leftMax + 1 + index] = m_ppbyte[rightWrite + 1 + index];
  473. }
  474. //
  475. // Sort the right
  476. //
  477. return Sort(leftMax + 1, leftMax + 1 + rightSize);
  478. }
  479. //////////////////////////////////////////////////////////////////////////////
  480. //
  481. // Find the longest match between the span and the dictionary
  482. //
  483. //////////////////////////////////////////////////////////////////////////////
  484. Span FindLongestMatch(const Span& span)
  485. {
  486. int min = 0;
  487. int max = m_length;
  488. int indexLongest = 0;
  489. int lengthLongest = 0;
  490. while (min <= max) {
  491. int index = (min + max) / 2;
  492. int length;
  493. int result =
  494. CompareString(
  495. span.m_pbyte,
  496. span.m_length,
  497. m_ppbyte[index],
  498. GetLength(m_ppbyte[index]),
  499. length
  500. );
  501. if (length > lengthLongest) {
  502. lengthLongest = length;
  503. indexLongest = index;
  504. }
  505. if (result == 0) {
  506. break;
  507. } else if (result == 1) {
  508. min = index + 1;
  509. } else {
  510. if (index == 0) {
  511. break;
  512. }
  513. max = index - 1;
  514. }
  515. }
  516. //
  517. // Find the longest valid span near the longest span
  518. //
  519. BYTE* pbyteLongest = m_ppbyte[indexLongest];
  520. if (lengthLongest > GetValidLength(pbyteLongest)) {
  521. //
  522. // Shorten the length
  523. //
  524. lengthLongest = GetValidLength(pbyteLongest);
  525. //
  526. // Search forward
  527. //
  528. int index = indexLongest + 1;
  529. while (index < m_length) {
  530. int length;
  531. int result =
  532. CompareString(
  533. span.m_pbyte,
  534. span.m_length,
  535. m_ppbyte[index],
  536. GetValidLength(m_ppbyte[index]),
  537. length
  538. );
  539. if (length == 0) {
  540. break;
  541. }
  542. if (length > lengthLongest) {
  543. pbyteLongest = m_ppbyte[index];
  544. lengthLongest = length;
  545. }
  546. index++;
  547. }
  548. //
  549. // Search backward
  550. //
  551. index = indexLongest - 1;
  552. while (index > 0) {
  553. int length;
  554. int result =
  555. CompareString(
  556. span.m_pbyte,
  557. span.m_length,
  558. m_ppbyte[index],
  559. GetValidLength(m_ppbyte[index]),
  560. length
  561. );
  562. if (length == 0) {
  563. break;
  564. }
  565. if (length > lengthLongest) {
  566. pbyteLongest = m_ppbyte[index];
  567. lengthLongest = length;
  568. }
  569. index--;
  570. }
  571. }
  572. //
  573. // return it
  574. //
  575. return Span(pbyteLongest, lengthLongest);
  576. }
  577. };
  578. //////////////////////////////////////////////////////////////////////////////
  579. //
  580. //
  581. //
  582. //////////////////////////////////////////////////////////////////////////////
  583. int m_indexNew ;
  584. int m_indexNoMatch;
  585. int m_countMatch ;
  586. int m_countNoMatch;
  587. //////////////////////////////////////////////////////////////////////////////
  588. //
  589. // Write out any unmatched bytes
  590. //
  591. //////////////////////////////////////////////////////////////////////////////
  592. static void WriteNoMatch(Stream* pstream, BYTE* pb)
  593. {
  594. while (m_indexNoMatch != m_indexNew) {
  595. int length = min(m_indexNew - m_indexNoMatch, m_lengthLargestNoMatch);
  596. pstream->Write(LengthType(1 - length));
  597. pstream->Write(pb + m_indexNoMatch, length);
  598. m_indexNoMatch += length;
  599. m_countNoMatch += length;
  600. }
  601. }
  602. //////////////////////////////////////////////////////////////////////////////
  603. //
  604. // File format
  605. //
  606. // short length
  607. // if (length > 0) {
  608. // uint index
  609. // } else {
  610. // BYTE data[1 - length]
  611. // }
  612. //
  613. //////////////////////////////////////////////////////////////////////////////
  614. static TRef<MemoryStream> Compress(
  615. const Span& spanOld,
  616. const Span& spanNew
  617. ) {
  618. Dictionary dictionary(spanOld, spanNew, LengthMax - 1);
  619. TRef<MemoryStream> pstream = new MemoryStream();
  620. //
  621. // Write out the length of the resultant file
  622. //
  623. pstream->Write(spanNew.m_length);
  624. //
  625. // Compress it
  626. //
  627. int indexPrint = 0;
  628. m_indexNew = 0;
  629. m_indexNoMatch = 0;
  630. m_countMatch = 0;
  631. m_countNoMatch = 0;
  632. while (m_indexNew < spanNew.m_length) {
  633. if (m_indexNew > indexPrint) {
  634. printf("Compressing %d\r", m_indexNew);
  635. indexPrint = m_indexNew + 10000;
  636. }
  637. Span span =
  638. dictionary.FindLongestMatch(
  639. Span(
  640. spanNew.m_pbyte + m_indexNew,
  641. min(spanNew.m_length - m_indexNew, m_lengthLargestMatch)
  642. )
  643. );
  644. if (span.m_length > 6) {
  645. WriteNoMatch(pstream, spanNew.m_pbyte);
  646. while (span.m_length > 0) {
  647. int length = min(span.m_length, m_lengthLargestMatch);
  648. pstream->Write(LengthType(length));
  649. int index = dictionary.GetIndex(span.m_pbyte);
  650. if (index > 32767) {
  651. pstream->Write(short(0x8000 | (index >> 8)));
  652. pstream->Write(BYTE(index & 0xff));
  653. } else {
  654. pstream->Write(short(index));
  655. }
  656. m_indexNew += length;
  657. m_indexNoMatch += length;
  658. span.m_pbyte += length;
  659. span.m_length -= length;
  660. m_countMatch += length;
  661. dictionary.IncreaseValidSize(length);
  662. }
  663. } else {
  664. m_indexNew += max(1, span.m_length);
  665. dictionary.IncreaseValidSize(1);
  666. }
  667. }
  668. //
  669. // Write out any remaining unmatched bytes
  670. //
  671. WriteNoMatch(pstream, spanNew.m_pbyte);
  672. //
  673. // Perf
  674. //
  675. printf(
  676. "%d bytes matched, %d didn't match\n"
  677. "Building dictionary took %g seconds.\n",
  678. m_countMatch,
  679. m_countNoMatch,
  680. dictionary.GetDTime()
  681. );
  682. return pstream;
  683. }
  684. //////////////////////////////////////////////////////////////////////////////
  685. //
  686. //
  687. //
  688. //////////////////////////////////////////////////////////////////////////////
  689. static TRef<MemoryStream> Decompress(
  690. const Span& spanOld,
  691. const Span& spanCompressed
  692. ) {
  693. TRef<MemoryStream> pstream = new MemoryStream();
  694. BYTE* pbyteCompressed = spanCompressed.m_pbyte;
  695. BYTE* pbyteCompressedEnd = spanCompressed.m_pbyte + spanCompressed.m_length;
  696. uint lengthNew; Extract(pbyteCompressed, lengthNew);
  697. BYTE* pbyteDictionary = new BYTE[spanOld.m_length + lengthNew];
  698. BYTE* pbyteNew = pbyteDictionary + spanOld.m_length;
  699. memcpy(pbyteDictionary, spanOld.m_pbyte, spanOld.m_length);
  700. while (pbyteCompressed < pbyteCompressedEnd) {
  701. LengthType length; Extract(pbyteCompressed, length);
  702. if (length > 0) {
  703. WORD indexTop; Extract(pbyteCompressed, indexTop);
  704. int index;
  705. if (indexTop & 0x8000) {
  706. BYTE indexBottom; Extract(pbyteCompressed, indexBottom);
  707. index = int(((indexTop & 0x7fff) << 8) | indexBottom);
  708. } else {
  709. index = indexTop;
  710. }
  711. memcpy(pbyteNew, pbyteDictionary + index, length);
  712. pbyteNew += length;
  713. } else {
  714. memcpy(pbyteNew, pbyteCompressed, 1 - length);
  715. pbyteCompressed += 1 - length;
  716. pbyteNew += 1 - length;
  717. }
  718. }
  719. ZAssert(pbyteCompressed == pbyteCompressedEnd);
  720. pstream->Write(pbyteDictionary + spanOld.m_length, lengthNew);
  721. delete pbyteDictionary;
  722. return pstream;
  723. }
  724. };
  725. //////////////////////////////////////////////////////////////////////////////
  726. //
  727. // Application
  728. //
  729. //////////////////////////////////////////////////////////////////////////////
  730. class Patch : public Win32App {
  731. public:
  732. //////////////////////////////////////////////////////////////////////////////
  733. //
  734. //
  735. //
  736. //////////////////////////////////////////////////////////////////////////////
  737. Patch()
  738. {
  739. }
  740. //////////////////////////////////////////////////////////////////////////////
  741. //
  742. //
  743. //
  744. //////////////////////////////////////////////////////////////////////////////
  745. TRef<MemoryStream> DoCompress(
  746. const Span& spanOld,
  747. const Span& spanNew
  748. ) {
  749. Time timeStart = Time::Now();
  750. printf("Original sizes, old: %d, new: %d\n", spanOld.m_length, spanNew.m_length);
  751. //
  752. // RLE Compress the two files
  753. //
  754. TRef<MemoryStream> pstreamOld = RLECompressor::Compress(spanOld);
  755. TRef<MemoryStream> pstreamNew = RLECompressor::Compress(spanNew);
  756. const Span& spanOldRLE = pstreamOld->GetSpan();
  757. const Span& spanNewRLE = pstreamNew->GetSpan();
  758. printf("RLE sizes, old: %d, new: %d\n", spanOldRLE.m_length, spanNewRLE.m_length);
  759. Time timeRLE = Time::Now();
  760. //
  761. // Differential compress
  762. //
  763. TRef<MemoryStream> pstreamCompressed =
  764. DifferentialCompressor::Compress(
  765. spanOldRLE,
  766. spanNewRLE
  767. );
  768. //
  769. // Report times
  770. //
  771. printf(
  772. "RLE took: %g seconds.\n"
  773. "Diff took: %g seconds.\n",
  774. timeRLE - timeStart,
  775. Time::Now() - timeRLE
  776. );
  777. //
  778. // return the stream
  779. //
  780. return pstreamCompressed;
  781. }
  782. //////////////////////////////////////////////////////////////////////////////
  783. //
  784. //
  785. //
  786. //////////////////////////////////////////////////////////////////////////////
  787. TRef<MemoryStream> DoDecompress(
  788. const Span& spanOld,
  789. const Span& spanPatch
  790. ) {
  791. TRef<MemoryStream> pstreamUnRLEOld =
  792. RLECompressor::Compress(spanOld);
  793. TRef<MemoryStream> pstreamUndiff =
  794. DifferentialCompressor::Decompress(
  795. pstreamUnRLEOld->GetSpan(),
  796. spanPatch
  797. );
  798. TRef<MemoryStream> pstreamUnRLENew =
  799. RLECompressor::Decompress(pstreamUndiff->GetSpan());
  800. return pstreamUnRLENew;
  801. }
  802. //////////////////////////////////////////////////////////////////////////////
  803. //
  804. //
  805. //
  806. //////////////////////////////////////////////////////////////////////////////
  807. void DoCompress(
  808. const ZString& strOld,
  809. const ZString& strNew,
  810. const ZString& strPatch
  811. ) {
  812. //
  813. // Open all the files
  814. //
  815. TRef<ZFile> pfileOld = new ZFile(strOld);
  816. ZAssert(pfileOld->IsValid());
  817. TRef<ZFile> pfileNew = new ZFile(strNew);
  818. ZAssert(pfileNew->IsValid());
  819. TRef<ZFile> pfilePatch = new ZWriteFile(strPatch);
  820. ZAssert(pfilePatch->IsValid());
  821. //
  822. // Compress
  823. //
  824. //Span spanOld((BYTE*)"abcduhfqeoixkcnmvoadsiufyasdnbxjcvhagd", 20);
  825. //Span spanNew((BYTE*)"cadbasdfasdfuihqweofiunxvoasdijnvaosid", 20);
  826. Span spanOld(pfileOld->GetPointer(), pfileOld->GetLength());
  827. Span spanNew(pfileNew->GetPointer(), pfileNew->GetLength());
  828. TRef<MemoryStream> pstreamCompressed = DoCompress(spanOld, spanNew);
  829. //
  830. // Make sure that decompressing produces the new file.
  831. //
  832. TRef<MemoryStream> pstreamDecompressed =
  833. DoDecompress(
  834. spanOld,
  835. pstreamCompressed->GetSpan()
  836. );
  837. BYTE* pbyte1 = spanNew.m_pbyte;
  838. BYTE* pbyte2 = pstreamDecompressed->GetSpan().m_pbyte;
  839. int length = spanNew.m_length;
  840. ZAssert(length == pstreamDecompressed->GetSpan().m_length);
  841. for(int index = 0; index < length; index++) {
  842. if (pbyte1[index] != pbyte2[index]) {
  843. ZError("Decompressed file doesn't match new file.");
  844. }
  845. }
  846. //
  847. // Write out the file
  848. //
  849. pfilePatch->Write(
  850. pstreamCompressed->GetSpan().m_pbyte,
  851. pstreamCompressed->GetSpan().m_length
  852. );
  853. }
  854. //////////////////////////////////////////////////////////////////////////////
  855. //
  856. //
  857. //
  858. //////////////////////////////////////////////////////////////////////////////
  859. void DoDecompress(
  860. const ZString& strOld,
  861. const ZString& strPatch,
  862. const ZString& strNew
  863. ) {
  864. //
  865. // Open all the files
  866. //
  867. TRef<ZFile> pfileOld = new ZFile(strOld);
  868. TRef<ZFile> pfilePatch = new ZFile(strPatch);
  869. TRef<ZFile> pfileNew = new ZWriteFile(strNew);
  870. //
  871. // Decompress
  872. //
  873. TRef<MemoryStream> pstreamDecompressed =
  874. DoDecompress(
  875. Span(pfileOld->GetPointer(), pfileOld->GetLength()),
  876. Span(pfilePatch->GetPointer(), pfilePatch->GetLength())
  877. );
  878. //
  879. // Write out the file
  880. //
  881. pfileNew->Write(
  882. pstreamDecompressed->GetSpan().m_pbyte,
  883. pstreamDecompressed->GetSpan().m_length
  884. );
  885. }
  886. //////////////////////////////////////////////////////////////////////////////
  887. //
  888. //
  889. //
  890. //////////////////////////////////////////////////////////////////////////////
  891. HRESULT Initialize(const ZString& strCommandLine)
  892. {
  893. PCC pcc = strCommandLine;
  894. CommandLineToken token(pcc, strCommandLine.GetLength());
  895. while (token.MoreTokens()) {
  896. ZString str;
  897. ZString strOld;
  898. ZString strNew;
  899. ZString strPatch;
  900. if (token.IsMinus(str)) {
  901. if (str == "compress") {
  902. if (token.IsString(strOld)) {
  903. if (token.IsString(strNew)) {
  904. if (token.IsString(strPatch)) {
  905. DoCompress(strOld, strNew, strPatch);
  906. return S_FALSE;
  907. }
  908. }
  909. }
  910. }
  911. } else if (token.IsString(strOld)) {
  912. if (token.IsString(strPatch)) {
  913. if (token.IsString(strNew)) {
  914. DoDecompress(strOld, strPatch, strNew);
  915. return S_FALSE;
  916. }
  917. }
  918. }
  919. break;
  920. }
  921. printf(
  922. "Usage: patch -compress oldfile newfile patchfile\n"
  923. " or patch oldfile patchfile newfile\n"
  924. );
  925. return S_FALSE;
  926. }
  927. } g_app;