summaryrefslogtreecommitdiff
path: root/audio_codec/libflac/crc.c (plain)
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
27static 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};
38static 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 */
57int 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 */
99const 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 */
121uint32_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