PageRenderTime 120ms CodeModel.GetById 10ms app.highlight 101ms RepoModel.GetById 1ms app.codeStats 0ms

/decoders/binary/deflate.d

http://github.com/wilkie/djehuty
D | 1817 lines | 890 code | 559 blank | 368 comment | 168 complexity | be746531b156c3088c297e287bc67f3f MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * deflate.d
   3 *
   4 * This file implements the DEFLATE compression algorithm.
   5 *
   6 * Author: Dave Wilkinson
   7 *
   8 */
   9
  10module decoders.binary.deflate;
  11
  12import core.endian;
  13import core.stream;
  14import core.definitions;
  15
  16import decoders.binary.decoder;
  17
  18private {
  19
  20	const auto DEFLATE_STATE_INIT							= 0;
  21
  22	const auto DEFLATE_STATE_READ_BYTE						= 1;
  23
  24	const auto DEFLATE_STATE_READ_BITS						= 2;
  25	const auto DEFLATE_STATE_READ_BIT						= 3;
  26
  27	const auto DEFLATE_STATE_READ_BITS_REV					= 4;
  28	const auto DEFLATE_STATE_READ_BIT_REV					= 5;
  29
  30	const auto DEFLATE_STATE_READ_BFINAL					= 6;
  31	const auto DEFLATE_STATE_READ_BTYPE						= 7;
  32
  33	const auto DEFLATE_STATE_DEFLATE_NO_COMPRESSION			= 8;
  34	const auto DEFLATE_STATE_DEFLATE_NO_COMPRESSION_SKIP	= 9;
  35	const auto DEFLATE_STATE_DEFLATE_NO_COMPRESSION_COPY	= 10;
  36
  37	const auto DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE		= 12;
  38	const auto DEFLATE_STATE_DEFLATE_FIXED_GET_LENGTH		= 13;
  39	const auto DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE		= 14;
  40	const auto DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE_EX	= 15;
  41
  42	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_COMPRESSION	= 16;
  43	const auto	DEFLATE_STATE_DEFLATE_DYNAMIC_HDIST			= 17;
  44	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_HCLEN			= 18;
  45	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_GET_CODE_LEN	= 19;
  46	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS	= 20;
  47
  48	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN16	= 21;
  49	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN17	= 22;
  50	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN18	= 23;
  51
  52	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_DIST	= 24;
  53
  54	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_BUILD_TREE		= 25;
  55
  56	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER		= 26;
  57	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_GET_LENGTH		= 27;
  58	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE	= 28;
  59	const auto DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DIST_EX	= 29;
  60
  61
  62	const auto DEFLATE_STATE_HANDLE_LENGTH_DISTANCE			= 30;
  63
  64
  65	// compression flags //
  66
  67	const auto DEFLATE_COMPRESSION_NO_COMPRESSION			= 0;
  68	const auto DEFLATE_COMPRESSION_FIXED_HUFFMAN			= 1;
  69	const auto DEFLATE_COMPRESSION_DYNAMIC_HUFFMAN			= 2;
  70	// -- 3 is reserved
  71
  72
  73
  74
  75	struct _huffman_range {
  76		ushort _huffman_base;			// base
  77
  78		ushort huffmanMinorCode;		// minimum code can be
  79		ushort huffmanMajorCode;		// maximum code can be
  80	}
  81
  82	struct _huffman_entry {
  83		ushort huffmanRangesCount;		// number of ranges
  84
  85		_huffman_range huffmanRanges[144];	// ranges
  86	}
  87
  88	struct _huffman_table {
  89		// tables listed by bit length (1 -- 16 bits)
  90		_huffman_entry huffman_entries[16];
  91	}
  92
  93
  94	struct _deflate_block_info {
  95		int deflateIsLastBlock;
  96		int deflateBlockType;
  97	}
  98
  99	struct _deflate_length_entry {
 100		ubyte deflateLengthExtraBits;
 101		ushort deflateLengthBase;
 102	}
 103
 104	static const _huffman_table deflateFixedHuffmanTable  = { [
 105
 106				{ 0, [{0}] },													//  1 bit
 107				{ 0, [{0}] },													//  2 bits
 108				{ 0, [{0}] },													//  3 bits
 109				{ 0, [{0}] },													//  4 bits
 110				{ 0, [{0}] },													//  5 bits
 111				{ 0, [{0}] },													//  6 bits
 112				{ 1, [ { 256, 0x00, 0x17 } ] },							//  7 bits
 113				{ 2, [ { 0, 0x30, 0xBF }, { 280, 0xC0, 0xC7 } ] },		//  8 bits
 114				{ 1, [ { 144, 0x190, 0x1FF } ] },						//  9 bits
 115
 116				// { 0 } ...											// 10 - 16 bits
 117
 118			] };
 119
 120	static const _deflate_length_entry deflateLengthTable[29] =
 121			[	{ 0, 3 },
 122				{ 0, 4 },
 123				{ 0, 5 },
 124				{ 0, 6 },
 125				{ 0, 7 },
 126				{ 0, 8 },
 127				{ 0, 9 },
 128				{ 0, 10 },
 129				{ 1, 11 },
 130				{ 1, 13 },
 131				{ 1, 15 },
 132				{ 1, 17 },
 133				{ 2, 19 },
 134				{ 2, 23 },
 135				{ 2, 27 },
 136				{ 2, 31 },
 137				{ 3, 35 },
 138				{ 3, 43 },
 139				{ 3, 51 },
 140				{ 3, 59 },
 141				{ 4, 67 },
 142				{ 4, 83 },
 143				{ 4, 99 },
 144				{ 4, 115 },
 145				{ 5, 131 },
 146				{ 5, 163 },
 147				{ 5, 195 },
 148				{ 5, 227 },
 149				{ 0, 258 } 	];
 150
 151	static const _deflate_length_entry globalDeflateDistanceTable[30] =
 152			[
 153				{ 0, 1 },
 154				{ 0, 2 },
 155				{ 0, 3 },
 156				{ 0, 4 },
 157				{ 1, 5 },
 158				{ 1, 7 },
 159				{ 2, 9 },
 160				{ 2, 13 },
 161				{ 3, 17 },
 162				{ 3, 25 },
 163				{ 4, 33 },
 164				{ 4, 49 },
 165				{ 5, 65 },
 166				{ 5, 97 },
 167				{ 6, 129 },
 168				{ 6, 193 },
 169				{ 7, 257 },
 170				{ 7, 385 },
 171				{ 8, 513 },
 172				{ 8, 769 },
 173				{ 9, 1025 },
 174				{ 9, 1537 },
 175				{ 10, 2049 },
 176				{ 10, 3073 },
 177				{ 11, 4097 },
 178				{ 11, 6145 },
 179				{ 12, 8193 },
 180				{ 12, 12289 },
 181				{ 13, 16385 },
 182				{ 13, 24577 }
 183			];
 184
 185	// IS USED TO REFER TO THE CORRECT SPOT IN THE CODE LENGTHS ARRAY
 186	// FOR COMPUTING HUFFMAN TABLES FOR DYNAMIC COMPRESSION
 187	// CODE LENGTHS OCCUR IN THIS ORDER:
 188	//   16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
 189	// WORKS UNDER THE ASSUMPTION THAT THE LATER CODE LENGTHS WILL BE 0 AND
 190	//  THUS NOT NECESSARY TO INCLUDE, PLUS THAT 16, 17, 18, 0 ARE
 191	// NECESSARY (THUS HCLEN + 4 IS THE NUMBER OF CODES TO RETRIEVE)
 192	static const ubyte deflateCodeLengthsReference[19] =
 193			[
 194				16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
 195			];
 196
 197
 198}
 199
 200// Section: Codecs/Binary
 201
 202// Description: This represents the DEFLATE Codec.
 203class DEFLATEDecoder : BinaryDecoder {
 204
 205	StreamData decode(Stream stream, Stream toStream) {
 206		uint counter;
 207
 208		for (;;) {
 209			switch (decoderState) {
 210
 211				// INIT DECODER //
 212			case DEFLATE_STATE_INIT:
 213
 214				//writeln("deflate start");
 215
 216				//////OutputDebugStringA("initing structure\n");
 217
 218
 219				// READ THE FIRST BYTE OF THE STREAM
 220
 221				deflateCurValue = 0;
 222				deflateCurValueBit = 0;
 223				deflateLastState = DEFLATE_STATE_READ_BFINAL;
 224
 225				decoderState = DEFLATE_STATE_READ_BYTE;
 226				decoderNextState = DEFLATE_STATE_READ_BIT;
 227
 228				//////OutputDebugString(String(stream.getRemaining()) + S("\n"));
 229
 230
 231
 232
 233				// READS A BYTE FROM THE STREAM //
 234
 235			case DEFLATE_STATE_READ_BYTE:
 236
 237				//writeln("read byte", stream.length());
 238
 239				if (!(stream.read(deflateCurByte))) {
 240					return StreamData.Required;
 241				}
 242				//writeln("read byte teres");
 243
 244				//////OutputDebugString(StringUtil::GetHexFromInt(deflateCurByte));
 245
 246				deflateCurMask = 1; // 10000000
 247				deflateCurBit = 0;
 248
 249				decoderState = decoderNextState;
 250				///writeln("read byte done");
 251
 252				continue;
 253
 254
 255				// READS A SEQUENCE OF BITS FROM THE STREAM //
 256
 257			case DEFLATE_STATE_READ_BITS:
 258
 259				if (deflateCurMask == 0) {
 260					// get the next byte from the stream
 261					decoderState = DEFLATE_STATE_READ_BYTE;
 262					decoderNextState = DEFLATE_STATE_READ_BITS;
 263					continue;
 264				}
 265
 266				if (deflateCurByte & deflateCurMask) {
 267					//////OutputDebugString(String(deflateCurValue) + S("\n"));
 268					//////OutputDebugString(String(deflateCurBit) + S(" - ") + String(deflateCurValueBit) + S("\n"));
 269					if (deflateCurBit > deflateCurValueBit) {
 270						deflateCurValue |= ((deflateCurByte & deflateCurMask) >> (deflateCurBit - deflateCurValueBit));
 271					}
 272					else if (deflateCurBit == deflateCurValueBit) {
 273						deflateCurValue |= (deflateCurByte & deflateCurMask);
 274					}
 275					else {
 276						deflateCurValue |= ((deflateCurByte & deflateCurMask) << (deflateCurValueBit - deflateCurBit));
 277					}
 278
 279					//////OutputDebugStringA("deflate - read bit: 1\n");
 280					//////OutputDebugString(String(deflateCurValue) + S("\n"));
 281				}
 282				else {
 283					//////OutputDebugStringA("deflate - read bit: 0\n");
 284				}
 285
 286				deflateCurMask <<= 1;
 287
 288				deflateBitsLeft--;
 289				deflateCurBit++;
 290				deflateCurValueBit++;
 291
 292				if (deflateBitsLeft == 0) {
 293					decoderState = deflateLastState;
 294				}
 295
 296				continue;
 297
 298			case DEFLATE_STATE_READ_BIT:
 299
 300				//writeln("read bit");
 301				if (deflateCurMask == 0) {
 302					// get the next byte from the stream
 303					decoderState = DEFLATE_STATE_READ_BYTE;
 304					decoderNextState = DEFLATE_STATE_READ_BIT;
 305				//writeln("read bit (break)");
 306					continue;
 307				}
 308
 309				if (deflateCurByte & deflateCurMask) {
 310					if (deflateCurBit > deflateCurValueBit) {
 311						deflateCurValue |= ((deflateCurByte & deflateCurMask) >> (deflateCurBit - deflateCurValueBit));
 312					}
 313					else if (deflateCurBit == deflateCurValueBit) {
 314						deflateCurValue |= (deflateCurByte & deflateCurMask);
 315					}
 316					else {
 317						deflateCurValue |= ((deflateCurByte & deflateCurMask) << (deflateCurValueBit - deflateCurBit));
 318					}
 319
 320					//////OutputDebugStringA("deflate - read bit: 1\n");
 321				}
 322				else {
 323					//////OutputDebugStringA("deflate - read bit: 0\n");
 324				}
 325
 326				deflateCurMask <<= 1;
 327				deflateCurBit++;
 328				deflateCurValueBit++;
 329
 330				decoderState = deflateLastState;
 331				//writeln("read bit done");
 332
 333				continue;
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347				// READS A SEQUENCE OF BITS FROM THE STREAM //
 348				// READS FROM MSB //
 349
 350			case DEFLATE_STATE_READ_BITS_REV:
 351
 352				if (deflateCurMask == 0) {
 353					// get the next byte from the stream
 354					decoderState = DEFLATE_STATE_READ_BYTE;
 355					decoderNextState = DEFLATE_STATE_READ_BITS_REV;
 356					continue;
 357				}
 358
 359				deflateCurValue <<= 1;
 360
 361				if (deflateCurByte & deflateCurMask) {
 362					deflateCurValue++;
 363					//////OutputDebugStringA("deflate - read bit: 1\n");
 364					//////OutputDebugString(String(deflateCurValue) + S("\n"));
 365				}
 366				else {
 367					//////OutputDebugStringA("deflate - read bit: 0\n");
 368				}
 369
 370				deflateCurMask <<= 1;
 371				deflateCurBit++;
 372
 373				deflateBitsLeft--;
 374
 375				if (deflateBitsLeft == 0) {
 376					decoderState = deflateLastState;
 377				}
 378
 379				continue;
 380
 381			case DEFLATE_STATE_READ_BIT_REV:
 382
 383				if (deflateCurMask == 0) {
 384					// get the next byte from the stream
 385					decoderState = DEFLATE_STATE_READ_BYTE;
 386					decoderNextState = DEFLATE_STATE_READ_BIT_REV;
 387					continue;
 388				}
 389
 390				deflateCurValue <<= 1;
 391
 392				if (deflateCurByte & deflateCurMask) {
 393					deflateCurValue++;
 394					//////OutputDebugStringA("deflate - read bit: 1\n");
 395					//////OutputDebugString(String(deflateCurValue) + S("\n"));
 396				}
 397				else {
 398					//////OutputDebugStringA("deflate - read bit: 0\n");
 399				}
 400				//////OutputDebugString(String(deflateCurValue) + S(": code\n"));
 401
 402				deflateCurMask <<= 1;
 403				deflateCurBit++;
 404
 405				deflateBitsLeft--;
 406
 407				decoderState = deflateLastState;
 408
 409				continue;
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422				// READ THE BLOCK'S BFINAL //
 423
 424				// THE BFINAL DENOTES WHETHER THIS IS THE LAST BLOCK //
 425
 426				// THIS VALUE IS IN CURVALUE //
 427
 428			case DEFLATE_STATE_READ_BFINAL:
 429
 430				deflateCurBlock.deflateIsLastBlock = deflateCurValue;
 431
 432				if (deflateCurBlock.deflateIsLastBlock) {
 433					//////OutputDebugStringA("deflate - this is final block\n");
 434				}
 435				else {
 436					//////OutputDebugStringA("deflate - this is not the final block\n");
 437				}
 438
 439				decoderState = DEFLATE_STATE_READ_BITS;
 440
 441				deflateLastState = DEFLATE_STATE_READ_BTYPE;
 442
 443				deflateCurValue = 0;
 444				deflateCurValueBit = 0;
 445
 446				deflateBitsLeft = 2;
 447
 448				continue;
 449
 450
 451				// READ THE BLOCK'S BTYPE //
 452				// BTYPE - DENOTES THE TYPE OF COMPRESSION //
 453			case DEFLATE_STATE_READ_BTYPE:
 454
 455				//////OutputDebugStringA("deflate - read BTYPE\n");
 456
 457				deflateCurBlock.deflateBlockType = deflateCurValue;
 458
 459				// RESET CUR VALUE, WE USE THIS
 460				deflateCurValue = 0;
 461				deflateCurValueBit = 0;
 462
 463				switch (deflateCurBlock.deflateBlockType) {
 464
 465					// NO COMPRESSION INIT //
 466				case DEFLATE_COMPRESSION_NO_COMPRESSION:
 467					//write("deflate - block compression: NONE\n");
 468
 469					// WILL REALIGN TO BYTE BOUNDARY AND THEN DECODE //
 470					decoderState = DEFLATE_STATE_DEFLATE_NO_COMPRESSION;
 471
 472					break;
 473
 474
 475
 476					// FIXED-HUFFMAN INIT //
 477				case DEFLATE_COMPRESSION_FIXED_HUFFMAN:
 478					//write("deflate - block compression: Fixed-Huffman\n");
 479
 480					deflateCurHuffmanTable = cast(_huffman_table*)&deflateFixedHuffmanTable;
 481
 482					// READ IN 7 BITS, THE MINIMUM CODE SIZE FOR FIXED-HUFFMAN TABLE
 483					deflateCurValue = 0;
 484					deflateCurValueBit = 0;
 485					deflateCurHuffmanBitLength = 6;
 486					deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
 487
 488					deflateBitsLeft = 7;
 489					decoderState = DEFLATE_STATE_READ_BITS_REV;
 490					deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE;
 491					break;
 492
 493
 494
 495				case DEFLATE_COMPRESSION_DYNAMIC_HUFFMAN:
 496					//write("deflate - block compression: Dynamic Huffman\n");
 497
 498					deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_COMPRESSION;
 499					deflateBitsLeft = 5;
 500					decoderState = DEFLATE_STATE_READ_BITS;
 501					break;
 502
 503
 504
 505				default:
 506					return StreamData.Invalid;
 507				}
 508
 509				continue;
 510
 511				// DECODER FOR 'NO COMPRESSION' TYPE (BTYPE == 0) //
 512
 513				// GET LEN
 514				// LEN - NUMBER OF DATA BYTES IN THE BLOCK
 515
 516			case DEFLATE_STATE_DEFLATE_NO_COMPRESSION:
 517				////OutputDebugStringA("deflate - decoding (no compression)\n");
 518
 519				// GET THE DATA LENGTH
 520				if (!(stream.read(&deflateDataLength, 2))) {
 521					return StreamData.Required;
 522				}
 523
 524				deflateDataLength = FromLittleEndian16(deflateDataLength);
 525
 526				decoderState = DEFLATE_STATE_DEFLATE_NO_COMPRESSION_SKIP;
 527
 528				// SKIP NLEN //
 529			case DEFLATE_STATE_DEFLATE_NO_COMPRESSION_SKIP:
 530
 531				if (!(stream.skip(2))) {
 532					return StreamData.Required;
 533				}
 534
 535				////OutputDebugStringA("deflate - copying data\n");
 536
 537				decoderState = DEFLATE_STATE_DEFLATE_NO_COMPRESSION_COPY;
 538
 539			case DEFLATE_STATE_DEFLATE_NO_COMPRESSION_COPY:
 540
 541				if (!(toStream.append(stream, deflateDataLength))) {
 542					return StreamData.Required;
 543				}
 544
 545				////OutputDebugStringA("deflate - block decompression done\n");
 546
 547				if (deflateCurBlock.deflateIsLastBlock) {
 548					////OutputDebugStringA("deflate - decompression done\n");
 549	//				writeln("deflate - copy - done");
 550					return StreamData.Complete;
 551				}
 552
 553				// READ ANOTHER BLOCK HEADER
 554
 555				deflateCurValue = 0;
 556				deflateCurValueBit = 0;
 557				deflateLastState = DEFLATE_STATE_READ_BFINAL;
 558
 559				decoderState = DEFLATE_STATE_READ_BIT;
 560
 561
 562
 563				continue;
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574				// DECODER FOR 'FIXED-HUFFMAN' COMPRESSION TYPE //
 575
 576				// DETERMINE IF CODE IS WITHIN HUFFMAN TABLES
 577				// OTHERWISE, ADD A BIT
 578				// UNLESS CURRENT BIT IS THE 7th BIT
 579			case DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE:
 580
 581				for (deflateCounter = 0; deflateCounter < deflateCurHuffmanEntry.huffmanRangesCount; deflateCounter++) {
 582					if ( (deflateCurValue >= deflateCurHuffmanEntry.huffmanRanges[deflateCounter].huffmanMinorCode) &&
 583						 (deflateCurValue <= deflateCurHuffmanEntry.huffmanRanges[deflateCounter].huffmanMajorCode) ) {
 584						// THIS IS A VALID CODE
 585						// GET THE DECODED LITERAL VALUE
 586
 587						deflateCurCode = deflateCurValue - deflateCurHuffmanEntry.huffmanRanges[deflateCounter].huffmanMinorCode;
 588						deflateCurCode += deflateCurHuffmanEntry.huffmanRanges[deflateCounter]._huffman_base;
 589
 590						if (deflateCurCode < 256) {
 591							// IT IS A LITERAL CODE
 592
 593							// ADD CODE TO OUTPUT STREAM
 594							toStream.append(cast(ubyte)deflateCurCode);
 595							//////OutputDebugString(S("output: ") + String(deflateCurCode) + S("\n"));
 596
 597							// RETURN TO GATHER ANOTHER CODE
 598							deflateCurValue = 0;
 599							deflateCurValueBit = 0;
 600							deflateCurHuffmanBitLength = 6;
 601							deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
 602
 603							deflateBitsLeft = 7;
 604							decoderState = DEFLATE_STATE_READ_BITS_REV;
 605							deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE;
 606
 607							//////OutputDebugString(S("deflate - code found: ") + String(deflateCurCode) + S("\n"));
 608
 609						}
 610						else if (deflateCurCode == 256) {
 611							// END OF BLOCK CODE
 612
 613							// RETURN TO GATHERING BLOCKS
 614							// IF THIS IS NOT THE LAST BLOCK
 615
 616							////OutputDebugString(S("deflate - end of code found: ") + String(deflateCurCode) + S("\n"));
 617
 618							if (deflateCurBlock.deflateIsLastBlock) {
 619	//							writeln("deflate - fixed - done");
 620								return StreamData.Complete;
 621							}
 622
 623							// READ ANOTHER BLOCK HEADER
 624
 625							deflateCurValue = 0;
 626							deflateCurValueBit = 0;
 627							deflateLastState = DEFLATE_STATE_READ_BFINAL;
 628
 629							decoderState = DEFLATE_STATE_READ_BIT;
 630						}
 631						else {
 632							// LENGTH CODE
 633
 634							// CALCULATE THE TRUE LENGTH
 635
 636							//////OutputDebugString(S("deflate - length code found: ") + String(deflateCurCode) + S("\n"));
 637
 638							deflateLength = deflateLengthTable[deflateCurCode - 257].deflateLengthBase;
 639
 640
 641							deflateCurValue = 0;
 642							deflateCurValueBit = 0;
 643
 644							if (deflateLengthTable[deflateCurCode - 257].deflateLengthExtraBits > 0) {
 645								decoderState = DEFLATE_STATE_READ_BITS;
 646								deflateBitsLeft = deflateLengthTable[deflateCurCode - 257].deflateLengthExtraBits;
 647								deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_GET_LENGTH;
 648							}
 649							else {
 650								// WE HAVE THE LENGTH, FIND THE DISTANCE
 651
 652								// IN FIXED-HUFFMAN, THE DISTANCE IS A FIXED 5 BIT VALUE, PLUS ANY EXTRA BITS
 653								// GIVEN IN THE TABLE FOR DISTANCE CODES
 654								decoderState = DEFLATE_STATE_READ_BITS_REV;
 655								deflateBitsLeft = 5;
 656								deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE;
 657							}
 658						}
 659
 660						break;
 661					}
 662				}
 663				if (decoderState == DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE) {
 664					//////OutputDebugStringA("deflate - Huffman code not found, reading another bit\n");
 665					// READ IN ANOTHER BIT
 666					// INCREMENT HUFFMAN ENTRY COUNTER
 667					deflateCurHuffmanEntry++;
 668					deflateCurHuffmanBitLength++;
 669
 670					decoderState = DEFLATE_STATE_READ_BIT_REV;
 671
 672					if (deflateCurHuffmanBitLength == 16) {
 673						//////OutputDebugStringA("deflate - Huffman maximum code length exceeded\n");
 674						return StreamData.Invalid;
 675					}
 676				}
 677
 678				continue;
 679
 680
 681
 682
 683
 684
 685
 686
 687				// INTERPRET THE RESULT OF THE EXTRA BITS //
 688				// CALCULATE THE TRUE LENGTH //
 689			case DEFLATE_STATE_DEFLATE_FIXED_GET_LENGTH:
 690
 691				deflateLength += deflateCurValue;
 692
 693				//////OutputDebugString(S("deflate - calculated length: ") + String(deflateLength) + S("\n"));
 694
 695				// FIND DISTANCE
 696
 697				// IN FIXED-HUFFMAN, THE DISTANCE IS A FIXED 5 BIT VALUE, PLUS ANY EXTRA BITS
 698				// GIVEN IN THE TABLE FOR DISTANCE CODES
 699				deflateBitsLeft = 5;
 700
 701				deflateCurValue = 0;
 702				deflateCurValueBit = 0;
 703
 704				decoderState = DEFLATE_STATE_READ_BITS_REV;
 705				deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE;
 706
 707				continue;
 708
 709				// CALCULATE DISTANCE //
 710
 711				// CURVALUE IS THE ROOT DISTANCE //
 712			case DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE:
 713
 714				deflateDistance = globalDeflateDistanceTable[deflateCurValue].deflateLengthBase;
 715				//////OutputDebugString(S("deflate - distance base: ") + String(deflateDistance) + S("\n"));
 716
 717				if (globalDeflateDistanceTable[deflateCurValue].deflateLengthExtraBits > 0) {
 718					decoderState = DEFLATE_STATE_READ_BITS;
 719
 720					deflateBitsLeft = globalDeflateDistanceTable[deflateCurValue].deflateLengthExtraBits;
 721					deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE_EX;
 722
 723					deflateCurValue = 0;
 724					deflateCurValueBit = 0;
 725				}
 726				else {
 727					// THE DISTANCE REQUIRES NO OTHER INPUT
 728
 729					// ADD TO THE DATA STREAM BY USING INTERPRET STATE
 730
 731					// RETURN TO GATHER ANOTHER CODE
 732					deflateCurValue = 0;
 733					deflateCurValueBit = 0;
 734					deflateCurHuffmanBitLength = 6;
 735					deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
 736
 737					deflateBitsLeft = 7;
 738					decoderState = DEFLATE_STATE_READ_BITS_REV;
 739					deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE;
 740
 741					//////OutputDebugString(S("deflate - code found: <len ") + String(deflateLength) + S(", dis ") + String(deflateDistance) + S(">\n"));
 742
 743					if (!toStream.duplicateFromEnd(deflateDistance, deflateLength)) {
 744						//////OutputDebugStringA("deflate - corrupt data - distance, length forced decoder out of range\n");
 745						return StreamData.Invalid;
 746					}
 747				}
 748
 749				continue;
 750
 751
 752				// CURVALUE IS THE EXTRA BITS FOR DISTANCE
 753			case DEFLATE_STATE_DEFLATE_FIXED_GET_DISTANCE_EX:
 754
 755				deflateDistance += deflateCurValue;
 756
 757				// ADD TO THE DATA STREAM BY USING INTERPRET STATE
 758
 759				// RETURN TO GATHER ANOTHER CODE
 760				deflateCurValue = 0;
 761				deflateCurValueBit = 0;
 762				deflateCurHuffmanBitLength = 6;
 763				deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
 764
 765				deflateBitsLeft = 7;
 766				decoderState = DEFLATE_STATE_READ_BITS_REV;
 767				deflateLastState = DEFLATE_STATE_DEFLATE_FIXED_CHECK_CODE;
 768
 769				//////OutputDebugString(S("deflate - code found: <len ") + String(deflateLength) + S(", dis ") + String(deflateDistance) + S(">\n"));
 770
 771				if (!toStream.duplicateFromEnd(deflateDistance, deflateLength)) {
 772					//////OutputDebugStringA("deflate - corrupt data - distance, length forced decoder out of range\n");
 773					return StreamData.Invalid;
 774				}
 775
 776				//////OutputDebugString(S("deflate - code found: <len ") + String(deflateLength) + S(", dis ") + String(deflateDistance) + S(">\n"));
 777
 778				continue;
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790				// CURVALUE HAS HLIT //
 791			case DEFLATE_STATE_DEFLATE_DYNAMIC_COMPRESSION:
 792
 793				//----writeln("deflate dynamic");
 794
 795				deflateHLIT = cast(ushort)deflateCurValue;
 796
 797				////OutputDebugString(S("HLIT: ") + String(deflateHLIT) + S("\n"));
 798
 799				// INITIALIZE CODE LENGTH HUFFMAN TABLE
 800				for (deflateCounter=0; deflateCounter < 16; deflateCounter++) {
 801					deflateCodeLengthTable.huffman_entries[deflateCounter].huffmanRangesCount = 0;
 802				}
 803
 804				// INITIALIZE THE CODE LENGTH COUNT
 805				for (deflateCounter=0; deflateCounter < 7; deflateCounter++) {
 806					deflateCodeLengthCount[deflateCounter] = 0;
 807				}
 808
 809				for (deflateCounter=0; deflateCounter < 8; deflateCounter++) {
 810					deflateHuffmanLengthCounts[deflateCounter] = 0;
 811				}
 812
 813				deflateBitsLeft = 5;
 814				decoderState = DEFLATE_STATE_READ_BITS;
 815				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_HDIST;
 816				deflateCurValue = 0;
 817				deflateCurValueBit = 0;
 818
 819				continue;
 820
 821			case DEFLATE_STATE_DEFLATE_DYNAMIC_HDIST:
 822				//----writeln("deflate dynamic hdist");
 823
 824				deflateHDIST = cast(ushort)deflateCurValue;
 825
 826				//////OutputDebugString(S("HDIST: ") + String(deflateHDIST));
 827
 828				deflateBitsLeft = 4;
 829				decoderState = DEFLATE_STATE_READ_BITS;
 830				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_HCLEN;
 831				deflateCurValue = 0;
 832				deflateCurValueBit = 0;
 833
 834				continue;
 835
 836			case DEFLATE_STATE_DEFLATE_DYNAMIC_HCLEN:
 837				//----writeln("deflate dynamic hclen");
 838
 839				deflateHCLEN = cast(ushort)deflateCurValue;
 840
 841				////OutputDebugString(S("HCLEN: ") + String(deflateHCLEN) + S("\n"));
 842
 843				////OutputDebugString(String(deflateHLIT) + S(", ") + String(deflateHDIST) + S(", ") + String(deflateHCLEN) + S("\n"));
 844
 845				// get (HCLEN + 4) number of 3 bit values: these correspond to the code lengths for the code length alphabet
 846				// holy freaking confusing!
 847				deflateCounterMax = deflateHCLEN + 4;
 848				deflateCounter = 0;
 849
 850				deflateBitsLeft = 3;
 851				decoderState = DEFLATE_STATE_READ_BITS;
 852				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_CODE_LEN;
 853				deflateCurValue = 0;
 854				deflateCurValueBit = 0;
 855
 856				continue;
 857
 858				// CURVALUE HOLDS THE NEXT CODE LENGTH //
 859			case DEFLATE_STATE_DEFLATE_DYNAMIC_GET_CODE_LEN:
 860				//----writeln("deflate dynamic get code len");
 861
 862				deflateCodeLengths[deflateCodeLengthsReference[deflateCounter]] = cast(ubyte)deflateCurValue;
 863
 864				if (deflateCurValue != 0) {
 865					deflateCodeLengthCount[deflateCurValue-1]++;
 866				}
 867
 868				//////OutputDebugString(String(deflateCurValue) + S(" !!! \n"));
 869				deflateHuffmanLengthCounts[deflateCurValue]++;
 870
 871				//////OutputDebugString(S("deflate - first tree - code length: ") + String(deflateCurValue) + S("\n"));
 872
 873				deflateCurValue = 0;
 874				deflateCurValueBit = 0;
 875
 876				deflateCounter++;
 877
 878				if (deflateCounter != deflateCounterMax) {
 879					// READ 3 MORE BITS
 880					deflateBitsLeft = 3;
 881					decoderState = DEFLATE_STATE_READ_BITS;
 882				}
 883				else {
 884					for ( ; deflateCounter < 19; deflateCounter++) {
 885						deflateCodeLengths[deflateCodeLengthsReference[deflateCounter]] = 0;
 886						deflateHuffmanLengthCounts[0]++;
 887					}
 888
 889					for (deflateCounter = 0; deflateCounter < 578; deflateCounter++) {
 890						deflateHuffmanTable[deflateCounter] = 0xFFFF;
 891					}
 892
 893
 894
 895					// BUILD CODE LENGTH TREE
 896					//////OutputDebugString(S("1: ") + String(deflateCodeLengthCount[0]) + S("\n"));
 897
 898
 899
 900
 901					uint pos, pos_exp, filled;
 902					ubyte bit;
 903
 904					deflateCounter = 0;
 905
 906					deflateHuffmanNextCodes[0] = 0;
 907					//////OutputDebugString(String(deflateHuffmanLengthCounts[0]) + S(" <-- len\n"));
 908					//////OutputDebugString(String(deflateHuffmanNextCodes[0]) + S("\n"));
 909
 910					uint p,o,curentry;
 911
 912					for ( p=1; p < 16; p++) {
 913						//////OutputDebugString(String(deflateHuffmanLengthCounts[p]) + S(" <-- len\n"));
 914						deflateHuffmanNextCodes[p] = cast(ushort)((deflateHuffmanNextCodes[p-1] + deflateHuffmanLengthCounts[p-1]) * 2);
 915						//////OutputDebugString(String(deflateHuffmanNextCodes[p]) + S(" <-- next code\n"));
 916					}
 917
 918					pos = 0;
 919					filled = 0;
 920
 921					for ( ; deflateCounter < 19; deflateCounter++) {
 922						//////OutputDebugString(String(deflateCounter) + S(": (") + String(deflateCodeLengths[deflateCounter]) + S(") ") + String(deflateHuffmanNextCodes[deflateCodeLengths[deflateCounter]]) + S("\n"));
 923						curentry = deflateHuffmanNextCodes[deflateCodeLengths[deflateCounter]]++;
 924
 925
 926						//////OutputDebugString(S("start - ") + String(pos) + S(",,, ") + String(deflateCodeLengths[deflateCounter]) + S("\n"));
 927
 928						// GO THROUGH EVERY BIT
 929						for (o=0; o < deflateCodeLengths[deflateCounter]; o++) {
 930							bit = cast(ubyte)((curentry >> (deflateCodeLengths[deflateCounter] - o - 1)) & 1);
 931
 932							pos_exp = (2 * pos) + bit;
 933						//////OutputDebugString(S("pos_exp - ") + String(pos_exp) + S("\n"));
 934
 935
 936							if ((o + 1) > (19 - 2)) {
 937								//////OutputDebugStringA("error - tree is mishaped\n");
 938							}
 939							else if (deflateHuffmanTable[pos_exp] == 0xFFFF) {
 940								//////OutputDebugStringA("not in tree\n");
 941								// IS THIS THE LAST BIT?
 942								if (o + 1 == deflateCodeLengths[deflateCounter]) {
 943									// JUST OUTPUT THE CODE
 944									//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(deflateCounter) + S(" (code)\n"));
 945
 946									deflateHuffmanTable[pos_exp] = cast(ushort)deflateCounter;
 947
 948									pos = 0;
 949								}
 950								else {
 951									filled++;
 952									//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(filled + 19) + S(" (address)\n"));
 953									deflateHuffmanTable[pos_exp] = cast(ushort)(filled + 19);
 954									pos = filled;
 955								}
 956							}
 957							else {
 958								//////OutputDebugStringA("is in tree\n");
 959								pos = deflateHuffmanTable[pos_exp] - 19;
 960								//////OutputDebugString(S("now - ") + String(pos) + S("\n"));
 961							}
 962						}
 963					}
 964
 965					p=0;
 966
 967					// table is built
 968
 969					// decode code lengths
 970
 971					deflateCounter = 0;
 972					deflateCounterMax = deflateHLIT + 257;
 973
 974					for (counter=0; counter<16; counter++) {
 975						deflateHuffmanLengthCounts[counter] = 0;
 976						deflateDistanceLengthCounts[counter] = 0;
 977					}
 978
 979					deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
 980
 981					//////OutputDebugString(S("deflate - minimum code length: ") + String(deflateCodeLengthCodeSize) + S("\n"));
 982
 983					//----writeln(deflateCodeLengthCodeSize-1);
 984
 985					deflateCurHuffmanTable = &deflateCodeLengthTable;
 986					deflateCurHuffmanEntry = &deflateCodeLengthTable.huffman_entries[deflateCodeLengthCodeSize-1];
 987
 988					deflateBitsLeft = deflateCodeLengthCodeSize;
 989					deflateCurHuffmanBitLength = deflateCodeLengthCodeSize;
 990
 991					deflateCurLengthArray = deflateHuffmanLengths.ptr;
 992					deflateCurLengthCountArray = deflateHuffmanLengthCounts.ptr;
 993
 994					decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
 995
 996					////OutputDebugStringA("deflate - length tree built\n");
 997
 998					deflateCurValue = 0;
 999					deflateCurValueBit = 0;
1000
1001					deflateTreePosition = 0;
1002				}
1003
1004				continue;
1005
1006
1007
1008
1009				// USE THE CODE LENGTH TABLE TO DECODE THE LENGTH DATA FOR THE REGULAR CODE TREE //
1010
1011				// CURVALUE IS THE CURRENT CODE //
1012			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS:
1013				//----writeln("deflate dynamic decode lens");
1014
1015				// GET BIT
1016
1017				//////OutputDebugStringA("deflate - decoding lengths\n");
1018
1019				if (deflateCurMask == 0) {
1020					// get the next byte from the stream
1021					decoderState = DEFLATE_STATE_READ_BYTE;
1022					decoderNextState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1023					continue;
1024				}
1025
1026				if (deflateCurByte & deflateCurMask) {
1027					deflateCurValue = 1;
1028					//////OutputDebugStringA("deflate - read bit: 1\n");
1029				}
1030				else {
1031					deflateCurValue = 0;
1032					//////OutputDebugStringA("deflate - read bit: 0\n");
1033				}
1034
1035				deflateCurMask <<= 1;
1036				deflateCurBit++;
1037
1038				// CHECK IN TREE
1039				if(deflateTreePosition >= 19) {
1040					////OutputDebugStringA("deflate - corrupt data\n");
1041					return StreamData.Invalid;
1042				}
1043
1044				deflateCurCode = deflateHuffmanTable[(2 * deflateTreePosition) + deflateCurValue];
1045
1046				if (deflateCurCode < 19) {
1047					deflateTreePosition = 0;
1048				}
1049				else {
1050					deflateTreePosition = cast(ushort)(deflateCurCode - 19);
1051				}
1052
1053				if (deflateTreePosition == 0) {
1054					//////OutputDebugStringA("deflate - found length code: ");
1055					//////OutputDebugString(String(deflateCurCode) + S("\n"));
1056
1057					// INTERPRET CODE
1058
1059					if (deflateCurCode < 16) {
1060						// 0...15 - LITERAL LENGTHS //
1061
1062						// JUST INSERT INTO ARRAY
1063						deflateCurLengthArray[deflateCounter] = cast(ubyte)deflateCurCode;
1064
1065						deflateCurLengthCountArray[deflateCurCode]++;
1066
1067						deflateCounter++;
1068
1069						if (deflateCounter == deflateCounterMax)
1070						{
1071							// WE HAVE GOTTEN THE MAXIMUM CODES WE WERE SUPPOSED TO FIND //
1072
1073							// WE HAVE TO DECODE THE DISTANCE ARRAY, OR THE TREE NOW
1074							decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_DIST;
1075							continue;
1076						}
1077
1078						// READ ANOTHER CODE
1079						deflateCurValue = 0;
1080						deflateCurValueBit = 0;
1081
1082						deflateCurHuffmanTable = &deflateCodeLengthTable;
1083						deflateCurHuffmanEntry = &deflateCodeLengthTable.huffman_entries[0];
1084
1085						deflateBitsLeft = 1;//deflateCodeLengthCodeSize;
1086						deflateCurHuffmanBitLength = 1;//deflateCodeLengthCodeSize;
1087
1088						//decoderState = DEFLATE_STATE_READ_BITS_REV;
1089					}
1090					else if (deflateCurCode == 16) {
1091
1092						// COPY PREVIOUS LENGTH 3 - 6 TIMES //
1093						// NEXT TWO [2] BITS DETERMINE LENGTH ( bits[2] + 3 ) //
1094
1095						deflateCurValue = 0;
1096						deflateCurValueBit = 0;
1097
1098						deflateBitsLeft = 2;
1099						decoderState = DEFLATE_STATE_READ_BITS;
1100						deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN16;
1101						continue;
1102					}
1103					else if (deflateCurCode == 17) {
1104						// REPEAT CODE LENGTH OF 0 FOR 3 - 10 TIMES
1105						// NEXT THREE [3] BITS DETERMINE LENGTH //
1106
1107						deflateCurValue = 0;
1108						deflateCurValueBit = 0;
1109
1110						deflateBitsLeft = 3;
1111						decoderState = DEFLATE_STATE_READ_BITS;
1112						deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN17;
1113						continue;
1114					}
1115					else if (deflateCurCode == 18) {
1116						// REPEAT CODE LENGTH OF 0 FOR 11 - 138 TIMES
1117						// NEXT SEVEN [7] BITS DETERMINE LENGTH //
1118
1119						deflateCurValue = 0;
1120						deflateCurValueBit = 0;
1121
1122						deflateBitsLeft = 7;
1123						decoderState = DEFLATE_STATE_READ_BITS;
1124						deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN18;
1125						continue;
1126					}
1127				}
1128
1129				continue;
1130
1131				// INTERPRET LENGTH CODE 16
1132			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN16:
1133				//----writeln("deflate dynamic decode len16");
1134
1135				// TAKE LAST CODE AND REPEAT 'CURVALUE' + 3 TIMES
1136
1137				deflateCurValue += 3;
1138
1139				//////OutputDebugString(String(deflateCurValue) + S("\n"));
1140
1141				if (deflateCounter != 0) {
1142					deflateCurCode = deflateCurLengthArray[deflateCounter-1];
1143				}
1144				else {
1145					////OutputDebugStringA("deflate - corrupt data\n");
1146					return StreamData.Invalid;
1147				}
1148
1149				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1150
1151				deflateCurHuffmanTable = &deflateCodeLengthTable;
1152				deflateCurHuffmanEntry = &deflateCodeLengthTable.huffman_entries[0];
1153
1154				deflateBitsLeft = 1;//deflateCodeLengthCodeSize;
1155				deflateCurHuffmanBitLength = 1;//deflateCodeLengthCodeSize;
1156
1157				decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1158
1159				for (counter=0 ; counter<deflateCurValue; counter++) {
1160					deflateCurLengthArray[deflateCounter] = cast(ubyte)deflateCurCode;
1161					deflateCurLengthCountArray[deflateCurCode]++;
1162
1163					deflateCounter++;
1164
1165					if (deflateCounter == deflateCounterMax) {
1166						// WE CANNOT REPEAT THE VALUE
1167
1168						decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_DIST;
1169						break;
1170					}
1171				}
1172
1173				deflateCurValue = 0;
1174				deflateCurValueBit = 0;
1175
1176				continue;
1177
1178				// INTERPRET LENGTH CODE 17, 18
1179			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN18:
1180				//----writeln("deflate dynamic decode len18");
1181
1182				deflateCurValue += 8;
1183
1184			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LEN17:
1185				//----writeln("deflate dynamic decode len17");
1186
1187				deflateCurValue += 3;
1188
1189				//////OutputDebugString(String(deflateCurValue) + S("\n"));
1190
1191				// TAKE 0 AND REPEAT 'CURVALUE' TIMES
1192
1193				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1194
1195				deflateCurHuffmanTable = &deflateCodeLengthTable;
1196				deflateCurHuffmanEntry = &deflateCodeLengthTable.huffman_entries[0];
1197
1198				deflateBitsLeft = 1;//deflateCodeLengthCodeSize;
1199				deflateCurHuffmanBitLength = 1;//deflateCodeLengthCodeSize;
1200
1201				decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1202
1203				for (counter=0 ; counter<deflateCurValue; counter++) {
1204					deflateCurLengthArray[deflateCounter] = 0;
1205					deflateCurLengthCountArray[0]++;
1206
1207					deflateCounter++;
1208
1209					if (deflateCounter == deflateCounterMax) {
1210						// WE CANNOT REPEAT THE VALUE
1211						// JUST STOP
1212						//////OutputDebugStringA("deflate - attempted to write a code out of bounds, continuing anyway\n");
1213
1214						decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_DIST;
1215						break;
1216					}
1217				}
1218
1219				deflateCurValue = 0;
1220				deflateCurValueBit = 0;
1221
1222				continue;
1223
1224			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_DIST:
1225				//----writeln("deflate dynamic decode dist");
1226
1227				if (deflateCurLengthArray == deflateDistanceLengths.ptr) {
1228					// FINISH INITIALIZING THE REST OF THE DISTANCE CODE LENGTH ARRAY //
1229
1230					//write out rest of entries to 0
1231					for (; deflateCounter < 32; deflateCounter++) {
1232						deflateDistanceLengths[deflateCounter] = 0;
1233						deflateDistanceLengthCounts[0]++;
1234					}
1235
1236					//for (counter = 0; counter < 32; counter++)
1237					//{
1238					//	//////OutputDebugString(S("distance: ") + String(counter+1) + S(": ") + String(deflateDistanceLengths[counter]) + S("\n"));
1239					//}
1240
1241					decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_BUILD_TREE;
1242					continue;
1243				}
1244
1245				// FINISH INITIALIZING THE REST OF THE HUFFMAN CODE LENGTH ARRAY //
1246
1247				//write out rest of entries to 0
1248				for (; deflateCounter < 288; deflateCounter++) {
1249					deflateHuffmanLengths[deflateCounter] = 0;
1250					deflateHuffmanLengthCounts[0]++;
1251				}
1252
1253				//for (counter = 0; counter < 287; counter++)
1254				//{
1255				//	//////OutputDebugString(String(counter) + S(": ") + String(deflateHuffmanLengths[counter]) + S("\n"));
1256				//}
1257
1258				// NOW INIT THE LENGTH DECODER TO BUILD THE DISTANCE ARRAY
1259				deflateCounter = 0;
1260				deflateCounterMax = deflateHDIST + 1;
1261
1262				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1263
1264				//////OutputDebugString(S("deflate - minimum code length: ") + String(deflateCodeLengthCodeSize) + S("\n"));
1265
1266				deflateCurHuffmanTable = &deflateCodeLengthTable;
1267				deflateCurHuffmanEntry = &deflateCodeLengthTable.huffman_entries[deflateCodeLengthCodeSize-1];
1268
1269				deflateBitsLeft = deflateCodeLengthCodeSize;
1270				deflateCurHuffmanBitLength = deflateCodeLengthCodeSize;
1271
1272				deflateCurLengthArray = deflateDistanceLengths.ptr;
1273				deflateCurLengthCountArray = deflateDistanceLengthCounts.ptr;
1274
1275				decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODE_LENS;
1276
1277				deflateCurValue = 0;
1278				deflateCurValueBit = 0;
1279
1280				continue;
1281
1282				// BUILD BOTH LENGTH AND DISTANCE CODE TREES
1283			case DEFLATE_STATE_DEFLATE_DYNAMIC_BUILD_TREE:
1284				//----writeln("deflate dynamic build tree");
1285
1286				for (deflateCounter = 0; deflateCounter < 578; deflateCounter++) {
1287					deflateHuffmanTable[deflateCounter] = 0xFFFF;
1288				}
1289
1290				for (deflateCounter = 0; deflateCounter < 68; deflateCounter++) {
1291					deflateDistanceTable[deflateCounter] = 0xFFFF;
1292				}
1293
1294
1295
1296				// BUILD CODE LENGTH TREE
1297				//////OutputDebugString(S("1: ") + String(deflateCodeLengthCount[0]) + S("\n"));
1298
1299
1300
1301
1302				uint pos, pos_exp, filled;
1303				ubyte bit;
1304
1305				uint p,o,curentry;
1306
1307				deflateHuffmanNextCodes[0] = 0;
1308				//////OutputDebugString(String(deflateHuffmanLengthCounts[0]) + S(" <-- len\n"));
1309				//////OutputDebugString(String(deflateHuffmanNextCodes[0]) + S("\n"));
1310
1311				for ( p=1; p < 16; p++) {
1312					//////OutputDebugString(String(deflateHuffmanLengthCounts[p]) + S(" <-- len\n"));
1313					deflateHuffmanNextCodes[p] = cast(ushort)((deflateHuffmanNextCodes[p-1] + deflateHuffmanLengthCounts[p-1]) * 2);
1314					//////OutputDebugString(String(deflateHuffmanNextCodes[p]) + S(" <-- next code\n"));
1315				}
1316
1317				pos = 0;
1318				filled = 0;
1319
1320				deflateCounter = 0;
1321
1322				for ( ; deflateCounter < 288; deflateCounter++) {
1323					//////OutputDebugString(String(deflateCounter) + S(": (") + String(deflateHuffmanLengths[deflateCounter]) + S(") ") + String(deflateHuffmanNextCodes[deflateHuffmanLengths[deflateCounter]]) + S("\n"));
1324					curentry = deflateHuffmanNextCodes[deflateHuffmanLengths[deflateCounter]]++;
1325
1326					//////OutputDebugStringA("deflate - curentry read\n");
1327
1328					// GO THROUGH EVERY BIT
1329					for (o=0; o < deflateHuffmanLengths[deflateCounter]; o++) {
1330						bit = cast(ubyte)((curentry >> (deflateHuffmanLengths[deflateCounter] - o - 1)) & 1);
1331
1332						pos_exp = (2 * pos) + bit;
1333
1334						if ((o + 1) > (288 - 2)) {
1335							//////OutputDebugStringA("error - tree is mishaped\n");
1336						}
1337						else if (deflateHuffmanTable[pos_exp] == 0xFFFF) {
1338							//////OutputDebugStringA("not in tree\n");
1339							// IS THIS THE LAST BIT?
1340							if (o + 1 == deflateHuffmanLengths[deflateCounter]) {
1341								// JUST OUTPUT THE CODE
1342								//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(deflateCounter) + S(" (code)\n"));
1343
1344								deflateHuffmanTable[pos_exp] = cast(ushort)deflateCounter;
1345
1346								pos = 0;
1347							}
1348							else {
1349								filled++;
1350								//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(filled + 288) + S(" (address)\n"));
1351								deflateHuffmanTable[pos_exp] = cast(ushort)(filled + 288);
1352								pos = filled;
1353							}
1354						}
1355						else {
1356							//////OutputDebugStringA("is in tree\n");
1357							pos = deflateHuffmanTable[pos_exp] - 288;
1358						}
1359					}
1360				}
1361
1362
1363
1364
1365
1366				deflateHuffmanNextCodes[0] = 0;
1367				//////OutputDebugString(String(deflateDistanceLengthCounts[0]) + S(" <-- len\n"));
1368				//////OutputDebugString(String(deflateHuffmanNextCodes[0]) + S("\n"));
1369
1370				for ( p=1; p < 16; p++) {
1371					//////OutputDebugString(String(deflateDistanceLengthCounts[p]) + S(" <-- len\n"));
1372					deflateHuffmanNextCodes[p] = cast(ushort)((deflateHuffmanNextCodes[p-1] + deflateDistanceLengthCounts[p-1]) * 2);
1373					//////OutputDebugString(String(deflateHuffmanNextCodes[p]) + S(" <-- next code\n"));
1374				}
1375
1376				pos = 0;
1377				filled = 0;
1378
1379				deflateCounter = 0;
1380
1381				for ( ; deflateCounter < 32; deflateCounter++) {
1382					//////OutputDebugString(String(deflateCounter) + S(": (") + String(deflateDistanceLengths[deflateCounter]) + S(") ") + String(deflateHuffmanNextCodes[deflateDistanceLengths[deflateCounter]]) + S("\n"));
1383					curentry = deflateHuffmanNextCodes[deflateDistanceLengths[deflateCounter]]++;
1384
1385					//////OutputDebugStringA("deflate - curentry read\n");
1386
1387					// GO THROUGH EVERY BIT
1388					for (o=0; o < deflateDistanceLengths[deflateCounter]; o++) {
1389						bit = cast(ubyte)((curentry >> (deflateDistanceLengths[deflateCounter] - o - 1)) & 1);
1390
1391						pos_exp = (2 * pos) + bit;
1392
1393						if ((o + 1) > (32 - 2)) {
1394							//////OutputDebugStringA("error - tree is mishaped\n");
1395						}
1396						else if (deflateDistanceTable[pos_exp] == 0xFFFF) {
1397							//////OutputDebugStringA("not in tree\n");
1398							// IS THIS THE LAST BIT?
1399							if (o + 1 == deflateDistanceLengths[deflateCounter]) {
1400								// JUST OUTPUT THE CODE
1401								//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(deflateCounter) + S(" (code)\n"));
1402
1403								deflateDistanceTable[pos_exp] = cast(ushort)deflateCounter;
1404
1405								pos = 0;
1406							}
1407							else {
1408								filled++;
1409								//////OutputDebugString(S(":") + String(pos_exp) + S(": ") + String(filled + 32) + S(" (address)\n"));
1410								deflateDistanceTable[pos_exp] = cast(ushort)(filled + 32);
1411								pos = filled;
1412							}
1413						}
1414						else {
1415							//////OutputDebugStringA("is in tree\n");
1416							pos = deflateDistanceTable[pos_exp] - 32;
1417						}
1418					}
1419				}
1420
1421				//OutputDebugStringA("deflate - trees built\n");
1422
1423				//////OutputDebugStringA("deflate - building code trees\n");
1424
1425				for (counter = 0; counter < 16; counter++) {
1426					//////OutputDebugString(String(counter+1) + S(" (length): ") + String(deflateHuffmanLengthCounts[counter]) + S("\n"));
1427				}
1428
1429				for (counter = 0; counter < 16; counter++) {
1430					//////OutputDebugString(String(counter+1) + S(" (distance): ") + String(deflateDistanceLengthCounts[counter]) + S("\n"));
1431				}
1432
1433				// BUILD CODE LENGTH TREE
1434
1435				// DECODE
1436
1437				// INIT HUFFMAN TO MINIUM CODE LENGTH
1438
1439				//deflateCurValue = 0;
1440				//deflateCurValueBit = 0;
1441				//deflateCurHuffmanBitLength = deflateCodeLengthCodeSize-1;
1442				//deflateCurHuffmanTable = &deflateInternalHuffmanTable;
1443				//deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
1444
1445				//deflateBitsLeft = deflateCodeLengthCodeSize;
1446				decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1447				//deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1448
1449				deflateTreePosition = 0;
1450				//////OutputDebugString(S("1: ") + String(deflateHuffmanLengthCounts[0]) + S("\n"));
1451
1452				continue;
1453
1454			case DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER:
1455				//writeln("deflate dynamic decoder");
1456				//----writeln("a");
1457				//////OutputDebugString(S("1: ") + String(deflateHuffmanLengthCounts[0]) + S("\n"));
1458				// GET BIT
1459
1460				if (deflateCurMask == 0) {
1461					// get the next byte from the stream
1462					decoderState = DEFLATE_STATE_READ_BYTE;
1463					decoderNextState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1464				//writeln("deflate dynamic decoder done (break)");
1465					continue;
1466				}
1467
1468				if (deflateCurByte & deflateCurMask) {
1469					deflateCurValue = 1;
1470					//////OutputDebugStringA("deflate - read bit: 1\n");
1471				}
1472				else {
1473					deflateCurValue = 0;
1474					//////OutputDebugStringA("deflate - read bit: 0\n");
1475				}
1476
1477
1478				deflateCurMask <<= 1;
1479				deflateCurBit++;
1480
1481				// CHECK IN TREE
1482				//if(deflateTreePosition >= numcodes) return 11; //error: you appeared outside the codetree
1483
1484				deflateCurCode = deflateHuffmanTable[(2 * deflateTreePosition) + deflateCurValue];
1485
1486				if (deflateCurCode < 288) {
1487					deflateTreePosition = 0;
1488				}
1489				else {
1490					deflateTreePosition = cast(ushort)(deflateCurCode - 288);
1491				}
1492
1493
1494				if (deflateTreePosition == 0) {
1495					//////OutputDebugStringA("deflate - found code: ");
1496					//////OutputDebugString(String(deflateCurCode) + S("\n"));
1497
1498					// INTERPRET CODE
1499
1500					if (deflateCurCode < 256) {
1501						// IT IS A LITERAL CODE
1502
1503						// ADD CODE TO OUTPUT STREAM
1504						toStream.append(cast(ubyte)deflateCurCode);
1505
1506						// RETURN TO GATHER ANOTHER CODE
1507
1508						deflateCurValue = 0;
1509						deflateCurValueBit = 0;
1510						deflateCurHuffmanBitLength = deflateCodeLengthCodeSize-1;
1511						deflateCurHuffmanTable = &deflateInternalHuffmanTable;
1512						deflateCurHuffmanEntry = &deflateCurHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
1513
1514						deflateBitsLeft = deflateCodeLengthCodeSize;
1515						decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1516						deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1517
1518						//////OutputDebugString(S("output: ") + String(deflateCurCode) + S("\n"));
1519
1520					}
1521					else if (deflateCurCode == 256) {
1522						// END OF BLOCK CODE
1523
1524						// RETURN TO GATHERING BLOCKS
1525						// IF THIS IS NOT THE LAST BLOCK
1526
1527						////OutputDebugString(S("deflate - end of code found: ") + String(deflateCurCode) + S("\n"));
1528
1529						if (deflateCurBlock.deflateIsLastBlock) {
1530							//////OutputDebugStringA("deflate - done\n");
1531	//						writeln("deflate - dynamic - done");
1532				//writeln("deflate dynamic decoder done (return)");
1533							return StreamData.Complete;
1534						}
1535
1536						// READ ANOTHER BLOCK HEADER
1537
1538						deflateCurValue = 0;
1539						deflateCurValueBit = 0;
1540						deflateLastState = DEFLATE_STATE_READ_BFINAL;
1541
1542						decoderState = DEFLATE_STATE_READ_BIT;
1543				//writeln("deflate dynamic decoder done (break2)");
1544						continue;
1545					}
1546					else {
1547						// LENGTH CODE
1548
1549						// CALCULATE THE TRUE LENGTH
1550
1551						//////OutputDebugString(S("deflate - length code found: ") + String(deflateCurCode - 257) + S("\n"));
1552
1553						deflateLength = deflateLengthTable[deflateCurCode - 257].deflateLengthBase;
1554
1555						deflateCurValue = 0;
1556						deflateCurValueBit = 0;
1557
1558						//----writeln("b2");
1559						if (deflateLengthTable[deflateCurCode - 257].deflateLengthExtraBits > 0) {
1560							//----writeln("c1");
1561							//////OutputDebugString(S("deflate - length code reading extra bits: ") + String(deflateLengthTable[deflateCurCode - 257].deflateLengthExtraBits) + S("\n"));
1562							decoderState = DEFLATE_STATE_READ_BITS;
1563							deflateBitsLeft = deflateLengthTable[deflateCurCode - 257].deflateLengthExtraBits;
1564							deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_LENGTH;
1565						}
1566						else {
1567							// WE ALREADY HAVE THE LENGTH, FIND THE DISTANCE
1568							//////OutputDebugString(S("deflate - length: ") + String(deflateLength) + S("\n"));
1569
1570							// IN DYNAMIC-HUFFMAN, DISTANCE IS REPRESENTED BY A DIFFERENT HUFFMAN TREE
1571							decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE;
1572
1573							//deflateBitsLeft = deflateDistanceCodeLengthCodeSize;
1574							//deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE;
1575
1576							//deflateCurDistanceBitLength = deflateDistanceCodeLengthCodeSize-1;
1577							//deflateCurDistanceEntry = &deflateInternalDistanceTable.huffman_entries[deflateCurDistanceBitLength];
1578						}
1579					}
1580				}
1581				//writeln("deflate dynamic decoder done");
1582
1583				continue;
1584
1585
1586
1587				// CURVALUE IS THE TOTAL OF THE EXTRA BITS //
1588			case DEFLATE_STATE_DEFLATE_DYNAMIC_GET_LENGTH:
1589				//----writeln("deflate dynamic get length");
1590
1591				deflateLength += deflateCurValue;
1592
1593				// READ IN DISTANCE CODE
1594				decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE;
1595
1596				deflateCurValue = 0;
1597				deflateCurValueBit = 0;
1598				deflateBitsLeft = deflateDistanceCodeLengthCodeSize;
1599				deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE;
1600
1601				//deflateCurDistanceBitLength = deflateDistanceCodeLengthCodeSize-1;
1602				//deflateCurDistanceEntry = &deflateInternalDistanceTable.huffman_entries[deflateCurDistanceBitLength];
1603
1604
1605				continue;
1606
1607
1608
1609				// CURVALUE IS THE RESULTING CODE //
1610				// ENSURE IT IS IN THE HUFFMAN TREE //
1611				// THEN WE CAN READ THE EXTRA BITS //
1612				// IF NOT, WE CAN READ ANOTHER BIT //
1613			case DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE:
1614				//----writeln("deflate dynamic get distance");
1615				//////OutputDebugStringA("deflate - (distance) input code: ");
1616				//////OutputDebugString(String(deflateCurValue) + S("\n"));
1617				// GET BIT
1618
1619				if (deflateCurMask == 0) {
1620					// get the next byte from the stream
1621					decoderState = DEFLATE_STATE_READ_BYTE;
1622					decoderNextState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DISTANCE;
1623					continue;
1624				}
1625
1626				if (deflateCurByte & deflateCurMask) {
1627					deflateCurValue = 1;
1628					//////OutputDebugStringA("deflate - read bit: 1\n");
1629				}
1630				else {
1631					deflateCurValue = 0;
1632					//////OutputDebugStringA("deflate - read bit: 0\n");
1633				}
1634
1635				deflateCurMask <<= 1;
1636				deflateCurBit++;
1637
1638				// CHECK IN TREE
1639				//if(deflateTreePosition >= numcodes) return 11; //error: you appeared outside the codetree
1640
1641				deflateCurCode = deflateDistanceTable[(2 * deflateTreePosition) + deflateCurValue];
1642
1643				if (deflateCurCode < 32) {
1644					deflateTreePosition = 0;
1645				}
1646				else {
1647					deflateTreePosition = cast(ushort)(deflateCurCode - 32);
1648				}
1649
1650				if (deflateTreePosition == 0) {
1651					//////OutputDebugStringA("deflate - found distance code: ");
1652					//////OutputDebugString(String(deflateCurCode) + S("\n"));
1653
1654					// INTERPRET CODE
1655
1656					deflateDistance = globalDeflateDistanceTable[deflateCurCode].deflateLengthBase;
1657					//////OutputDebugString(S("deflate - distance base: ") + String(deflateDistance) + S("\n"));
1658
1659					if (globalDeflateDistanceTable[deflateCurCode].deflateLengthExtraBits > 0) {
1660						decoderState = DEFLATE_STATE_READ_BITS;
1661
1662						deflateBitsLeft = globalDeflateDistanceTable[deflateCurCode].deflateLengthExtraBits;
1663						deflateLastState = DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DIST_EX;
1664
1665						deflateCurValue = 0;
1666						deflateCurValueBit = 0;
1667					}
1668					else {
1669						// THE DISTANCE REQUIRES NO OTHER INPUT
1670
1671						// ADD TO THE DATA STREAM
1672
1673						// RETURN TO GET ANOTHER CODE
1674						//deflateCurValue = 0;
1675						//deflateCurValueBit = 0;
1676						//deflateCurHuffmanBitLength = deflateCodeLengthCodeSize-1;
1677						//deflateCurHuffmanTable = &deflateInternalHuffmanTable;
1678						//deflateCurHuffmanEntry = &deflateInternalHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
1679
1680						//deflateBitsLeft = deflateCodeLengthCodeSize;
1681
1682						if (!toStream.duplicateFromEnd(deflateDistance, deflateLength)) {
1683							//////OutputDebugStringA("deflate - corrupt data - distance, length forced decoder out of range\n");
1684							return StreamData.Invalid;
1685						}
1686
1687						decoderState = DEFLATE_STATE_DEFLATE_DYNAMIC_DECODER;
1688
1689						//////OutputDebugString(S("deflate - code found: len:") + String(deflateLength) + S(" dist: ") + String(deflateDistance) + S("\n"));
1690
1691						//////OutputDebugString(S("<len ") + String(deflateLength));
1692						//////OutputDebugString(S(", dis ") + String(deflateDistance) + S(">\n"));
1693
1694					}
1695				}
1696
1697				continue;
1698
1699				// CURVALUE IS THE RESULT OF THE EXTRA BITS //
1700			case DEFLATE_STATE_DEFLATE_DYNAMIC_GET_DIST_EX:
1701				//----writeln("deflate dynamic get dist ex");
1702
1703				deflateDistance += deflateCurValue;
1704
1705				deflateCurValue = 0;
1706				deflateCurValueBit = 0;
1707				//deflateCurHuffmanBitLength = deflateCodeLengthCodeSize-1;
1708				//deflateCurHuffmanTable = &deflateInternalHuffmanTable;
1709				//deflateCurHuffmanEntry = &deflateInternalHuffmanTable.huffman_entries[deflateCurHuffmanBitLength];
1710
1711				deflateBitsLeft = deflateCodeLengthCodeSize;
1712
1713				if (!toStre

Large files files are truncated, but you can click here to view the full file