summaryrefslogtreecommitdiffstats
path: root/private/windows/diamond/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'private/windows/diamond/quantum')
-rw-r--r--private/windows/diamond/quantum/arc.h28
-rw-r--r--private/windows/diamond/quantum/arith.c364
-rw-r--r--private/windows/diamond/quantum/arith.h32
-rw-r--r--private/windows/diamond/quantum/bit.c201
-rw-r--r--private/windows/diamond/quantum/bit.h20
-rw-r--r--private/windows/diamond/quantum/comp.c1103
-rw-r--r--private/windows/diamond/quantum/comp.h28
-rw-r--r--private/windows/diamond/quantum/crc32.h4
-rw-r--r--private/windows/diamond/quantum/dcomp.c764
-rw-r--r--private/windows/diamond/quantum/dcomp.h32
-rw-r--r--private/windows/diamond/quantum/decomp.h30
-rw-r--r--private/windows/diamond/quantum/defs.h43
-rw-r--r--private/windows/diamond/quantum/dirs1
-rw-r--r--private/windows/diamond/quantum/dirwalk.h88
-rw-r--r--private/windows/diamond/quantum/dummy.h46
-rw-r--r--private/windows/diamond/quantum/log.h7
-rw-r--r--private/windows/diamond/quantum/lz.c719
-rw-r--r--private/windows/diamond/quantum/lz.h60
-rw-r--r--private/windows/diamond/quantum/mem.h11
-rw-r--r--private/windows/diamond/quantum/qci.c249
-rw-r--r--private/windows/diamond/quantum/qci.h268
-rw-r--r--private/windows/diamond/quantum/qci.nt/makefile2
-rw-r--r--private/windows/diamond/quantum/qci.nt/sources16
-rw-r--r--private/windows/diamond/quantum/qdi.c446
-rw-r--r--private/windows/diamond/quantum/qdi.h445
-rw-r--r--private/windows/diamond/quantum/qdi.nt/makefile2
-rw-r--r--private/windows/diamond/quantum/qdi.nt/sources15
-rw-r--r--private/windows/diamond/quantum/qdi_int.h35
-rw-r--r--private/windows/diamond/quantum/quantum.h71
-rw-r--r--private/windows/diamond/quantum/rtl.h23
-rw-r--r--private/windows/diamond/quantum/view.h15
31 files changed, 5168 insertions, 0 deletions
diff --git a/private/windows/diamond/quantum/arc.h b/private/windows/diamond/quantum/arc.h
new file mode 100644
index 000000000..3e196da50
--- /dev/null
+++ b/private/windows/diamond/quantum/arc.h
@@ -0,0 +1,28 @@
+// ARC.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __ARC
+#define __ARC
+
+#include <stdio.h>
+#include "quantum.h"
+
+
+typedef struct
+ {
+ FILE *ArcFile, *TxtFile;
+ APARMS *AParms;
+ int OpenCounter;
+ } ARC;
+
+
+void Arc_Header_Read( APARMS *AParms );
+void Arc_Create( APARMS *AParms );
+void Arc_Extract( APARMS *AParms, BOOL ExtractFlag );
+
+#endif // arc.h
diff --git a/private/windows/diamond/quantum/arith.c b/private/windows/diamond/quantum/arith.c
new file mode 100644
index 000000000..bc30a0e89
--- /dev/null
+++ b/private/windows/diamond/quantum/arith.c
@@ -0,0 +1,364 @@
+// ARITH.C
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 Cinematronics
+// All rights reserved.
+//
+// This file contains trade secrets of Cinematronics.
+// Do NOT distribute!
+
+#include "arith.h"
+#include "bit.h"
+
+
+#define CODE_VALUE_BITS 16 // number of bits in a code value
+
+#define TOP_VALUE ((1L << CODE_VALUE_BITS)-1) // largest code value
+
+
+#ifdef PAQ
+
+struct
+ {
+ unsigned short Low, High;
+ unsigned short Code;
+ int UnderflowBits;
+ } Arith;
+
+
+void FAST Arith_Init( void )
+ {
+ Bit_Init();
+
+ Arith.Low = 0;
+ Arith.High = TOP_VALUE;
+ Arith.UnderflowBits = 0;
+ }
+
+
+// Flush the remaining significant bits.
+
+void FAST Arith_Close( void )
+ {
+ Bit_Write( Arith.Low & 0x4000 );
+
+ Arith.UnderflowBits++;
+
+ while( Arith.UnderflowBits > 0 )
+ {
+ Bit_Write( ~Arith.Low & 0x4000 );
+
+ Arith.UnderflowBits--;
+ }
+
+ // Just output enough bits to fill another word so we don't
+ // run out of bits in the final call to Arith_Remove_Symbol.
+
+ Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 );
+ Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 );
+ Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 );
+ Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 ); Bit_Write( 0 );
+
+ Bit_Flush();
+ }
+
+
+void FAST Arith_Encode_Bits( int Value, int NumBits )
+ {
+#ifdef BIT_CONSTANTS
+ Bit_Delayed_Write( CODE_VALUE_BITS + Arith.UnderflowBits, Value, NumBits );
+#else
+ SYMBOL Symbol;
+ int V;
+
+ if( NumBits >= 12 )
+ {
+ NumBits -= 12;
+
+ V = Value >> NumBits;
+
+ Symbol.Scale = 1 << 12;
+ Symbol.Low = V & ((1 << 12) - 1);
+ Symbol.High = Symbol.Low + 1;
+
+ Arith_Encode_Symbol( &Symbol );
+ }
+
+ if( NumBits )
+ {
+ Symbol.Scale = 1 << NumBits;
+ Symbol.Low = Value & (Symbol.Scale - 1);
+ Symbol.High = Symbol.Low + 1;
+
+ Arith_Encode_Symbol( &Symbol );
+ }
+#endif
+ }
+
+
+void FAST Arith_Encode_Symbol( SYMBOL *Symbol )
+ {
+ unsigned long Range;
+
+ // These three lines rescale high and low for the new symbol.
+
+ Range = (unsigned long) (Arith.High - Arith.Low) + 1L;
+ Arith.High = Arith.Low +
+ (unsigned short)((Range * Symbol->High) / Symbol->Scale - 1);
+ Arith.Low = Arith.Low +
+ (unsigned short)((Range * Symbol->Low) / Symbol->Scale);
+
+ // This loop turns out new bits until high and low are far enough
+ // apart to have stabilized.
+
+ while( 1 )
+ {
+ // If this test passes, it means that the MSDigits match, and can
+ // be sent to the output stream.
+
+ if( (Arith.High & 0x8000) == (Arith.Low & 0x8000) )
+ {
+ Bit_Write( Arith.High & 0x8000 );
+
+ while( Arith.UnderflowBits > 0 )
+ {
+ Bit_Write( ~Arith.High & 0x8000 );
+
+ Arith.UnderflowBits--;
+ }
+ }
+ else
+ {
+ // If this test passes, the numbers are in danger of underflow, because
+ // the MSDigits don't match, and the 2nd digits are just one apart.
+
+ if( (Arith.Low & 0x4000) && !(Arith.High & 0x4000) )
+ {
+ Arith.UnderflowBits++;
+
+ Arith.Low &= 0x3FFF;
+ Arith.High |= 0x4000;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ Arith.Low <<= 1;
+ Arith.High <<= 1;
+
+ Arith.High++;
+ }
+ }
+
+#else // UNPAQ
+
+#ifdef UNPAQLIB
+
+extern char *pbSource;
+extern int cbSource;
+extern int fSourceOverflow;
+
+static int BitsValid;
+static int BitsValue;
+
+#define Bit_Init() /* void Bit_Init(void) */ \
+ ( /* { */ \
+ BitsValid = 0 /* BitsValid = 0; */ \
+ ) /* } */
+
+#define Bit_Read() /* int Bit_Read(void) */ \
+ ( /* { */ \
+ BitsValid ? /* if (BitsValid != 0) */ \
+ ( /* { */ \
+ BitsValid--, /* BitsValid--; */ \
+ BitsValue <<= 1, /* BitsValue <<= 1; */ \
+ (BitsValue & 0x0100) /* return(BitsValue & 0x0100); */ \
+ ) /* } */ \
+ : /* else */ \
+ ( /* { */ \
+ cbSource ? /* if (cbSource != 0) */ \
+ ( /* { */ \
+ cbSource--, /* cbSource--; */ \
+ BitsValid = 7, /* BitsValid = 7; */ \
+ BitsValue = *pbSource++, /* BitsValue = *pbSource++; */ \
+ BitsValue <<= 1, /* BitsValue <<= 1; */ \
+ (BitsValue & 0x0100) /* return(BitsValue & 0x0100); */ \
+ ) /* } */ \
+ : /* else */ \
+ ( /* { */ \
+ fSourceOverflow = 1, /* fSourceOverflow = 1; */ \
+ 0 /* return(0); */ \
+ ) /* } */ \
+ ) /* } */ \
+ ) /* } */
+
+#endif /* def UNPAQLIB */
+
+struct
+ {
+ unsigned short Low, High;
+ unsigned short Code;
+ } Arith;
+
+
+void FAST Arith_Init( void )
+ {
+ int i;
+
+ Bit_Init();
+
+ for( i = sizeof( Arith.Code ) * 8; i; i-- )
+ {
+ Arith.Code <<= 1;
+ if (Bit_Read())
+ {
+ Arith.Code |= 1;
+ }
+ }
+
+ Arith.Low = 0;
+ Arith.High = TOP_VALUE;
+ }
+
+
+long FAST Arith_Decode_Bits( int NumBits )
+ {
+#ifdef BIT_CONSTANTS
+ register long Value = 0;
+
+ while( NumBits-- )
+ {
+ Value <<= 1;
+
+ if (Bit_Read())
+ {
+ Value |= 1;
+ }
+ }
+
+ return( Value );
+#else
+ long Value = 0;
+ SYMBOL Symbol;
+ int i;
+
+ if( NumBits >= 12 )
+ {
+ NumBits -= 12;
+
+ Symbol.Scale = 1 << 12;
+
+ Value = Arith_GetCount( Symbol.Scale );
+
+ Symbol.Low = Value;
+ Symbol.High = Value + 1;
+
+ Arith_Remove_Symbol( Symbol );
+ }
+
+ if( NumBits )
+ {
+ Symbol.Scale = 1 << NumBits;
+
+ i = Arith_GetCount( Symbol.Scale );
+
+ Symbol.Low = i;
+ Symbol.High = i + 1;
+
+ Arith_Remove_Symbol( Symbol );
+
+ Value = (Value << NumBits) + i;
+ }
+
+ return( Value );
+#endif
+ }
+
+
+/*
+ * When decoding, this routine is called to figure out which symbol
+ * is presently waiting to be decoded. This routine expects to get
+ * the current model scale in the s->scale parameter, and it returns
+ * a count that corresponds to the present floating point code:
+ *
+ * code = count / s->scale
+ */
+
+int FAST2 Arith_GetCount( unsigned short Scale )
+ {
+ unsigned long Range;
+ short int Count;
+
+ Range = (unsigned long) (Arith.High - Arith.Low) + 1L;
+ Count = (short) ( ((
+ (unsigned long)(Arith.Code - Arith.Low) + 1L) * Scale - 1) / Range);
+
+ return( Count );
+ }
+
+
+void FAST Arith_Close( void )
+ {
+ }
+
+
+/*
+ * Just figuring out what the present symbol is doesn't remove
+ * it from the input bit stream. After the character has been
+ * decoded, this routine has to be called to remove it from the
+ * input stream.
+ */
+
+void FAST2 Arith_Remove_Symbol( SYMBOL Symbol )
+ {
+ unsigned long Range;
+
+ // First, the range is expanded to account for the symbol removal.
+
+ Range = (unsigned long) (Arith.High - Arith.Low) + 1L;
+ Arith.High = Arith.Low +
+ (unsigned short)((Range * Symbol.High) / Symbol.Scale - 1);
+ Arith.Low = Arith.Low +
+ (unsigned short)((Range * Symbol.Low) / Symbol.Scale);
+
+ // Next, any possible bits are shipped out.
+
+ while( 1 )
+ {
+ // If the MSDigits match, the bits will be shifted out.
+
+ if ((Arith.High ^ Arith.Low) & 0x8000)
+ {
+ // Else, if underflow is threatening, shift out the 2nd MSDigit.
+
+ if( (Arith.Low & 0x4000) && (Arith.High & 0x4000) == 0 )
+ {
+ Arith.Code ^= 0x4000;
+ Arith.Low &= 0x3FFF;
+ Arith.High |= 0x4000;
+ }
+ else
+ {
+ // Otherwise, nothing can be shifted out, so I return.
+
+ return;
+ }
+ }
+
+ Arith.Low <<= 1;
+ Arith.High <<= 1;
+ Arith.High |= 1;
+ Arith.Code <<= 1;
+
+ if (Bit_Read())
+ {
+ Arith.Code |= 1;
+ }
+ }
+ }
+
+#endif /* PAQ */
diff --git a/private/windows/diamond/quantum/arith.h b/private/windows/diamond/quantum/arith.h
new file mode 100644
index 000000000..c80bf349a
--- /dev/null
+++ b/private/windows/diamond/quantum/arith.h
@@ -0,0 +1,32 @@
+// ARITH.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __ARITH
+#define __ARITH
+
+#include "defs.h"
+
+typedef struct
+ {
+ unsigned short Low, High;
+ unsigned short Scale;
+ } SYMBOL;
+
+
+void FAST Arith_Init( void );
+void FAST Arith_Close( void );
+
+void FAST Arith_Encode_Symbol( SYMBOL *Symbol );
+void FAST Arith_Encode_Bits( int Value, int NumBits );
+
+long FAST Arith_Decode_Bits( int NumBits );
+
+int FAST2 Arith_GetCount( unsigned short Scale );
+void FAST2 Arith_Remove_Symbol( SYMBOL Symbol );
+
+#endif // arith.h
diff --git a/private/windows/diamond/quantum/bit.c b/private/windows/diamond/quantum/bit.c
new file mode 100644
index 000000000..ebf9b8d65
--- /dev/null
+++ b/private/windows/diamond/quantum/bit.c
@@ -0,0 +1,201 @@
+// BIT.C
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 Cinematronics
+// All rights reserved.
+//
+// This file contains trade secrets of Cinematronics.
+// Do NOT distribute!
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef PAQLIB //msliger
+#include "arc.h"
+#endif //msliger
+
+#ifdef PAQLIB //msliger
+#include "quantum.h" //msliger
+#endif //msliger
+
+#include "bit.h"
+
+#ifndef PAQLIB //msliger
+extern ARC Arc; //msliger
+#endif //msliger
+
+#ifdef PAQLIB //msliger
+extern char *pbTarget; //msliger
+extern int cbTarget; //msliger
+extern int fTargetOverflow; //msliger
+extern int cbResult; //msliger
+#endif //msliger
+
+
+#define DELAYED_WRITE_QUEUE_SIZE 512
+
+typedef struct _DELAYED_WRITE
+ {
+ long BitCounter; // when TotalBits == BitCounter, write it out
+ int Value;
+ int NumBits;
+ struct _DELAYED_WRITE *Next; // for the circular queue
+ } DELAYED_WRITE;
+
+
+struct
+ {
+ int NumBits;
+ long TotalBits;
+ short This;
+
+#ifdef BIT_CONSTANTS
+ DELAYED_WRITE *Head, *Tail; // circular queue of delayed writes
+ DELAYED_WRITE Queue[ DELAYED_WRITE_QUEUE_SIZE ];
+ long QueueSize; // number of bits waiting in the queue
+#endif
+ } Bit;
+
+
+#ifdef PAQ //msliger
+#ifndef PAQLIB //msliger
+long Bit_GetTotal( void )
+ {
+ return( Bit.TotalBits );
+ }
+#endif //PAQLIB //msliger
+#endif //PAQ //msliger
+
+
+void Bit_Init( void )
+ {
+#ifdef BIT_CONSTANTS //msliger
+ int i;
+#endif //msliger
+
+ Bit.TotalBits = Bit.NumBits = 0;
+
+#ifdef BIT_CONSTANTS
+ for( i = 0; i < DELAYED_WRITE_QUEUE_SIZE - 1; i++ )
+ {
+ Bit.Queue[ i ].Next = &Bit.Queue[ i + 1 ];
+ }
+
+ Bit.Queue[ DELAYED_WRITE_QUEUE_SIZE - 1 ].Next = Bit.Queue;
+
+ Bit.Head = Bit.Tail = Bit.Queue;
+ Bit.QueueSize = 0;
+#endif
+ }
+
+#ifdef UNPAQ //msliger
+
+int Bit_Read( void )
+ {
+ if( !Bit.NumBits )
+ {
+ Bit.NumBits = 8;
+
+ if( (Bit.This = fgetc( Arc.ArcFile )) == EOF )
+ {
+ puts( "ERR: Premature EOF in input." );
+ exit( -1 );
+ }
+ }
+
+ Bit.This <<= 1;
+ Bit.NumBits--;
+
+ return( Bit.This & 0x0100 );
+ }
+
+#endif /* UNPAQ */ //msliger
+
+#ifdef PAQ //msliger
+
+void Bit_Write( int Value )
+ {
+ Bit.This <<= 1;
+
+ if( Value ) Bit.This++;
+
+ Bit.TotalBits++;
+
+ if( ++Bit.NumBits == 8 )
+ {
+ Bit.NumBits = 0;
+#ifndef PAQLIB //msliger
+ putc( Bit.This, Arc.ArcFile );
+#else //msliger
+ if (cbTarget) //msliger
+ { //msliger
+ cbTarget--; //msliger
+ *pbTarget++ = (BYTE) Bit.This; //msliger
+ cbResult++; //msliger
+ } //msliger
+ else //msliger
+ { //msliger
+ fTargetOverflow = 1; //msliger
+ } //msliger
+#endif //msliger
+ }
+
+#ifdef BIT_CONSTANTS
+ // Write out any bits that have been buffered.
+
+ while( Bit.QueueSize && Bit.Head->BitCounter == Bit.TotalBits )
+ {
+ Bit.QueueSize -= Bit.Head->NumBits;
+
+ while( Bit.Head->NumBits-- )
+ {
+ Bit_Write( Bit.Head->Value & (1L << Bit.Head->NumBits) );
+ }
+
+ Bit.Head = Bit.Head->Next;
+ }
+#endif
+ }
+
+
+#ifdef BIT_CONSTANTS
+void Bit_Delayed_Write( int Delay, int Value, int NumBits )
+ {
+ if( NumBits )
+ {
+ Bit.Tail->BitCounter = Bit.TotalBits + Bit.QueueSize + Delay;
+ Bit.Tail->Value = Value;
+ Bit.Tail->NumBits = NumBits;
+
+ Bit.Tail = Bit.Tail->Next;
+
+ Bit.QueueSize += NumBits;
+
+ if( Bit.Tail == Bit.Head )
+ {
+ puts( "ERR: Delayed-write buffer overflowed." );
+ exit( -1 );
+ }
+ }
+ }
+#endif
+
+
+void Bit_Flush( void )
+ {
+ while( Bit.NumBits )
+ {
+ Bit_Write( 0 );
+ }
+
+#ifdef BIT_CONSTANTS
+ if( Bit.QueueSize )
+ {
+ puts( "ERR: Delayed-write buffer underflowed." );
+ exit( -1 );
+ }
+#endif
+ }
+#endif /* PAQ */ //msliger
diff --git a/private/windows/diamond/quantum/bit.h b/private/windows/diamond/quantum/bit.h
new file mode 100644
index 000000000..fe3fc6ddc
--- /dev/null
+++ b/private/windows/diamond/quantum/bit.h
@@ -0,0 +1,20 @@
+// BIT.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __BITIO
+#define __BITIO
+
+
+void Bit_Init( void );
+int Bit_Read( void );
+void Bit_Write( int Value );
+void Bit_Delayed_Write( int Delay, int Value, int NumBits );
+void Bit_Flush( void );
+long Bit_GetTotal( void );
+
+#endif // bit.h
diff --git a/private/windows/diamond/quantum/comp.c b/private/windows/diamond/quantum/comp.c
new file mode 100644
index 000000000..1d066fdee
--- /dev/null
+++ b/private/windows/diamond/quantum/comp.c
@@ -0,0 +1,1103 @@
+// COMP.C
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 Cinematronics
+// All rights reserved.
+//
+// This file contains trade secrets of Cinematronics.
+// Do NOT distribute!
+
+/*
+ * History
+ *
+ * 06-Jul-1994 msliger fixes for MIPS
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef STAFFORD
+#include <alloc.h>
+#include <mem.h>
+#else
+#include <string.h> // Get memmove()
+#endif // STAFFORD
+
+#include "quantum.h"
+#ifndef PAQLIB //msliger
+#include "arc.h"
+#endif //msliger
+#include "rtl.h"
+#include "comp.h"
+#include "lz.h"
+
+#ifdef PAQLIB //msliger
+#include "arith.h" //msliger
+#endif //msliger
+
+
+#ifndef PAQLIB //msliger
+extern ARC Arc;
+#endif //msliger
+
+
+#define HASH_SHIFT 6
+#define HASH_BITS (HASH_SHIFT * 3)
+
+#define HASH_MASK ((1L << HASH_BITS) - 1)
+#define HASH_UPDATE( x ) \
+ (Comp.HashVal = (WORD)(((Comp.HashVal << HASH_SHIFT) ^ (x)) & HASH_MASK))
+ //4 1 1321 1 1 12 34
+
+
+#define HASH_TABLE_SIZE (1L << HASH_BITS)
+
+#define MAX_MOVES 8
+#define MAX_MATCHES (MAX_MOVES-1)
+
+
+typedef struct
+ {
+#ifndef PAQLIB //msliger
+ FILE *TxtFile; // the current file being compressed
+#else //msliger
+ BYTE *pbSource; //msliger the source data buffer
+ int cbSource; //msliger available source data size
+ BYTE WindowBits; //msliger needed in Comp_Reset()
+#endif //msliger
+
+ BYTE *Buf; // the file buffer
+ int Cur; // current position in the buffer
+ int Left; // left and right edges in the buffer
+ int Right;
+
+ long BufSize; // size of the buffer
+
+ DWORD FileSize; // size of the file being compressed
+ DWORD Compressed; // bytes compressed so far
+
+ int *MatchTable; // hash table for identifying matches
+ int *MatchChain; // match chain
+
+ long WindowSize; // size of the history window
+
+ long ValidDistances[ MATCH_MAX + 1 ]; // valid distances for each match len
+
+ WORD HashVal; // current hash value
+
+ int MatchFutilityCutoff;
+ int MaxMatches;
+
+#ifndef PAQLIB //msliger
+ BOOL ShowStatus;
+
+ WORD Checksum;
+#endif //msliger
+ //msliger
+ int ReachedEOF; //msliger track EOF, don't refill after
+ //msliger
+ int CompressionLevel; //msliger selected compression level
+ } COMP;
+
+
+COMP Comp;
+
+
+// Fills the buffer for compression.
+
+void Comp_FillBuf( void )
+ {
+ static int c;
+ int i;
+
+ // Need to move the characters down the buffer?
+
+ if( Comp.Left > 0 )
+ {
+ memmove( Comp.Buf, Comp.Buf + Comp.Left, Comp.Right - Comp.Left );
+
+ memmove( Comp.MatchChain,
+ Comp.MatchChain + Comp.Left,
+ (Comp.Right - Comp.Left) * sizeof( *Comp.MatchChain ) );
+
+ for( i = 0; i < HASH_TABLE_SIZE; i++ )
+ {
+ Comp.MatchTable[ i ] -= Comp.Left;
+
+ if( Comp.MatchTable[ i ] < 0 ) Comp.MatchTable[ i ] = -1;
+ }
+
+ Comp.Cur -= Comp.Left;
+ Comp.Right -= Comp.Left;
+
+ for( i = 0; i < Comp.Cur; i++ )
+ {
+ if (Comp.MatchChain[ i ] >= 0) //msliger
+ { //msliger
+ Comp.MatchChain[ i ] -= Comp.Left;
+ //msliger
+ if( Comp.MatchChain[ i ] < 0 ) Comp.MatchChain[ i ] = -1; //msliger
+ } //msliger
+ }
+
+ Comp.Left = 0;
+ }
+
+ // Fill the rest of the buffer from the input file.
+
+ c = ~EOF; //msliger
+
+ while( Comp.Right < Comp.BufSize &&
+#ifndef PAQLIB //msliger
+ (c = getc( Comp.TxtFile )) != EOF )
+#else //msliger
+ (c = Comp.cbSource ? //msliger
+ (Comp.cbSource--, *Comp.pbSource++) : EOF) != EOF) //msliger
+#endif //msliger
+ {
+ Comp.Buf[ Comp.Right++ ] = c;
+
+#ifndef PAQLIB //msliger
+ Comp.Checksum ^= c;
+
+ if( Comp.Checksum & 0x8000 ) // simulate a ROL in C, yucky!
+ {
+ Comp.Checksum <<= 1;
+ Comp.Checksum++;
+ }
+ else
+ {
+ Comp.Checksum <<= 1;
+ }
+#endif // !PAQLIB //msliger
+ }
+ if (c == EOF) //msliger
+ { //msliger
+ Comp.ReachedEOF = 1; //msliger
+ } //msliger
+ }
+
+
+#include <sys\stat.h>
+
+void Comp_Init( BYTE WindowBits, int CompressionLevel ) //msliger
+ {
+ int i;
+ long MinBufSize;
+ BYTE *TotalBuf;
+ void *Reserved;
+#ifndef PAQLIB //msliger
+ struct stat statbuf;
+
+ // If stdout is redirected to a file don't
+ // display the percent-complete info.
+
+ fstat( fileno( stdout ), &statbuf );
+ Comp.ShowStatus = (statbuf.st_mode & S_IFCHR);
+#endif //msliger
+
+ Comp.WindowSize = 1 << WindowBits;
+ Comp.CompressionLevel = CompressionLevel; //msliger
+
+#ifdef PAQLIB //msliger
+ Comp.WindowBits = WindowBits; //msliger
+#endif //msliger
+
+ Comp.ValidDistances[ MATCH_MIN ] = (1L << TINY_WINDOW_MAX);
+ Comp.ValidDistances[ MATCH_MIN + 1 ] = (1L << SHORT_WINDOW_MAX);
+
+ for( i = MATCH_MIN + 2; i <= MATCH_MAX; i++ )
+ {
+ Comp.ValidDistances[ i ] = (1L << WINDOW_MAX) - 1;
+ }
+
+ Lz_Init( WindowBits ); //msliger
+
+ // Set aside 64K of reserved space so we don't use all
+ // available memory for the history buffer. This is just
+ // to make sure there is room for file buffers, growing
+ // the stack etc later.
+
+ Reserved = Rtl_Malloc( 64 * 1024L );
+
+ Comp.MatchTable = Rtl_Malloc( HASH_TABLE_SIZE * sizeof( int ) );
+
+ MinBufSize = Comp.WindowSize + MATCH_MAX + 1024;
+
+#if 1
+ for( Comp.BufSize = MinBufSize * 2;
+ Comp.BufSize >= MinBufSize;
+ Comp.BufSize -= 0x8000 )
+ {
+ TotalBuf = Rtl_Malloc( Comp.BufSize * (sizeof( int ) + 1) );
+
+ if( TotalBuf ) break;
+ }
+#else
+ Comp.BufSize = MinBufSize * 5 / 4;
+
+ TotalBuf = Rtl_Malloc( Comp.BufSize * (sizeof( int ) + 1) );
+#endif
+
+ if( !TotalBuf || !Reserved || !Comp.MatchTable )
+ {
+ puts( "ERR: Out of memory." );
+ exit( -1 );
+ }
+
+ Rtl_Free( Reserved );
+
+ /* moved the int's first to dodge a MIPS alignment fault */
+
+ Comp.MatchChain = (int *) TotalBuf;
+ Comp.Buf = TotalBuf + Comp.BufSize * sizeof(int);
+
+ if( Comp.BufSize < MinBufSize * 4 / 3 )
+ {
+ if( Comp.BufSize < MinBufSize * 8 / 7 )
+ {
+ puts( "\nCritically short of memory." );
+ puts( "Compression will be much slower." );
+ }
+ else
+ {
+ puts( "\nA few quarts low on memory." );
+ puts( "Compression will be slower." );
+ }
+ }
+
+//BUGBUG 25-May-94 msliger Init of hash tables should be done with memset
+ for( i = 0; i < HASH_TABLE_SIZE; i++ )
+ {
+ Comp.MatchTable[ i ] = -1;
+ }
+
+ for( i = 0; i < Comp.BufSize; i++ )
+ {
+ Comp.MatchChain[ i ] = -1;
+ }
+
+ Comp.Left = Comp.Cur = Comp.Right = 0;
+ }
+
+
+// Searches for the longest match in the buffer.
+// Returns the match length.
+
+int Comp_FindLongestMatch( MATCH *Match )
+ {
+ BYTE *Str;
+ BYTE *Cur;
+ int Rover;
+ int More = Comp.MatchFutilityCutoff;
+ int Len;
+ int Max;
+
+ Match->Len = 0;
+
+ if( (Rover = Comp.MatchTable[ Comp.HashVal ]) < 0 )
+ {
+ return( 0 );
+ }
+
+ Max = min( Comp.Right - Comp.Cur, MATCH_MAX );
+
+ if( Max >= MATCH_MIN )
+ {
+ while( Rover >= Comp.Left )
+ {
+ Cur = Comp.Buf + Comp.Cur;
+ Str = Comp.Buf + Rover;
+ Len = 0;
+
+ while( *Str == *Cur && Len < Max )
+ {
+ Len++;
+ Str++;
+ Cur++;
+ }
+
+ if( Len > Match->Len && Len >= MATCH_MIN )
+ {
+ if( Cur - Str <= Comp.ValidDistances[ Len ] )
+ {
+ More = Comp.MatchFutilityCutoff;
+
+ Match->Len = Len;
+ Match->Dist = Cur - Str;
+
+ if( Len == Max ) return( Len );
+ }
+ }
+
+ if( !--More ) return( Match->Len );
+
+ Rover = Comp.MatchChain[ Rover ];
+ }
+ }
+
+ return( Match->Len );
+ }
+
+
+// Searches for the longest matches in the buffer.
+// Returns the number of matches found.
+//
+// The matches are returned in order of length, that is,
+// Match[ 0 ] is the longest.
+
+int New_Comp_FindLongestMatches( MATCH Match[ MAX_MATCHES ] )
+ {
+ BYTE *Str, *Cur;
+ int i, NumMatches = 0, Rover, More = Comp.MatchFutilityCutoff;
+ int Len;
+ int Max;
+
+ Match[ 0 ].Len = 0;
+
+ if( (Rover = Comp.MatchTable[ Comp.HashVal ]) < 0 )
+ {
+ return( 0 );
+ }
+
+ Max = min( Comp.Right - Comp.Cur, MATCH_MAX );
+
+ if( Max >= MATCH_MIN )
+ {
+ while( Rover >= Comp.Left )
+ {
+ Cur = Comp.Buf + Comp.Cur;
+ Str = Comp.Buf + Rover;
+ Len = 0;
+
+ while( *Str == *Cur && Len < Max )
+ {
+ Len++;
+ Str++;
+ Cur++;
+ }
+
+ if( Len > Match[ 0 ].Len && Len >= MATCH_MIN )
+ {
+ if( Cur - Str <= Comp.ValidDistances[ Len ] )
+ {
+ More = Comp.MatchFutilityCutoff;
+
+ // Move the other matches down
+ for( i = Comp.MaxMatches - 1; i > 0; i-- )
+ {
+ Match[ i ] = Match[ i - 1 ];
+ }
+
+ Match[ 0 ].Len = Len;
+ Match[ 0 ].Dist = Cur - Str;
+
+ if( NumMatches < Comp.MaxMatches ) NumMatches++;
+
+ if( Len == Max ) break;
+ }
+ }
+
+ if( !--More ) break;
+
+ Rover = Comp.MatchChain[ Rover ];
+ }
+ }
+
+ return( NumMatches );
+ }
+
+
+int Comp_FindLongestMatches( MATCH Match[ MAX_MATCHES ] )
+ {
+ int i, j, Num;
+
+ Num = New_Comp_FindLongestMatches( Match );
+
+ if( Num == 0 || Num == Comp.MaxMatches ) return( Num );
+
+ // OK, here's a trick. If there are fewer than Comp.MaxMatches matches try
+ // to synthesize shorter matches by copying matches and reducing their
+ // lengths by one.
+
+ for( i = 0; i < Num - 1 && Num < Comp.MaxMatches; i++ )
+ {
+ if( Match[ i ].Len > Match[ i + 1 ].Len + 1 )
+ {
+ if( Match[ i ].Dist <= Comp.ValidDistances[ Match[ i ].Len - 1 ] )
+ {
+ // Move the other matches down
+ for( j = Num; j > i; j-- )
+ {
+ Match[ j ] = Match[ j - 1 ];
+ }
+
+ Match[ i + 1 ].Len--;
+
+ Num++;
+ }
+ }
+ }
+
+ for( i = 1; i < Comp.MaxMatches; i++ )
+ {
+ if( i == Num )
+ {
+ Match[ i ] = Match[ i - 1 ];
+
+ Match[ i ].Len--;
+
+ if( Match[ i ].Dist <= Comp.ValidDistances[ Match[ i ].Len ] )
+ {
+ Num++;
+ }
+ }
+ }
+
+ return( Num );
+ }
+
+
+void Comp_Advance( int NumBytes )
+ {
+ Comp.Compressed += NumBytes;
+
+ while( NumBytes-- )
+ {
+ Comp.MatchChain[ Comp.Cur ] = Comp.MatchTable[ Comp.HashVal ];
+
+ #ifdef DEBUG
+ if( Comp.MatchChain[ Comp.Cur ] >= Comp.Cur )
+ {
+ puts( "ERR: Advance." );
+ exit( -1 );
+ }
+ #endif
+
+ Comp.MatchTable[ Comp.HashVal ] = Comp.Cur;
+
+ Comp.Cur++;
+
+ HASH_UPDATE( Comp.Buf[ Comp.Cur + 2 ] );
+ }
+
+ if( Comp.Cur > Comp.WindowSize )
+ {
+ Comp.Left = Comp.Cur - Comp.WindowSize;
+ }
+ else
+ {
+ Comp.Left = 0;
+ }
+
+//BUGBUG 25-May-94 msliger (fixed) needed buffer refill before WindowSize
+// So I moved the refill call down to make it not conditional on
+// Cur > WindowSize.
+//BUGBUG 25-May-94 msliger (fixed) Source data overshoot
+// This code must limit itself to the amount of data currently in
+// the window. The size of the buffer is immaterial at this point.
+ if (( Comp.Cur >= Comp.Right - MATCH_MAX ) //msliger
+ && (!Comp.ReachedEOF)) //msliger no needless memmove
+ { //msliger
+ Comp_FillBuf(); //msliger
+ } //msliger
+ }
+
+
+int Comp_FindBetterMatch( int OldMatchLen )
+ {
+ MATCH Match;
+ WORD OldHashVal = Comp.HashVal;
+
+ Comp.Cur++;
+
+ HASH_UPDATE( Comp.Buf[ Comp.Cur + 2 ] );
+
+ Comp_FindLongestMatch( &Match );
+
+ Comp.Cur--;
+ Comp.HashVal = OldHashVal;
+
+ return( Match.Len > OldMatchLen );
+ }
+
+
+typedef double CostType;
+
+
+typedef struct
+ {
+ CostType Cost; // cost, in bits (scaled if an int)
+ short int Literal; // -1 if it's really a match
+ MATCH Match; // if it's a literal then Match.Len == 1
+ } MOVE;
+
+
+typedef struct
+ {
+ short int Best; // best move
+ short int Cur; // current move being tried, may become Best
+ short int NumMoves; // number of moves, 1 to MAX_MOVES
+ MOVE Moves[ MAX_MOVES ];
+ } OPT_ITEM;
+
+#define TREE_SIZE (MATCH_MAX * 5)
+
+struct
+ {
+ int Len; // number of items
+ #ifdef DEBUG
+ int NumSolutions;
+ #endif
+ CostType TotalCost[ TREE_SIZE + 1 ];
+ OPT_ITEM List[ TREE_SIZE + 1 ];
+ } Opt;
+
+
+void Search( int Node, CostType CostSoFar )
+ {
+ int i;
+
+ if( Node >= Opt.Len ) // finished?
+ {
+ #ifdef DEBUG
+ if( Node > Opt.Len )
+ {
+ puts( "ERR: Exceeded table size limit." );
+ exit( -1 );
+ }
+ #endif
+
+ if( CostSoFar < Opt.TotalCost[ Node ] )
+ {
+ #ifdef DEBUG
+ Opt.NumSolutions++;
+ #endif
+
+ Opt.TotalCost[ Node ] = CostSoFar;
+
+ // save the best path
+
+ for( i = 1; i < Opt.Len; i++ )
+ {
+ Opt.List[ i ].Best = -1;
+ }
+
+ for( i = 0; i < Opt.Len; )
+ {
+#if 0
+ x = Opt.List[ i ].Cur;
+
+ Opt.List[ i ].Best = x;
+
+ i += Opt.List[ i ].Moves[ x ].Match.Len;
+#else
+ i += Opt.List[ i ].Moves[ Opt.List[ i ].Best =
+ Opt.List[ i ].Cur ].Match.Len;
+#endif
+ }
+ }
+ }
+ else
+ {
+ if( CostSoFar < Opt.TotalCost[ Node ] )
+ {
+ if( CostSoFar < Opt.TotalCost[ Opt.Len ] )
+ {
+ if( Opt.List[ Node ].Best >= 0 )
+ {
+ static CostType Diff;
+
+ // Aha! We have found an intersection into a best-path.
+ // Saves us a lot of time!
+
+ // First, update the costs from the point of intersection
+ // to the goal.
+
+ Diff = Opt.TotalCost[ Node ] - CostSoFar;
+
+ for( i = Node; i < Opt.Len; )
+ {
+ Opt.TotalCost[ i ] -= Diff;
+
+ i += Opt.List[ i ].Moves[ Opt.List[ i ].Best ].Match.Len;
+ }
+
+ Opt.TotalCost[ i ] -= Diff; // Opt.Len
+
+ // Second, this IS the best path so eliminate any others.
+
+ for( i = 1; i < Node; i++ )
+ {
+ Opt.List[ i ].Best = -1;
+ }
+
+ // Third, update the best path to the point of intersection.
+
+ for( i = 0; i < Node; )
+ {
+#if 0
+ x = Opt.List[ i ].Cur;
+
+ Opt.List[ i ].Best = x;
+
+ i += Opt.List[ i ].Moves[ x ].Match.Len;
+#else
+ i += Opt.List[ i ].Moves[ Opt.List[ i ].Best =
+ Opt.List[ i ].Cur ].Match.Len;
+#endif
+ }
+ }
+ else
+ {
+ Opt.TotalCost[ Node ] = CostSoFar;
+
+ for( i = Opt.List[ Node ].NumMoves - 1; i >= 0; i-- ) // try each move
+ {
+ Opt.List[ Node ].Cur = i;
+
+ Search( Opt.List[ Node ].Moves[ i ].Match.Len + Node,
+ Opt.List[ Node ].Moves[ i ].Cost + CostSoFar );
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+// this outputs the final result
+
+void GenerateOutput( void )
+ {
+ int i, Best;
+
+ for( i = 0; i < Opt.Len; )
+ {
+ Best = Opt.List[ i ].Best;
+
+ #ifdef DEBUG
+ if( Best < 0 || Best >= MAX_MOVES )
+ {
+ puts( "ERR: 'Best' range." );
+ exit( -1 );
+ }
+ #endif
+
+ if( Opt.List[ i ].Moves[ Best ].Literal < 0 )
+ {
+ Lz_Encode_Match( &Opt.List[ i ].Moves[ Best ].Match );
+ }
+ else
+ {
+ Lz_Encode_Literal( Opt.List[ i ].Moves[ Best ].Literal );
+ }
+
+ i += Opt.List[ i ].Moves[ Best ].Match.Len;
+ }
+
+ #ifdef DEBUG
+ if( i != Opt.Len )
+ {
+ puts( "ERR: Misaligned output." );
+ exit( -1 );
+ }
+ #endif
+ }
+
+
+void Optimize( void )
+ {
+ int i;
+ CostType Total;
+
+ Total = 0.1;
+
+ Opt.TotalCost[ 0 ] = Total;
+
+ for( i = 0; i < Opt.Len; i++ )
+ {
+ Opt.List[ i ].Best = -1;
+
+ Total += Opt.List[ i ].Moves[ 0 ].Cost; // assume a simple literal
+
+ Opt.TotalCost[ i + 1 ] = Total;
+ }
+
+ #ifdef DEBUG
+ Opt.NumSolutions = 0;
+ #endif
+
+ Search( 0, 0 );
+
+ #ifdef DEBUG
+ if( Opt.NumSolutions == 0 )
+ {
+ puts( "ERR: No solution." );
+ exit( -1 );
+ }
+ #endif
+
+ GenerateOutput();
+ }
+
+
+// Compresses a file.
+
+void Comp_Compress_Slow( void )
+ {
+ int i, j, Len, Cut, NumMatches;
+ MATCH Match[ MAX_MATCHES ];
+#ifndef PAQLIB //msliger
+ unsigned Counter = 1024;
+#endif //msliger
+ LONGDOUBLE DeltaCost = 0.0;
+
+ while( Comp.Compressed < Comp.FileSize )
+ {
+ Cut = 1;
+ Opt.Len = 0;
+
+ while( Cut )
+ {
+#ifndef PAQLIB //msliger
+ if( --Counter == 0 ) // Reassure the user that
+ { // something is really happening.
+ Counter = 2048;
+
+ if( Comp.ShowStatus )
+ {
+ printf( "\b\b\b\b\b%4.1f%%",
+ Comp.Compressed * 99.9 / (double)Comp.FileSize );
+ }
+ }
+#endif //msliger
+
+ Cut--;
+
+ Opt.List[ Opt.Len ].NumMoves = 1;
+
+ Opt.List[ Opt.Len ].Moves[ 0 ].Literal = Comp.Buf[ Comp.Cur ];
+ Opt.List[ Opt.Len ].Moves[ 0 ].Match.Len = 1;
+ Opt.List[ Opt.Len ].Moves[ 0 ].Cost =
+ Lz_Encode_Literal_Cost( Comp.Buf[ Comp.Cur ] ) + DeltaCost;
+
+ if( (NumMatches = Comp_FindLongestMatches( Match )) != 0 )
+ {
+ Opt.List[ Opt.Len ].NumMoves = NumMatches + 1;
+
+ i = 0;
+
+ do
+ {
+ Opt.List[ Opt.Len ].Moves[ NumMatches ].Literal = -1;
+ Opt.List[ Opt.Len ].Moves[ NumMatches ].Match = Match[ i ];
+ Opt.List[ Opt.Len ].Moves[ NumMatches ].Cost =
+ Lz_Encode_Match_Cost( &Match[ i ] ) + DeltaCost;
+
+ i++;
+ }
+ while( --NumMatches );
+
+ if( Match[ 0 ].Len > Cut ) Cut = Match[ 0 ].Len - 1;
+ }
+
+ Opt.Len++;
+
+ DeltaCost = Opt.Len / (TREE_SIZE / 4.1);
+
+ Comp_Advance( 1 );
+
+ if( Opt.Len == TREE_SIZE )
+ {
+ // We've reached the end of the list so set up an artificial
+ // cutting point. This degrades compression but only very
+ // slightly. In practice, I expect this code to execute only
+ // on long run-lengths which should be pretty much optimized
+ // anyway.
+
+ Cut = 0;
+
+ // We need too make sure that no matches overlap beyond
+ // the end of the list.
+
+ for( i = Opt.Len - 1; i > Opt.Len - MATCH_MAX; i-- )
+ {
+ for( j = 1; j < Opt.List[ i ].NumMoves; j++ )
+ {
+ Len = Opt.Len - i;
+
+ if( Opt.List[ i ].Moves[ j ].Match.Len > Len )
+ {
+ // OK, now we have a match which is too long.
+ // Try to truncate it.
+
+ if( Len < MATCH_MIN || Opt.List[ i ].Moves[ j ].Match.Dist >
+ Comp.ValidDistances[ Len ] )
+ {
+ // Truncating it makes it too short so just ditch
+ // the whole thing by replacing it with its literal.
+
+ // Assume the literal is stored as the first move.
+
+ Opt.List[ i ].Moves[ j ] = Opt.List[ i ].Moves[ 0 ];
+ }
+ else
+ {
+ Opt.List[ i ].Moves[ j ].Match.Len = Len;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Optimize();
+ }
+ }
+
+
+// Compresses a file.
+
+void Comp_Compress_Fast( void )
+ {
+ MATCH Match;
+#ifndef PAQLIB //msliger
+ unsigned Counter = 2048;
+#endif //msliger
+
+ while( Comp.Compressed < Comp.FileSize )
+ {
+#ifndef PAQLIB //msliger
+ if( --Counter == 0 ) // Reassure the user that
+ { // something is really happening.
+ Counter = 4096;
+
+ if( Comp.ShowStatus )
+ {
+ printf( "\b\b\b\b\b%4.1f%%",
+ Comp.Compressed * 99.9 / (double)Comp.FileSize );
+ }
+ }
+#endif //msliger
+
+ if( Comp_FindLongestMatch( &Match ) )
+ {
+ if( Comp.CompressionLevel == 1 || //msliger
+ !Comp_FindBetterMatch( Match.Len ) )
+ {
+ Lz_Encode_Match( &Match );
+
+ Comp_Advance( Match.Len );
+ }
+ else
+ {
+ Lz_Encode_Literal( Comp.Buf[ Comp.Cur ] );
+
+ Comp_Advance( 1 );
+ }
+ }
+ else
+ {
+ Lz_Encode_Literal( Comp.Buf[ Comp.Cur ] );
+
+ Comp_Advance( 1 );
+ }
+ }
+ }
+
+
+#include "bit.h"
+
+#ifndef PAQLIB //msliger
+WORD Comp_Compress( char *FileName, long FileSize )
+ {
+ long BitsOutput = Bit_GetTotal();
+
+ Comp.FileSize = FileSize;
+ Comp.Compressed = 0;
+ Comp.Checksum = 0;
+ Comp.TxtFile = fopen( FileName, "rb" );
+ Comp.ReachedEOF = 0; //msliger
+
+ if (setvbuf(Comp.TxtFile,NULL,_IOFBF,131072)) //msliger
+ { //msliger
+ printf("source setvbuf failed.\n"); //msliger
+ } //msliger
+ //msliger
+ Comp_FillBuf();
+
+//BUGBUG 25-May-94 msliger trouble for size < 3 ?
+ HASH_UPDATE( Comp.Buf[ 0 ] );
+ HASH_UPDATE( Comp.Buf[ 1 ] );
+ HASH_UPDATE( Comp.Buf[ 2 ] );
+
+ if( Comp.ShowStatus )
+ {
+ printf( " 0.0%%" ); //BUGBUG 24-May-94 msliger (fixed) "%" to "%%"
+ }
+
+ switch( Comp.CompressionLevel ) //msliger
+ {
+ case 1:
+ Comp.MatchFutilityCutoff = 5;
+ Comp_Compress_Fast();
+ break;
+ case 2:
+ Comp.MatchFutilityCutoff = 50;
+ Comp_Compress_Fast();
+ break;
+ case 3:
+ Comp.MatchFutilityCutoff = 250;
+ Comp_Compress_Fast();
+ break;
+ case 4:
+ Comp.MatchFutilityCutoff = 100;
+ Comp.MaxMatches = MAX_MATCHES - 3;
+ Comp_Compress_Slow();
+ break;
+ case 5:
+ Comp.MatchFutilityCutoff = 200;
+ Comp.MaxMatches = MAX_MATCHES - 2;
+ Comp_Compress_Slow();
+ break;
+ case 6:
+ Comp.MatchFutilityCutoff = 400;
+ Comp.MaxMatches = MAX_MATCHES - 1;
+ Comp_Compress_Slow();
+ break;
+ case 7:
+ Comp.MatchFutilityCutoff = 1000;
+ Comp.MaxMatches = MAX_MATCHES;
+ Comp_Compress_Slow();
+ }
+
+ fclose( Comp.TxtFile );
+
+ if( Comp.ShowStatus )
+ {
+ printf( "\b\b\b\b\b\b100.0%%" );
+ }
+
+ BitsOutput = Bit_GetTotal() - BitsOutput;
+
+ if( BitsOutput == 0 ) BitsOutput = 8;
+ if( FileSize == 0 ) FileSize = 1;
+
+ printf( " %5.1f%%", ((double)BitsOutput / (double)FileSize) * (100.0/8.0) );
+
+ return( Comp.Checksum );
+ }
+#endif /* not PAQLIB */ //msliger
+
+
+#ifdef PAQLIB //msliger (entire function)
+
+int cbTarget; // public (to BIT.C)
+char *pbTarget;
+int fTargetOverflow;
+int cbResult;
+
+WORD Comp_CompressBlock( void *pbSource, UINT cbSource,
+ void *pbDest, UINT cbDest, UINT *pcbResult )
+ {
+ Comp.FileSize = cbSource;
+ Comp.Compressed = 0;
+ Comp.pbSource = pbSource;
+ Comp.cbSource = cbSource;
+ Comp.ReachedEOF = 0; //msliger
+
+ cbTarget = cbDest; // hack these along to BIT.C
+ pbTarget = pbDest;
+ fTargetOverflow = 0;
+ cbResult = 0;
+
+ Arith_Init(); // start each block clean
+
+ Comp_FillBuf();
+
+//BUGBUG 25-May-94 msliger trouble for size < 3 ?
+ HASH_UPDATE( Comp.Buf[ 0 ] );
+ HASH_UPDATE( Comp.Buf[ 1 ] );
+ HASH_UPDATE( Comp.Buf[ 2 ] );
+
+ switch( Comp.CompressionLevel ) //msliger
+ {
+ case 1:
+ Comp.MatchFutilityCutoff = 5;
+ Comp_Compress_Fast();
+ break;
+ case 2:
+ Comp.MatchFutilityCutoff = 50;
+ Comp_Compress_Fast();
+ break;
+ case 3:
+ Comp.MatchFutilityCutoff = 250;
+ Comp_Compress_Fast();
+ break;
+ case 4:
+ Comp.MatchFutilityCutoff = 100;
+ Comp.MaxMatches = MAX_MATCHES - 3;
+ Comp_Compress_Slow();
+ break;
+ case 5:
+ Comp.MatchFutilityCutoff = 200;
+ Comp.MaxMatches = MAX_MATCHES - 2;
+ Comp_Compress_Slow();
+ break;
+ case 6:
+ Comp.MatchFutilityCutoff = 400;
+ Comp.MaxMatches = MAX_MATCHES - 1;
+ Comp_Compress_Slow();
+ break;
+ case 7:
+ Comp.MatchFutilityCutoff = 1000;
+ Comp.MaxMatches = MAX_MATCHES;
+ Comp_Compress_Slow();
+ }
+
+ Arith_Close(); // flush out remaining bits
+
+ *pcbResult = cbResult;
+
+ return( fTargetOverflow );
+ }
+#endif /* PAQLIB */ //msliger
+
+
+void Comp_Close( void )
+ {
+ Lz_Close();
+
+ Rtl_Free( Comp.MatchTable );
+ Rtl_Free( Comp.MatchChain ); /* Comp.Buf goes with it */
+ }
+
+
+#ifdef PAQLIB //msliger (entire function)
+
+// this code is only suitable for use with Comp_CompressBlock()
+
+void Comp_Reset( void )
+ {
+ int i;
+
+ Lz_Close();
+ Lz_Init( Comp.WindowBits );
+
+//BUGBUG 25-May-94 msliger Init of hash tables should be done with memset
+ for( i = 0; i < HASH_TABLE_SIZE; i++ )
+ {
+ Comp.MatchTable[ i ] = -1;
+ }
+
+ for( i = 0; i < Comp.BufSize; i++ )
+ {
+ Comp.MatchChain[ i ] = -1;
+ }
+
+ Comp.Left = Comp.Cur = Comp.Right = 0;
+ }
+#endif /* PAQLIB */ //msliger
diff --git a/private/windows/diamond/quantum/comp.h b/private/windows/diamond/quantum/comp.h
new file mode 100644
index 000000000..0226e40fd
--- /dev/null
+++ b/private/windows/diamond/quantum/comp.h
@@ -0,0 +1,28 @@
+// COMP.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __COMP
+#define __COMP
+
+#include <stdio.h>
+#include "defs.h"
+
+void Comp_Init( BYTE WindowBits, int CompressionLevel ); //msliger
+void Comp_Close( void );
+
+#ifndef PAQLIB //msliger
+WORD Comp_Compress( char *FileName, long FileSize );
+#endif //msliger
+
+#ifdef PAQLIB //msliger
+WORD Comp_CompressBlock( void *pbSrc, UINT cbSrc, //msliger
+ void *pbDst, UINT cbDst, UINT *pcbResult ); //msliger
+void Comp_Reset( void ); //msliger
+#endif //msliger
+
+#endif // comp.h
diff --git a/private/windows/diamond/quantum/crc32.h b/private/windows/diamond/quantum/crc32.h
new file mode 100644
index 000000000..25da8ce55
--- /dev/null
+++ b/private/windows/diamond/quantum/crc32.h
@@ -0,0 +1,4 @@
+extern void CRC32Reset(void);
+extern void CRC32Restore(long);
+extern void CRC32Update(unsigned char *,unsigned);
+extern long CRC32Result(void);
diff --git a/private/windows/diamond/quantum/dcomp.c b/private/windows/diamond/quantum/dcomp.c
new file mode 100644
index 000000000..6985c09c5
--- /dev/null
+++ b/private/windows/diamond/quantum/dcomp.c
@@ -0,0 +1,764 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1994
+ * Copyright (c) 1993,1994 Cinematronics
+ * All Rights Reserved.
+ *
+ * DCOMP.C: decompressor core
+ *
+ * History:
+ * 08-Jul-1994 msliger Added disk-based ring buffer support.
+ * 14-Jul-1994 msliger Fixed build of UNPAQ app.
+ * 30-Aug-1994 msliger Fixed marking buffer dirty if newest.
+ * 01-Feb-1995 msliger Fixed reporting ring init failures.
+ */
+
+// DCOMP.C
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 Cinematronics
+// All rights reserved.
+//
+// This file contains trade secrets of Cinematronics.
+// Do NOT distribute!
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef STAFFORD
+#include <alloc.h>
+#endif // STAFFORD
+
+#include "quantum.h"
+
+#ifndef UNPAQLIB //msliger
+#include "arc.h"
+#endif //msliger
+
+#include "dcomp.h"
+#include "lz.h"
+#include "rtl.h"
+
+#ifndef UNPAQLIB //msliger
+extern ARC Arc;
+#endif //msliger
+
+#ifdef UNPAQLIB //msliger
+#include "arith.h"
+#endif
+
+#ifdef UNPAQLIB
+#define DISK_RING /* enable DISK_RING support code */
+#endif
+
+#ifdef DISK_RING
+#include <fcntl.h> /* for disk ring buffer code */
+#include <sys\stat.h>
+
+#include "qdi.h" /* for RINGNAME, file functions */
+#include "qdi_int.h" /* lastContext */
+#endif //msliger
+
+
+typedef struct
+ {
+ BYTE HUGE *Buf; // history buffer: NULL -> using disk ring buffer
+ BYTE HUGE *BufEnd; // last byte in history buffer + 1
+
+ BYTE HUGE *CurPtr; // pointer to oldest byte in history buffer
+ unsigned long Cur; // current position in the history buffer
+ long WindowMask; // used to normalize Cur for wrapping
+ long WindowSize; // size of the history window
+#ifndef UNPAQLIB //msliger
+ long NumBytes; // total number of bytes to decompress
+ FILE *OutFile; // the output file
+ WORD Checksum;
+#else //msliger
+ unsigned short NumBytes; // total number of bytes to decompress
+ BYTE *OutBuffer; //msliger the output buffer
+ int fOutOverflow; //msliger if too little space in output buffer
+ BYTE WindowBits; //msliger needed in DComp_Reset()
+ int fRingFault; // if disk callbacks fail
+#endif //msliger
+ } DCOMP;
+
+
+DCOMP DComp;
+
+void (FAST2 NEAR *DComp_Token_Match)( MATCH Match );
+void (FAST2 NEAR *DComp_Token_Literal)( int Chr );
+
+static void FAST2 DComp_Internal_Match( MATCH Match );
+static void FAST2 DComp_Internal_Literal( int Chr );
+
+
+#ifdef DISK_RING /* virtual ring manager */
+
+#define BUFFER_SIZE (4096) /* must be 2^Nth */
+
+#define MIN_BUFFERS 3 /* minimum number we want */
+
+
+typedef struct aBuffer
+{
+ struct aBuffer FAR *pLinkNewer; /* link to more recently used */
+ struct aBuffer FAR *pLinkOlder; /* link to less recently used */
+ int BufferPage; /* what page this is, -1 -> invalid */
+ int BufferDirty; /* NZ -> needs to be written */
+ BYTE Buffer[BUFFER_SIZE]; /* content */
+} BUFFER, FAR *PBUFFER;
+
+
+typedef struct
+{
+ PBUFFER pBuffer; /* pointer to buffer, NULL if not present */
+ int fDiskValid; /* NZ -> this page has been written to disk */
+} PAGETABLEENTRY;
+
+
+static struct
+{
+ int Handle; /* ring file handle */
+ PBUFFER RingBuffer; /* current output ring buffer */
+ BYTE FAR *RingPointer; /* current output pointer (into RingBuffer) */
+ BYTE FAR *RingPointerLimit; /* address of last byte of RingBuffer + 1 */
+ int RingPages; /* how many pages there are total */
+ PBUFFER pNewest; /* pointer to most recently used buffer */
+ PBUFFER pOldest; /* pointer to least recently used buffer */
+ PAGETABLEENTRY FAR *PageTable; /* pointer to array of pointers */
+} Disk;
+
+
+static int FAST DComp_Ring_Init(void);
+static void FAST DComp_Ring_Reset(void);
+static PBUFFER FAST DComp_Ring_Load(int page,int fWrite);
+static void FAST2 DComp_Ring_Match( MATCH Match );
+static void FAST2 DComp_Ring_Literal( int Chr );
+static void FAST DComp_Ring_Close(void);
+
+#endif /* DISK_RING */
+
+
+int FAST DComp_Init( BYTE WindowBits ) //msliger
+ {
+ DComp.WindowSize = 1L << WindowBits; //msliger
+ DComp.WindowMask = DComp.WindowSize - 1;
+ DComp.Cur = 0;
+
+#ifdef UNPAQLIB //msliger
+ DComp.fRingFault = 0;
+ DComp.WindowBits = WindowBits; //msliger
+#endif //msliger
+
+ if( (DComp.Buf = Rtl_Malloc( DComp.WindowSize )) != NULL )
+ {
+ DComp_Token_Match = DComp_Internal_Match; /* use internal buffering */
+ DComp_Token_Literal = DComp_Internal_Literal;
+
+ DComp.CurPtr = DComp.Buf;
+ DComp.BufEnd = DComp.Buf + DComp.WindowSize;
+ }
+#ifdef DISK_RING
+ else if (DComp_Ring_Init()) /* try disk ring buffer */
+ {
+ DComp_Token_Match = DComp_Ring_Match; /* use disk buffering */
+ DComp_Token_Literal = DComp_Ring_Literal;
+ }
+#endif
+ else
+ {
+ return(1); /* if can't create ring buffer */
+ }
+
+ Lz_Init( WindowBits ); //msliger
+
+ return(0);
+ }
+
+
+void FAST2 DComp_Internal_Match( MATCH Match )
+ {
+ BYTE HUGE *SrcPtr;
+ register BYTE Chr;
+
+ if (DComp.NumBytes >= (unsigned) Match.Len)
+ {
+ SrcPtr = DComp.Buf + ((DComp.Cur - Match.Dist) & DComp.WindowMask);
+
+ DComp.NumBytes -= Match.Len;
+ DComp.Cur += Match.Len;
+
+ while (Match.Len--)
+ {
+#ifdef UNPAQLIB
+ Chr = *SrcPtr;
+
+ *DComp.CurPtr = Chr;
+
+ *DComp.OutBuffer++ = Chr;
+#else
+ Chr = *SrcPtr;
+
+ *DComp.CurPtr = Chr;
+
+ putc( Chr, DComp.OutFile );
+
+ DComp.Checksum ^= Chr;
+
+ if( DComp.Checksum & 0x8000 ) // simulate a ROL in C, yucky!
+ {
+ DComp.Checksum <<= 1;
+ DComp.Checksum++;
+ }
+ else
+ {
+ DComp.Checksum <<= 1;
+ }
+#endif
+
+ if (++SrcPtr == DComp.BufEnd)
+ {
+ SrcPtr = DComp.Buf;
+ }
+
+ if (++DComp.CurPtr == DComp.BufEnd)
+ {
+ DComp.CurPtr = DComp.Buf;
+ }
+ }
+ }
+ else /* match too large to fit */
+ {
+ DComp.NumBytes = 0;
+#ifdef UNPAQLIB
+ DComp.fOutOverflow = 1;
+#endif
+ }
+ }
+
+
+void FAST2 DComp_Internal_Literal( int Chr )
+ {
+ DComp.NumBytes--;
+ DComp.Cur++;
+
+#ifndef UNPAQLIB
+ putc( (BYTE) Chr, DComp.OutFile );
+
+ DComp.Checksum ^= (BYTE) Chr;
+
+ if( DComp.Checksum & 0x8000 ) // simulate a ROL in C, yucky!
+ {
+ DComp.Checksum <<= 1;
+ DComp.Checksum++;
+ }
+ else
+ {
+ DComp.Checksum <<= 1;
+ }
+#else
+ *DComp.OutBuffer++ = (BYTE) Chr;
+#endif
+
+ *DComp.CurPtr = (BYTE) Chr;
+
+ if (++DComp.CurPtr == DComp.BufEnd)
+ {
+ DComp.CurPtr = DComp.Buf;
+ }
+ }
+
+
+#ifndef UNPAQLIB
+WORD FAST DComp_Decompress( FILE *OutputFile, long NumBytes )
+ {
+ DComp.OutFile = OutputFile;
+ DComp.NumBytes = NumBytes;
+ DComp.Checksum = 0;
+
+ {
+ while( DComp.NumBytes )
+ {
+ Lz_NextToken();
+ }
+ }
+
+ if( DComp.NumBytes < 0 )
+ {
+ puts( "ERR: Incorrect file size." );
+ exit( -1 );
+ }
+
+ return( DComp.Checksum );
+ }
+#endif /* not UNPAQLIB */ //msliger
+
+#ifdef UNPAQLIB
+
+char *pbSource;
+int cbSource;
+int fSourceOverflow;
+
+WORD FAST DComp_DecompressBlock( void *pbSrc,UINT cbSrc,void *pbDst,UINT cbDst )
+ {
+ DComp.NumBytes = cbDst;
+ DComp.OutBuffer = pbDst;
+ DComp.fOutOverflow = 0;
+
+ pbSource = pbSrc; // pass these along to BIT.C
+ cbSource = cbSrc;
+ fSourceOverflow = 0;
+
+ Arith_Init();
+
+ while( (DComp.NumBytes) && (!fSourceOverflow) )
+ {
+ Lz_NextToken();
+ }
+
+ Arith_Close();
+
+ return( fSourceOverflow || DComp.fOutOverflow || DComp.fRingFault);
+ }
+#endif
+
+
+void FAST DComp_Close( void )
+ {
+#ifdef DISK_RING
+ if (DComp.Buf == NULL)
+ {
+ DComp_Ring_Close(); /* if using a disk-based ring buffer */
+ }
+ else
+ {
+ Rtl_Free( DComp.Buf ); /* if using memory-based ring buffer */
+ }
+#else
+ Rtl_Free( DComp.Buf ); /* always memory-based */
+#endif
+
+ Lz_Close();
+ }
+
+
+#ifdef UNPAQLIB
+
+// this code is only for use with DComp_DecompressBlock()
+
+void FAST DComp_Reset( void )
+ {
+ Lz_Close();
+
+ DComp.Cur = 0;
+ DComp.CurPtr = DComp.Buf;
+ DComp.fRingFault = 0;
+
+#ifdef DISK_RING
+ if (DComp.Buf == NULL)
+ {
+ DComp_Ring_Reset();
+ }
+#endif
+
+ Lz_Init( DComp.WindowBits );
+ }
+#endif /* UNPAQLIB */
+
+
+#ifdef DISK_RING
+
+// disk-based ring buffer support code
+
+static int FAST DComp_Ring_Init(void)
+{
+ RINGNAME ringName;
+ PBUFFER pBuffer;
+ int cBuffers;
+
+ if (lastContext->pfnOpen == NULL)
+ {
+ return(0); /* failed, no disk services */
+ }
+
+ ringName.wildName[0] = '*';
+ ringName.wildName[1] = '\0';
+ ringName.fileSize = DComp.WindowSize;
+
+ Disk.Handle = lastContext->pfnOpen((char FAR *) &ringName,
+ (_O_BINARY|_O_RDWR|_O_CREAT),(_S_IREAD|_S_IWRITE));
+
+ if (Disk.Handle == -1)
+ {
+ return(0); /* failed, can't make disk file */
+ }
+
+ Disk.RingPages = (int) (DComp.WindowSize / BUFFER_SIZE);
+ if (Disk.RingPages < MIN_BUFFERS)
+ {
+ Disk.RingPages = MIN_BUFFERS; /* if DComp.WindowSize < BUFFER_SIZE */
+ }
+
+ Disk.PageTable = Rtl_Malloc(sizeof(PAGETABLEENTRY) * Disk.RingPages);
+ if (Disk.PageTable == NULL)
+ {
+ lastContext->pfnClose(Disk.Handle); /* close the file */
+
+ return(0); /* failed, can't get page table */
+ }
+
+ Disk.pNewest = NULL;
+
+ /* DComp_Ring_Close() can be used to abort from this point on */
+
+ for (cBuffers = 0; cBuffers < Disk.RingPages; cBuffers++)
+ {
+ pBuffer = Rtl_Malloc(sizeof(BUFFER));
+
+ if (pBuffer != NULL)
+ {
+ pBuffer->pLinkNewer = NULL; /* none are newer */
+ pBuffer->pLinkOlder = Disk.pNewest; /* all the others older now */
+
+ if (Disk.pNewest != NULL)
+ {
+ Disk.pNewest->pLinkNewer = pBuffer; /* old guy now knows about new */
+ }
+ else /* if nobody else */
+ {
+ Disk.pOldest = pBuffer; /* guess I'm the oldest too */
+ }
+
+ Disk.pNewest = pBuffer; /* I'm the newest */
+ }
+ else /* if pBuffer == NULL */
+ {
+ if (cBuffers < MIN_BUFFERS) /* less than minimum? */
+ {
+ DComp_Ring_Close(); /* give it up */
+
+ return(0); /* failed, can't get min buffers */
+ }
+ else /* if we got the minimum */
+ {
+ break; /* got enough, quit trying */
+ }
+ }
+ }
+
+ DComp_Ring_Reset(); /* init everything else */
+
+ return(1); /* ring buffer created */
+}
+
+
+static void FAST DComp_Ring_Reset(void)
+{
+ PBUFFER walker;
+ int iPage;
+
+ for (walker = Disk.pNewest; walker != NULL; walker = walker->pLinkOlder)
+ {
+ walker->BufferPage = -1; /* buffer is not valid */
+ walker->BufferDirty = 0; /* and doesn't need writing */
+ }
+
+ for (iPage = 0; iPage < Disk.RingPages; iPage++)
+ {
+ Disk.PageTable[iPage].pBuffer = NULL; /* not in memory */
+ Disk.PageTable[iPage].fDiskValid = 0; /* not on disk */
+ }
+
+ Disk.RingBuffer = DComp_Ring_Load(0,1); /* make a page 0 for writing */
+
+ if (Disk.RingBuffer != NULL) /* always will pass */
+ {
+ Disk.RingPointer = Disk.RingBuffer->Buffer;
+ Disk.RingPointerLimit = Disk.RingPointer + BUFFER_SIZE;
+ }
+}
+
+
+static void FAST2 DComp_Ring_Match( MATCH Match )
+{
+ long SrcOffset; /* offset into output ring */
+ int SrcPage; /* page # where that offset lies */
+ int Chunk; /* number of bytes this pass */
+ BYTE FAR *SrcPtr; /* pointer to source bytes */
+ BYTE Chr; /* data character */
+ PBUFFER SrcBuffer; /* buffer where source data is */
+ int SrcBufferOffset; /* offset within the buffer */
+ int newPage;
+
+ if (DComp.NumBytes >= (unsigned) Match.Len)
+ {
+ SrcOffset = (DComp.Cur - Match.Dist) & DComp.WindowMask;
+ DComp.NumBytes -= Match.Len;
+ DComp.Cur += Match.Len;
+
+ /* promote current output page to make sure it's never discarded */
+
+ if (DComp_Ring_Load(Disk.RingBuffer->BufferPage,0) == NULL)
+ {
+ DComp.NumBytes = 0;
+
+ DComp.fRingFault = 1;
+
+ return;
+ }
+
+ while (Match.Len)
+ {
+ /* Limit: number of bytes requested */
+
+ Chunk = Match.Len; /* try for everything */
+
+ /* Limit: space remaining on current output page */
+
+ if ((Disk.RingPointerLimit - Disk.RingPointer) < Chunk)
+ {
+ Chunk = Disk.RingPointerLimit - Disk.RingPointer;
+ }
+
+ SrcPage = (int) (SrcOffset / BUFFER_SIZE);
+ SrcBufferOffset = (int) (SrcOffset % BUFFER_SIZE);
+
+ SrcBuffer = DComp_Ring_Load(SrcPage,0); /* for reading */
+ if (SrcBuffer == NULL)
+ {
+ DComp.NumBytes = 0;
+
+ DComp.fRingFault = 1;
+
+ return;
+ }
+
+ SrcPtr = SrcBuffer->Buffer + SrcBufferOffset;
+
+ /* Limit: number of source bytes on current output page */
+
+ if ((BUFFER_SIZE - SrcBufferOffset) < Chunk)
+ {
+ Chunk = (BUFFER_SIZE - SrcBufferOffset);
+ }
+
+ SrcOffset += Chunk;
+ SrcOffset &= DComp.WindowMask;
+ Match.Len -= Chunk;
+
+ while (Chunk--) /* copy this chunk */
+ {
+ Chr = *SrcPtr++;
+
+ *Disk.RingPointer++ = Chr;
+
+ *DComp.OutBuffer++ = Chr;
+ }
+
+ if (Disk.RingPointer == Disk.RingPointerLimit)
+ {
+ newPage = (Disk.RingBuffer->BufferPage + 1);
+ if (newPage >= Disk.RingPages)
+ {
+ newPage = 0;
+ }
+
+ Disk.RingBuffer = DComp_Ring_Load(newPage,1); /* for writing */
+ if (Disk.RingBuffer == NULL)
+ {
+ DComp.NumBytes = 0;
+
+ DComp.fRingFault = 1;
+
+ return;
+ }
+
+ Disk.RingPointer = Disk.RingBuffer->Buffer;
+ Disk.RingPointerLimit = Disk.RingPointer + BUFFER_SIZE;
+ }
+ } /* while Match.Len */
+ } /* if Match.Len size OK */
+ else /* match too large to fit */
+ {
+ DComp.NumBytes = 0;
+
+ DComp.fOutOverflow = 1;
+ }
+}
+
+
+static void FAST2 DComp_Ring_Literal( int Chr )
+{
+ int newPage;
+
+ DComp.NumBytes--;
+ DComp.Cur++;
+
+ *DComp.OutBuffer++ = (BYTE) Chr;
+
+ *Disk.RingPointer = (BYTE) Chr;
+
+ if (++Disk.RingPointer == Disk.RingPointerLimit)
+ {
+ newPage = (Disk.RingBuffer->BufferPage + 1);
+ if (newPage >= Disk.RingPages)
+ {
+ newPage = 0;
+ }
+
+ Disk.RingBuffer = DComp_Ring_Load(newPage,1); /* for writing */
+ if (Disk.RingBuffer == NULL)
+ {
+ DComp.NumBytes = 0;
+
+ DComp.fRingFault = 1;
+
+ return;
+ }
+
+ Disk.RingPointer = Disk.RingBuffer->Buffer;
+ Disk.RingPointerLimit = Disk.RingPointer + BUFFER_SIZE;
+ }
+}
+
+
+/* Bring page into a buffer, return a pointer to that buffer. fWrite */
+/* indicates the caller's intentions for this buffer, NZ->consider it */
+/* dirty now. Returns NULL if there is a paging fault (callback */
+/* failed) or if any internal assertions fail. */
+
+static PBUFFER FAST DComp_Ring_Load(int page,int fWrite)
+{
+ PBUFFER pBuffer;
+ long iPagefileOffset;
+
+ pBuffer = Disk.PageTable[page].pBuffer; /* look up this page */
+
+ if (pBuffer != NULL) /* if it's in the table */
+ {
+ if (pBuffer != Disk.pNewest) /* promote if not newest */
+ {
+ pBuffer->pLinkNewer->pLinkOlder = pBuffer->pLinkOlder;
+
+ if (pBuffer->pLinkOlder != NULL) /* if there is someone older */
+ {
+ pBuffer->pLinkOlder->pLinkNewer = pBuffer->pLinkNewer;
+ }
+ else
+ {
+ Disk.pOldest = pBuffer->pLinkNewer;
+ }
+
+ /* link into head of chain */
+
+ Disk.pNewest->pLinkNewer = pBuffer; /* newest now knows one newer */
+ pBuffer->pLinkNewer = NULL; /* nobody's newer */
+ pBuffer->pLinkOlder = Disk.pNewest; /* everybody's older */
+ Disk.pNewest = pBuffer; /* I'm the newest */
+ }
+
+ pBuffer->BufferDirty |= fWrite; /* might already be dirty */
+
+ return(pBuffer); /* return my handle */
+ }
+
+ /* desired page is not in the table; discard oldest & use it */
+
+ /* assertion check: current output buffer appears to be the oldest */
+
+ if (Disk.pOldest == Disk.RingBuffer)
+ {
+ return(NULL);
+ }
+
+ pBuffer = Disk.pOldest; /* choose the oldest buffer */
+
+ if (pBuffer->BufferPage != -1) /* take it out of page table */
+ {
+ Disk.PageTable[pBuffer->BufferPage].pBuffer = NULL; /* not here now */
+
+ if (pBuffer->BufferDirty) /* write on eject, if dirty */
+ {
+ iPagefileOffset = (long) pBuffer->BufferPage * BUFFER_SIZE;
+
+ if (lastContext->pfnSeek(Disk.Handle,iPagefileOffset,SEEK_SET) !=
+ iPagefileOffset)
+ {
+ return(NULL);
+ }
+
+ if (lastContext->pfnWrite(Disk.Handle,pBuffer->Buffer,BUFFER_SIZE) !=
+ BUFFER_SIZE)
+ {
+ return(NULL);
+ }
+
+ Disk.PageTable[pBuffer->BufferPage].fDiskValid = 1;
+ }
+ }
+
+ Disk.pOldest = Disk.pOldest->pLinkNewer; /* newer is now oldest */
+ Disk.pOldest->pLinkOlder = NULL; /* oldest knows none older */
+
+ Disk.pNewest->pLinkNewer = pBuffer;
+ pBuffer->pLinkNewer = NULL; /* link into head of chain */
+ pBuffer->pLinkOlder = Disk.pNewest;
+ Disk.pNewest = pBuffer;
+
+ /* add new buffer to paging table */
+
+ Disk.PageTable[page].pBuffer = pBuffer; /* add new to paging table */
+
+ /* if this disk page is valid, load it */
+
+ if (Disk.PageTable[page].fDiskValid)
+ {
+ iPagefileOffset = (long) page * BUFFER_SIZE;
+
+ if (lastContext->pfnSeek(Disk.Handle,iPagefileOffset,SEEK_SET) !=
+ iPagefileOffset)
+ {
+ return(NULL);
+ }
+
+ if (lastContext->pfnRead(Disk.Handle,pBuffer->Buffer,BUFFER_SIZE) !=
+ BUFFER_SIZE)
+ {
+ return(NULL);
+ }
+ }
+ else if (!fWrite)
+ {
+ /* assertion failure, trying to load a never-written page from disk */
+
+ return(NULL);
+ }
+
+ pBuffer->BufferDirty = fWrite; /* might be dirty now */
+ pBuffer->BufferPage = page; /* our new page number */
+
+ return(pBuffer); /* return new handle */
+}
+
+
+static void FAST DComp_Ring_Close(void)
+{
+ PBUFFER pBuffer, pNext; /* buffer walk pointer */
+
+ Rtl_Free(Disk.PageTable); /* discard page table */
+
+ pBuffer = Disk.pNewest;
+
+ while (pBuffer != NULL) /* discard buffer chain */
+ {
+ pNext = pBuffer->pLinkOlder;
+ Rtl_Free(pBuffer);
+ pBuffer = pNext;
+ }
+
+ lastContext->pfnClose(Disk.Handle); /* close that file (and delete) */
+}
+
+#endif /* DISK_RING */
diff --git a/private/windows/diamond/quantum/dcomp.h b/private/windows/diamond/quantum/dcomp.h
new file mode 100644
index 000000000..9877cfb64
--- /dev/null
+++ b/private/windows/diamond/quantum/dcomp.h
@@ -0,0 +1,32 @@
+// DCOMP.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __DCOMP
+#define __DCOMP
+
+#include <stdio.h>
+#include "defs.h" //msliger
+#include "lz.h"
+
+int FAST DComp_Init( BYTE WindowBits ); //msliger
+void FAST DComp_Close( void );
+
+#ifndef UNPAQLIB //msliger
+WORD FAST DComp_Decompress( FILE *OutputFile, long NumBytes );
+#endif //msliger
+
+#ifdef UNPAQLIB //msliger
+WORD FAST DComp_DecompressBlock( void FAR *pbSrc, UINT cbSrc, //msliger
+ void FAR *pbDst, UINT cbDst ); //msliger
+void FAST DComp_Reset( void ); //msliger
+#endif //msliger
+
+extern void (FAST2 *DComp_Token_Match)( MATCH Match );
+extern void (FAST2 *DComp_Token_Literal)( int Chr );
+
+#endif // dcomp.h
diff --git a/private/windows/diamond/quantum/decomp.h b/private/windows/diamond/quantum/decomp.h
new file mode 100644
index 000000000..fbeab0ab9
--- /dev/null
+++ b/private/windows/diamond/quantum/decomp.h
@@ -0,0 +1,30 @@
+/*
+ * Microsoft Confidential
+ * Copyright (c) 1994 Microsoft Corporation
+ * Copyright (c) 1993,1994 Cinematronics
+ * Copyright (c) 1993,1994 David Stafford
+ * All Rights Reserved.
+ *
+ * Quantum file archiver and compressor
+ * Advanced data compression
+ *
+ * Copyright (c) 1993,1994 David Stafford
+ * All rights reserved.
+ *
+ * This file contains trade secrets of Cinematronics.
+ * Do NOT distribute!
+ */
+
+/*
+ * DECOMP.H: QDI core header
+ *
+ * History:
+ * 09-Jul-1994 msliger Built from DCOMP.H
+ * 18-Aug-1994 msliger Renamed these to allow both compressors.
+ */
+
+extern int FAST DComp386_Init( BYTE WindowBits );
+extern UINT FAST DComp386_DecompressBlock( void FAR *pbSrc, UINT cbSrc,
+ void FAR *pbDst, UINT cbDst );
+extern void FAST DComp386_Reset( void );
+extern void FAST DComp386_Close( void );
diff --git a/private/windows/diamond/quantum/defs.h b/private/windows/diamond/quantum/defs.h
new file mode 100644
index 000000000..4aa478a7f
--- /dev/null
+++ b/private/windows/diamond/quantum/defs.h
@@ -0,0 +1,43 @@
+#ifndef __DEFS
+#define __DEFS
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef int BOOL;
+typedef unsigned int UINT; //msliger
+
+#ifndef NEAR
+#ifdef BIT16
+#define NEAR __near
+#else
+#define NEAR
+#endif
+#endif
+
+#ifndef FAR
+#ifdef BIT16
+#define FAR __far
+#else
+#define FAR
+#endif
+#endif
+
+#ifndef HUGE
+#ifdef BIT16
+#define HUGE __huge
+#else
+#define HUGE
+#endif
+#endif
+
+
+#ifdef BIT16
+#define FAST __near __pascal
+#define FAST2 __near __fastcall
+#else
+#define FAST
+#define FAST2 __fastcall
+#endif
+
+#endif // defs.h
diff --git a/private/windows/diamond/quantum/dirs b/private/windows/diamond/quantum/dirs
new file mode 100644
index 000000000..65bcdc5e7
--- /dev/null
+++ b/private/windows/diamond/quantum/dirs
@@ -0,0 +1 @@
+DIRS=qci.nt qdi.nt
diff --git a/private/windows/diamond/quantum/dirwalk.h b/private/windows/diamond/quantum/dirwalk.h
new file mode 100644
index 000000000..54c34955d
--- /dev/null
+++ b/private/windows/diamond/quantum/dirwalk.h
@@ -0,0 +1,88 @@
+/* ---------------------------------------------------------------------------------------------------------------------------- */
+/* */
+/* DIRWALK.H */
+/* */
+/* Definitions for the DirectoryWalk function found in DIRWALK.C, and the related processing calls needed. */
+/* */
+/* ---------------------------------------------------------------------------------------------------------------------------- */
+
+/* int DirectoryWalk(path,Directory,File,DirectoryEnd) */
+
+extern int DirectoryWalk(const char *, /* path to search, ie, "C:\" */
+ int (*)(void *,const char *,const char *,void **), /* pointer to Directory() or NULL */
+ int (*)(void *,const char *,const char *,unsigned,unsigned,unsigned,long), /* pointer to File() or NULL */
+ int (*)(void *,const char *,const char *,void *)); /* pointer to DirectoryEnd() or NULL */
+
+#define DW_MEMORY -10 /* unable to malloc() for internal use */
+#define DW_ERROR -11 /* find first/next reported an error */
+#define DW_DEPTH -12 /* path name became too long */
+#define DW_NO_ERROR 0 /* no error detected */
+
+/*
+ User function definitions:
+
+ The parentID and childID values are "void *"s to DirectoryWalk. They are not used internally. The user may assign
+ any meaning desired to the value. DirectoryWalk simply requests an assignment via the Directory(), and reports the
+ corresponding assignment with each file reported to File(), then to DirectoryEnd().
+
+
+ int Directory(parentID,directory,path,childID)
+ void *parentID; / the handle for the directory where this directory was found /
+ const char *directory; / the name of the directory found, ie, "DOS" /
+ const char *path; / the full name of the directory, ie, "C:\DOS" /
+ void **childID; / Directory() assigns this directory a handle, and passes it back through here /
+
+ If Directory() returns a non-zero value, DirectoryWalk will terminate and return that value. If NULL is passed
+ to DirectoryWalk() for a Directory() pointer, subdirectories will not be searched. For subdirectory searching
+ without specific per-directory processing, create a simple function which always returns DW_NO_ERROR (any other
+ return will terminate the search.)
+
+
+ int File(parentID,filename,path,attributes,filetime,filedate,filesize)
+ void *parentID; / the handle for the directory where this file was found /
+ const char *filename; / the name of the file found, ie, "ANSI.SYS" /
+ const char *path; / the full name of the directory where file was found, ie, "C:\DOS" /
+ unsigned attributes; / the file's attribute bits /
+ unsigned filetime; / the file's "last modification" time /
+ unsigned filedate; / the file's "last modification" date /
+ long filesize; / the file's size in bytes /
+
+ If File() returns a value other than DW_NO_ERROR, DirectoryWalk will terminate and return that value. NULL can
+ be passed to DirectoryWalk() for a File() pointer; file entries found will be ignored.
+
+
+ int DirectoryEnd(parentID,directory,path,childID)
+ void *parentID; / the handle for the directory where this directory was found /
+ const char *directory; / the name of the directory found, ie, "DOS" /
+ const char *path; / the full name of the directory, ie, "C:\DOS" /
+ void *childID; / the handle assigned this directory by Directory() /
+
+ If NULL is passed to DirectoryWalk for the DirectoryEnd() pointer, no report of end of directories will be made.
+ If DirectoryEnd returns a value other than DW_NO_ERROR, DirectoryWalk will terminate and return that value.
+
+
+ The attributes field bits are defined as follows: (see the #define's below)
+
+ ---- ---- ---- ---1 file is read-only
+ ---- ---- ---- --1- file is hidden
+ ---- ---- ---- -1-- file is a "system" file
+ ---- ---- --1- ---- file's "modified" ("archive") bit is set
+ xxxx xxxx xx-x x--- undefined (should be masked by user)
+
+ The filetime field is in the MS-DOS format:
+
+ ---- ---- ---x xxxx seconds / 2 (0..29)
+ ---- -xxx xxx- ---- minutes (0..59)
+ xxxx x--- ---- ---- hours (0..23)
+
+ The filedate field is in the MS-DOS format:
+
+ ---- ---- ---x xxxx day of month (1..31)
+ ---- ---x xxx- ---- month (1..12)
+ xxxx xxx- ---- ---- year-1980 (0..127)
+*/
+
+#define ATTR_READONLY 0x0001
+#define ATTR_HIDDEN 0x0002
+#define ATTR_SYSTEM 0x0004
+#define ATTR_ARCHIVE 0x0020
diff --git a/private/windows/diamond/quantum/dummy.h b/private/windows/diamond/quantum/dummy.h
new file mode 100644
index 000000000..b41150f11
--- /dev/null
+++ b/private/windows/diamond/quantum/dummy.h
@@ -0,0 +1,46 @@
+#include "defs.h"
+
+#define WINAPI __stdcall __import
+
+#define PAGE_NOACCESS 0x01
+#define PAGE_READONLY 0x02
+#define PAGE_READWRITE 0x04
+#define PAGE_WRITECOPY 0x08
+#define PAGE_EXECUTE 0x10
+#define PAGE_EXECUTE_READ 0x20
+#define PAGE_EXECUTE_READWRITE 0x40
+#define PAGE_EXECUTE_WRITECOPY 0x80
+#define PAGE_GUARD 0x100
+#define PAGE_NOCACHE 0x200
+#define MEM_COMMIT 0x1000
+#define MEM_RESERVE 0x2000
+#define MEM_DECOMMIT 0x4000
+#define MEM_RELEASE 0x8000
+#define MEM_FREE 0x10000
+#define MEM_PRIVATE 0x20000
+#define MEM_MAPPED 0x40000
+#define MEM_TOP_DOWN 0x100000
+#define SEC_FILE 0x800000
+#define SEC_IMAGE 0x1000000
+#define SEC_RESERVE 0x4000000
+#define SEC_COMMIT 0x8000000
+#define SEC_NOCACHE 0x10000000
+#define MEM_IMAGE SEC_IMAGE
+
+
+void *
+WINAPI
+VirtualAlloc(
+ void *lpAddress,
+ DWORD dwSize,
+ DWORD flAllocationType,
+ DWORD flProtect
+ );
+
+BOOL
+WINAPI
+VirtualFree(
+ void *lpAddress,
+ DWORD dwSize,
+ DWORD dwFreeType
+ );
diff --git a/private/windows/diamond/quantum/log.h b/private/windows/diamond/quantum/log.h
new file mode 100644
index 000000000..373c5fda1
--- /dev/null
+++ b/private/windows/diamond/quantum/log.h
@@ -0,0 +1,7 @@
+#ifdef STAFFORD
+#define LONGDOUBLE long double
+#else
+#define LONGDOUBLE double
+#endif
+
+LONGDOUBLE MYLOG( LONGDOUBLE x );
diff --git a/private/windows/diamond/quantum/lz.c b/private/windows/diamond/quantum/lz.c
new file mode 100644
index 000000000..4d91da0a0
--- /dev/null
+++ b/private/windows/diamond/quantum/lz.c
@@ -0,0 +1,719 @@
+// LZ.C
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 Cinematronics
+// All rights reserved.
+//
+// This file contains trade secrets of Cinematronics.
+// Do NOT distribute!
+
+
+#ifdef STAFFORD
+#define ASM asm
+#else
+#define ASM __asm
+#endif
+
+
+#ifndef __PCC__
+ #pragma auto_inline(on)
+#endif
+
+#include <stdlib.h>
+#include "arith.h"
+#include "quantum.h" //msliger
+#include "lz.h"
+#include "comp.h"
+#include "dcomp.h"
+
+#ifdef __PCC__ //msliger
+#include "log.h"
+#endif //msliger
+
+typedef struct
+ {
+ unsigned Freq;
+ unsigned Symbol;
+ } COUNT;
+
+
+typedef struct
+ {
+ int Num; // Number of symbols in this table, max of 64
+#ifdef PAQ
+ int Lookup[ 65 ]; // Given a symbol identifies its index
+#endif
+ int SortCountdown;
+ COUNT Table[ 65 ]; // Yucky but 64+1 is the largest we ever need...
+ } COUNT_RECORD;
+
+
+struct
+ {
+ COUNT_RECORD TokenType;
+ COUNT_RECORD Literal1;
+ COUNT_RECORD Literal2;
+ COUNT_RECORD Literal3;
+ COUNT_RECORD Literal4;
+
+ COUNT_RECORD MatchCode;
+
+ COUNT_RECORD WindowCode;
+ COUNT_RECORD TinyWindowCode;
+ COUNT_RECORD ShortWindowCode;
+ } Count;
+
+
+typedef struct
+ {
+#ifdef PAQ
+ unsigned MatchCodeTrans[ MATCH_NUM ];
+#endif
+ unsigned MatchCodeBase[ MATCH_CODES ];
+
+#ifdef PAQ
+ unsigned WindowCodeTrans[ 2048 + (1 << (WINDOW_MAX-10)) ];
+#endif
+ long WindowCodeBase[ WINDOW_CODES ];
+
+#ifdef DEBUG
+ long Stat[ 7 ];
+#endif
+ } LZ;
+
+LZ Lz;
+
+// Extra bits for each match length code
+
+unsigned MatchCodeExtra[ MATCH_CODES ] =
+ { 0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 };
+
+// Extra bits for each distance code
+
+unsigned WindowCodeExtra[ WINDOW_CODES ] =
+ { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,
+ 12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19 };
+
+
+extern LONGDOUBLE FAST MYLOG( LONGDOUBLE x );
+
+
+void FAST Lz_Init( BYTE WindowBits ) //msliger
+ {
+ int i, k;
+ long Base, WindowSize;
+
+ WindowSize = 1L << WindowBits; //msliger
+
+ for( Base = i = 0; i < MATCH_CODES; i++ )
+ {
+ Lz.MatchCodeBase[ i ] = (unsigned) Base;
+
+ for( k = 0; k < (1 << MatchCodeExtra[ i ]); k++ )
+ {
+#ifdef PAQ
+ Lz.MatchCodeTrans[ Base++ ] = i;
+#else
+ Base++;
+#endif
+ }
+ }
+
+ for( Base = i = 0; i < WINDOW_CODES; i++ )
+ {
+ if( Base < WindowSize )
+ {
+ Count.WindowCode.Num = i + 1;
+
+ if( Base < 1 << (TINY_WINDOW_MAX) )
+ {
+ Count.TinyWindowCode.Num = i + 1;
+ }
+
+ if( Base < 1L << (SHORT_WINDOW_MAX) )
+ {
+ Count.ShortWindowCode.Num = i + 1;
+ }
+ }
+
+ Lz.WindowCodeBase[ i ] = Base;
+
+ Base += (1L << WindowCodeExtra[ i ]);
+ }
+
+#ifdef PAQ
+ for( i = 0; i < 2048; i++ )
+ {
+ for( k = 0; Lz.WindowCodeBase[ k ] <= i; k++ )
+ ;
+
+ Lz.WindowCodeTrans[ i ] = k - 1;
+ }
+
+ Base = 2;
+
+ for( k = k - 1; k < WINDOW_CODES; k++ )
+ {
+ for( i = 0; i < (1 << (WindowCodeExtra[ k ] - 10)); i++ )
+ {
+ Lz.WindowCodeTrans[ 2048 + Base++ ] = k;
+ }
+ }
+#endif
+
+ Count.TokenType.Num = 7;
+ Count.TokenType.SortCountdown = 4;
+
+ for( i = 0; i <= 7; i++ )
+ {
+ Count.TokenType.Table[ i ].Freq = 7 - i;
+ Count.TokenType.Table[ i ].Symbol = i;
+
+#ifdef PAQ
+ Count.TokenType.Lookup[ i ] = i;
+#endif
+ }
+
+ Count.Literal1.Num =
+ Count.Literal2.Num =
+ Count.Literal3.Num =
+ Count.Literal4.Num = 64;
+
+ Count.Literal1.SortCountdown =
+ Count.Literal2.SortCountdown =
+ Count.Literal3.SortCountdown =
+ Count.Literal4.SortCountdown = 4;
+
+ for( i = 0; i <= 64; i++ )
+ {
+ Count.Literal1.Table[ i ].Freq = 64 - i;
+ Count.Literal2.Table[ i ].Freq = 64 - i;
+ Count.Literal3.Table[ i ].Freq = 64 - i;
+ Count.Literal4.Table[ i ].Freq = 64 - i;
+
+ Count.Literal1.Table[ i ].Symbol = i;
+ Count.Literal2.Table[ i ].Symbol = i;
+ Count.Literal3.Table[ i ].Symbol = i;
+ Count.Literal4.Table[ i ].Symbol = i;
+
+#ifdef PAQ
+ Count.Literal1.Lookup[ i ] = i;
+ Count.Literal2.Lookup[ i ] = i;
+ Count.Literal3.Lookup[ i ] = i;
+ Count.Literal4.Lookup[ i ] = i;
+#endif
+ }
+
+ Count.MatchCode.Num = MATCH_CODES;
+ Count.MatchCode.SortCountdown = 4;
+
+ for( i = 0; i <= MATCH_CODES; i++ )
+ {
+ Count.MatchCode.Table[ i ].Freq = MATCH_CODES - i;
+ Count.MatchCode.Table[ i ].Symbol = i;
+
+#ifdef PAQ
+ Count.MatchCode.Lookup[ i ] = i;
+#endif
+ }
+
+ Count.WindowCode.SortCountdown = 4;
+ Count.TinyWindowCode.SortCountdown = 4;
+ Count.ShortWindowCode.SortCountdown = 4;
+
+ for( i = 0; i <= WINDOW_CODES; i++ )
+ {
+ Count.WindowCode.Table[ i ].Freq = Count.WindowCode.Num - i;
+ Count.TinyWindowCode.Table[ i ].Freq = Count.TinyWindowCode.Num - i;
+ Count.ShortWindowCode.Table[ i ].Freq = Count.ShortWindowCode.Num - i;
+
+ Count.WindowCode.Table[ i ].Symbol = i;
+ Count.TinyWindowCode.Table[ i ].Symbol = i;
+ Count.ShortWindowCode.Table[ i ].Symbol = i;
+
+#ifdef PAQ
+ Count.WindowCode.Lookup[ i ] = i;
+ Count.TinyWindowCode.Lookup[ i ] = i;
+ Count.ShortWindowCode.Lookup[ i ] = i;
+#endif
+ }
+
+#ifndef UNPAQLIB //msliger
+ Arith_Init();
+#endif //msliger
+ }
+
+
+void FAST Lz_Close( void )
+ {
+ #ifdef DEBUG
+ #ifdef PAQ
+ printf( "\n\n" );
+ printf( "Stats:\n" );
+ printf( "Literal 0 = %ld\n", Lz.Stat[ 0 ] );
+ printf( "Literal 1 = %ld\n", Lz.Stat[ 1 ] );
+ printf( "Literal 2 = %ld\n", Lz.Stat[ 2 ] );
+ printf( "Literal 3 = %ld\n", Lz.Stat[ 3 ] );
+ printf( "Match 3 = %ld\n", Lz.Stat[ 4 ] );
+ printf( "Match 4 = %ld\n", Lz.Stat[ 5 ] );
+ printf( "Match 5+ = %ld\n", Lz.Stat[ 6 ] );
+ #endif
+ #endif
+
+#ifndef PAQLIB //msliger
+#ifndef UNPAQLIB //msliger
+ Arith_Close();
+#endif //msliger
+#endif //msliger
+ }
+
+
+void FAST Lz_Bump( COUNT_RECORD NEAR *Rec )
+ {
+ COUNT NEAR *pTab;
+ int Num;
+ int i, j;
+ COUNT Scratch;
+
+ pTab = Rec->Table;
+ Num = Rec->Num;
+
+ if( --Rec->SortCountdown == 0 )
+ {
+ Rec->SortCountdown = 50;
+
+ // Change all the frequencies to their absolute values divided by two.
+
+ for( i = 0; i < Num; i++ )
+ {
+ pTab[ i ].Freq -= pTab[ i + 1 ].Freq;
+
+ pTab[ i ].Freq++;
+ pTab[ i ].Freq >>= 1;
+ }
+
+ // Sort them.
+ // Yes, this could be a faster sort but the list is never
+ // more than 64 items and it spends very little time here.
+
+ for( i = 0; i < Num; i++ )
+ {
+ for( j = i + 1; j < Num; j++ )
+ {
+ if( pTab[ j ].Freq > pTab[ i ].Freq )
+ {
+ Scratch = pTab[ i ];
+ pTab[ i ] = pTab[ j ];
+ pTab[ j ] = Scratch;
+ }
+ }
+ }
+
+ // Recreate the relative frequencies.
+
+ for( i = Num - 1; i >= 0; i-- )
+ {
+ pTab[ i ].Freq += pTab[ i + 1 ].Freq;
+ }
+
+#ifdef PAQ
+ // Rebuild the lookup table.
+
+ for( i = 0; i < Num; i++ )
+ {
+ Rec->Lookup[ pTab[ i ].Symbol ] = i;
+ }
+#endif
+ }
+ else /* SortCountDown != 0 */
+ {
+ for( i = Num - 1; i >= 0; i-- )
+ {
+ pTab[ i ].Freq >>= 1;
+
+ if( pTab[ i ].Freq <= pTab[ i + 1 ].Freq )
+ {
+ pTab[ i ].Freq = pTab[ i + 1 ].Freq + 1;
+ }
+ }
+ }
+ }
+
+
+#ifdef PAQ
+
+// Maps a distance into a window code
+
+int FAST Lz_MapDistanceToWindowCode( long Distance )
+ {
+ if( Distance < 2048 )
+ {
+ return( Lz.WindowCodeTrans[ Distance ] );
+ }
+ else
+ {
+ return( Lz.WindowCodeTrans[ 2048 + (Distance >> 10) ] );
+ }
+ }
+
+
+LONGDOUBLE FAST EstimateBits( long Occur, long Total )
+ {
+ #ifdef DEBUG
+ if( Occur <= 0 || Total <= 0 )
+ {
+ puts( "ERR: Domain" );
+ exit( -1 );
+ }
+ #endif
+
+ return( MYLOG( (LONGDOUBLE)Total / (LONGDOUBLE)Occur ) );
+ }
+
+
+void FAST Lz_Encode_Symbol( COUNT_RECORD *Rec, int Sym )
+ {
+ register COUNT NEAR *pTab;
+ SYMBOL Symbol;
+ int Index = Rec->Lookup[ Sym ];
+
+ Symbol.High = Rec->Table[ Index ].Freq;
+ Symbol.Low = Rec->Table[ Index + 1 ].Freq;
+ Symbol.Scale = Rec->Table[ 0 ].Freq;
+
+ Arith_Encode_Symbol( &Symbol );
+
+ pTab = (COUNT NEAR *) Rec->Table;
+
+ do
+ {
+ pTab->Freq += MAGIC_INC;
+ pTab++;
+ }
+ while( Index-- );
+
+ if( Rec->Table[ 0 ].Freq > MAGIC_MAX )
+ {
+ Lz_Bump( Rec );
+ }
+ }
+
+
+LONGDOUBLE FAST Lz_Encode_Symbol_Cost( COUNT_RECORD *Rec, int Sym )
+ {
+ int Index = Rec->Lookup[ Sym ];
+
+ return( EstimateBits(
+ Rec->Table[ Index ].Freq - Rec->Table[ Index + 1 ].Freq,
+ Rec->Table[ 0 ].Freq ) );
+ }
+
+
+LONGDOUBLE FAST Lz_Encode_Match_Cost( MATCH *Match )
+ {
+ int Code;
+ LONGDOUBLE Total;
+
+ switch( Match->Len )
+ {
+ case 3:
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 4 );
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Total += Lz_Encode_Symbol_Cost( &Count.TinyWindowCode, Code );
+ break;
+ case 4:
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 5 );
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Total += Lz_Encode_Symbol_Cost( &Count.ShortWindowCode, Code );
+ break;
+ default:
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 6 );
+ Code = Lz.MatchCodeTrans[ Match->Len - 5 ];
+ Total += Lz_Encode_Symbol_Cost( &Count.MatchCode, Code );
+ Total += MatchCodeExtra[ Code ];
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Total += Lz_Encode_Symbol_Cost( &Count.WindowCode, Code );
+ }
+
+ Total += WindowCodeExtra[ Code ];
+
+ return( Total );
+ }
+
+
+void FAST Lz_Encode_Match( MATCH *Match )
+ {
+ int Code;
+
+ switch( Match->Len )
+ {
+ case 3:
+ #ifdef DEBUG
+ Lz.Stat[ 4 ]++;
+ #endif
+
+ Lz_Encode_Symbol( &Count.TokenType, 4 );
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Lz_Encode_Symbol( &Count.TinyWindowCode, Code );
+ break;
+
+ case 4:
+ #ifdef DEBUG
+ Lz.Stat[ 5 ]++;
+ #endif
+
+ Lz_Encode_Symbol( &Count.TokenType, 5 );
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Lz_Encode_Symbol( &Count.ShortWindowCode, Code );
+ break;
+
+ default:
+ #ifdef DEBUG
+ Lz.Stat[ 6 ]++;
+ #endif
+
+ Lz_Encode_Symbol( &Count.TokenType, 6 );
+ Code = Lz.MatchCodeTrans[ Match->Len - 5 ];
+ Lz_Encode_Symbol( &Count.MatchCode, Code );
+ Arith_Encode_Bits( Match->Len - 5 - Lz.MatchCodeBase[ Code ],
+ MatchCodeExtra[ Code ] );
+ Code = Lz_MapDistanceToWindowCode( Match->Dist - 1 );
+ Lz_Encode_Symbol( &Count.WindowCode, Code );
+ }
+
+ Arith_Encode_Bits( Match->Dist - 1 - Lz.WindowCodeBase[ Code ],
+ WindowCodeExtra[ Code ] );
+ }
+
+
+LONGDOUBLE FAST Lz_Encode_Literal_Cost( int Chr )
+ {
+ LONGDOUBLE Total;
+
+ if( Chr < 64 )
+ {
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 0 ) +
+ Lz_Encode_Symbol_Cost( &Count.Literal1, Chr );
+ }
+ else
+ {
+ if( Chr < 128 )
+ {
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 1 ) +
+ Lz_Encode_Symbol_Cost( &Count.Literal2, Chr - 64 );
+ }
+ else
+ {
+ if( Chr < 192 )
+ {
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 2 ) +
+ Lz_Encode_Symbol_Cost( &Count.Literal3, Chr - 128 );
+ }
+ else
+ {
+ Total = Lz_Encode_Symbol_Cost( &Count.TokenType, 3 ) +
+ Lz_Encode_Symbol_Cost( &Count.Literal4, Chr - 192 );
+ }
+ }
+ }
+
+ return( Total );
+ }
+
+
+void FAST Lz_Encode_Literal( int Chr )
+ {
+ if( Chr < 64 )
+ {
+ #ifdef DEBUG
+ Lz.Stat[ 0 ]++;
+ #endif
+ Lz_Encode_Symbol( &Count.TokenType, 0 );
+ Lz_Encode_Symbol( &Count.Literal1, Chr );
+ }
+ else
+ {
+ if( Chr < 128 )
+ {
+ #ifdef DEBUG
+ Lz.Stat[ 1 ]++;
+ #endif
+ Lz_Encode_Symbol( &Count.TokenType, 1 );
+ Lz_Encode_Symbol( &Count.Literal2, Chr - 64 );
+ }
+ else
+ {
+ if( Chr < 192 )
+ {
+ #ifdef DEBUG
+ Lz.Stat[ 2 ]++;
+ #endif
+ Lz_Encode_Symbol( &Count.TokenType, 2 );
+ Lz_Encode_Symbol( &Count.Literal3, Chr - 128 );
+ }
+ else
+ {
+ #ifdef DEBUG
+ Lz.Stat[ 3 ]++;
+ #endif
+ Lz_Encode_Symbol( &Count.TokenType, 3 );
+ Lz_Encode_Symbol( &Count.Literal4, Chr - 192 );
+ }
+ }
+ }
+ }
+
+
+#else //UNPAQ
+
+#define LZ_DECODE_SYMBOL(Rec,Sym) \
+ { \
+/* SYMBOL Symbol; / I defined these at the top of */ \
+/* unsigned Counter; / the calling function because */ \
+/* int Index; / the compiler wasn't re-using */ \
+/* register COUNT NEAR *pTab; / the local variable space. */ \
+ \
+ Symbol.Scale = Rec.Table[ 0 ].Freq; \
+ \
+ Counter = Arith_GetCount( Symbol.Scale ); \
+ \
+ Index = 0; \
+ \
+ while ( Rec.Table[ Index + 1 ].Freq > Counter ) \
+ { \
+ Index++; \
+ } \
+ \
+ Sym = Rec.Table[ Index ].Symbol; \
+ \
+ Symbol.High = Rec.Table[ Index ].Freq; \
+ Symbol.Low = Rec.Table[ Index + 1 ].Freq; \
+ \
+ Arith_Remove_Symbol( Symbol ); \
+ \
+ pTab = (COUNT NEAR *) &Rec.Table; \
+ \
+ do \
+ { \
+ pTab->Freq += MAGIC_INC; \
+ pTab++; \
+ } \
+ while( Index-- ); \
+ \
+ if( Rec.Table[ 0 ].Freq > MAGIC_MAX ) \
+ { \
+ Lz_Bump((COUNT_RECORD NEAR *)&Rec ); \
+ } \
+ }
+
+
+void FAST Lz_NextToken( void )
+ {
+ int Code;
+ MATCH Match;
+ SYMBOL Symbol; /* ref'd from macro */
+ unsigned Counter; /* ref'd from macro */
+ int Index; /* ref'd from macro */
+ register COUNT NEAR *pTab; /* ref'd from macro */
+
+ LZ_DECODE_SYMBOL(Count.TokenType,Code);
+
+ switch( Code )
+ {
+ case 0:
+ LZ_DECODE_SYMBOL(Count.Literal1,Code);
+ DComp_Token_Literal( Code );
+ break;
+
+ case 1:
+ LZ_DECODE_SYMBOL(Count.Literal2,Code);
+ DComp_Token_Literal( Code + 64 );
+ break;
+
+ case 2:
+ LZ_DECODE_SYMBOL(Count.Literal3,Code);
+ DComp_Token_Literal( Code + 128 );
+ break;
+
+ case 3:
+ LZ_DECODE_SYMBOL(Count.Literal4,Code);
+ DComp_Token_Literal( Code + 192 );
+ break;
+
+ case 4:
+ Match.Len = 3;
+ LZ_DECODE_SYMBOL(Count.TinyWindowCode,Code);
+ Match.Dist = Lz.WindowCodeBase[ Code ] +
+ Arith_Decode_Bits( WindowCodeExtra[ Code ] ) + 1;
+ DComp_Token_Match( Match );
+ break;
+
+ case 5:
+ Match.Len = 4;
+ LZ_DECODE_SYMBOL(Count.ShortWindowCode,Code);
+ Match.Dist = Lz.WindowCodeBase[ Code ] +
+ Arith_Decode_Bits( WindowCodeExtra[ Code ] ) + 1;
+ DComp_Token_Match( Match );
+ break;
+
+ case 6:
+ LZ_DECODE_SYMBOL(Count.MatchCode,Code);
+ Match.Len = Lz.MatchCodeBase[ Code ] +
+ (short) Arith_Decode_Bits( MatchCodeExtra[ Code ] ) + 5;
+ LZ_DECODE_SYMBOL(Count.WindowCode,Code);
+ Match.Dist = Lz.WindowCodeBase[ Code ] +
+ Arith_Decode_Bits( WindowCodeExtra[ Code ] ) + 1;
+ DComp_Token_Match( Match );
+ break;
+ }
+ }
+
+#endif
+
+
+#ifdef PAQ
+
+// Estimates the number of bits required to represent a symbol
+// given the total number of occurances of this symbol and the
+// total number of occurances of all symbols (an order-0 probability).
+
+#ifndef __PCC__
+
+#undef HUGE /* defined by MATH.H */
+
+#include <math.h>
+
+//#if defined(_MIPS_) || defined(_ALPHA_)
+#ifndef _X86_
+#ifndef logl
+#define logl(x) ((LONGDOUBLE)log((double)(x)))
+#endif
+#ifndef M_LN2
+#define M_LN2 0.6931471805599
+#endif
+#endif
+
+LONGDOUBLE FAST MYLOG( LONGDOUBLE x )
+ {
+//#if defined(_MIPS_) || defined(_ALPHA_)
+#ifndef _X86_
+ return( logl( x ) / M_LN2 );
+#else
+
+ ASM fldln2 // st(0) = log( x )
+ ASM fld x
+ ASM fyl2x
+
+ ASM fldln2 // st(0) = st(0) / log( 2 )
+ ASM fdivp st(1),st
+
+ ASM fstp x
+
+ return( x );
+#endif /* 0 */
+ }
+#endif /* ! PCC */
+
+#endif /* PAQ */
diff --git a/private/windows/diamond/quantum/lz.h b/private/windows/diamond/quantum/lz.h
new file mode 100644
index 000000000..a19994abf
--- /dev/null
+++ b/private/windows/diamond/quantum/lz.h
@@ -0,0 +1,60 @@
+// LZ.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __LZ
+#define __LZ
+
+#include "defs.h"
+
+#define MATCH_NUM 257
+#define MATCH_MIN 3
+#define MATCH_MAX (MATCH_NUM + MATCH_MIN - 1)
+#define MATCH_CODES 27
+
+#define WINDOW_MIN 10 // the sliding window size
+#define WINDOW_DEFAULT 20 // 2**N bits
+#define WINDOW_MAX 21
+#define WINDOW_CODES 42
+#define WINDOW_SHIFT 8
+#define WINDOW_BREAK (1 << WINDOW_SHIFT)
+#define WINDOW_TOTAL ((1 << (WINDOW_MAX - WINDOW_SHIFT))+WINDOW_BREAK)
+
+// Matches of length MATCH_MIN use a shorter window because:
+//
+// 1. Encoding them with very large distances is inefficient.
+// 2. They occur pretty often and deserve their own frequency table.
+
+#define TINY_WINDOW_MAX 12 // 4K max
+#define SHORT_WINDOW_MAX 18 // 256K max
+
+#define MAGIC_MAX 3800 // was 4000 in 0.18 and earlier versions
+#define MAGIC_INC 8
+
+typedef struct
+ {
+ short Len;
+ long Dist;
+ } MATCH;
+
+
+#ifdef STAFFORD
+#define LONGDOUBLE long double
+#else
+#define LONGDOUBLE double
+#endif
+
+void FAST Lz_Init( BYTE WindowBits ); //msliger
+void FAST Lz_NextToken( void );
+void FAST Lz_Encode_Match( MATCH *Match );
+LONGDOUBLE FAST Lz_Encode_Match_Cost( MATCH *Match );
+void FAST Lz_Encode_Literal( int Ch );
+LONGDOUBLE FAST Lz_Encode_Literal_Cost( int Ch );
+void FAST Lz_Close( void );
+
+
+#endif
diff --git a/private/windows/diamond/quantum/mem.h b/private/windows/diamond/quantum/mem.h
new file mode 100644
index 000000000..9a476ba0e
--- /dev/null
+++ b/private/windows/diamond/quantum/mem.h
@@ -0,0 +1,11 @@
+// MEM.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+
+void *Mem_Malloc( long x );
+void Mem_Free( void *x );
diff --git a/private/windows/diamond/quantum/qci.c b/private/windows/diamond/quantum/qci.c
new file mode 100644
index 000000000..50b00d0bf
--- /dev/null
+++ b/private/windows/diamond/quantum/qci.c
@@ -0,0 +1,249 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1994
+ * All Rights Reserved.
+ *
+ * QCI.C: Quantum Compression Interface
+ *
+ * History:
+ * 20-Jan-1994 msliger Initial version (stub).
+ * 23-Jan-1994 msliger Real version (not a stub).
+ * 11-Feb-1994 msliger Changed M*ICreate() to adjust size.
+ * 13-Feb-1994 msliger revised type names, ie, UINT16 -> UINT.
+ * changed handles to HANDLEs.
+ * normalized MCI_MEMORY type.
+ * 24-Feb-1994 msliger Changed alloc,free to common typedefs.
+ * Changed MCI_MEMORY to MI_MEMORY.
+ * Restructured allocation/destruction.
+ * 15-Mar-1994 msliger Changes for 32 bits.
+ * 22-Mar-1994 msliger Changed interface USHORT to UINT.
+ * 26-May-1994 msliger Adapted to Quantum compression from MCI.C
+ * 27-May-1994 msliger Added configuration parameter.
+ * 30-May-1994 msliger Changed to QCI* names.
+ * 15-Jun-1994 msliger Use passed in alloc/free everywhere
+ */
+
+/* --- preprocessor ------------------------------------------------------- */
+
+#include <stdio.h> /* for NULL */
+#include <string.h> /* for memcpy() */
+
+#include "qci.h" /* types, prototype verification, error codes */
+
+#include "comp.h" /* features in COMP.C */
+
+#include "rtl.h" /* Rtl_Malloc/Free definitions */
+
+#define MAX_GROWTH 10240 /* don't know what it will really be */
+
+
+/* MAKE_SIGNATURE - Construct a structure signature
+ *
+ * Entry:
+ * a,b,c,d - four characters
+ *
+ * Exit:
+ * Returns constructed SIGNATURE
+ *
+ * Example:
+ * strct->signature = MAKE_SIGNATURE('b','e','n','s')
+ */
+
+#define MAKE_SIGNATURE(a,b,c,d) (a + (b<<8) + (c<<16) + (d<<24))
+#define BAD_SIGNATURE (0L)
+#define QCI_SIGNATURE MAKE_SIGNATURE('Q','C','I','C')
+
+/* --- QCI context structure ---------------------------------------------- */
+
+typedef ULONG SIGNATURE; /* structure signature */
+
+struct QCI_CONTEXT /* private structure */
+{
+ SIGNATURE signature; /* for validation */
+ PFNALLOC pfnAlloc; /* memory alloc function */
+ PFNFREE pfnFree; /* memory free function */
+ UINT cbDataBlockMax; /* promised max data size */
+};
+
+typedef struct QCI_CONTEXT FAR *PMCC_CONTEXT; /* a pointer to one */
+
+#define PMCCfromHMC(h) ((PMCC_CONTEXT)(h)) /* handle to pointer */
+#define HMCfromPMCC(p) ((QCI_CONTEXT_HANDLE)(p)) /* pointer to handle */
+
+
+/* --- local variables ---------------------------------------------------- */
+
+/*
+ * pmccLast - Remember last QCI context for use by Rtl_Malloc
+ * and Rtl_Free.
+ */
+static PMCC_CONTEXT pmccLast;
+
+
+/* --- QCICreateCompression() --------------------------------------------- */
+
+int DIAMONDAPI QCICreateCompression(
+ UINT * pcbDataBlockMax, /* max uncompressed data block */
+ void FAR * pvConfiguration, /* implementation-defined */
+ PFNALLOC pfnma, /* Memory allocation function */
+ PFNFREE pfnmf, /* Memory free function */
+ UINT * pcbDstBufferMin, /* gets required output buffer */
+ QCI_CONTEXT_HANDLE * pmchHandle) /* gets newly-created handle */
+{
+ PMCC_CONTEXT context; /* new context */
+ int FAR *pConfiguration; /* to get configuration details */
+ BYTE cWindowBits; /* for Quantum implementation */
+ int iCompressionLevel; /* for Quantum implementation */
+
+ *pmchHandle = (QCI_CONTEXT_HANDLE) 0; /* wait until it's valid */
+
+ pConfiguration = pvConfiguration; /* get a pointer we can use */
+ cWindowBits = (BYTE) pConfiguration[0]; /* get window bits config */
+ iCompressionLevel = pConfiguration[1]; /* get compress level config */
+
+ if ((cWindowBits < 10) || (cWindowBits > 21))
+ {
+ return(MCI_ERROR_CONFIGURATION); /* can't accept that */
+ }
+
+ if ((iCompressionLevel < 1) || (iCompressionLevel > 7))
+ {
+ return(MCI_ERROR_CONFIGURATION); /* can't accept that */
+ }
+
+ if (pConfiguration[2] != -1)
+ {
+ return(MCI_ERROR_CONFIGURATION); /* don't know any others */
+ }
+
+ if ((*pcbDataBlockMax == 0) || (*pcbDataBlockMax > 32768u))
+ {
+ *pcbDataBlockMax = 32768u; /* help with source block size */
+ }
+
+ context = pfnma(sizeof(struct QCI_CONTEXT));
+ if (context == NULL)
+ {
+ return(MCI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
+ }
+
+ context->pfnAlloc = pfnma;
+ context->pfnFree = pfnmf;
+ context->cbDataBlockMax = *pcbDataBlockMax; /* remember agreement */
+ context->signature = QCI_SIGNATURE;
+ pmccLast = context; /* Set for Rtl_Malloc/Free */
+
+ *pcbDstBufferMin = /* we'll expand sometimes */
+ *pcbDataBlockMax + MAX_GROWTH;
+
+ Comp_Init(cWindowBits,iCompressionLevel); /* setup compressor */
+
+ /* pass context back to caller */
+
+ *pmchHandle = HMCfromPMCC(context);
+
+ return(MCI_ERROR_NO_ERROR); /* tell caller all is well */
+}
+
+/* --- QCICompress() ------------------------------------------------------ */
+
+int DIAMONDAPI QCICompress(
+ QCI_CONTEXT_HANDLE hmc, /* compression context */
+ void FAR * pbSrc, /* source buffer */
+ UINT cbSrc, /* source actual size */
+ void FAR * pbDst, /* target buffer */
+ UINT cbDst, /* size of target buffer */
+ UINT * pcbResult) /* gets target actual size */
+{
+ PMCC_CONTEXT context; /* pointer to the context */
+ int result; /* return code */
+
+ context = PMCCfromHMC(hmc); /* get pointer from handle */
+ pmccLast = context; /* Save for Rtl_Malloc/Free */
+
+ if (context->signature != QCI_SIGNATURE)
+ {
+ return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ if (cbSrc > context->cbDataBlockMax)
+ {
+ return(MCI_ERROR_BAD_PARAMETERS); /* violated max block promise */
+ }
+
+ if (cbDst < (context->cbDataBlockMax + MAX_GROWTH))
+ {
+ return(MCI_ERROR_BAD_PARAMETERS); /* violated min buffer request */
+ }
+
+ result = Comp_CompressBlock(pbSrc,cbSrc,pbDst,cbDst,pcbResult);
+
+ if (result == 0)
+ {
+ return(MCI_ERROR_NO_ERROR); /* report no failure */
+ }
+ else
+ {
+ return(MCI_ERROR_FAILED); /* report failure */
+ }
+}
+
+/* --- QCIResetCompression() ---------------------------------------------- */
+
+int DIAMONDAPI QCIResetCompression(QCI_CONTEXT_HANDLE hmc)
+{
+ PMCC_CONTEXT context; /* pointer to the context */
+
+ context = PMCCfromHMC(hmc); /* get pointer from handle */
+ pmccLast = context; /* Save for Rtl_Malloc/Free */
+
+ if (context->signature != QCI_SIGNATURE)
+ {
+ return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ Comp_Reset(); /* do it */
+
+ return(MCI_ERROR_NO_ERROR); /* if tag is OK */
+}
+
+/* --- QCIDestroyCompression() -------------------------------------------- */
+
+int DIAMONDAPI QCIDestroyCompression(QCI_CONTEXT_HANDLE hmc)
+{
+ PMCC_CONTEXT context; /* pointer to context */
+
+ context = PMCCfromHMC(hmc); /* get pointer from handle */
+ pmccLast = context; /* Save for Rtl_Malloc/Free */
+
+ if (context->signature != QCI_SIGNATURE)
+ {
+ return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ Comp_Close(); /* shut down compressor */
+
+ context->signature = BAD_SIGNATURE; /* destroy signature */
+
+ context->pfnFree(context); /* self-destruct */
+ pmccLast = NULL; /* No context for Rtl_Malloc/Free */
+
+ return(MCI_ERROR_NO_ERROR); /* success */
+}
+
+/* --- Rtl_Malloc() ------------------------------------------------------- */
+
+void * FAST Rtl_Malloc( long x )
+ {
+ return pmccLast->pfnAlloc((ULONG) x);
+ }
+
+
+/* --- Rtl_Free() --------------------------------------------------------- */
+
+void FAST Rtl_Free( void *x )
+ {
+ pmccLast->pfnFree(x);
+ }
+
+/* ------------------------------------------------------------------------ */
diff --git a/private/windows/diamond/quantum/qci.h b/private/windows/diamond/quantum/qci.h
new file mode 100644
index 000000000..27eeda50b
--- /dev/null
+++ b/private/windows/diamond/quantum/qci.h
@@ -0,0 +1,268 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1993,1994
+ * All Rights Reserved.
+ *
+ * QCI.H - Diamond Memory Compression Interface (QCI)
+ *
+ * History:
+ * 30-May-1994 msliger Created from MCI.H by global replace.
+ * 31-May-1994 msliger Documented the configuration info.
+ * 08-Aug-1994 msliger pragma pack'd configuration array.
+ *
+ * Functions:
+ * QCICreateCompression - Create and reset an QCI compression context
+ * QCICloneCompression - Make a copy of a compression context
+ * QCICompress - Compress a block of data
+ * QCIResetCompression - Reset compression context
+ * QCIDestroyCompression - Destroy QCI compression context
+ *
+ * Types:
+ * QCI_CONTEXT_HANDLE - Handle to an QCI compression context
+ * PFNALLOC - Memory allocation function for QCI
+ * PFNFREE - Free memory function for QCI
+ */
+
+/* --- types -------------------------------------------------------------- */
+
+#ifndef DIAMONDAPI
+#define DIAMONDAPI __cdecl
+#endif
+
+#ifndef _BYTE_DEFINED
+#define _BYTE_DEFINED
+typedef unsigned char BYTE;
+#endif
+
+#ifndef _UINT_DEFINED
+#define _UINT_DEFINED
+typedef unsigned int UINT;
+#endif
+
+#ifndef _ULONG_DEFINED
+#define _ULONG_DEFINED
+typedef unsigned long ULONG;
+#endif
+
+#ifndef FAR
+#ifdef BIT16
+#define FAR far
+#else
+#define FAR
+#endif
+#endif
+
+#ifndef HUGE
+#ifdef BIT16
+#define HUGE huge
+#else
+#define HUGE
+#endif
+#endif
+
+#ifndef _MI_MEMORY_DEFINED
+#define _MI_MEMORY_DEFINED
+typedef void HUGE * MI_MEMORY;
+#endif
+
+#ifndef _MHANDLE_DEFINED
+#define _MHANDLE_DEFINED
+typedef unsigned long MHANDLE;
+#endif
+
+/* --- QCI-defined types -------------------------------------------------- */
+
+/* QCI_CONTEXT_HANDLE - Handle to an QCI compression context */
+
+typedef MHANDLE QCI_CONTEXT_HANDLE; /* hmc */
+
+
+/*** PFNALLOC - Memory allocation function for QCI
+ *
+ * Entry:
+ * cb - Size in bytes of memory block to allocate
+ *
+ * Exit-Success:
+ * Returns !NULL pointer to memory block
+ *
+ * Exit-Failure:
+ * Returns NULL; insufficient memory
+ */
+#ifndef _PFNALLOC_DEFINED
+#define _PFNALLOC_DEFINED
+typedef MI_MEMORY (FAR DIAMONDAPI *PFNALLOC)(ULONG cb); /* pfnma */
+#endif
+
+
+/*** PFNFREE - Free memory function for QCI
+ *
+ * Entry:
+ * pv - Memory block allocated by matching PFNALLOC function
+ *
+ * Exit:
+ * Memory block freed.
+ */
+#ifndef _PFNFREE_DEFINED
+#define _PFNFREE_DEFINED
+typedef void (FAR DIAMONDAPI *PFNFREE)(MI_MEMORY pv); /* pfnmf */
+#endif
+
+/* --- prototypes --------------------------------------------------------- */
+
+/*** QCICreateCompression - Create QCI compression context
+ *
+ * Entry:
+ * pcbDataBlockMax *largest uncompressed data block size desired,
+ * gets largest uncompressed data block allowed
+ * pvConfiguration passes implementation-specific info to compressor.
+ * pfnma memory allocation function pointer
+ * pfnmf memory free function pointer
+ * pcbDstBufferMin gets required compressed data buffer size
+ * pmchHandle gets newly-created context's handle
+ *
+ * Exit-Success:
+ * Returns MCI_ERROR_NO_ERROR;
+ * *pcbDataBlockMax, *pcbDstBufferMin, *pmchHandle filled in.
+ *
+ * Exit-Failure:
+ * MCI_ERROR_NOT_ENOUGH_MEMORY, could not allocate enough memory.
+ * MCI_ERROR_BAD_PARAMETERS, something wrong with parameters.
+ */
+int FAR DIAMONDAPI QCICreateCompression(
+ UINT FAR * pcbDataBlockMax, /* max uncompressed data block size */
+ void FAR * pvConfiguration, /* See QUANTUMCONFIGURATION */
+ PFNALLOC pfnma, /* Memory allocation function ptr */
+ PFNFREE pfnmf, /* Memory free function ptr */
+ UINT FAR * pcbDstBufferMin, /* gets required output buffer size */
+ QCI_CONTEXT_HANDLE FAR *pmchHandle); /* gets newly-created handle */
+
+
+/*** QCICloneCompression - Make a copy of a compression context
+ *
+ * Entry:
+ * hmc handle to current compression context
+ * pmchHandle gets newly-created handle
+ *
+ * Exit-Success:
+ * Returns MCI_ERROR_NO_ERROR;
+ * *pmchHandle filled in.
+ *
+ * Exit-Failure:
+ * Returns:
+ * MCI_ERROR_BAD_PARAMETERS, something wrong with parameters.
+ * MCI_ERROR_NOT_ENOUGH_MEMORY, could not allocate enough memory.
+ *
+ * NOTES:
+ * (1) This API is intended to permit "roll-back" of a sequence of
+ * of QCICompress() calls. Before starting a sequence that may need
+ * to be rolled-back, use QCICloneCompression() to save the state of
+ * the compression context, then do the QCICompress() calls. If the
+ * sequence is successful, the "cloned" hmc can be destroyed with
+ * QCIDestroyCompression(). If the sequence is *not* successful, then
+ * the original hmc can be destroyed, and the cloned one can be used
+ * to restart as if the sequence of QCICompress() calls had never
+ * occurred.
+ */
+int FAR DIAMONDAPI QCICloneCompression(
+ QCI_CONTEXT_HANDLE hmc, /* current compression context */
+ QCI_CONTEXT_HANDLE *pmchHandle); /* gets newly-created handle */
+
+
+/*** QCICompress - Compress a block of data
+ *
+ * Entry:
+ * hmc handle to compression context
+ * pbSrc source buffer (uncompressed data)
+ * cbSrc size of data to be compressed
+ * pbDst destination buffer (for compressed data)
+ * cbDst size of destination buffer
+ * pcbResult receives compressed size of data
+ *
+ * Exit-Success:
+ * Returns MCI_ERROR_NO_ERROR;
+ * *pcbResult has size of compressed data in pbDst.
+ * Compression context possibly updated.
+ *
+ * Exit-Failure:
+ * MCI_ERROR_BAD_PARAMETERS, something wrong with parameters.
+ */
+int FAR DIAMONDAPI QCICompress(
+ QCI_CONTEXT_HANDLE hmc, /* compression context */
+ void FAR * pbSrc, /* source buffer */
+ UINT cbSrc, /* source buffer size */
+ void FAR * pbDst, /* target buffer */
+ UINT cbDst, /* target buffer size */
+ UINT FAR * pcbResult); /* gets target data size */
+
+
+/*** QCIResetCompression - Reset compression history (if any)
+ *
+ * De-compression can only be started on a block which was compressed
+ * immediately following a QCICreateCompression() or QCIResetCompression()
+ * call. This function forces such a new "compression boundary" to be
+ * created (only by causing the compressor to ignore history, can the data
+ * output be decompressed without history.)
+ *
+ * Entry:
+ * hmc - handle to compression context
+ *
+ * Exit-Success:
+ * Returns MCI_ERROR_NO_ERROR;
+ * Compression context reset.
+ *
+ * Exit-Failure:
+ * Returns MCI_ERROR_BAD_PARAMETERS, invalid context handle.
+ */
+int FAR DIAMONDAPI QCIResetCompression(QCI_CONTEXT_HANDLE hmc);
+
+
+/*** QCIDestroyCompression - Destroy QCI compression context
+ *
+ * Entry:
+ * hmc - handle to compression context
+ *
+ * Exit-Success:
+ * Returns MCI_ERROR_NO_ERROR;
+ * Compression context destroyed.
+ *
+ * Exit-Failure:
+ * Returns MCI_ERROR_BAD_PARAMETERS, invalid context handle.
+ */
+int FAR DIAMONDAPI QCIDestroyCompression(QCI_CONTEXT_HANDLE hmc);
+
+/* --- constants ---------------------------------------------------------- */
+
+/* return codes */
+
+#define MCI_ERROR_NO_ERROR 0
+#define MCI_ERROR_NOT_ENOUGH_MEMORY 1
+#define MCI_ERROR_BAD_PARAMETERS 2
+#define MCI_ERROR_BUFFER_OVERFLOW 3
+#define MCI_ERROR_FAILED 4
+#define MCI_ERROR_CONFIGURATION 5
+
+/* --- Quantum configuration details ------------------------------------- */
+
+/*** Quantum pvConfiguration structure
+ *
+ * For the Quantum compressor, two parameters are configurable, the
+ * "compression level", which controls the compressor's aggression,
+ * and "window bits", which defines the size of the buffer needed by
+ * the decompressor (which affects the compressor's output).
+ */
+
+#pragma pack (2)
+
+typedef struct {
+ int WindowBits; // log2(buffersize), 10..21 (1K..2M)
+ int CompressionLevel; // 1..3 = fast/less compression
+ // 4..7 = slow/more compression
+//BUGBUG 01-Jun-1994 bens What is this 3rd int for?
+ int HackHack; // Has to be -1, why?
+} QUANTUMCONFIGURATION; /* qcfg */
+
+#pragma pack ()
+
+typedef QUANTUMCONFIGURATION *PQUANTUMCONFIGURATION; /* pqcfg */
+
+/* ----------------------------------------------------------------------- */
diff --git a/private/windows/diamond/quantum/qci.nt/makefile b/private/windows/diamond/quantum/qci.nt/makefile
new file mode 100644
index 000000000..8fe92222f
--- /dev/null
+++ b/private/windows/diamond/quantum/qci.nt/makefile
@@ -0,0 +1,2 @@
+!include $(NTMAKEENV)\makefile.def
+ \ No newline at end of file
diff --git a/private/windows/diamond/quantum/qci.nt/sources b/private/windows/diamond/quantum/qci.nt/sources
new file mode 100644
index 000000000..b9c2209b1
--- /dev/null
+++ b/private/windows/diamond/quantum/qci.nt/sources
@@ -0,0 +1,16 @@
+MAJORCOMP=diamond
+MINORCOMP=quantum_qci
+
+TARGETNAME=qci
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=LIBRARY
+
+C_DEFINES=-DBIT_CONSTANTS -DPAQ -DPAQLIB
+
+SOURCES=..\qci.c \
+ ..\comp.c \
+ ..\arith.c \
+ ..\lz.c \
+ ..\bit.c
+
+UMTYPE=console
diff --git a/private/windows/diamond/quantum/qdi.c b/private/windows/diamond/quantum/qdi.c
new file mode 100644
index 000000000..b9e27bbcd
--- /dev/null
+++ b/private/windows/diamond/quantum/qdi.c
@@ -0,0 +1,446 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1994
+ * All Rights Reserved.
+ *
+ * QDI.C: Quantum Decompression Interface
+ *
+ * History:
+ * 20-Jan-1994 msliger Initial version.
+ * 11-Feb-1994 msliger Changed M*ICreate() to adjust size.
+ * 13-Feb-1994 msliger revised type names, ie, UINT16 -> UINT.
+ * changed handles to HANDLEs.
+ * 24-Feb-1994 msliger Changed alloc,free to common typedefs.
+ * 22-Mar-1994 msliger Changed interface USHORT to UINT.
+ * 28-May-1994 msliger Created from MDI.C for Quantum.
+ * Added configuration parameter.
+ * 30-May-1994 msliger Changed to QDI* names.
+ * 08-Jul-1994 msliger Support for disk-based ring buffer.
+ * 27-Jul-1994 msliger Changed to allow ASM decompressor.
+ * 10-Aug-1994 msliger Changed to assert the requested decompress
+ * size for improved resistance to corrupted
+ * input data.
+ * 18-Aug-1994 msliger Implemented 286 decompress option.
+ * 31-Jan-1995 msliger Supported QDICreateDecompression query.
+ * 01-Feb-1995 msliger QDICreate no longer reserves memory.
+ */
+
+/* --- preprocessor ------------------------------------------------------- */
+
+/*
+ * Quantum Decompression is a very complicated, time consuming process, so
+ * we wrote a hand tuned 386 version. Unfortunately, some environments
+ * (80286 Win3.x machines and the Windows NT x86 emulation for Mips, Alpha,
+ * etc.) cannot run 386 code. So, we need to build different flavors of
+ * QDI.LIB:
+ * 16-bit QDI.LIB - has 286 & 386 versions
+ * 16-bit QDI3.LIB - 386-only version
+ * 32-bit QDI.LIB - 32-bit only version (for Win32 apps)
+ *
+ * There are two symbols which can be defined to affect how this code is
+ * built, USE_C_SRC and USE_386_ASM:
+ *
+ * USE_386_ASM Links the 386 assembler source (for i386+ non-Win32 only!)
+ *
+ * USE_C_SRC Links the C source. For any application. For
+ * 16-bit applications, this forces use of large memory model,
+ * and will generate externs for certain compiler run-time
+ * helpers, like __aFulmul.
+ * This is the DEFAULT if neither symbol is defined.
+ *
+ * These symbols can be defined in the following combinations:
+ * USE_386_ASM Only the 386 ASM code for 16-bit environments is available.
+ * ==> This is intended for Chicago setup, since Chicago only
+ * runs on i386 or better CPUs.
+ *
+ * USE_C_SRC Only the "portable" C code is available.
+ * ==> For Win32 builds, used by NT setup and Win32 EXTRACT.EXE,
+ * and Win32 ACME Setup.
+ *
+ * <both> Both "portable" C and the 16-bit 386 are available. The
+ * caller can force the use of the C code (compiled for 286,
+ * for compatibility purposes) or the 386 code, *or* can allow
+ * QDI to detect the CPU type and select the appropriate code.
+ * For 16-bit applications, this forces use of large memory
+ * model, and will generate externs for certain compiler run-
+ * time helpers, like __aNulshr.
+ * ==> For 16-bit ACME, which has to pass down the CPU type as
+ * determined by calling the Win16 API, since our CPU
+ * detection code is not reliable in 286-prot mode!
+ * ==> For 16-bit EXTRACT.EXE, which will rely upon the CPU
+ * detection code!
+ *
+ * <neither> Same as USE_C_SRC
+ */
+
+#include <stdio.h> /* for NULL */
+
+#ifdef USE_386_ASM
+#ifdef USE_C_SRC
+#define USE_BOTH /* means both are present */
+#endif
+#else /* if not USE_386_ASM */
+#ifndef USE_C_SRC
+#define USE_C_SRC /* make sure USE_C_SRC is defined if not USE_386_ASM */
+#endif
+#endif
+
+#include "qdi.h" /* types, prototype verification, error codes */
+#include "qdi_int.h" /* QDI internal structures */
+
+#ifdef USE_C_SRC
+#include "dcomp.h" /* features in DCOMP.C */
+#include "rtl.h" /* functions we gotta do for you */
+#endif
+
+#ifdef USE_386_ASM
+#include "decomp.h" /* features in DECOMP.ASM */
+#endif
+
+#ifdef USE_BOTH
+static int GetCPUtype(void); /* internal CPU determination */
+#endif
+
+#define MAX_GROWTH 10240 /* don't know what it will really be */
+
+#pragma warning(disable:4704) /* because of in-line asm code */
+
+/* MAKE_SIGNATURE - Construct a structure signature
+ *
+ * Entry:
+ * a,b,c,d - four characters
+ *
+ * Exit:
+ * Returns constructed SIGNATURE
+ *
+ * Example:
+ * strct->signature = MAKE_SIGNATURE('b','e','n','s')
+ */
+
+#define MAKE_SIGNATURE(a,b,c,d) (a + (b<<8) + (c<<16) + (d<<24))
+#define BAD_SIGNATURE (0L)
+#define QDI_SIGNATURE MAKE_SIGNATURE('Q','D','I','C')
+
+/* --- QDI context structure ---------------------------------------------- */
+
+PMDC_CONTEXT lastContext; /* needed for callbacks */
+
+#define PMDCfromHMD(h) ((PMDC_CONTEXT)(h)) /* handle to pointer */
+#define HMDfromPMDC(p) ((QDI_CONTEXT_HANDLE)(p)) /* pointer to handle */
+
+/* --- QDICreateDecompression() ------------------------------------------- */
+
+int FAR DIAMONDAPI QDICreateDecompression(
+ UINT FAR * pcbDataBlockMax, /* max uncompressed data block */
+ void FAR * pvConfiguration, /* implementation-defined */
+ PFNALLOC pfnma, /* Memory allocation function */
+ PFNFREE pfnmf, /* Memory free function */
+ UINT FAR * pcbSrcBufferMin, /* gets required input buffer */
+ QDI_CONTEXT_HANDLE FAR * pmdhHandle, /* gets newly-created handle */
+ PFNOPEN pfnopen, /* open a file callback */
+ PFNREAD pfnread, /* read a file callback */
+ PFNWRITE pfnwrite, /* write a file callback */
+ PFNCLOSE pfnclose, /* close a file callback */
+ PFNSEEK pfnseek) /* seek in file callback */
+{
+ PMDC_CONTEXT context; /* new context */
+ PFQUANTUMDECOMPRESS pConfig; /* to get configuration details */
+
+ pConfig = pvConfiguration; /* get a pointer we can use */
+
+ if ((pConfig->WindowBits < 10) || (pConfig->WindowBits > 21))
+ {
+ return(MDI_ERROR_CONFIGURATION); /* can't accept that */
+ }
+
+ if ((*pcbDataBlockMax == 0) || (*pcbDataBlockMax > 32768u))
+ {
+ *pcbDataBlockMax = 32768u; /* help with source block size */
+ }
+
+ *pcbSrcBufferMin = /* we'll expand sometimes */
+ *pcbDataBlockMax + MAX_GROWTH;
+
+ if (pmdhHandle == NULL) /* if no context requested, */
+ {
+ return(MDI_ERROR_NO_ERROR); /* return from query mode */
+ }
+
+#ifdef USE_BOTH
+ if (pConfig->fCPUtype == QDI_CPU_UNKNOWN)
+ {
+ pConfig->fCPUtype = GetCPUtype(); /* figure out if not told */
+ }
+ else if ((pConfig->fCPUtype != QDI_CPU_80286) &&
+ (pConfig->fCPUtype != QDI_CPU_80386))
+ {
+ return(MDI_ERROR_CONFIGURATION); /* bogus parameter used */
+ }
+#else /* not USE_BOTH */
+#ifdef USE_386_ASM
+ if (pConfig->fCPUtype == QDI_CPU_UNKNOWN)
+ {
+ pConfig->fCPUtype = QDI_CPU_80386;
+ }
+ else if (pConfig->fCPUtype != QDI_CPU_80386)
+ {
+ return(MDI_ERROR_CONFIGURATION); /* bogus parameter used */
+ }
+#else /* must be USE_C_SRC only */
+ /** Nothing to do -- we just call the C code, which was either compiled */
+ /* 16-bit or 32-bit. We could validate the parms, but no real need to */
+#endif /* USE_386_ASM */
+#endif /* USE_BOTH */
+
+ *pmdhHandle = (QDI_CONTEXT_HANDLE) 0; /* wait until it's valid */
+
+ context = pfnma(sizeof(struct QDI_CONTEXT));
+ if (context == NULL)
+ {
+ return(MDI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
+ }
+
+ context->pfnAlloc = pfnma; /* remember where alloc() is */
+ context->pfnFree = pfnmf; /* remember where free() is */
+ context->pfnOpen = pfnopen; /* remember where pfnopen() is */
+ context->pfnRead = pfnread; /* remember where pfnread() is */
+ context->pfnWrite = pfnwrite; /* remember where pfnwrite() is */
+ context->pfnClose = pfnclose; /* remember where pfnclose() is */
+ context->pfnSeek = pfnseek; /* remember where pfnseek() is */
+ context->cbDataBlockMax = *pcbDataBlockMax; /* remember agreement */
+ context->fCPUtype = pConfig->fCPUtype; /* remember CPU type */
+
+ context->signature = QDI_SIGNATURE; /* install signature */
+
+ lastContext = context; /* hand off to memory wrapper */
+
+#ifdef USE_C_SRC
+#ifdef USE_BOTH
+ if (context->fCPUtype == QDI_CPU_80286)
+#endif /* USE_BOTH */
+ {
+ /** Do the C source init **/
+ if (DComp_Init((BYTE) (pConfig->WindowBits)) != 0) /* setup decompressor */
+ {
+ pfnmf(context); /* self-destruct */
+
+ return(MDI_ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+#endif /* USE_C_SRC */
+
+#ifdef USE_386_ASM
+#ifdef USE_BOTH
+ else /* if (context->fCPUtype == QDI_CPU_80386) */
+#endif /* USE_BOTH */
+ {
+ /** Do the 386 ASM init **/
+ if (DComp386_Init((BYTE) (pConfig->WindowBits)) != 0) /* setup decompressor */
+ {
+ pfnmf(context); /* self-destruct */
+
+ return(MDI_ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+#endif /* USE_386_ASM */
+
+ /* pass context back to caller */
+
+ *pmdhHandle = HMDfromPMDC(context);
+
+ return(MDI_ERROR_NO_ERROR); /* tell caller all is well */
+}
+
+/* --- QDIDecompress() ---------------------------------------------------- */
+
+int FAR DIAMONDAPI QDIDecompress(
+ QDI_CONTEXT_HANDLE hmd, /* decompression context */
+ void FAR * pbSrc, /* source buffer */
+ UINT cbSrc, /* source actual size */
+ void FAR * pbDst, /* target buffer */
+ UINT FAR * pcbResult) /* gets actual target size */
+{
+ PMDC_CONTEXT context; /* pointer to the context */
+ int result; /* return code */
+
+ context = PMDCfromHMD(hmd); /* get pointer from handle */
+
+ if (context->signature != QDI_SIGNATURE)
+ {
+ return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ lastContext = context; /* hand off to memory wrapper */
+
+ if (*pcbResult > context->cbDataBlockMax)
+ {
+ return(MDI_ERROR_BUFFER_OVERFLOW); /* violated max block promise */
+ }
+
+#ifdef USE_C_SRC
+#ifdef USE_BOTH
+ if (context->fCPUtype == QDI_CPU_80286)
+#endif /* USE_BOTH */
+ {
+ result = DComp_DecompressBlock(pbSrc,cbSrc,pbDst,*pcbResult);
+ }
+#endif /* USE_C_SRC */
+
+#ifdef USE_386_ASM
+#ifdef USE_BOTH
+ else /* (context->fCPUtype == QDI_CPU_80386) */
+#endif /* USE_BOTH */
+ {
+ result = DComp386_DecompressBlock(pbSrc,cbSrc,pbDst,*pcbResult);
+ }
+#endif /* USE_386_ASM */
+
+ if (result == 0)
+ {
+ return(MDI_ERROR_NO_ERROR); /* report no failure */
+ }
+ else
+ {
+ return(MDI_ERROR_FAILED); /* report failure */
+ }
+}
+
+/* --- QDIResetDecompression() -------------------------------------------- */
+
+int FAR DIAMONDAPI QDIResetDecompression(QDI_CONTEXT_HANDLE hmd)
+{
+ PMDC_CONTEXT context; /* pointer to the context */
+
+ context = PMDCfromHMD(hmd); /* get pointer from handle */
+
+ if (context->signature != QDI_SIGNATURE)
+ {
+ return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ lastContext = context; /* hand off to memory wrapper */
+
+#ifdef USE_C_SRC
+#ifdef USE_BOTH
+ if (context->fCPUtype == QDI_CPU_80286)
+#endif /* USE_BOTH */
+ {
+ DComp_Reset(); /* do it */
+ }
+#endif /* USE_C_SRC */
+
+#ifdef USE_386_ASM
+#ifdef USE_BOTH
+ else /* if (context->fCPUtype == QDI_CPU_80386) */
+#endif /* USE_BOTH */
+ {
+ DComp386_Reset(); /* do it */
+ }
+#endif /* USE_386_ASM */
+
+ return(MDI_ERROR_NO_ERROR); /* if tag is OK */
+}
+
+/* --- QDIDestroyDecompression() ------------------------------------------ */
+
+int FAR DIAMONDAPI QDIDestroyDecompression(QDI_CONTEXT_HANDLE hmd)
+{
+ PMDC_CONTEXT context; /* pointer to the context */
+
+ context = PMDCfromHMD(hmd); /* get pointer from handle */
+
+ if (context->signature != QDI_SIGNATURE)
+ {
+ return(MDI_ERROR_BAD_PARAMETERS); /* missing signature */
+ }
+
+ lastContext = context; /* hand off to memory wrapper */
+
+#ifdef USE_C_SRC
+#ifdef USE_BOTH
+ if (context->fCPUtype == QDI_CPU_80286)
+#endif /* USE_BOTH */
+ {
+ DComp_Close(); /* shut down decompressor */
+ }
+#endif /* USE_C_SRC */
+
+#ifdef USE_386_ASM
+#ifdef USE_BOTH
+ else /* if (context->fCPUtype == QDI_CPU_80386) */
+#endif /* USE_BOTH */
+ {
+ DComp386_Close(); /* shut down decompressor */
+ }
+#endif /* USE_386_ASM */
+
+ context->signature = BAD_SIGNATURE; /* destroy signature */
+
+ context->pfnFree(context); /* self-destruct */
+
+ return(MDI_ERROR_NO_ERROR); /* success */
+}
+
+
+#ifdef USE_C_SRC
+
+/* --- Rtl_Malloc() ------------------------------------------------------- */
+
+void * FAST Rtl_Malloc( long x )
+ {
+ return(lastContext->pfnAlloc((ULONG) x));
+ }
+
+/* --- Rtl_Free() --------------------------------------------------------- */
+
+void FAST Rtl_Free( void *x )
+ {
+ lastContext->pfnFree(x);
+ }
+
+#endif /* USE_C_SRC */
+
+#ifdef USE_BOTH
+
+/* --- GetCPUtype() ------------------------------------------------------- */
+
+#define ASM __asm
+
+/*** GetCPUtype - Determine CPU type (286 vs. 386 or better)
+ *
+ * [Logic taken from emm386/smartdrv.]
+ *
+ * Entry:
+ * none:
+ *
+ * Exit:
+ * Returns QDI_CPU_80286 if on i286 or compatible.
+ * Returns QDI_CPU_80386 if on i386 or better (or compatible).
+ */
+static int GetCPUtype(void)
+{
+ int f286;
+
+ ASM pushf /* preserve original flags */
+ ASM mov ax,7000h /* try to set some special flags bits */
+ ASM push ax /* put up for popf */
+ ASM popf /* pull number into flags */
+ ASM pushf /* push flags back */
+ ASM pop ax /* pull flags into AX */
+ ASM popf /* restore original flags */
+ ASM and ax,7000h /* check for 386-specific bits */
+ ASM mov f286,ax /* return the result */
+
+ if (f286 != 0)
+ {
+ return(QDI_CPU_80386);
+ }
+ else
+ {
+ return(QDI_CPU_80286);
+ }
+}
+
+#endif /* USE_BOTH */
+
+/* ------------------------------------------------------------------------ */
diff --git a/private/windows/diamond/quantum/qdi.h b/private/windows/diamond/quantum/qdi.h
new file mode 100644
index 000000000..e3a635290
--- /dev/null
+++ b/private/windows/diamond/quantum/qdi.h
@@ -0,0 +1,445 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1993,1994
+ * All Rights Reserved.
+ *
+ * QDI.H - Diamond Memory Decompression Interface (QDI)
+ *
+ * History:
+ * 01-Dec-1993 bens Initial version.
+ * 16-Jan-1994 msliger Split into MCI, MDI.
+ * 11-Feb-1994 msliger Changed M*ICreate() to adjust size.
+ * 13-Feb-1994 msliger revised type names, ie, UINT16 -> UINT.
+ * changed handles to HANDLEs.
+ * normalized MDI_MEMORY type.
+ * 24-Feb-1994 msliger Changed alloc,free to common typedefs.
+ * Changed HANDLE to MHANDLE.
+ * Changed MDI_MEMORY to MI_MEMORY.
+ * 22-Mar-1994 msliger Changed !INT32 to BIT16.
+ * Changed interface USHORT to UINT.
+ * 28-May-1994 msliger Added configuration parms, error code.
+ * 30-May-1994 msliger Created from MDI.H by global replace.
+ * 31-May-1994 msliger Documented the configuration info.
+ * 01-Jul-1994 msliger Added support for ring buffer on disk.
+ * 27-Jul-1994 msliger Added more def's to support ASM build.
+ * 08-Aug-1994 msliger pragma pack'd configuration array.
+ * 18-Aug-1994 msliger Added CPU type to configuration array.
+ * 22-Aug-1994 msliger Clarified *pcbResult in QDIDecompress(),
+ * changed it's name to pcbDecompressed.
+ * 31-Jan-1995 msliger Supported MDICreateDecompression query.
+ *
+ * Functions:
+ * QDICreateDecompression - Create and reset an QDI decompression context
+ * QDIDecompress - Decompress a block of data
+ * QDIResetDecompression - Reset QDI decompression context
+ * QDIDestroyDecompression - Destroy QDI Decompression context
+ *
+ * Types:
+ * QDI_CONTEXT_HANDLE - Handle to an QDI decompression context
+ * PFNALLOC - Memory allocation function for QDI
+ * PFNFREE - Free memory function for QDI
+ */
+
+/* --- types -------------------------------------------------------------- */
+
+#ifndef DIAMONDAPI
+#define DIAMONDAPI __cdecl
+#endif
+
+#ifndef _BYTE_DEFINED
+#define _BYTE_DEFINED
+typedef unsigned char BYTE;
+#endif
+
+#ifndef _UINT_DEFINED
+#define _UINT_DEFINED
+typedef unsigned int UINT;
+#endif
+
+#ifndef _ULONG_DEFINED
+#define _ULONG_DEFINED
+typedef unsigned long ULONG;
+#endif
+
+#ifndef NEAR
+#ifdef BIT16
+#define NEAR __near
+#else
+#define NEAR
+#endif
+#endif
+
+#ifndef FAR
+#ifdef BIT16
+#define FAR __far
+#else
+#define FAR
+#endif
+#endif
+
+#ifndef HUGE
+#ifdef BIT16
+#define HUGE __huge
+#else
+#define HUGE
+#endif
+#endif
+
+#ifndef FAST
+#ifdef BIT16
+#define FAST __near __pascal
+#else
+#define FAST
+#endif
+#endif
+
+#ifndef FAST2
+#ifdef BIT16
+#define FAST2 __near __fastcall
+#else
+#define FAST2 __fastcall
+#endif
+#endif
+
+#ifndef _MI_MEMORY_DEFINED
+#define _MI_MEMORY_DEFINED
+typedef void HUGE * MI_MEMORY;
+#endif
+
+#ifndef _MHANDLE_DEFINED
+#define _MHANDLE_DEFINED
+typedef unsigned long MHANDLE;
+#endif
+
+#ifndef UNALIGNED
+#ifndef NEEDS_ALIGNMENT
+#define UNALIGNED
+#else
+#define UNALIGNED __unaligned
+#endif
+#endif
+
+
+/*
+ * QDI will try to create a virtual ring buffer on disk if the pfnalloc call
+ * to create the buffer fails. These functions provide QDI the disk access
+ * features needed.
+ *
+ * These are modeled after the C run-time routines _open, _read,
+ * _write, _close, and _lseek. The values for the PFNOPEN oflag
+ * and pmode calls are those defined for _open. QDI expects error
+ * handling to be identical to these C run-time routines.
+ *
+ * As long as you faithfully copy these aspects, you can supply
+ * any functions you like!
+ *
+ * For PFNOPEN, the pszFile parameter will take on a special form for QDI's
+ * temporary file. The special form appears as a file named "*". Such a
+ * name field should be cast into the struct below, which contains the
+ * required file's size as shown in the RINGNAME structure below.
+ *
+ * Example open and close callbacks are provided. It is assumed that the
+ * client will provide more adaptive code for determining the temporary
+ * file's name and drive location, based on environment variables and the
+ * amount of free disk space. This sample code has hard-coded the actual
+ * path and fails if there is not enough free space. This code creates the
+ * file, then attempts to expand it to the requested size by writing a byte
+ * (any byte) at the requested size - 1. (This approach is not suitable for
+ * a file system which can support sparse files.)
+ *
+ * The callback routine may create this file on any path, and with any name,
+ * as appropriate. If the file cannot be created with the requested size,
+ * the PFNOPEN should fail. The file really should be placed on a local
+ * fixed disk. It would not be appropriate for the file to be placed on a
+ * compressed drive or a floppy disk. If the client has access to alternate
+ * memory, such as XMS or EMS, these operations could be emuluated.
+ *
+ * static int tempHandle = -1;
+ *
+ * int FAR DIAMONDAPI MyOpen(char FAR *pszFile,int oflag,int pmode)
+ * {
+ * if (*pszFile == '*')
+ * {
+ * PRINGNAME pringDescriptor;
+ *
+ * pringDescriptor = (PRINGNAME) pszFile;
+ *
+ * tempHandle = _open("C:\\qdi_temp.$$$",oflag,pmode);
+ *
+ * if (tempHandle != -1)
+ * {
+ * _lseek(tempHandle,(pringDescriptor->fileSize - 1),SEEK_SET);
+ *
+ * if (_write(tempHandle,&tempHandle,1) != 1)
+ * {
+ * _close(tempHandle);
+ * remove("C:\\qdi_temp.$$$");
+ * tempHandle = -1;
+ * }
+ * }
+ *
+ * return(tempHandle);
+ * }
+ * else
+ * {
+ * * QDI only will call with *pszFile == '*' *
+ * }
+ * }
+ *
+ * The callback provider must watch for the corresponding PFNCLOSE call on
+ * the returned handle, and delete the created file after closing. (The
+ * file handle and file name assigned to the temporary file must be tracked;
+ * a close operation on that handle must be trapped, so the temporary file
+ * can be deleted as well.)
+ *
+ * The client does not need to worry about multiple concurrent opens of the
+ * temporary file, or more than a single temporary file (from QDI).
+ *
+ * int FAR DIAMONDAPI MyClose(int handle)
+ * {
+ * int result;
+ *
+ * result = _close(handle);
+ *
+ * if (handle == tempHandle)
+ * {
+ * remove("C:\\qdi_temp.$$$");
+ * tempHandle = -1;
+ * }
+ *
+ * return(result);
+ * }
+ */
+
+typedef int (FAR DIAMONDAPI *PFNOPEN) (char FAR *pszFile,int oflag,int pmode);
+typedef UINT (FAR DIAMONDAPI *PFNREAD) (int hf, void FAR *pv, UINT cb);
+typedef UINT (FAR DIAMONDAPI *PFNWRITE)(int hf, void FAR *pv, UINT cb);
+typedef int (FAR DIAMONDAPI *PFNCLOSE)(int hf);
+typedef long (FAR DIAMONDAPI *PFNSEEK) (int hf, long dist, int seektype);
+
+#pragma pack (1)
+
+typedef struct
+{
+ char wildName[2]; /* set to { '*', '\0' } */
+ unsigned long fileSize; /* the required file size in bytes */
+} RINGNAME, FAR *PRINGNAME;
+
+#pragma pack ()
+
+/* --- QDI-defined types -------------------------------------------------- */
+
+/* QDI_CONTEXT_HANDLE - Handle to a QDI decompression context */
+
+typedef MHANDLE QDI_CONTEXT_HANDLE; /* hmd */
+
+
+/*** PFNALLOC - Memory allocation function for QDI
+ *
+ * Entry:
+ * cb - Size in bytes of memory block to allocate
+ *
+ * Exit-Success:
+ * Returns !NULL pointer to memory block
+ *
+ * Exit-Failure:
+ * Returns NULL; insufficient memory
+ */
+#ifndef _PFNALLOC_DEFINED
+#define _PFNALLOC_DEFINED
+typedef MI_MEMORY (FAR DIAMONDAPI *PFNALLOC)(ULONG cb); /* pfnma */
+#endif
+
+
+/*** PFNFREE - Free memory function for QDI
+ *
+ * Entry:
+ * pv - Memory block allocated by matching PFNALLOC function
+ *
+ * Exit:
+ * Memory block freed.
+ */
+#ifndef _PFNFREE_DEFINED
+#define _PFNFREE_DEFINED
+typedef void (FAR DIAMONDAPI *PFNFREE)(MI_MEMORY pv); /* pfnmf */
+#endif
+
+/* --- prototypes --------------------------------------------------------- */
+
+/*** QDICreateDecompression - Create QDI decompression context
+ *
+ * Entry:
+ * pcbDataBlockMax *largest uncompressed data block size expected,
+ * gets largest uncompressed data block allowed
+ * pvConfiguration passes implementation-specific info to decompressor.
+ * pfnma memory allocation function pointer
+ * pfnmf memory free function pointer
+ * pcbSrcBufferMin gets max compressed buffer size
+ * pmdhHandle gets newly-created context's handle
+ * pfnopen file open function pointer (or NULL)
+ * pfnread file read function pointer (or don't care)
+ * pfnwrite file write function pointer (or don't care)
+ * pfnclose file close function pointer (or don't care)
+ * pfnseek file seek function pointer (or don't care)
+ *
+ * If NULL is provided for pfnopen, and the ring buffer cannot be
+ * created via pfnma, QDICreateDecompression will fail.
+ *
+ * If pmdhHandle==NULL, *pcbDataBlockMax and *pcbSrcBufferMin will be
+ * filled in, but no context will be created. This query will allow
+ * the caller to determine required buffer sizes before creating a
+ * context.
+ *
+ * Exit-Success:
+ * Returns MDI_ERROR_NO_ERROR;
+ * *pcbDataBlockMax, *pcbSrcBufferMin, *pmdhHandle filled in.
+ *
+ * Exit-Failure:
+ * MDI_ERROR_NOT_ENOUGH_MEMORY, could not allocate enough memory.
+ * MDI_ERROR_BAD_PARAMETERS, something wrong with parameters.
+ * *pcbDataBlockMax, *pcbSrcBufferMin, *pmdhHandle undefined.
+ */
+int FAR DIAMONDAPI QDICreateDecompression(
+ UINT FAR * pcbDataBlockMax, /* max uncompressed data block size */
+ void FAR * pvConfiguration, /* implementation-defined */
+ PFNALLOC pfnma, /* Memory allocation function ptr */
+ PFNFREE pfnmf, /* Memory free function ptr */
+ UINT FAR * pcbSrcBufferMin, /* gets max. comp. buffer size */
+ QDI_CONTEXT_HANDLE FAR * pmdhHandle, /* gets newly-created handle */
+ PFNOPEN pfnopen, /* open a file callback */
+ PFNREAD pfnread, /* read a file callback */
+ PFNWRITE pfnwrite, /* write a file callback */
+ PFNCLOSE pfnclose, /* close a file callback */
+ PFNSEEK pfnseek); /* seek in file callback */
+
+
+/*** QDIDecompress - Decompress a block of data
+ *
+ * Entry:
+ * hmd handle to decompression context
+ * pbSrc source buffer (compressed data)
+ * cbSrc compressed size of data to be decompressed
+ * pbDst destination buffer (for decompressed data)
+ * *pcbDecompressed (ptr to UINT) the expected de-compressed size
+ * of this data block. (same as cbSrc from the
+ * QCICompress() call.).
+ *
+ * Exit-Success:
+ * Returns MDI_ERROR_NO_ERROR;
+ * *pcbDecompressed has size of decompressed data in pbDst.
+ * Decompression context updated.
+ *
+ * Exit-Failure:
+ * MDI_ERROR_BAD_PARAMETERS, something wrong with parameters.
+ * MDI_ERROR_BUFFER_OVERFLOW, cbSrc is too small to yield the
+ * requested *pcbDecompressed count. cbSrc before QDIDecompressed
+ * should always equal *pcbResult after QCICompress(), and
+ * *pcbDecompressed before QDIDecompress should always equal the
+ * cbSrc before QCICompress().
+ * MDI_ERROR_FAILED, either cbSrc is too small, *pcbDecompressed is too
+ * large, or *pbSrc is corrupt.
+ *
+ * Note:
+ * Set your cbDecompressed to the expected de-compressed size of this
+ * data block, then call QDIDecompress() with the address of your
+ * cbDecompressed.
+ */
+int FAR DIAMONDAPI QDIDecompress(
+ QDI_CONTEXT_HANDLE hmd, /* decompression context */
+ void FAR * pbSrc, /* source buffer */
+ UINT cbSrc, /* source data size */
+ void FAR * pbDst, /* target buffer */
+ UINT FAR * pcbDecompressed); /* target data size */
+
+
+/*** QDIResetDecompression - Reset decompression history (if any)
+ *
+ * De-compression can only be started on a block which was compressed
+ * immediately following a MCICreateCompression() or MCIResetCompression()
+ * call. This function provides notification to the decompressor that the
+ * next compressed block begins on a compression boundary.
+ *
+ * Entry:
+ * hmd - handle to decompression context
+ *
+ * Exit-Success:
+ * Returns MDI_ERROR_NO_ERROR;
+ * Decompression context reset.
+ *
+ * Exit-Failure:
+ * Returns MDI_ERROR_BAD_PARAMETERS, invalid context handle.
+ */
+int FAR DIAMONDAPI QDIResetDecompression(QDI_CONTEXT_HANDLE hmd);
+
+
+/*** QDIDestroyDecompression - Destroy QDI decompression context
+ *
+ * Entry:
+ * hmd - handle to decompression context
+ *
+ * Exit-Success:
+ * Returns MDI_ERROR_NO_ERROR;
+ * Decompression context destroyed.
+ *
+ * Exit-Failure:
+ * Returns MDI_ERROR_BAD_PARAMETERS, invalid context handle.
+ */
+int FAR DIAMONDAPI QDIDestroyDecompression(QDI_CONTEXT_HANDLE hmd);
+
+/* --- constants ---------------------------------------------------------- */
+
+/* return codes */
+
+#define MDI_ERROR_NO_ERROR 0
+#define MDI_ERROR_NOT_ENOUGH_MEMORY 1
+#define MDI_ERROR_BAD_PARAMETERS 2
+#define MDI_ERROR_BUFFER_OVERFLOW 3
+#define MDI_ERROR_FAILED 4
+#define MDI_ERROR_CONFIGURATION 5
+
+/* --- Quantum configuration details ------------------------------------- */
+
+/*** Quantum pvConfiguration structure
+ *
+ * For the Quantum decompressor, two parameters are configurable, the
+ * "window bits", which defines the size of the buffer needed by the
+ * the decompressor (must match the value used to compress), and the CPU
+ * type, which controls whether 386 opcodes will be used or not. If
+ * "unknown" is provided for the fCPUtype, QDI will attempt to determine
+ * the CPU type itself, which could fail or produce system faults on
+ * non-DOS platforms (like Windows.) Windows apps should use GetWinFlags()
+ * or a similiar method, and never pass "unknown".
+ *
+ * pvConfiguration points to this structure.
+ */
+
+#pragma pack (1)
+
+typedef struct {
+ int WindowBits; /* log2(buffersize), 10..21 (1K..2M) */
+ int fCPUtype; /* controls internal code selection */
+} QUANTUMDECOMPRESS; /* qdec */
+
+#pragma pack ()
+
+typedef QUANTUMDECOMPRESS *PQUANTUMDECOMPRESS; /* pqdec */
+typedef QUANTUMDECOMPRESS FAR *PFQUANTUMDECOMPRESS; /* pfqdec */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * QDI_CPU_UNKNOWN detection does *not* work when running under Windows
+ * in 286 protected mode! Call GetWinFlags() to determine
+ * the CPU type and pass it explicitly!
+ */
+
+#define QDI_CPU_UNKNOWN (-1) /* internally determined */
+
+/*
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+#define QDI_CPU_80286 (0) /* '286 opcodes only */
+#define QDI_CPU_80386 (1) /* '386 opcodes used */
+#define QDI_CPU_CONSERVATIVE (QDI_CPU_80286)
+
+/* ----------------------------------------------------------------------- */
diff --git a/private/windows/diamond/quantum/qdi.nt/makefile b/private/windows/diamond/quantum/qdi.nt/makefile
new file mode 100644
index 000000000..8fe92222f
--- /dev/null
+++ b/private/windows/diamond/quantum/qdi.nt/makefile
@@ -0,0 +1,2 @@
+!include $(NTMAKEENV)\makefile.def
+ \ No newline at end of file
diff --git a/private/windows/diamond/quantum/qdi.nt/sources b/private/windows/diamond/quantum/qdi.nt/sources
new file mode 100644
index 000000000..be6d54685
--- /dev/null
+++ b/private/windows/diamond/quantum/qdi.nt/sources
@@ -0,0 +1,15 @@
+MAJORCOMP=diamond
+MINORCOMP=quantum_qdi
+
+TARGETNAME=qdi
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=LIBRARY
+
+C_DEFINES=-DBIT_CONSTANTS -DUNPAQ -DUNPAQLIB
+
+SOURCES=..\qdi.c \
+ ..\dcomp.c \
+ ..\arith.c \
+ ..\lz.c
+
+UMTYPE=console
diff --git a/private/windows/diamond/quantum/qdi_int.h b/private/windows/diamond/quantum/qdi_int.h
new file mode 100644
index 000000000..dab9ad01b
--- /dev/null
+++ b/private/windows/diamond/quantum/qdi_int.h
@@ -0,0 +1,35 @@
+/*
+ * Microsoft Confidential
+ * Copyright (C) Microsoft Corporation 1994
+ * All Rights Reserved.
+ *
+ * QDI_INT.H: Quantum Decompression Interface private data
+ *
+ * History:
+ * 20-Jun-1994 msliger Initial version.
+ * 18-Aug-1994 msliger Added CPU type.
+ */
+
+/* --- QDI context structure ---------------------------------------------- */
+
+typedef ULONG SIGNATURE; /* structure signature */
+
+struct QDI_CONTEXT /* private structure */
+{
+ SIGNATURE signature; /* for validation */
+ PFNALLOC pfnAlloc; /* where the alloc() is */
+ PFNFREE pfnFree; /* where the free() is */
+ PFNOPEN pfnOpen; /* open a file callback or NULL */
+ PFNREAD pfnRead; /* read a file callback */
+ PFNWRITE pfnWrite; /* write a file callback */
+ PFNCLOSE pfnClose; /* close a file callback */
+ PFNSEEK pfnSeek; /* seek in file callback */
+ UINT cbDataBlockMax; /* promised max data size */
+ UINT fCPUtype; /* CPU we're running on, QDI_CPU_xxx */
+};
+
+typedef struct QDI_CONTEXT FAR *PMDC_CONTEXT; /* a pointer to one */
+
+extern PMDC_CONTEXT lastContext; /* needed for memory callbacks */
+
+/* ------------------------------------------------------------------------ */
diff --git a/private/windows/diamond/quantum/quantum.h b/private/windows/diamond/quantum/quantum.h
new file mode 100644
index 000000000..8de238c95
--- /dev/null
+++ b/private/windows/diamond/quantum/quantum.h
@@ -0,0 +1,71 @@
+// QUANTUM.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __QUANTUM
+#define __QUANTUM
+
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef int BOOL;
+
+#ifndef FALSE
+ #define FALSE 0
+ #define TRUE !FALSE
+#endif
+
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 23
+
+#define FILES_MAX 1024 // maximum number of files in an archive
+
+#define ARCHIVE_SIGNATURE 0x5344 // 'DS', used to identify a Quantum archive
+
+
+// The archive file header
+
+typedef struct
+ {
+ WORD Signature;
+ BYTE VersionMajor;
+ BYTE VersionMinor;
+ WORD NumFiles;
+ BYTE WindowBits;
+ BYTE CompFlags;
+ } AHEADER;
+
+
+// The archive header is immediately followed by the list of files
+
+typedef struct
+ {
+ char *Name;
+ char *Alias; // if not NULL, the alias name to put in a new archive
+ char *Comment;
+ DWORD Size;
+ WORD Time;
+ WORD Date;
+ WORD Checksum;
+ } AFILE;
+
+
+typedef struct
+ {
+ char *ArchiveName;
+ WORD NumFiles;
+ AFILE *Files;
+ BYTE VersionMajor;
+ BYTE VersionMinor;
+ BYTE WindowBits; // number of bits to address the history window
+ int CompressionLevel;
+ long SizeLimit; // limit of an archive size, for multiple volumes
+ } APARMS;
+
+
+#endif // quantum.h
diff --git a/private/windows/diamond/quantum/rtl.h b/private/windows/diamond/quantum/rtl.h
new file mode 100644
index 000000000..d8dfff685
--- /dev/null
+++ b/private/windows/diamond/quantum/rtl.h
@@ -0,0 +1,23 @@
+// RTL.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __RTL
+#define __RTL
+
+#include <io.h>
+#include "defs.h"
+
+char * FAST Rtl_GetPathNameOnly( char *PathName, char *FileName );
+char * FAST Rtl_GetFileNameOnly( char *FileName );
+char * FAST Rtl_GetFileNameSuffixOnly( char *FileName );
+void FAST Rtl_DOS_to_ftime( WORD Date, WORD Time, struct ftime *FTime );
+int FAST Rtl_ftime_to_DOS( WORD *Date, WORD *Time, struct ftime *FTime );
+void * FAST Rtl_Malloc( long x );
+void FAST Rtl_Free( void *x );
+
+#endif
diff --git a/private/windows/diamond/quantum/view.h b/private/windows/diamond/quantum/view.h
new file mode 100644
index 000000000..ad3a81104
--- /dev/null
+++ b/private/windows/diamond/quantum/view.h
@@ -0,0 +1,15 @@
+// VIEW.H
+//
+// Quantum file archiver and compressor
+// Advanced data compression
+//
+// Copyright (c) 1993,1994 David Stafford
+// All rights reserved.
+
+#ifndef __VIEW
+#define __VIEW
+
+
+void View( char *ArchiveName );
+
+#endif // view.h