Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.1 KiB

  1. /* DEC/CMS REPLACEMENT HISTORY, Element ZIP.C */
  2. /* *1 14-NOV-1996 10:27:08 ANIGBOGU "[113914]Compress data to zip format using the deflate algorithm" */
  3. /* DEC/CMS REPLACEMENT HISTORY, Element ZIP.C */
  4. /* PRIVATE FILE
  5. ******************************************************************************
  6. **
  7. ** (c) Copyright Schlumberger Technology Corp., unpublished work, created 1996.
  8. **
  9. ** This computer program includes Confidential, Proprietary Information and is
  10. ** a Trade Secret of Schlumberger Technology Corp. All use, disclosure, and/or
  11. ** reproduction is prohibited unless authorized in writing by Schlumberger.
  12. ** All Rights Reserved.
  13. **
  14. ******************************************************************************
  15. **
  16. ** compress/zip.c
  17. **
  18. ** PURPOSE
  19. **
  20. ** Compress data using the deflate algorithm
  21. **
  22. ** SPECIAL REQUIREMENTS & NOTES
  23. **
  24. ** AUTHOR
  25. **
  26. ** J. C. Anigbogu
  27. ** Austin Systems Center
  28. ** Nov 1996
  29. **
  30. ******************************************************************************
  31. */
  32. #include <ctype.h>
  33. #include <sys/types.h>
  34. #include "comppriv.h"
  35. CompressStatus_t Copy(CompParam_t *comp);
  36. /* ===========================================================================
  37. * Deflate in to out.
  38. * IN assertions: the input and output buffers are cleared.
  39. */
  40. CompressStatus_t
  41. Zip(
  42. int CompLevel, /* compression level */
  43. CompParam_t *Comp
  44. )
  45. {
  46. unsigned char Flags = 0; /* general purpose bit flags */
  47. unsigned short DeflateFlags = 0; /* pkzip -es, -en or -ex equivalent */
  48. long TimeStamp = 0; /* time_stamp */
  49. LocalBits_t *Bits;
  50. DeflateParam_t *Defl; /* window offset of current block */
  51. LocalDef_t *Deflt;
  52. int Method = CompLevel ? DEFLATED : STORED;
  53. CompressStatus_t Status = COMPRESS_OK;
  54. Comp->OutBytes = 0;
  55. /* Write the header to the gzip buffer. See algorithm.doc for the format */
  56. PutByte(GZIP_MAGIC[0], Comp); /* magic header */
  57. PutByte(GZIP_MAGIC[1], Comp);
  58. PutByte(Method, Comp); /* compression method */
  59. PutByte(Flags, Comp); /* general flags */
  60. PutLong(TimeStamp, Comp);
  61. Comp->pCRC->Compute(NULL, 0);
  62. Comp->HeaderBytes = Comp->OutBytes;
  63. if (Method == STORED)
  64. {
  65. PutByte((unsigned char)0, Comp); /* extra flags */
  66. PutByte(OS_CODE, Comp); /* OS identifier */
  67. Status = Copy(Comp);
  68. if (COMPRESS_OK != Status)
  69. return Status;
  70. }
  71. else
  72. {
  73. Bits = (LocalBits_t *)CompressMalloc(sizeof(LocalBits_t), &Status);
  74. if (Status != COMPRESS_OK)
  75. return Status;
  76. InitializeBits(Bits);
  77. InitMatchBuffer();
  78. Defl = (DeflateParam_t *)CompressMalloc(sizeof(DeflateParam_t), &Status);
  79. if (Status != COMPRESS_OK)
  80. {
  81. CompressFree(Bits);
  82. return Status;
  83. }
  84. Deflt = (LocalDef_t *)CompressMalloc(sizeof(LocalDef_t), &Status);
  85. if (Status != COMPRESS_OK)
  86. {
  87. CompressFree(Bits);
  88. CompressFree(Defl);
  89. return Status;
  90. }
  91. if ((Status = InitLongestMatch(CompLevel, &DeflateFlags,
  92. Defl, Deflt, Comp)) != COMPRESS_OK)
  93. {
  94. CompressFree(Bits);
  95. CompressFree(Defl);
  96. CompressFree(Deflt);
  97. return Status;
  98. }
  99. PutByte((unsigned char)DeflateFlags, Comp); /* extra flags */
  100. PutByte(OS_CODE, Comp); /* OS identifier */
  101. (void)Deflate(CompLevel, Bits, Defl, Deflt, Comp);
  102. CompressFree(Bits);
  103. CompressFree(Defl);
  104. CompressFree(Deflt);
  105. PutLong((unsigned __int32)(*Comp->pCRC), Comp);
  106. PutLong(Comp->BytesIn, Comp);
  107. Comp->HeaderBytes += 2*sizeof(unsigned long);
  108. Status = FlushOutputBuffer(Comp);
  109. if (COMPRESS_OK != Status)
  110. return Status;
  111. }
  112. /* Write the crc and uncompressed size */
  113. return Status;
  114. }
  115. /* ===========================================================================
  116. * Read new data from the current input buffer and
  117. * update the crc and input data size.
  118. * IN assertion: size >= 2 (for end-of-line translation)
  119. */
  120. int
  121. ReadBuffer(
  122. char *Input,
  123. unsigned int Size,
  124. CompParam_t *Comp
  125. )
  126. {
  127. unsigned long Length;
  128. Assert(Comp->InputSize == 0, "input buffer not empty");
  129. /* Read as much as possible */
  130. Length = MIN(Comp->GlobalSize - Comp->BytesIn, (unsigned long)Size);
  131. if (Length == 0)
  132. return (int)Length;
  133. memcpy((char *)Input, (char *)Comp->GlobalInput + Comp->BytesIn,
  134. (int)Length);
  135. Comp->pCRC->Compute((unsigned char *)Input, (unsigned int)Length);
  136. Comp->BytesIn += Length;
  137. return (int)Length;
  138. }
  139. /* ===========================================================================
  140. * Read a new buffer from the current input.
  141. */
  142. int
  143. FillBuffer(
  144. unsigned char *Input,
  145. unsigned int Size,
  146. CompParam_t *Comp
  147. )
  148. {
  149. /* Point to the input buffer */
  150. Comp->Input = Comp->InputBuffer;
  151. Comp->GlobalInput = Input;
  152. Comp->GlobalSize = Size;
  153. Comp->WindowSize = (unsigned long) DWSIZE;
  154. ClearBuffers(Comp); /* clear input and output buffers */
  155. Comp->PtrOutput = NULL;
  156. return (int)Size;
  157. }
  158. /* ===========================================================================
  159. * Copy input to output unchanged
  160. * IN assertion: comp->GlobalSize bytes have already been read in comp->GlobalInput.
  161. */
  162. CompressStatus_t
  163. Copy(
  164. CompParam_t *Comp
  165. )
  166. {
  167. CompressStatus_t Status = COMPRESS_OK;
  168. Comp->pCRC->Compute(Comp->GlobalInput, (unsigned int)Comp->GlobalSize);
  169. PutLong((unsigned __int32)(*Comp->pCRC), Comp);
  170. PutLong(Comp->GlobalSize, Comp);
  171. Status = FlushOutputBuffer(Comp);
  172. if (COMPRESS_OK != Status)
  173. return Status;
  174. Status = WriteBuffer(Comp, Comp->GlobalInput,
  175. (unsigned int)Comp->GlobalSize);
  176. if (COMPRESS_OK != Status)
  177. return Status;
  178. Comp->BytesOut += Comp->GlobalSize;
  179. return Status;
  180. }