]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/common/alignment.c
Imported to git.
[icculus/xz.git] / src / liblzma / common / alignment.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       alignment.c
4 /// \brief      Calculates preferred alignments of different filters
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 "common.h"
21
22
23 extern LZMA_API uint32_t
24 lzma_alignment_input(const lzma_options_filter *filters, uint32_t guess)
25 {
26         for (size_t i = 0; filters[i].id != LZMA_VLI_VALUE_UNKNOWN; ++i) {
27                 switch (filters[i].id) {
28                 case LZMA_FILTER_COPY:
29                 case LZMA_FILTER_DELTA:
30                         // The same as the input, check the next filter.
31                         continue;
32
33                 case LZMA_FILTER_SUBBLOCK:
34                         if (filters[i].options == NULL)
35                                 return LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
36                         else
37                                 return ((const lzma_options_subblock *)(
38                                         filters[i].options))->alignment;
39
40                 case LZMA_FILTER_X86:
41                         return 1;
42
43                 case LZMA_FILTER_ARMTHUMB:
44                         return 2;
45
46                 case LZMA_FILTER_POWERPC:
47                 case LZMA_FILTER_ARM:
48                 case LZMA_FILTER_SPARC:
49                         return 4;
50
51                 case LZMA_FILTER_IA64:
52                         return 16;
53
54                 case LZMA_FILTER_LZMA: {
55                         const lzma_options_lzma *lzma = filters[i].options;
56                         return 1 << MAX(lzma->pos_bits,
57                                         lzma->literal_pos_bits);
58                 }
59
60                 default:
61                         return UINT32_MAX;
62                 }
63         }
64
65         return guess;
66 }
67
68
69 extern LZMA_API uint32_t
70 lzma_alignment_output(const lzma_options_filter *filters, uint32_t guess)
71 {
72         // Check if there is only an implicit Copy filter.
73         if (filters[0].id == LZMA_VLI_VALUE_UNKNOWN)
74                 return guess;
75
76         // Find the last filter in the chain.
77         size_t i = 0;
78         while (filters[i + 1].id != LZMA_VLI_VALUE_UNKNOWN)
79                 ++i;
80
81         do {
82                 switch (filters[i].id) {
83                 case LZMA_FILTER_COPY:
84                 case LZMA_FILTER_DELTA:
85                         // It's the same as the input alignment, so
86                         // check the next filter.
87                         continue;
88
89                 case LZMA_FILTER_SUBBLOCK:
90                         if (filters[i].options == NULL)
91                                 return LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
92                         else
93                                 return ((const lzma_options_subblock *)(
94                                         filters[i].options))->alignment;
95
96                 case LZMA_FILTER_X86:
97                 case LZMA_FILTER_LZMA:
98                         return 1;
99
100                 case LZMA_FILTER_ARMTHUMB:
101                         return 2;
102
103                 case LZMA_FILTER_POWERPC:
104                 case LZMA_FILTER_ARM:
105                 case LZMA_FILTER_SPARC:
106                         return 4;
107
108                 case LZMA_FILTER_IA64:
109                         return 16;
110
111                 default:
112                         return UINT32_MAX;
113                 }
114         } while (i-- != 0);
115
116         // If we get here, we have the same alignment as the input data.
117         return guess;
118 }