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