]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/subblock/subblock_encoder.c
Imported to git.
[icculus/xz.git] / src / liblzma / subblock / subblock_encoder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       subblock_encoder.c
4 /// \brief      Encoder of the Subblock filter
5 //
6 //  Copyright (C) 2007 Lasse Collin
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2.1 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 ///////////////////////////////////////////////////////////////////////////////
19
20 #include "subblock_encoder.h"
21 #include "raw_encoder.h"
22
23
24 #define REPEAT_COUNT_MAX (1U << 28)
25
26 /// Number of bytes the data chunk being repeated must be before we care
27 /// about alignment. This is somewhat arbitrary. It just doesn't make sense
28 /// to waste bytes for alignment when the data chunk is very small.
29 ///
30 /// TODO Rename and use this also for Subblock Data?
31 #define RLE_MIN_SIZE_FOR_ALIGN 3
32
33 #define write_byte(b) \
34 do { \
35         out[*out_pos] = b; \
36         ++*out_pos; \
37         ++coder->alignment.out_pos; \
38 } while (0)
39
40
41 struct lzma_coder_s {
42         lzma_next_coder next;
43         bool next_finished;
44
45         enum {
46                 SEQ_FILL,
47                 SEQ_FLUSH,
48                 SEQ_RLE_COUNT_0,
49                 SEQ_RLE_COUNT_1,
50                 SEQ_RLE_COUNT_2,
51                 SEQ_RLE_COUNT_3,
52                 SEQ_RLE_SIZE,
53                 SEQ_RLE_DATA,
54                 SEQ_DATA_SIZE_0,
55                 SEQ_DATA_SIZE_1,
56                 SEQ_DATA_SIZE_2,
57                 SEQ_DATA_SIZE_3,
58                 SEQ_DATA,
59                 SEQ_SUBFILTER_INIT,
60                 SEQ_SUBFILTER_FLAGS,
61         } sequence;
62
63         lzma_options_subblock *options;
64
65         lzma_vli uncompressed_size;
66
67         size_t pos;
68         uint32_t tmp;
69
70         struct {
71                 uint32_t multiple;
72                 uint32_t in_pending;
73                 uint32_t in_pos;
74                 uint32_t out_pos;
75         } alignment;
76
77         struct {
78                 uint8_t *data;
79                 size_t size;
80                 size_t limit;
81         } subblock;
82
83         struct {
84                 uint8_t buffer[LZMA_SUBBLOCK_RLE_MAX];
85                 size_t size;
86                 lzma_vli count;
87         } rle;
88
89         struct {
90                 enum {
91                         SUB_NONE,
92                         SUB_SET,
93                         SUB_RUN,
94                         SUB_FINISH,
95                         SUB_END_MARKER,
96                 } mode;
97
98                 bool got_input;
99
100                 uint8_t *flags;
101                 size_t flags_size;
102
103                 lzma_next_coder subcoder;
104
105         } subfilter;
106
107         struct {
108                 size_t pos;
109                 size_t size;
110                 uint8_t buffer[LZMA_BUFFER_SIZE];
111         } temp;
112 };
113
114
115 /// \brief      Aligns the output buffer
116 ///
117 /// Aligns the output buffer so that after skew bytes the output position is
118 /// a multiple of coder->alignment.multiple.
119 static bool
120 subblock_align(lzma_coder *coder, uint8_t *restrict out,
121                 size_t *restrict out_pos, size_t out_size, uint32_t skew)
122 {
123         assert(*out_pos < out_size);
124
125         const uint32_t target = coder->alignment.in_pos
126                         % coder->alignment.multiple;
127
128         while ((coder->alignment.out_pos + skew)
129                         % coder->alignment.multiple != target) {
130                 // Zero indicates padding.
131                 write_byte(0x00);
132
133                 // Check if output buffer got full and indicate it to
134                 // the caller.
135                 if (*out_pos == out_size)
136                         return true;
137         }
138
139         coder->alignment.in_pos += coder->alignment.in_pending;
140         coder->alignment.in_pending = 0;
141
142         // Output buffer is not full.
143         return false;
144 }
145
146
147 /// \brief      Checks if buffer contains repeated data
148 ///
149 /// \param      needle      Buffer containing a single repeat chunk
150 /// \param      needle_size Size of needle in bytes
151 /// \param      buf         Buffer to search for repeated needles
152 /// \param      buf_chunks  Buffer size is buf_chunks * needle_size.
153 ///
154 /// \return     True if the whole buf is filled with repeated needles.
155 ///
156 static bool
157 is_repeating(const uint8_t *restrict needle, size_t needle_size,
158                 const uint8_t *restrict buf, size_t buf_chunks)
159 {
160         while (buf_chunks-- != 0) {
161                 if (memcmp(buf, needle, needle_size) != 0)
162                         return false;
163
164                 buf += needle_size;
165         }
166
167         return true;
168 }
169
170
171 /// \brief      Optimizes the repeating style and updates coder->sequence
172 static void
173 subblock_rle_flush(lzma_coder *coder)
174 {
175         // The Subblock decoder can use memset() when the size of the data
176         // being repeated is one byte, so we check if the RLE buffer is
177         // filled with a single repeating byte.
178         if (coder->rle.size > 1) {
179                 const uint8_t b = coder->rle.buffer[0];
180                 size_t i = 0;
181                 while (true) {
182                         if (coder->rle.buffer[i] != b)
183                                 break;
184
185                         if (++i == coder->rle.size) {
186                                 // TODO Integer overflow check maybe,
187                                 // although this needs at least 2**63 bytes
188                                 // of input until it gets triggered...
189                                 coder->rle.count *= coder->rle.size;
190                                 coder->rle.size = 1;
191                                 break;
192                         }
193                 }
194         }
195
196         if (coder->rle.count > REPEAT_COUNT_MAX)
197                 coder->tmp = REPEAT_COUNT_MAX - 1;
198         else
199                 coder->tmp = coder->rle.count - 1;
200
201         coder->sequence = SEQ_RLE_COUNT_0;
202
203         return;
204 }
205
206
207 /// \brief      Resizes coder->subblock.data for a new size limit
208 static lzma_ret
209 subblock_data_size(lzma_coder *coder, lzma_allocator *allocator,
210                 size_t new_limit)
211 {
212         // Verify that the new limit is valid.
213         if (new_limit < LZMA_SUBBLOCK_DATA_SIZE_MIN
214                         || new_limit > LZMA_SUBBLOCK_DATA_SIZE_MAX)
215                 return LZMA_HEADER_ERROR;
216
217         // Ff the new limit is different than the previous one, we need
218         // to reallocate the data buffer.
219         if (new_limit != coder->subblock.limit) {
220                 lzma_free(coder->subblock.data, allocator);
221                 coder->subblock.data = lzma_alloc(new_limit, allocator);
222                 if (coder->subblock.data == NULL)
223                         return LZMA_MEM_ERROR;
224         }
225
226         coder->subblock.limit = new_limit;
227
228         return LZMA_OK;
229 }
230
231
232 static lzma_ret
233 subblock_buffer(lzma_coder *coder, lzma_allocator *allocator,
234                 const uint8_t *restrict in, size_t *restrict in_pos,
235                 size_t in_size, uint8_t *restrict out,
236                 size_t *restrict out_pos, size_t out_size, lzma_action action)
237 {
238         // Verify that there is a sane amount of input.
239         if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
240                 const lzma_vli in_avail = in_size - *in_pos;
241                 if (action == LZMA_FINISH) {
242                         if (in_avail != coder->uncompressed_size)
243                                 return LZMA_DATA_ERROR;
244                 } else {
245                         if (in_avail > coder->uncompressed_size)
246                                 return LZMA_DATA_ERROR;
247                 }
248         }
249
250         // Check if we need to do something special with the Subfilter.
251         if (coder->options != NULL && coder->options->allow_subfilters) {
252                 switch (coder->options->subfilter_mode) {
253                 case LZMA_SUBFILTER_NONE:
254                         if (coder->subfilter.mode != SUB_NONE)
255                                 return LZMA_PROG_ERROR;
256                         break;
257
258                 case LZMA_SUBFILTER_SET:
259                         if (coder->subfilter.mode != SUB_NONE)
260                                 return LZMA_HEADER_ERROR;
261
262                         coder->subfilter.mode = SUB_SET;
263                         coder->subfilter.got_input = false;
264
265                         if (coder->sequence == SEQ_FILL)
266                                 coder->sequence = SEQ_FLUSH;
267
268                         break;
269
270                 case LZMA_SUBFILTER_RUN:
271                         if (coder->subfilter.mode != SUB_RUN)
272                                 return LZMA_PROG_ERROR;
273                         break;
274
275                 case LZMA_SUBFILTER_FINISH:
276                         if (coder->subfilter.mode == SUB_RUN)
277                                 coder->subfilter.mode = SUB_FINISH;
278                         else if (coder->subfilter.mode != SUB_FINISH)
279                                 return LZMA_PROG_ERROR;
280
281                         if (!coder->subfilter.got_input)
282                                 return LZMA_PROG_ERROR;
283
284                         break;
285
286                 default:
287                         return LZMA_HEADER_ERROR;
288                 }
289         }
290
291         // Main loop
292         while (*out_pos < out_size)
293         switch (coder->sequence) {
294         case SEQ_FILL: {
295                 // Grab the new Subblock Data Size and reallocate the buffer.
296                 if (coder->subblock.size == 0 && coder->options != NULL
297                                 && coder->options->subblock_data_size
298                                         != coder->subblock.limit) {
299                         const lzma_ret ret = subblock_data_size(coder,
300                                         allocator, coder->options
301                                                 ->subblock_data_size);
302                         if (ret != LZMA_OK)
303                                 return ret;
304                 }
305
306                 if (coder->subfilter.mode == SUB_NONE) {
307                         assert(coder->subfilter.subcoder.code == NULL);
308
309                         // No Subfilter is enabled, just copy the data as is.
310                         // NOTE: uncompressed_size cannot overflow because we
311                         // have checked/ it in the beginning of this function.
312                         const size_t in_used = bufcpy(in, in_pos, in_size,
313                                         coder->subblock.data,
314                                         &coder->subblock.size,
315                                         coder->subblock.limit);
316
317                         if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
318                                 coder->uncompressed_size -= in_used;
319
320                         coder->alignment.in_pending += in_used;
321
322                 } else {
323                         const size_t in_start = *in_pos;
324                         lzma_ret ret;
325
326                         if (coder->subfilter.mode == SUB_FINISH) {
327                                 // Let the Subfilter write out pending data,
328                                 // but don't give it any new input anymore.
329                                 size_t dummy = 0;
330                                 ret = coder->subfilter.subcoder.code(coder
331                                                 ->subfilter.subcoder.coder,
332                                                 allocator, NULL, &dummy, 0,
333                                                 coder->subblock.data,
334                                                 &coder->subblock.size,
335                                                 coder->subblock.limit,
336                                                 LZMA_FINISH);
337                         } else {
338                                 // Give our input data to the Subfilter. Note
339                                 // that action can be LZMA_FINISH. In that
340                                 // case, we filter everything until the end
341                                 // of the input. The application isn't required
342                                 // to separately set LZMA_SUBBLOCK_FINISH.
343                                 ret = coder->subfilter.subcoder.code(coder
344                                                 ->subfilter.subcoder.coder,
345                                                 allocator, in, in_pos, in_size,
346                                                 coder->subblock.data,
347                                                 &coder->subblock.size,
348                                                 coder->subblock.limit,
349                                                 action);
350                         }
351
352                         const size_t in_used = *in_pos - in_start;
353
354                         if (in_used > 0)
355                                 coder->subfilter.got_input = true;
356
357                         // NOTE: uncompressed_size cannot overflow because we
358                         // have checked it in the beginning of this function.
359                         if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
360                                 coder->uncompressed_size -= *in_pos - in_start;
361
362                         coder->alignment.in_pending += in_used;
363
364                         if (ret == LZMA_STREAM_END) {
365                                 // We don't strictly need to do this, but
366                                 // doing it sounds like a good idea, because
367                                 // otherwise the Subfilter's memory could be
368                                 // left allocated for long time, and would
369                                 // just waste memory.
370                                 lzma_next_coder_end(&coder->subfilter.subcoder,
371                                                 allocator);
372
373                                 assert(coder->options != NULL);
374                                 coder->options->subfilter_mode
375                                                 = LZMA_SUBFILTER_NONE;
376
377                                 assert(coder->subfilter.mode == SUB_FINISH
378                                                 || action == LZMA_FINISH);
379                                 coder->subfilter.mode = SUB_END_MARKER;
380
381                                 // Flush now. Even if coder->subblock.size
382                                 // happens to be zero, we still need to go
383                                 // to SEQ_FLUSH to write the Subfilter Unset
384                                 // indicator.
385                                 coder->sequence = SEQ_FLUSH;
386                                 break;
387                         }
388
389                         // Return if an error occurred.
390                         if (ret != LZMA_OK)
391                                 return ret;
392                 }
393
394                 // If we ran out of input before the whole buffer
395                 // was filled, return to application.
396                 if (coder->subblock.size < coder->subblock.limit
397                                 && action != LZMA_FINISH)
398                         return LZMA_OK;
399
400                 coder->sequence = SEQ_FLUSH;
401         }
402
403         // Fall through
404
405         case SEQ_FLUSH:
406                 if (coder->options != NULL) {
407                         // Update the alignment variable.
408                         coder->alignment.multiple = coder->options->alignment;
409                         if (coder->alignment.multiple
410                                         < LZMA_SUBBLOCK_ALIGNMENT_MIN
411                                         || coder->alignment.multiple
412                                         > LZMA_SUBBLOCK_ALIGNMENT_MAX)
413                                 return LZMA_HEADER_ERROR;
414
415                         // Run-length encoder
416                         //
417                         // First check if there is some data pending and we
418                         // have an obvious need to flush it immediatelly.
419                         if (coder->rle.count > 0
420                                         && (coder->rle.size
421                                                         != coder->options->rle
422                                                 || coder->subblock.size
423                                                         % coder->rle.size)) {
424                                 subblock_rle_flush(coder);
425                                 break;
426                         }
427
428                         // Grab the (possibly new) RLE chunk size and
429                         // validate it.
430                         coder->rle.size = coder->options->rle;
431                         if (coder->rle.size > LZMA_SUBBLOCK_RLE_MAX)
432                                 return LZMA_HEADER_ERROR;
433
434                         if (coder->subblock.size != 0
435                                         && coder->rle.size
436                                                 != LZMA_SUBBLOCK_RLE_OFF
437                                         && coder->subblock.size
438                                                 % coder->rle.size == 0) {
439
440                                 // Initialize coder->rle.buffer if we don't
441                                 // have RLE already running.
442                                 if (coder->rle.count == 0)
443                                         memcpy(coder->rle.buffer,
444                                                         coder->subblock.data,
445                                                         coder->rle.size);
446
447                                 // Test if coder->subblock.data is repeating.
448                                 const size_t count = coder->subblock.size
449                                                 / coder->rle.size;
450                                 if (is_repeating(coder->rle.buffer,
451                                                 coder->rle.size,
452                                                 coder->subblock.data, count)) {
453                                         if (LZMA_VLI_VALUE_MAX - count
454                                                         < coder->rle.count)
455                                                 return LZMA_PROG_ERROR;
456
457                                         coder->rle.count += count;
458                                         coder->subblock.size = 0;
459
460                                 } else if (coder->rle.count > 0) {
461                                         // It's not repeating or at least not
462                                         // with the same byte sequence as the
463                                         // earlier Subblock Data buffers. We
464                                         // have some data pending in the RLE
465                                         // buffer already, so do a flush.
466                                         // Once flushed, we will check again
467                                         // if the Subblock Data happens to
468                                         // contain a different repeating
469                                         // sequence.
470                                         subblock_rle_flush(coder);
471                                         break;
472                                 }
473                         }
474                 }
475
476                 // If we now have some data left in coder->subblock, the RLE
477                 // buffer is empty and we must write a regular Subblock Data.
478                 if (coder->subblock.size > 0) {
479                         assert(coder->rle.count == 0);
480                         coder->tmp = coder->subblock.size - 1;
481                         coder->sequence = SEQ_DATA_SIZE_0;
482                         break;
483                 }
484
485                 // Check if we should enable Subfilter.
486                 if (coder->subfilter.mode == SUB_SET) {
487                         if (coder->rle.count > 0)
488                                 subblock_rle_flush(coder);
489                         else
490                                 coder->sequence = SEQ_SUBFILTER_INIT;
491                         break;
492                 }
493
494                 // Check if we have just finished Subfiltering.
495                 if (coder->subfilter.mode == SUB_END_MARKER) {
496                         if (coder->rle.count > 0) {
497                                 subblock_rle_flush(coder);
498                                 break;
499                         }
500
501                         write_byte(0x50);
502                         coder->subfilter.mode = SUB_NONE;
503                         if (*out_pos == out_size)
504                                 return LZMA_OK;
505                 }
506
507                 // Check if we have already written everything.
508                 if (action == LZMA_FINISH && *in_pos == in_size
509                                 && coder->subfilter.mode == SUB_NONE) {
510                         if (coder->rle.count > 0) {
511                                 subblock_rle_flush(coder);
512                                 break;
513                         }
514
515                         if (coder->uncompressed_size
516                                         == LZMA_VLI_VALUE_UNKNOWN) {
517                                 // NOTE: No need to use write_byte() here
518                                 // since we are finishing.
519                                 out[*out_pos] = 0x10;
520                                 ++*out_pos;
521                         } else if (coder->uncompressed_size != 0) {
522                                 return LZMA_DATA_ERROR;
523                         }
524
525                         return LZMA_STREAM_END;
526                 }
527
528                 // Otherwise we have more work to do.
529                 coder->sequence = SEQ_FILL;
530                 break;
531
532         case SEQ_RLE_COUNT_0:
533                 // Make the Data field properly aligned, but only if the data
534                 // chunk to be repeated isn't extremely small. We have four
535                 // bytes for Count and one byte for Size, thus the number five.
536                 if (coder->rle.size >= RLE_MIN_SIZE_FOR_ALIGN
537                                 && subblock_align(
538                                         coder, out, out_pos, out_size, 5))
539                         return LZMA_OK;
540
541                 assert(coder->rle.count > 0);
542
543                 write_byte(0x30 | (coder->tmp & 0x0F));
544
545                 coder->sequence = SEQ_RLE_COUNT_1;
546                 break;
547
548         case SEQ_RLE_COUNT_1:
549                 write_byte(coder->tmp >> 4);
550                 coder->sequence = SEQ_RLE_COUNT_2;
551                 break;
552
553         case SEQ_RLE_COUNT_2:
554                 write_byte(coder->tmp >> 12);
555                 coder->sequence = SEQ_RLE_COUNT_3;
556                 break;
557
558         case SEQ_RLE_COUNT_3:
559                 write_byte(coder->tmp >> 20);
560
561                 if (coder->rle.count > REPEAT_COUNT_MAX)
562                         coder->rle.count -= REPEAT_COUNT_MAX;
563                 else
564                         coder->rle.count = 0;
565
566                 coder->sequence = SEQ_RLE_SIZE;
567                 break;
568
569         case SEQ_RLE_SIZE:
570                 assert(coder->rle.size >= LZMA_SUBBLOCK_RLE_MIN);
571                 assert(coder->rle.size <= LZMA_SUBBLOCK_RLE_MAX);
572                 write_byte(coder->rle.size - 1);
573                 coder->sequence = SEQ_RLE_DATA;
574                 break;
575
576         case SEQ_RLE_DATA:
577                 bufcpy(coder->rle.buffer, &coder->pos, coder->rle.size,
578                                 out, out_pos, out_size);
579                 if (coder->pos < coder->rle.size)
580                         return LZMA_OK;
581
582                 coder->alignment.out_pos += coder->rle.size;
583
584                 coder->pos = 0;
585                 coder->sequence = SEQ_FLUSH;
586                 break;
587
588         case SEQ_DATA_SIZE_0:
589                 // We need four bytes for the Size field.
590                 if (subblock_align(coder, out, out_pos, out_size, 4))
591                         return LZMA_OK;
592
593                 write_byte(0x20 | (coder->tmp & 0x0F));
594                 coder->sequence = SEQ_DATA_SIZE_1;
595                 break;
596
597         case SEQ_DATA_SIZE_1:
598                 write_byte(coder->tmp >> 4);
599                 coder->sequence = SEQ_DATA_SIZE_2;
600                 break;
601
602         case SEQ_DATA_SIZE_2:
603                 write_byte(coder->tmp >> 12);
604                 coder->sequence = SEQ_DATA_SIZE_3;
605                 break;
606
607         case SEQ_DATA_SIZE_3:
608                 write_byte(coder->tmp >> 20);
609                 coder->sequence = SEQ_DATA;
610                 break;
611
612         case SEQ_DATA:
613                 bufcpy(coder->subblock.data, &coder->pos,
614                                 coder->subblock.size, out, out_pos, out_size);
615                 if (coder->pos < coder->subblock.size)
616                         return LZMA_OK;
617
618                 coder->alignment.out_pos += coder->subblock.size;
619
620                 coder->subblock.size = 0;
621                 coder->pos = 0;
622                 coder->sequence = SEQ_FLUSH;
623                 break;
624
625         case SEQ_SUBFILTER_INIT: {
626                 assert(coder->subblock.size == 0);
627                 assert(coder->rle.count == 0);
628                 assert(coder->subfilter.mode == SUB_SET);
629                 assert(coder->options != NULL);
630
631                 // There must be a filter specified.
632                 if (coder->options->subfilter_options.id
633                                 == LZMA_VLI_VALUE_UNKNOWN)
634                         return LZMA_HEADER_ERROR;
635
636                 // Initialize a raw encoder to work as a Subfilter.
637                 lzma_options_filter options[2];
638                 options[0] = coder->options->subfilter_options;
639                 options[1].id = LZMA_VLI_VALUE_UNKNOWN;
640
641                 lzma_ret ret = lzma_raw_encoder_init(
642                                 &coder->subfilter.subcoder, allocator,
643                                 options, LZMA_VLI_VALUE_UNKNOWN, false);
644                 if (ret != LZMA_OK)
645                         return ret;
646
647                 // Encode the Filter Flags field into a buffer. This should
648                 // never fail since we have already successfully initialized
649                 // the Subfilter itself. Check it still, and return
650                 // LZMA_PROG_ERROR instead of whatever the ret would say.
651                 ret = lzma_filter_flags_size(
652                                 &coder->subfilter.flags_size, options);
653                 assert(ret == LZMA_OK);
654                 if (ret != LZMA_OK)
655                         return LZMA_PROG_ERROR;
656
657                 coder->subfilter.flags = lzma_alloc(
658                                 coder->subfilter.flags_size, allocator);
659                 if (coder->subfilter.flags == NULL)
660                         return LZMA_MEM_ERROR;
661
662                 // Now we have a big-enough buffer. Encode the Filter Flags.
663                 // Like above, this should never fail.
664                 size_t dummy = 0;
665                 ret = lzma_filter_flags_encode(coder->subfilter.flags,
666                                 &dummy, coder->subfilter.flags_size, options);
667                 assert(ret == LZMA_OK);
668                 assert(dummy == coder->subfilter.flags_size);
669                 if (ret != LZMA_OK || dummy != coder->subfilter.flags_size)
670                         return LZMA_PROG_ERROR;
671
672                 // Write a Subblock indicating a new Subfilter.
673                 write_byte(0x40);
674
675                 coder->options->subfilter_mode = LZMA_SUBFILTER_RUN;
676                 coder->subfilter.mode = SUB_RUN;
677                 coder->sequence = SEQ_SUBFILTER_FLAGS;
678         }
679
680         // Fall through
681
682         case SEQ_SUBFILTER_FLAGS:
683                 // Copy the Filter Flags to the output stream.
684                 bufcpy(coder->subfilter.flags, &coder->pos,
685                                 coder->subfilter.flags_size,
686                                 out, out_pos, out_size);
687                 if (coder->pos < coder->subfilter.flags_size)
688                         return LZMA_OK;
689
690                 lzma_free(coder->subfilter.flags, allocator);
691                 coder->subfilter.flags = NULL;
692
693                 coder->pos = 0;
694                 coder->sequence = SEQ_FILL;
695                 break;
696
697         default:
698                 return LZMA_PROG_ERROR;
699         }
700
701         return LZMA_OK;
702 }
703
704
705 static lzma_ret
706 subblock_encode(lzma_coder *coder, lzma_allocator *allocator,
707                 const uint8_t *restrict in, size_t *restrict in_pos,
708                 size_t in_size, uint8_t *restrict out,
709                 size_t *restrict out_pos, size_t out_size, lzma_action action)
710 {
711         if (coder->next.code == NULL)
712                 return subblock_buffer(coder, allocator, in, in_pos, in_size,
713                                 out, out_pos, out_size, action);
714
715         while (*out_pos < out_size
716                         && (*in_pos < in_size || action == LZMA_FINISH)) {
717                 if (!coder->next_finished
718                                 && coder->temp.pos == coder->temp.size) {
719                         coder->temp.pos = 0;
720                         coder->temp.size = 0;
721
722                         const lzma_ret ret = coder->next.code(coder->next.coder,
723                                         allocator, in, in_pos, in_size,
724                                         coder->temp.buffer, &coder->temp.size,
725                                         LZMA_BUFFER_SIZE, action);
726                         if (ret == LZMA_STREAM_END) {
727                                 assert(action == LZMA_FINISH);
728                                 coder->next_finished = true;
729                         } else if (coder->temp.size == 0 || ret != LZMA_OK) {
730                                 return ret;
731                         }
732                 }
733
734                 const lzma_ret ret = subblock_buffer(coder, allocator,
735                                 coder->temp.buffer, &coder->temp.pos,
736                                 coder->temp.size, out, out_pos, out_size,
737                                 coder->next_finished ? LZMA_FINISH : LZMA_RUN);
738                 if (ret == LZMA_STREAM_END) {
739                         assert(action == LZMA_FINISH);
740                         assert(coder->next_finished);
741                         return LZMA_STREAM_END;
742                 }
743
744                 if (ret != LZMA_OK)
745                         return ret;
746         }
747
748         return LZMA_OK;
749 }
750
751
752 static void
753 subblock_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
754 {
755         lzma_next_coder_end(&coder->next, allocator);
756         lzma_next_coder_end(&coder->subfilter.subcoder, allocator);
757         lzma_free(coder->subblock.data, allocator);
758         lzma_free(coder->subfilter.flags, allocator);
759         return;
760 }
761
762
763 extern lzma_ret
764 lzma_subblock_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
765                 const lzma_filter_info *filters)
766 {
767         if (next->coder == NULL) {
768                 next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
769                 if (next->coder == NULL)
770                         return LZMA_MEM_ERROR;
771
772                 next->coder->next = LZMA_NEXT_CODER_INIT;
773                 next->coder->subblock.data = NULL;
774                 next->coder->subblock.limit = 0;
775                 next->coder->subfilter.subcoder = LZMA_NEXT_CODER_INIT;
776         } else {
777                 lzma_next_coder_end(&next->coder->subfilter.subcoder,
778                                 allocator);
779                 lzma_free(next->coder->subfilter.flags, allocator);
780         }
781
782         next->coder->subfilter.flags = NULL;
783
784         next->coder->next_finished = false;
785         next->coder->sequence = SEQ_FILL;
786         next->coder->options = filters[0].options;
787         next->coder->uncompressed_size = filters[0].uncompressed_size;
788         next->coder->pos = 0;
789
790         next->coder->alignment.in_pending = 0;
791         next->coder->alignment.in_pos = 0;
792         next->coder->alignment.out_pos = 0;
793         next->coder->subblock.size = 0;
794         next->coder->rle.count = 0;
795         next->coder->subfilter.mode = SUB_NONE;
796
797         next->coder->temp.pos = 0;
798         next->coder->temp.size = 0;
799
800         // Grab some values from the options structure if it is available.
801         size_t subblock_size_limit;
802         if (next->coder->options != NULL) {
803                 if (next->coder->options->alignment
804                                         < LZMA_SUBBLOCK_ALIGNMENT_MIN
805                                 || next->coder->options->alignment
806                                         > LZMA_SUBBLOCK_ALIGNMENT_MAX) {
807                         subblock_encoder_end(next->coder, allocator);
808                         return LZMA_HEADER_ERROR;
809                 }
810                 next->coder->alignment.multiple
811                                 = next->coder->options->alignment;
812                 subblock_size_limit = next->coder->options->subblock_data_size;
813         } else {
814                 next->coder->alignment.multiple
815                                 = LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
816                 subblock_size_limit = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT;
817         }
818
819         {
820                 const lzma_ret ret = subblock_data_size(next->coder, allocator,
821                                 subblock_size_limit);
822                 if (ret != LZMA_OK) {
823                         subblock_encoder_end(next->coder, allocator);
824                         return ret;
825                 }
826         }
827
828         {
829                 const lzma_ret ret = lzma_next_filter_init(&next->coder->next,
830                                 allocator, filters + 1);
831                 if (ret != LZMA_OK) {
832                         subblock_encoder_end(next->coder, allocator);
833                         return ret;
834                 }
835         }
836
837         next->code = &subblock_encode;
838         next->end = &subblock_encoder_end;
839
840         return LZMA_OK;
841 }