ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

dcl.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/dcl.h"
00024 #include "common/debug.h"
00025 #include "common/memstream.h"
00026 #include "common/stream.h"
00027 #include "common/textconsole.h"
00028 
00029 namespace Common {
00030 
00031 class DecompressorDCL {
00032 public:
00033     bool unpack(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize);
00034 
00035 protected:
00041     void init(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize);
00042 
00049     uint32 getBitsLSB(int n);
00050 
00055     byte getByteLSB();
00056 
00057     void fetchBitsLSB();
00058 
00063     void putByte(byte b);
00064 
00065     int huffman_lookup(const int *tree);
00066 
00067     uint32 _dwBits;         
00068     byte _nBits;            
00069     uint32 _sourceSize;     
00070     uint32 _targetSize;     
00071     bool _targetFixedSize;  
00072     uint32 _bytesRead;      
00073     uint32 _bytesWritten;   
00074     SeekableReadStream *_sourceStream;
00075     WriteStream *_targetStream;
00076 };
00077 
00078 void DecompressorDCL::init(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize) {
00079     _sourceStream = sourceStream;
00080     _targetStream = targetStream;
00081     _sourceSize = sourceStream->size();
00082     _targetSize = targetSize;
00083     _targetFixedSize = targetFixedSize;
00084     _nBits = 0;
00085     _bytesRead = _bytesWritten = 0;
00086     _dwBits = 0;
00087 }
00088 
00089 void DecompressorDCL::fetchBitsLSB() {
00090     while (_nBits <= 24) {
00091         _dwBits |= ((uint32)_sourceStream->readByte()) << _nBits;
00092         _nBits += 8;
00093         _bytesRead++;
00094     }
00095 }
00096 
00097 uint32 DecompressorDCL::getBitsLSB(int n) {
00098     // Fetching more data to buffer if needed
00099     if (_nBits < n)
00100         fetchBitsLSB();
00101     uint32 ret = (_dwBits & ~(~0UL << n));
00102     _dwBits >>= n;
00103     _nBits -= n;
00104     return ret;
00105 }
00106 
00107 byte DecompressorDCL::getByteLSB() {
00108     return getBitsLSB(8);
00109 }
00110 
00111 void DecompressorDCL::putByte(byte b) {
00112     _targetStream->writeByte(b);
00113     _bytesWritten++;
00114 }
00115 
00116 #define HUFFMAN_LEAF 0x40000000
00117 // Branch node
00118 #define BN(pos, left, right)  ((left << 12) | (right)),
00119 // Leaf node
00120 #define LN(pos, value)  ((value) | HUFFMAN_LEAF),
00121 
00122 static const int length_tree[] = {
00123     BN(0, 1, 2)
00124     BN(1, 3, 4)     BN(2, 5, 6)
00125     BN(3, 7, 8)     BN(4, 9, 10)    BN(5, 11, 12)  LN(6, 1)
00126     BN(7, 13, 14)   BN(8, 15, 16)   BN(9, 17, 18)  LN(10, 3)  LN(11, 2)  LN(12, 0)
00127     BN(13, 19, 20)  BN(14, 21, 22)  BN(15, 23, 24) LN(16, 6)  LN(17, 5)  LN(18, 4)
00128     BN(19, 25, 26)  BN(20, 27, 28)  LN(21, 10)     LN(22, 9)  LN(23, 8)  LN(24, 7)
00129     BN(25, 29, 30)  LN(26, 13)      LN(27, 12)     LN(28, 11)
00130     LN(29, 15)      LN(30, 14)
00131     0 // We need something witout a comma at the end
00132 };
00133 
00134 static const int distance_tree[] = {
00135     BN(0, 1, 2)
00136     BN(1, 3, 4)       BN(2, 5, 6)
00137     //
00138     BN(3, 7, 8)       BN(4, 9, 10)      BN(5, 11, 12)     LN(6, 0)
00139     BN(7, 13, 14)     BN(8, 15, 16)     BN(9, 17, 18)     BN(10, 19, 20)
00140     BN(11, 21, 22)    BN(12, 23, 24)
00141     //
00142     BN(13, 25, 26)    BN(14, 27, 28)    BN(15, 29, 30)    BN(16, 31, 32)
00143     BN(17, 33, 34)    BN(18, 35, 36)    BN(19, 37, 38)    BN(20, 39, 40)
00144     BN(21, 41, 42)    BN(22, 43, 44)    LN(23, 2)         LN(24, 1)
00145     //
00146     BN(25, 45, 46)    BN(26, 47, 48)    BN(27, 49, 50)    BN(28, 51, 52)
00147     BN(29, 53, 54)    BN(30, 55, 56)    BN(31, 57, 58)    BN(32, 59, 60)
00148     BN(33, 61, 62)    BN(34, 63, 64)    BN(35, 65, 66)    BN(36, 67, 68)
00149     BN(37, 69, 70)    BN(38, 71, 72)    BN(39, 73, 74)    BN(40, 75, 76)
00150     LN(41, 6)         LN(42, 5)         LN(43, 4)         LN(44, 3)
00151     //
00152     BN(45, 77, 78)    BN(46, 79, 80)    BN(47, 81, 82)    BN(48, 83, 84)
00153     BN(49, 85, 86)    BN(50, 87, 88)    BN(51, 89, 90)    BN(52, 91, 92)
00154     BN(53, 93, 94)    BN(54, 95, 96)    BN(55, 97, 98)    BN(56, 99, 100)
00155     BN(57, 101, 102)  BN(58, 103, 104)  BN(59, 105, 106)  BN(60, 107, 108)
00156     BN(61, 109, 110)  LN(62, 21)        LN(63, 20)        LN(64, 19)
00157     LN(65, 18)        LN(66, 17)        LN(67, 16)        LN(68, 15)
00158     LN(69, 14)        LN(70, 13)        LN(71, 12)        LN(72, 11)
00159     LN(73, 10)        LN(74, 9)         LN(75, 8)         LN(76, 7)
00160     //
00161     BN(77, 111, 112)  BN(78, 113, 114)  BN(79, 115, 116)  BN(80, 117, 118)
00162     BN(81, 119, 120)  BN(82, 121, 122)  BN(83, 123, 124)  BN(84, 125, 126)
00163     LN(85, 47)        LN(86, 46)        LN(87, 45)        LN(88, 44)
00164     LN(89, 43)        LN(90, 42)        LN(91, 41)        LN(92, 40)
00165     LN(93, 39)        LN(94, 38)        LN(95, 37)        LN(96, 36)
00166     LN(97, 35)        LN(98, 34)        LN(99, 33)        LN(100, 32)
00167     LN(101, 31)       LN(102, 30)       LN(103, 29)       LN(104, 28)
00168     LN(105, 27)       LN(106, 26)       LN(107, 25)       LN(108, 24)
00169     LN(109, 23)       LN(110, 22)       LN(111, 63)       LN(112, 62)
00170     LN(113, 61)       LN(114, 60)       LN(115, 59)       LN(116, 58)
00171     LN(117, 57)       LN(118, 56)       LN(119, 55)       LN(120, 54)
00172     LN(121, 53)       LN(122, 52)       LN(123, 51)       LN(124, 50)
00173     LN(125, 49)       LN(126, 48)
00174     0 // We need something witout a comma at the end
00175 };
00176 
00177 static const int ascii_tree[] = {
00178     BN(0, 1, 2)       BN(1, 3, 4)       BN(2, 5, 6)       BN(3, 7, 8)
00179     BN(4, 9, 10)      BN(5, 11, 12)     BN(6, 13, 14)     BN(7, 15, 16)
00180     BN(8, 17, 18)     BN(9, 19, 20)     BN(10, 21, 22)    BN(11, 23, 24)
00181     BN(12, 25, 26)    BN(13, 27, 28)    BN(14, 29, 30)    BN(15, 31, 32)
00182     BN(16, 33, 34)    BN(17, 35, 36)    BN(18, 37, 38)    BN(19, 39, 40)
00183     BN(20, 41, 42)    BN(21, 43, 44)    BN(22, 45, 46)    BN(23, 47, 48)
00184     BN(24, 49, 50)    BN(25, 51, 52)    BN(26, 53, 54)    BN(27, 55, 56)
00185     BN(28, 57, 58)    BN(29, 59, 60)    LN(30, 32)
00186     //
00187     BN(31, 61, 62)    BN(32, 63, 64)    BN(33, 65, 66)    BN(34, 67, 68)
00188     BN(35, 69, 70)    BN(36, 71, 72)    BN(37, 73, 74)    BN(38, 75, 76)
00189     BN(39, 77, 78)    BN(40, 79, 80)    BN(41, 81, 82)    BN(42, 83, 84)
00190     BN(43, 85, 86)    BN(44, 87, 88)    BN(45, 89, 90)    BN(46, 91, 92)
00191     BN(47, 93, 94)    BN(48, 95, 96)    BN(49, 97, 98)    LN(50, 117)
00192     LN(51, 116)       LN(52, 115)       LN(53, 114)       LN(54, 111)
00193     LN(55, 110)       LN(56, 108)       LN(57, 105)       LN(58, 101)
00194     LN(59, 97)        LN(60, 69)
00195     //
00196     BN(61, 99, 100)   BN(62, 101, 102)  BN(63, 103, 104)  BN(64, 105, 106)
00197     BN(65, 107, 108)  BN(66, 109, 110)  BN(67, 111, 112)  BN(68, 113, 114)
00198     BN(69, 115, 116)  BN(70, 117, 118)  BN(71, 119, 120)  BN(72, 121, 122)
00199     BN(73, 123, 124)  BN(74, 125, 126)  BN(75, 127, 128)  BN(76, 129, 130)
00200     BN(77, 131, 132)  BN(78, 133, 134)  LN(79, 112)       LN(80, 109)
00201     LN(81, 104)       LN(82, 103)       LN(83, 102)       LN(84, 100)
00202     LN(85, 99)        LN(86, 98)        LN(87, 84)        LN(88, 83)
00203     LN(89, 82)        LN(90, 79)        LN(91, 78)        LN(92, 76)
00204     LN(93, 73)        LN(94, 68)        LN(95, 67)        LN(96, 65)
00205     LN(97, 49)        LN(98, 45)
00206     //
00207     BN(99, 135, 136)  BN(100, 137, 138) BN(101, 139, 140) BN(102, 141, 142)
00208     BN(103, 143, 144) BN(104, 145, 146) BN(105, 147, 148) BN(106, 149, 150)
00209     BN(107, 151, 152) BN(108, 153, 154) BN(109, 155, 156) BN(110, 157, 158)
00210     BN(111, 159, 160) BN(112, 161, 162) BN(113, 163, 164) LN(114, 119)
00211     LN(115, 107)      LN(116, 85)       LN(117, 80)       LN(118, 77)
00212     LN(119, 70)       LN(120, 66)       LN(121, 61)       LN(122, 56)
00213     LN(123, 55)       LN(124, 53)       LN(125, 52)       LN(126, 51)
00214     LN(127, 50)       LN(128, 48)       LN(129, 46)       LN(130, 44)
00215     LN(131, 41)       LN(132, 40)       LN(133, 13)       LN(134, 10)
00216     //
00217     BN(135, 165, 166) BN(136, 167, 168) BN(137, 169, 170) BN(138, 171, 172)
00218     BN(139, 173, 174) BN(140, 175, 176) BN(141, 177, 178) BN(142, 179, 180)
00219     BN(143, 181, 182) BN(144, 183, 184) BN(145, 185, 186) BN(146, 187, 188)
00220     BN(147, 189, 190) BN(148, 191, 192) LN(149, 121)      LN(150, 120)
00221     LN(151, 118)      LN(152, 95)       LN(153, 91)       LN(154, 87)
00222     LN(155, 72)       LN(156, 71)       LN(157, 58)       LN(158, 57)
00223     LN(159, 54)       LN(160, 47)       LN(161, 42)       LN(162, 39)
00224     LN(163, 34)       LN(164, 9)
00225     //
00226     BN(165, 193, 194) BN(166, 195, 196) BN(167, 197, 198) BN(168, 199, 200)
00227     BN(169, 201, 202) BN(170, 203, 204) BN(171, 205, 206) BN(172, 207, 208)
00228     BN(173, 209, 210) BN(174, 211, 212) BN(175, 213, 214) BN(176, 215, 216)
00229     BN(177, 217, 218) BN(178, 219, 220) BN(179, 221, 222) BN(180, 223, 224)
00230     BN(181, 225, 226) BN(182, 227, 228) BN(183, 229, 230) BN(184, 231, 232)
00231     BN(185, 233, 234) LN(186, 93)       LN(187, 89)       LN(188, 88)
00232     LN(189, 86)       LN(190, 75)       LN(191, 62)       LN(192, 43)
00233     //
00234     BN(193, 235, 236) BN(194, 237, 238) BN(195, 239, 240) BN(196, 241, 242)
00235     BN(197, 243, 244) BN(198, 245, 246) BN(199, 247, 248) BN(200, 249, 250)
00236     BN(201, 251, 252) BN(202, 253, 254) BN(203, 255, 256) BN(204, 257, 258)
00237     BN(205, 259, 260) BN(206, 261, 262) BN(207, 263, 264) BN(208, 265, 266)
00238     BN(209, 267, 268) BN(210, 269, 270) BN(211, 271, 272) BN(212, 273, 274)
00239     BN(213, 275, 276) BN(214, 277, 278) BN(215, 279, 280) BN(216, 281, 282)
00240     BN(217, 283, 284) BN(218, 285, 286) BN(219, 287, 288) BN(220, 289, 290)
00241     BN(221, 291, 292) BN(222, 293, 294) BN(223, 295, 296) BN(224, 297, 298)
00242     BN(225, 299, 300) BN(226, 301, 302) BN(227, 303, 304) BN(228, 305, 306)
00243     BN(229, 307, 308) LN(230, 122)      LN(231, 113)      LN(232, 38)
00244     LN(233, 36)       LN(234, 33)
00245     //
00246     BN(235, 309, 310) BN(236, 311, 312) BN(237, 313, 314) BN(238, 315, 316)
00247     BN(239, 317, 318) BN(240, 319, 320) BN(241, 321, 322) BN(242, 323, 324)
00248     BN(243, 325, 326) BN(244, 327, 328) BN(245, 329, 330) BN(246, 331, 332)
00249     BN(247, 333, 334) BN(248, 335, 336) BN(249, 337, 338) BN(250, 339, 340)
00250     BN(251, 341, 342) BN(252, 343, 344) BN(253, 345, 346) BN(254, 347, 348)
00251     BN(255, 349, 350) BN(256, 351, 352) BN(257, 353, 354) BN(258, 355, 356)
00252     BN(259, 357, 358) BN(260, 359, 360) BN(261, 361, 362) BN(262, 363, 364)
00253     BN(263, 365, 366) BN(264, 367, 368) BN(265, 369, 370) BN(266, 371, 372)
00254     BN(267, 373, 374) BN(268, 375, 376) BN(269, 377, 378) BN(270, 379, 380)
00255     BN(271, 381, 382) BN(272, 383, 384) BN(273, 385, 386) BN(274, 387, 388)
00256     BN(275, 389, 390) BN(276, 391, 392) BN(277, 393, 394) BN(278, 395, 396)
00257     BN(279, 397, 398) BN(280, 399, 400) BN(281, 401, 402) BN(282, 403, 404)
00258     BN(283, 405, 406) BN(284, 407, 408) BN(285, 409, 410) BN(286, 411, 412)
00259     BN(287, 413, 414) BN(288, 415, 416) BN(289, 417, 418) BN(290, 419, 420)
00260     BN(291, 421, 422) BN(292, 423, 424) BN(293, 425, 426) BN(294, 427, 428)
00261     BN(295, 429, 430) BN(296, 431, 432) BN(297, 433, 434) BN(298, 435, 436)
00262     LN(299, 124)      LN(300, 123)      LN(301, 106)      LN(302, 92)
00263     LN(303, 90)       LN(304, 81)       LN(305, 74)       LN(306, 63)
00264     LN(307, 60)       LN(308, 0)
00265     //
00266     BN(309, 437, 438) BN(310, 439, 440) BN(311, 441, 442) BN(312, 443, 444)
00267     BN(313, 445, 446) BN(314, 447, 448) BN(315, 449, 450) BN(316, 451, 452)
00268     BN(317, 453, 454) BN(318, 455, 456) BN(319, 457, 458) BN(320, 459, 460)
00269     BN(321, 461, 462) BN(322, 463, 464) BN(323, 465, 466) BN(324, 467, 468)
00270     BN(325, 469, 470) BN(326, 471, 472) BN(327, 473, 474) BN(328, 475, 476)
00271     BN(329, 477, 478) BN(330, 479, 480) BN(331, 481, 482) BN(332, 483, 484)
00272     BN(333, 485, 486) BN(334, 487, 488) BN(335, 489, 490) BN(336, 491, 492)
00273     BN(337, 493, 494) BN(338, 495, 496) BN(339, 497, 498) BN(340, 499, 500)
00274     BN(341, 501, 502) BN(342, 503, 504) BN(343, 505, 506) BN(344, 507, 508)
00275     BN(345, 509, 510) LN(346, 244)      LN(347, 243)      LN(348, 242)
00276     LN(349, 238)      LN(350, 233)      LN(351, 229)      LN(352, 225)
00277     LN(353, 223)      LN(354, 222)      LN(355, 221)      LN(356, 220)
00278     LN(357, 219)      LN(358, 218)      LN(359, 217)      LN(360, 216)
00279     LN(361, 215)      LN(362, 214)      LN(363, 213)      LN(364, 212)
00280     LN(365, 211)      LN(366, 210)      LN(367, 209)      LN(368, 208)
00281     LN(369, 207)      LN(370, 206)      LN(371, 205)      LN(372, 204)
00282     LN(373, 203)      LN(374, 202)      LN(375, 201)      LN(376, 200)
00283     LN(377, 199)      LN(378, 198)      LN(379, 197)      LN(380, 196)
00284     LN(381, 195)      LN(382, 194)      LN(383, 193)      LN(384, 192)
00285     LN(385, 191)      LN(386, 190)      LN(387, 189)      LN(388, 188)
00286     LN(389, 187)      LN(390, 186)      LN(391, 185)      LN(392, 184)
00287     LN(393, 183)      LN(394, 182)      LN(395, 181)      LN(396, 180)
00288     LN(397, 179)      LN(398, 178)      LN(399, 177)      LN(400, 176)
00289     LN(401, 127)      LN(402, 126)      LN(403, 125)      LN(404, 96)
00290     LN(405, 94)       LN(406, 64)       LN(407, 59)       LN(408, 37)
00291     LN(409, 35)       LN(410, 31)       LN(411, 30)       LN(412, 29)
00292     LN(413, 28)       LN(414, 27)       LN(415, 25)       LN(416, 24)
00293     LN(417, 23)       LN(418, 22)       LN(419, 21)       LN(420, 20)
00294     LN(421, 19)       LN(422, 18)       LN(423, 17)       LN(424, 16)
00295     LN(425, 15)       LN(426, 14)       LN(427, 12)       LN(428, 11)
00296     LN(429, 8)        LN(430, 7)        LN(431, 6)        LN(432, 5)
00297     LN(433, 4)        LN(434, 3)        LN(435, 2)        LN(436, 1)
00298     LN(437, 255)      LN(438, 254)      LN(439, 253)      LN(440, 252)
00299     LN(441, 251)      LN(442, 250)      LN(443, 249)      LN(444, 248)
00300     LN(445, 247)      LN(446, 246)      LN(447, 245)      LN(448, 241)
00301     LN(449, 240)      LN(450, 239)      LN(451, 237)      LN(452, 236)
00302     LN(453, 235)      LN(454, 234)      LN(455, 232)      LN(456, 231)
00303     LN(457, 230)      LN(458, 228)      LN(459, 227)      LN(460, 226)
00304     LN(461, 224)      LN(462, 175)      LN(463, 174)      LN(464, 173)
00305     LN(465, 172)      LN(466, 171)      LN(467, 170)      LN(468, 169)
00306     LN(469, 168)      LN(470, 167)      LN(471, 166)      LN(472, 165)
00307     LN(473, 164)      LN(474, 163)      LN(475, 162)      LN(476, 161)
00308     LN(477, 160)      LN(478, 159)      LN(479, 158)      LN(480, 157)
00309     LN(481, 156)      LN(482, 155)      LN(483, 154)      LN(484, 153)
00310     LN(485, 152)      LN(486, 151)      LN(487, 150)      LN(488, 149)
00311     LN(489, 148)      LN(490, 147)      LN(491, 146)      LN(492, 145)
00312     LN(493, 144)      LN(494, 143)      LN(495, 142)      LN(496, 141)
00313     LN(497, 140)      LN(498, 139)      LN(499, 138)      LN(500, 137)
00314     LN(501, 136)      LN(502, 135)      LN(503, 134)      LN(504, 133)
00315     LN(505, 132)      LN(506, 131)      LN(507, 130)      LN(508, 129)
00316     LN(509, 128)      LN(510, 26)
00317 };
00318 
00319 int DecompressorDCL::huffman_lookup(const int *tree) {
00320     int pos = 0;
00321 
00322     while (!(tree[pos] & HUFFMAN_LEAF)) {
00323         int bit = getBitsLSB(1);
00324         debug(8, "[%d]:%d->", pos, bit);
00325         pos = bit ? tree[pos] & 0xFFF : tree[pos] >> 12;
00326     }
00327 
00328     debug(8, "=%02x\n", tree[pos] & 0xffff);
00329     return tree[pos] & 0xFFFF;
00330 }
00331 
00332 #define DCL_BINARY_MODE 0
00333 #define DCL_ASCII_MODE 1
00334 
00335 #define MIDI_SETUP_BUNDLE_FILE_MAXIMUM_DICTIONARY_SIZE 4096
00336 
00337 bool DecompressorDCL::unpack(SeekableReadStream *sourceStream, WriteStream *targetStream, uint32 targetSize, bool targetFixedSize) {
00338     byte   dictionary[MIDI_SETUP_BUNDLE_FILE_MAXIMUM_DICTIONARY_SIZE];
00339     uint16 dictionaryPos = 0;
00340     uint16 dictionarySize = 0;
00341     uint16 dictionaryMask = 0;
00342     int value;
00343     uint16 tokenOffset = 0;
00344     uint16 tokenLength = 0;
00345 
00346     init(sourceStream, targetStream, targetSize, targetFixedSize);
00347 
00348     byte mode = getByteLSB();
00349     byte dictionaryType = getByteLSB();
00350 
00351     if (mode != DCL_BINARY_MODE && mode != DCL_ASCII_MODE) {
00352         warning("DCL-INFLATE: Error: Encountered mode %02x, expected 00 or 01", mode);
00353         return false;
00354     }
00355 
00356     // TODO: original code supported 3 as well???
00357     // Was this an accident or on purpose? And the original code did just give out a warning
00358     // and didn't error out at all
00359     switch (dictionaryType) {
00360     case 4:
00361         dictionarySize = 1024;
00362         break;
00363     case 5:
00364         dictionarySize = 2048;
00365         break;
00366     case 6:
00367         dictionarySize = 4096;
00368         break;
00369     default:
00370         warning("DCL-INFLATE: Error: unsupported dictionary type %02x", dictionaryType);
00371         return false;
00372     }
00373     dictionaryMask = dictionarySize - 1;
00374 
00375     while ((!targetFixedSize) || (_bytesWritten < _targetSize)) {
00376         if (getBitsLSB(1)) { // (length,distance) pair
00377             value = huffman_lookup(length_tree);
00378 
00379             if (value < 8)
00380                 tokenLength = value + 2;
00381             else
00382                 tokenLength = 8 + (1 << (value - 7)) + getBitsLSB(value - 7);
00383 
00384             if (tokenLength == 519)
00385                 break; // End of stream signal
00386 
00387             debug(8, " | ");
00388 
00389             value = huffman_lookup(distance_tree);
00390 
00391             if (tokenLength == 2)
00392                 tokenOffset = (value << 2) | getBitsLSB(2);
00393             else
00394                 tokenOffset = (value << dictionaryType) | getBitsLSB(dictionaryType);
00395             tokenOffset++;
00396 
00397             debug(8, "\nCOPY(%d from %d)\n", tokenLength, tokenOffset);
00398 
00399             if (_targetFixedSize) {
00400                 if (tokenLength + _bytesWritten > _targetSize) {
00401                     warning("DCL-INFLATE Error: Write out of bounds while copying %d bytes (declared unpacked size is %d bytes, current is %d + %d bytes)",
00402                             tokenLength, _targetSize, _bytesWritten, tokenLength);
00403                     return false;
00404                 }
00405             }
00406 
00407             if (_bytesWritten < tokenOffset) {
00408                 warning("DCL-INFLATE Error: Attempt to copy from before beginning of input stream (declared unpacked size is %d bytes, current is %d bytes)",
00409                         _targetSize, _bytesWritten);
00410                 return false;
00411             }
00412 
00413             uint16 dictionaryBaseIndex = (dictionaryPos - tokenOffset) & dictionaryMask;
00414             uint16 dictionaryIndex = dictionaryBaseIndex;
00415             uint16 dictionaryNextIndex = dictionaryPos;
00416 
00417             while (tokenLength) {
00418                 // Write byte from dictionary
00419                 putByte(dictionary[dictionaryIndex]);
00420                 debug(9, "\33[32;31m%02x\33[37;37m ", dictionary[dictionaryIndex]);
00421 
00422                 dictionary[dictionaryNextIndex] = dictionary[dictionaryIndex];
00423 
00424                 dictionaryNextIndex = (dictionaryNextIndex + 1) & dictionaryMask;
00425                 dictionaryIndex = (dictionaryIndex + 1) & dictionaryMask;
00426 
00427                 if (dictionaryIndex == dictionaryPos)
00428                     dictionaryIndex = dictionaryBaseIndex;
00429                 if (dictionaryNextIndex == dictionarySize)
00430                     dictionaryNextIndex = 0;
00431 
00432                 tokenLength--;
00433             }
00434             dictionaryPos = dictionaryNextIndex;
00435             debug(9, "\n");
00436 
00437         } else { // Copy byte verbatim
00438             value = (mode == DCL_ASCII_MODE) ? huffman_lookup(ascii_tree) : getByteLSB();
00439             putByte(value);
00440 
00441             // Also remember it inside dictionary
00442             dictionary[dictionaryPos] = value;
00443             dictionaryPos++;
00444             if (dictionaryPos >= dictionarySize)
00445                 dictionaryPos = 0;
00446 
00447             debug(9, "\33[32;31m%02x \33[37;37m", value);
00448         }
00449     }
00450 
00451     if (_targetFixedSize) {
00452         if (_bytesWritten != _targetSize)
00453             warning("DCL-INFLATE Error: Inconsistent bytes written (%d) and target buffer size (%d)", _bytesWritten, _targetSize);
00454         return _bytesWritten == _targetSize;
00455     }
00456     return true; // For targets featuring dynamic size we always succeed
00457 }
00458 
00459 bool decompressDCL(ReadStream *src, byte *dest, uint32 packedSize, uint32 unpackedSize) {
00460     bool success = false;
00461     DecompressorDCL dcl;
00462 
00463     if (!src || !dest)
00464         return false;
00465 
00466     byte *sourceBufferPtr = (byte *)malloc(packedSize);
00467     if (!sourceBufferPtr)
00468         return false;
00469 
00470     // Read source into memory
00471     src->read(sourceBufferPtr, packedSize);
00472 
00473     Common::MemoryReadStream  *sourceStream = new MemoryReadStream(sourceBufferPtr, packedSize, DisposeAfterUse::YES);
00474     Common::MemoryWriteStream *targetStream = new MemoryWriteStream(dest, unpackedSize);
00475 
00476     success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
00477     delete sourceStream;
00478     delete targetStream;
00479     return success;
00480 }
00481 
00482 SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream, uint32 packedSize, uint32 unpackedSize) {
00483     bool success = false;
00484     byte *targetPtr = nullptr;
00485     Common::MemoryWriteStream *targetStream;
00486     DecompressorDCL dcl;
00487 
00488     targetPtr = (byte *)malloc(unpackedSize);
00489     if (!targetPtr)
00490         return nullptr;
00491 
00492     targetStream = new MemoryWriteStream(targetPtr, unpackedSize);
00493 
00494     success = dcl.unpack(sourceStream, targetStream, unpackedSize, true);
00495     delete targetStream;
00496 
00497     if (!success) {
00498         free(targetPtr);
00499         return nullptr;
00500     }
00501     return new MemoryReadStream(targetPtr, unpackedSize, DisposeAfterUse::YES);
00502 }
00503 
00504 // This one figures out the unpacked size by itself
00505 // Needed for at least Simon 2, because the unpacked size is not stored anywhere
00506 SeekableReadStream *decompressDCL(SeekableReadStream *sourceStream) {
00507     Common::MemoryWriteStreamDynamic *targetStream;
00508     DecompressorDCL dcl;
00509 
00510     targetStream = new MemoryWriteStreamDynamic(DisposeAfterUse::NO);
00511 
00512     if (dcl.unpack(sourceStream, targetStream, 0, false)) {
00513         byte *targetPtr = targetStream->getData();
00514         uint32 unpackedSize = targetStream->size();
00515         delete targetStream;
00516         return new MemoryReadStream(targetPtr, unpackedSize, DisposeAfterUse::YES);
00517     }
00518     delete targetStream;
00519     return nullptr;
00520 }
00521 
00522 } // End of namespace Common


Generated on Sat Feb 16 2019 05:00:48 for ResidualVM by doxygen 1.7.1
curved edge   curved edge