deflate_stored.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /* deflate_stored.c -- store data without compression using deflation algorithm
  2. *
  3. * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
  4. * For conditions of distribution and use, see copyright notice in zlib.h
  5. */
  6. #include "zbuild.h"
  7. #include "deflate.h"
  8. #include "deflate_p.h"
  9. #include "functable.h"
  10. /* ===========================================================================
  11. * Copy without compression as much as possible from the input stream, return
  12. * the current block state.
  13. *
  14. * In case deflateParams() is used to later switch to a non-zero compression
  15. * level, s->matches (otherwise unused when storing) keeps track of the number
  16. * of hash table slides to perform. If s->matches is 1, then one hash table
  17. * slide will be done when switching. If s->matches is 2, the maximum value
  18. * allowed here, then the hash table will be cleared, since two or more slides
  19. * is the same as a clear.
  20. *
  21. * deflate_stored() is written to minimize the number of times an input byte is
  22. * copied. It is most efficient with large input and output buffers, which
  23. * maximizes the opportunities to have a single copy from next_in to next_out.
  24. */
  25. Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush) {
  26. /* Smallest worthy block size when not flushing or finishing. By default
  27. * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
  28. * large input and output buffers, the stored block size will be larger.
  29. */
  30. unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
  31. /* Copy as many min_block or larger stored blocks directly to next_out as
  32. * possible. If flushing, copy the remaining available input to next_out as
  33. * stored blocks, if there is enough space.
  34. */
  35. unsigned len, left, have, last = 0;
  36. unsigned used = s->strm->avail_in;
  37. do {
  38. /* Set len to the maximum size block that we can copy directly with the
  39. * available input data and output space. Set left to how much of that
  40. * would be copied from what's left in the window.
  41. */
  42. len = MAX_STORED; /* maximum deflate stored block length */
  43. have = (s->bi_valid + 42) >> 3; /* number of header bytes */
  44. if (s->strm->avail_out < have) /* need room for header */
  45. break;
  46. /* maximum stored block length that will fit in avail_out: */
  47. have = s->strm->avail_out - have;
  48. left = (int)s->strstart - s->block_start; /* bytes left in window */
  49. if (len > (unsigned long)left + s->strm->avail_in)
  50. len = left + s->strm->avail_in; /* limit len to the input */
  51. len = MIN(len, have); /* limit len to the output */
  52. /* If the stored block would be less than min_block in length, or if
  53. * unable to copy all of the available input when flushing, then try
  54. * copying to the window and the pending buffer instead. Also don't
  55. * write an empty block when flushing -- deflate() does that.
  56. */
  57. if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || len != left + s->strm->avail_in))
  58. break;
  59. /* Make a dummy stored block in pending to get the header bytes,
  60. * including any pending bits. This also updates the debugging counts.
  61. */
  62. last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
  63. zng_tr_stored_block(s, (char *)0, 0L, last);
  64. /* Replace the lengths in the dummy stored block with len. */
  65. s->pending -= 4;
  66. put_short(s, (uint16_t)len);
  67. put_short(s, (uint16_t)~len);
  68. /* Write the stored block header bytes. */
  69. PREFIX(flush_pending)(s->strm);
  70. /* Update debugging counts for the data about to be copied. */
  71. cmpr_bits_add(s, len << 3);
  72. sent_bits_add(s, len << 3);
  73. /* Copy uncompressed bytes from the window to next_out. */
  74. if (left) {
  75. left = MIN(left, len);
  76. memcpy(s->strm->next_out, s->window + s->block_start, left);
  77. s->strm->next_out += left;
  78. s->strm->avail_out -= left;
  79. s->strm->total_out += left;
  80. s->block_start += (int)left;
  81. len -= left;
  82. }
  83. /* Copy uncompressed bytes directly from next_in to next_out, updating
  84. * the check value.
  85. */
  86. if (len) {
  87. PREFIX(read_buf)(s->strm, s->strm->next_out, len);
  88. s->strm->next_out += len;
  89. s->strm->avail_out -= len;
  90. s->strm->total_out += len;
  91. }
  92. } while (last == 0);
  93. /* Update the sliding window with the last s->w_size bytes of the copied
  94. * data, or append all of the copied data to the existing window if less
  95. * than s->w_size bytes were copied. Also update the number of bytes to
  96. * insert in the hash tables, in the event that deflateParams() switches to
  97. * a non-zero compression level.
  98. */
  99. used -= s->strm->avail_in; /* number of input bytes directly copied */
  100. if (used) {
  101. /* If any input was used, then no unused input remains in the window,
  102. * therefore s->block_start == s->strstart.
  103. */
  104. if (used >= s->w_size) { /* supplant the previous history */
  105. s->matches = 2; /* clear hash */
  106. memcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
  107. s->strstart = s->w_size;
  108. s->insert = s->strstart;
  109. } else {
  110. if (s->window_size - s->strstart <= used) {
  111. /* Slide the window down. */
  112. s->strstart -= s->w_size;
  113. memcpy(s->window, s->window + s->w_size, s->strstart);
  114. if (s->matches < 2)
  115. s->matches++; /* add a pending slide_hash() */
  116. s->insert = MIN(s->insert, s->strstart);
  117. }
  118. memcpy(s->window + s->strstart, s->strm->next_in - used, used);
  119. s->strstart += used;
  120. s->insert += MIN(used, s->w_size - s->insert);
  121. }
  122. s->block_start = (int)s->strstart;
  123. }
  124. s->high_water = MAX(s->high_water, s->strstart);
  125. /* If the last block was written to next_out, then done. */
  126. if (last)
  127. return finish_done;
  128. /* If flushing and all input has been consumed, then done. */
  129. if (flush != Z_NO_FLUSH && flush != Z_FINISH && s->strm->avail_in == 0 && (int)s->strstart == s->block_start)
  130. return block_done;
  131. /* Fill the window with any remaining input. */
  132. have = s->window_size - s->strstart;
  133. if (s->strm->avail_in > have && s->block_start >= (int)s->w_size) {
  134. /* Slide the window down. */
  135. s->block_start -= (int)s->w_size;
  136. s->strstart -= s->w_size;
  137. memcpy(s->window, s->window + s->w_size, s->strstart);
  138. if (s->matches < 2)
  139. s->matches++; /* add a pending slide_hash() */
  140. have += s->w_size; /* more space now */
  141. s->insert = MIN(s->insert, s->strstart);
  142. }
  143. have = MIN(have, s->strm->avail_in);
  144. if (have) {
  145. PREFIX(read_buf)(s->strm, s->window + s->strstart, have);
  146. s->strstart += have;
  147. s->insert += MIN(have, s->w_size - s->insert);
  148. }
  149. s->high_water = MAX(s->high_water, s->strstart);
  150. /* There was not enough avail_out to write a complete worthy or flushed
  151. * stored block to next_out. Write a stored block to pending instead, if we
  152. * have enough input for a worthy block, or if flushing and there is enough
  153. * room for the remaining input as a stored block in the pending buffer.
  154. */
  155. have = (s->bi_valid + 42) >> 3; /* number of header bytes */
  156. /* maximum stored block length that will fit in pending: */
  157. have = MIN(s->pending_buf_size - have, MAX_STORED);
  158. min_block = MIN(have, s->w_size);
  159. left = (int)s->strstart - s->block_start;
  160. if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) {
  161. len = MIN(left, have);
  162. last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0;
  163. zng_tr_stored_block(s, (char *)s->window + s->block_start, len, last);
  164. s->block_start += (int)len;
  165. PREFIX(flush_pending)(s->strm);
  166. }
  167. /* We've done all we can with the available input and output. */
  168. return last ? finish_started : need_more;
  169. }