ffmpeg / libavutil / crc.c @ d71ad089
History | View | Annotate | Download (4.99 KB)
1 | 04d7f601 | Diego Biurrun | /*
|
---|---|---|---|
2 | * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||
3 | *
|
||
4 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
5 | *
|
||
6 | * FFmpeg is free software; you can redistribute it and/or
|
||
7 | 04d7f601 | Diego Biurrun | * modify it under the terms of the GNU Lesser General Public
|
8 | * License as published by the Free Software Foundation; either
|
||
9 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
10 | 04d7f601 | Diego Biurrun | *
|
11 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
12 | 04d7f601 | Diego Biurrun | * 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 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
18 | 04d7f601 | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
19 | */
|
||
20 | |||
21 | e503674c | Diego Biurrun | #include "config.h" |
22 | #include "bswap.h" |
||
23 | 43a80cce | Michael Niedermayer | #include "crc.h" |
24 | |||
25 | b250f9c6 | Aurelien Jacobs | #if CONFIG_HARDCODED_TABLES
|
26 | 3abe5fbd | Aurelien Jacobs | #include "crc_data.h" |
27 | 08cb1950 | Michael Niedermayer | #else
|
28 | 3abe5fbd | Aurelien Jacobs | static struct { |
29 | uint8_t le; |
||
30 | uint8_t bits; |
||
31 | uint32_t poly; |
||
32 | } av_crc_table_params[AV_CRC_MAX] = { |
||
33 | [AV_CRC_8_ATM] = { 0, 8, 0x07 }, |
||
34 | [AV_CRC_16_ANSI] = { 0, 16, 0x8005 }, |
||
35 | [AV_CRC_16_CCITT] = { 0, 16, 0x1021 }, |
||
36 | [AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 }, |
||
37 | [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 }, |
||
38 | }; |
||
39 | static AVCRC av_crc_table[AV_CRC_MAX][257]; |
||
40 | 08cb1950 | Michael Niedermayer | #endif
|
41 | 43a80cce | Michael Niedermayer | |
42 | /**
|
||
43 | 7d685b48 | Diego Biurrun | * Initializes a CRC table.
|
44 | * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024
|
||
45 | 43a80cce | Michael Niedermayer | * @param cts_size size of ctx in bytes
|
46 | 7d685b48 | Diego Biurrun | * @param le If 1, the lowest bit represents the coefficient for the highest
|
47 | * exponent of the corresponding polynomial (both for poly and
|
||
48 | * actual CRC).
|
||
49 | * If 0, you must swap the CRC parameter and the result of av_crc
|
||
50 | 45e3c163 | Reimar Döffinger | * if you need the standard representation (can be simplified in
|
51 | * most cases to e.g. bswap16):
|
||
52 | * bswap_32(crc << (32-bits))
|
||
53 | * @param bits number of bits for the CRC
|
||
54 | * @param poly generator polynomial without the x**bits coefficient, in the
|
||
55 | * representation as specified by le
|
||
56 | 43a80cce | Michael Niedermayer | * @return <0 on failure
|
57 | */
|
||
58 | int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){ |
||
59 | int i, j;
|
||
60 | uint32_t c; |
||
61 | |||
62 | if (bits < 8 || bits > 32 || poly >= (1LL<<bits)) |
||
63 | return -1; |
||
64 | if (ctx_size != sizeof(AVCRC)*257 && ctx_size != sizeof(AVCRC)*1024) |
||
65 | return -1; |
||
66 | |||
67 | for (i = 0; i < 256; i++) { |
||
68 | if (le) {
|
||
69 | for (c = i, j = 0; j < 8; j++) |
||
70 | c = (c>>1)^(poly & (-(c&1))); |
||
71 | ctx[i] = c; |
||
72 | } else {
|
||
73 | for (c = i << 24, j = 0; j < 8; j++) |
||
74 | c = (c<<1) ^ ((poly<<(32-bits)) & (((int32_t)c)>>31) ); |
||
75 | ctx[i] = bswap_32(c); |
||
76 | } |
||
77 | } |
||
78 | ctx[256]=1; |
||
79 | b250f9c6 | Aurelien Jacobs | #if !CONFIG_SMALL
|
80 | 43a80cce | Michael Niedermayer | if(ctx_size >= sizeof(AVCRC)*1024) |
81 | for (i = 0; i < 256; i++) |
||
82 | for(j=0; j<3; j++) |
||
83 | ctx[256*(j+1) + i]= (ctx[256*j + i]>>8) ^ ctx[ ctx[256*j + i]&0xFF ]; |
||
84 | a08d38ee | Michael Niedermayer | #endif
|
85 | 43a80cce | Michael Niedermayer | |
86 | return 0; |
||
87 | } |
||
88 | |||
89 | 45e3c163 | Reimar Döffinger | /**
|
90 | 89c9ff50 | Diego Biurrun | * Gets an initialized standard CRC table.
|
91 | 3abe5fbd | Aurelien Jacobs | * @param crc_id ID of a standard CRC
|
92 | * @return a pointer to the CRC table or NULL on failure
|
||
93 | */
|
||
94 | const AVCRC *av_crc_get_table(AVCRCId crc_id){
|
||
95 | b250f9c6 | Aurelien Jacobs | #if !CONFIG_HARDCODED_TABLES
|
96 | 37d3e066 | Aurelien Jacobs | if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id])-1]) |
97 | 3abe5fbd | Aurelien Jacobs | if (av_crc_init(av_crc_table[crc_id],
|
98 | av_crc_table_params[crc_id].le, |
||
99 | av_crc_table_params[crc_id].bits, |
||
100 | av_crc_table_params[crc_id].poly, |
||
101 | sizeof(av_crc_table[crc_id])) < 0) |
||
102 | return NULL; |
||
103 | #endif
|
||
104 | return av_crc_table[crc_id];
|
||
105 | } |
||
106 | |||
107 | /**
|
||
108 | 89c9ff50 | Diego Biurrun | * Calculates the CRC of a block.
|
109 | * @param crc CRC of previous blocks if any or initial value for CRC
|
||
110 | 45e3c163 | Reimar Döffinger | * @return CRC updated with the data from the given block
|
111 | *
|
||
112 | * @see av_crc_init() "le" parameter
|
||
113 | */
|
||
114 | 43a80cce | Michael Niedermayer | uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length){ |
115 | const uint8_t *end= buffer+length;
|
||
116 | |||
117 | b250f9c6 | Aurelien Jacobs | #if !CONFIG_SMALL
|
118 | d468ff0f | Jeff Downs | if(!ctx[256]) { |
119 | while(((intptr_t) buffer & 3) && buffer < end) |
||
120 | crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8);
|
||
121 | |||
122 | 43a80cce | Michael Niedermayer | while(buffer<end-3){ |
123 | 07014467 | Michael Niedermayer | crc ^= le2me_32(*(const uint32_t*)buffer); buffer+=4; |
124 | 43a80cce | Michael Niedermayer | crc = ctx[3*256 + ( crc &0xFF)] |
125 | ^ctx[2*256 + ((crc>>8 )&0xFF)] |
||
126 | ^ctx[1*256 + ((crc>>16)&0xFF)] |
||
127 | ^ctx[0*256 + ((crc>>24) )]; |
||
128 | } |
||
129 | d468ff0f | Jeff Downs | } |
130 | a08d38ee | Michael Niedermayer | #endif
|
131 | 43a80cce | Michael Niedermayer | while(buffer<end)
|
132 | crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8);
|
||
133 | |||
134 | return crc;
|
||
135 | } |
||
136 | |||
137 | #ifdef TEST
|
||
138 | #undef printf
|
||
139 | f3635240 | Diego Biurrun | int main(void){ |
140 | 43a80cce | Michael Niedermayer | uint8_t buf[1999];
|
141 | int i;
|
||
142 | 3abe5fbd | Aurelien Jacobs | int p[4][3]={{AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04}, |
143 | {AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0}, |
||
144 | {AV_CRC_16_ANSI , 0x8005, 0x1FBB }, |
||
145 | {AV_CRC_8_ATM , 0x07, 0xE3 },}; |
||
146 | const AVCRC *ctx;
|
||
147 | 43a80cce | Michael Niedermayer | |
148 | for(i=0; i<sizeof(buf); i++) |
||
149 | buf[i]= i+i*i; |
||
150 | |||
151 | for(i=0; i<4; i++){ |
||
152 | 3abe5fbd | Aurelien Jacobs | ctx = av_crc_get_table(p[i][0]);
|
153 | printf("crc %08X =%X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf))); |
||
154 | 43a80cce | Michael Niedermayer | } |
155 | f3635240 | Diego Biurrun | return 0; |
156 | 43a80cce | Michael Niedermayer | } |
157 | #endif |