1 ///////////////////////////////////////////////////////////////////////////////
3 /// \file alone_decoder.c
4 /// \brief Decoder for LZMA_Alone files
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
14 #include "lzma_encoder.h"
17 #define ALONE_HEADER_SIZE (1 + 4 + 8)
29 uint8_t header
[ALONE_HEADER_SIZE
];
34 alone_encode(lzma_coder
*coder
,
35 const lzma_allocator
*allocator
lzma_attribute((__unused__
)),
36 const uint8_t *restrict in
, size_t *restrict in_pos
,
37 size_t in_size
, uint8_t *restrict out
,
38 size_t *restrict out_pos
, size_t out_size
,
41 while (*out_pos
< out_size
)
42 switch (coder
->sequence
) {
44 lzma_bufcpy(coder
->header
, &coder
->header_pos
,
46 out
, out_pos
, out_size
);
47 if (coder
->header_pos
< ALONE_HEADER_SIZE
)
50 coder
->sequence
= SEQ_CODE
;
54 return coder
->next
.code(coder
->next
.coder
,
55 allocator
, in
, in_pos
, in_size
,
56 out
, out_pos
, out_size
, action
);
60 return LZMA_PROG_ERROR
;
68 alone_encoder_end(lzma_coder
*coder
, const lzma_allocator
*allocator
)
70 lzma_next_end(&coder
->next
, allocator
);
71 lzma_free(coder
, allocator
);
76 // At least for now, this is not used by any internal function.
78 alone_encoder_init(lzma_next_coder
*next
, const lzma_allocator
*allocator
,
79 const lzma_options_lzma
*options
)
81 lzma_next_coder_init(&alone_encoder_init
, next
, allocator
);
83 if (next
->coder
== NULL
) {
84 next
->coder
= lzma_alloc(sizeof(lzma_coder
), allocator
);
85 if (next
->coder
== NULL
)
86 return LZMA_MEM_ERROR
;
88 next
->code
= &alone_encode
;
89 next
->end
= &alone_encoder_end
;
90 next
->coder
->next
= LZMA_NEXT_CODER_INIT
;
93 // Basic initializations
94 next
->coder
->sequence
= SEQ_HEADER
;
95 next
->coder
->header_pos
= 0;
98 // - Properties (1 byte)
99 if (lzma_lzma_lclppb_encode(options
, next
->coder
->header
))
100 return LZMA_OPTIONS_ERROR
;
102 // - Dictionary size (4 bytes)
103 if (options
->dict_size
< LZMA_DICT_SIZE_MIN
)
104 return LZMA_OPTIONS_ERROR
;
106 // Round up to the next 2^n or 2^n + 2^(n - 1) depending on which
107 // one is the next unless it is UINT32_MAX. While the header would
108 // allow any 32-bit integer, we do this to keep the decoder of liblzma
109 // accepting the resulting files.
110 uint32_t d
= options
->dict_size
- 1;
119 unaligned_write32le(next
->coder
->header
+ 1, d
);
121 // - Uncompressed size (always unknown and using EOPM)
122 memset(next
->coder
->header
+ 1 + 4, 0xFF, 8);
124 // Initialize the LZMA encoder.
125 const lzma_filter_info filters
[2] = {
127 .init
= &lzma_lzma_encoder_init
,
128 .options
= (void *)(options
),
134 return lzma_next_filter_init(&next
->coder
->next
, allocator
, filters
);
140 lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
141 const lzma_options_alone *options)
143 lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
148 extern LZMA_API(lzma_ret
)
149 lzma_alone_encoder(lzma_stream
*strm
, const lzma_options_lzma
*options
)
151 lzma_next_strm_init(alone_encoder_init
, strm
, options
);
153 strm
->internal
->supported_actions
[LZMA_RUN
] = true;
154 strm
->internal
->supported_actions
[LZMA_FINISH
] = true;