blob: 97221dffebcc43e97b326c3817171d651dfe5e25
1 | /* |
2 | * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> |
3 | * |
4 | * This file is part of FFmpeg. |
5 | * |
6 | * FFmpeg is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * License as published by the Free Software Foundation; either |
9 | * version 2.1 of the License, or (at your option) any later version. |
10 | * |
11 | * FFmpeg is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License along with FFmpeg; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ |
20 | |
21 | #include "bswap.h" |
22 | #include "crc.h" |
23 | |
24 | #if CONFIG_HARDCODED_TABLES |
25 | #include "crc_data.h" |
26 | #else |
27 | static struct { |
28 | uint8_t le; |
29 | uint8_t bits; |
30 | uint32_t poly; |
31 | } av_crc_table_params[AV_CRC_MAX] = { |
32 | [AV_CRC_8_ATM] = { 0, 8, 0x07 }, |
33 | [AV_CRC_16_ANSI] = { 0, 16, 0x8005 }, |
34 | [AV_CRC_16_CCITT] = { 0, 16, 0x1021 }, |
35 | [AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 }, |
36 | [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 }, |
37 | }; |
38 | static AVCRC av_crc_table[AV_CRC_MAX][257]; |
39 | #endif |
40 | |
41 | /** |
42 | * Initializes a CRC table. |
43 | * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 |
44 | * @param cts_size size of ctx in bytes |
45 | * @param le If 1, the lowest bit represents the coefficient for the highest |
46 | * exponent of the corresponding polynomial (both for poly and |
47 | * actual CRC). |
48 | * If 0, you must swap the CRC parameter and the result of av_crc |
49 | * if you need the standard representation (can be simplified in |
50 | * most cases to e.g. bswap16): |
51 | * bswap_32(crc << (32-bits)) |
52 | * @param bits number of bits for the CRC |
53 | * @param poly generator polynomial without the x**bits coefficient, in the |
54 | * representation as specified by le |
55 | * @return <0 on failure |
56 | */ |
57 | int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size) |
58 | { |
59 | int i, j; |
60 | uint32_t c; |
61 | |
62 | if (bits < 8 || bits > 32 || poly >= (1LL << bits)) { |
63 | return -1; |
64 | } |
65 | if (ctx_size != sizeof(AVCRC) * 257 && ctx_size != sizeof(AVCRC) * 1024) { |
66 | return -1; |
67 | } |
68 | |
69 | for (i = 0; i < 256; i++) { |
70 | if (le) { |
71 | for (c = i, j = 0; j < 8; j++) { |
72 | c = (c >> 1) ^(poly & (-(c & 1))); |
73 | } |
74 | ctx[i] = c; |
75 | } else { |
76 | for (c = i << 24, j = 0; j < 8; j++) { |
77 | c = (c << 1) ^((poly << (32 - bits)) & (((int32_t)c) >> 31)); |
78 | } |
79 | ctx[i] = bswap_32(c); |
80 | } |
81 | } |
82 | ctx[256] = 1; |
83 | //#if !CONFIG_SMALL |
84 | if (ctx_size >= sizeof(AVCRC) * 1024) |
85 | for (i = 0; i < 256; i++) |
86 | for (j = 0; j < 3; j++) { |
87 | ctx[256 * (j + 1) + i] = (ctx[256 * j + i] >> 8) ^ ctx[ ctx[256 * j + i] & 0xFF ]; |
88 | } |
89 | //#endif |
90 | |
91 | return 0; |
92 | } |
93 | |
94 | /** |
95 | * Gets an initialized standard CRC table. |
96 | * @param crc_id ID of a standard CRC |
97 | * @return a pointer to the CRC table or NULL on failure |
98 | */ |
99 | const AVCRC *av_crc_get_table(AVCRCId crc_id) |
100 | { |
101 | //#if !CONFIG_HARDCODED_TABLES |
102 | if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id]) - 1]) |
103 | if (av_crc_init(av_crc_table[crc_id], |
104 | av_crc_table_params[crc_id].le, |
105 | av_crc_table_params[crc_id].bits, |
106 | av_crc_table_params[crc_id].poly, |
107 | sizeof(av_crc_table[crc_id])) < 0) { |
108 | return NULL; |
109 | } |
110 | //#endif |
111 | return av_crc_table[crc_id]; |
112 | } |
113 | |
114 | /** |
115 | * Calculates the CRC of a block. |
116 | * @param crc CRC of previous blocks if any or initial value for CRC |
117 | * @return CRC updated with the data from the given block |
118 | * |
119 | * @see av_crc_init() "le" parameter |
120 | */ |
121 | uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length) |
122 | { |
123 | const uint8_t *end = buffer + length; |
124 | |
125 | //#if !CONFIG_SMALL |
126 | if (!ctx[256]) { |
127 | while (((intptr_t) buffer & 3) && buffer < end) { |
128 | crc = ctx[((uint8_t)crc) ^ *buffer++] ^(crc >> 8); |
129 | } |
130 | |
131 | while (buffer < end - 3) { |
132 | crc ^= le2me_32(*(const uint32_t*)buffer); |
133 | buffer += 4; |
134 | crc = ctx[3 * 256 + (crc & 0xFF)] |
135 | ^ ctx[2 * 256 + ((crc >> 8) & 0xFF)] |
136 | ^ ctx[1 * 256 + ((crc >> 16) & 0xFF)] |
137 | ^ ctx[0 * 256 + ((crc >> 24))]; |
138 | } |
139 | } |
140 | //#endif |
141 | while (buffer < end) { |
142 | crc = ctx[((uint8_t)crc) ^ *buffer++] ^(crc >> 8); |
143 | } |
144 | |
145 | return crc; |
146 | } |
147 |