VirtualBox

source: vbox/trunk/src/libs/liblzma-5.8.1/common/microlzma_encoder.c@ 108911

Last change on this file since 108911 was 108911, checked in by vboxsync, 4 weeks ago

libs/liblzma: Applied and adjusted our liblzma changes to 5.8.1 and export to OSE. jiraref:VBP-1635

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property sync-process set to export
File size: 3.7 KB
Line 
1// SPDX-License-Identifier: 0BSD
2
3///////////////////////////////////////////////////////////////////////////////
4//
5/// \file microlzma_encoder.c
6/// \brief Encode into MicroLZMA format
7//
8// Author: Lasse Collin
9//
10///////////////////////////////////////////////////////////////////////////////
11
12#include "lzma_encoder.h"
13
14
15typedef struct {
16 /// LZMA1 encoder
17 lzma_next_coder lzma;
18
19 /// LZMA properties byte (lc/lp/pb)
20 uint8_t props;
21} lzma_microlzma_coder;
22
23
24static lzma_ret
25microlzma_encode(void *coder_ptr, const lzma_allocator *allocator,
26 const uint8_t *restrict in, size_t *restrict in_pos,
27 size_t in_size, uint8_t *restrict out,
28 size_t *restrict out_pos, size_t out_size, lzma_action action)
29{
30 lzma_microlzma_coder *coder = coder_ptr;
31
32 // Remember *out_pos so that we can overwrite the first byte with
33 // the LZMA properties byte.
34 const size_t out_start = *out_pos;
35
36 // Remember *in_pos so that we can set it based on how many
37 // uncompressed bytes were actually encoded.
38 const size_t in_start = *in_pos;
39
40 // Set the output size limit based on the available output space.
41 // We know that the encoder supports set_out_limit() so
42 // LZMA_OPTIONS_ERROR isn't possible. LZMA_BUF_ERROR is possible
43 // but lzma_code() has an assertion to not allow it to be returned
44 // from here and I don't want to change that for now, so
45 // LZMA_BUF_ERROR becomes LZMA_PROG_ERROR.
46 uint64_t uncomp_size;
47 if (coder->lzma.set_out_limit(coder->lzma.coder,
48 &uncomp_size, out_size - *out_pos) != LZMA_OK)
49 return LZMA_PROG_ERROR;
50
51 // set_out_limit fails if this isn't true.
52 assert(out_size - *out_pos >= 6);
53
54 // Encode as much as possible.
55 const lzma_ret ret = coder->lzma.code(coder->lzma.coder, allocator,
56 in, in_pos, in_size, out, out_pos, out_size, action);
57
58 if (ret != LZMA_STREAM_END) {
59 if (ret == LZMA_OK) {
60 assert(0);
61 return LZMA_PROG_ERROR;
62 }
63
64 return ret;
65 }
66
67 // The first output byte is bitwise-negation of the properties byte.
68 // We know that there is space for this byte because set_out_limit
69 // and the actual encoding succeeded.
70 out[out_start] = (uint8_t)(~coder->props);
71
72 // The LZMA encoder likely read more input than it was able to encode.
73 // Set *in_pos based on uncomp_size.
74 assert(uncomp_size <= in_size - in_start);
75 *in_pos = in_start + (size_t)(uncomp_size);
76
77 return ret;
78}
79
80
81static void
82microlzma_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
83{
84 lzma_microlzma_coder *coder = coder_ptr;
85 lzma_next_end(&coder->lzma, allocator);
86 lzma_free(coder, allocator);
87 return;
88}
89
90
91static lzma_ret
92microlzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
93 const lzma_options_lzma *options)
94{
95 lzma_next_coder_init(&microlzma_encoder_init, next, allocator);
96
97 lzma_microlzma_coder *coder = next->coder;
98
99 if (coder == NULL) {
100 coder = lzma_alloc(sizeof(lzma_microlzma_coder), allocator);
101 if (coder == NULL)
102 return LZMA_MEM_ERROR;
103
104 next->coder = coder;
105 next->code = &microlzma_encode;
106 next->end = &microlzma_encoder_end;
107
108 coder->lzma = LZMA_NEXT_CODER_INIT;
109 }
110
111 // Encode the properties byte. Bitwise-negation of it will be the
112 // first output byte.
113 if (lzma_lzma_lclppb_encode(options, &coder->props))
114 return LZMA_OPTIONS_ERROR;
115
116 // Initialize the LZMA encoder.
117 const lzma_filter_info filters[2] = {
118 {
119 .id = LZMA_FILTER_LZMA1,
120 .init = &lzma_lzma_encoder_init,
121 .options = (void *)(options),
122 }, {
123 .init = NULL,
124 }
125 };
126
127 return lzma_next_filter_init(&coder->lzma, allocator, filters);
128}
129
130
131extern LZMA_API(lzma_ret)
132lzma_microlzma_encoder(lzma_stream *strm, const lzma_options_lzma *options)
133{
134 lzma_next_strm_init(microlzma_encoder_init, strm, options);
135
136 strm->internal->supported_actions[LZMA_FINISH] = true;
137
138 return LZMA_OK;
139
140}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette