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 "config.h" 22#include "common.h" 23#include "bswap.h" 24#include "crc.h" 25 26#if CONFIG_HARDCODED_TABLES 27#include "crc_data.h" 28#else 29static struct { 30 uint8_t le; 31 uint8_t bits; 32 uint32_t poly; 33} av_crc_table_params[AV_CRC_MAX] = { 34 [AV_CRC_8_ATM] = { 0, 8, 0x07 }, 35 [AV_CRC_16_ANSI] = { 0, 16, 0x8005 }, 36 [AV_CRC_16_CCITT] = { 0, 16, 0x1021 }, 37 [AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 }, 38 [AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 }, 39}; 40static AVCRC av_crc_table[AV_CRC_MAX][257]; 41#endif 42 43/** 44 * Initializes a CRC table. 45 * @param ctx must be an array of size sizeof(AVCRC)*257 or sizeof(AVCRC)*1024 46 * @param cts_size size of ctx in bytes 47 * @param le If 1, the lowest bit represents the coefficient for the highest 48 * exponent of the corresponding polynomial (both for poly and 49 * actual CRC). 50 * If 0, you must swap the CRC parameter and the result of av_crc 51 * if you need the standard representation (can be simplified in 52 * most cases to e.g. bswap16): 53 * bswap_32(crc << (32-bits)) 54 * @param bits number of bits for the CRC 55 * @param poly generator polynomial without the x**bits coefficient, in the 56 * representation as specified by le 57 * @return <0 on failure 58 */ 59int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){ 60 int i, j; 61 uint32_t c; 62 63 if (bits < 8 || bits > 32 || poly >= (1LL<<bits)) 64 return -1; 65 if (ctx_size != sizeof(AVCRC)*257 && ctx_size != sizeof(AVCRC)*1024) 66 return -1; 67 68 for (i = 0; i < 256; i++) { 69 if (le) { 70 for (c = i, j = 0; j < 8; j++) 71 c = (c>>1)^(poly & (-(c&1))); 72 ctx[i] = c; 73 } else { 74 for (c = i << 24, j = 0; j < 8; j++) 75 c = (c<<1) ^ ((poly<<(32-bits)) & (((int32_t)c)>>31) ); 76 ctx[i] = bswap_32(c); 77 } 78 } 79 ctx[256]=1; 80#if !CONFIG_SMALL 81 if(ctx_size >= sizeof(AVCRC)*1024) 82 for (i = 0; i < 256; i++) 83 for(j=0; j<3; j++) 84 ctx[256*(j+1) + i]= (ctx[256*j + i]>>8) ^ ctx[ ctx[256*j + i]&0xFF ]; 85#endif 86 87 return 0; 88} 89 90/** 91 * Gets an initialized standard CRC table. 92 * @param crc_id ID of a standard CRC 93 * @return a pointer to the CRC table or NULL on failure 94 */ 95const AVCRC *av_crc_get_table(AVCRCId crc_id){ 96#if !CONFIG_HARDCODED_TABLES 97 if (!av_crc_table[crc_id][FF_ARRAY_ELEMS(av_crc_table[crc_id])-1]) 98 if (av_crc_init(av_crc_table[crc_id], 99 av_crc_table_params[crc_id].le, 100 av_crc_table_params[crc_id].bits, 101 av_crc_table_params[crc_id].poly, 102 sizeof(av_crc_table[crc_id])) < 0) 103 return NULL; 104#endif 105 return av_crc_table[crc_id]; 106} 107 108/** 109 * Calculates the CRC of a block. 110 * @param crc CRC of previous blocks if any or initial value for CRC 111 * @return CRC updated with the data from the given block 112 * 113 * @see av_crc_init() "le" parameter 114 */ 115uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length){ 116 const uint8_t *end= buffer+length; 117 118#if !CONFIG_SMALL 119 if(!ctx[256]) { 120 while(((intptr_t) buffer & 3) && buffer < end) 121 crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8); 122 123 while(buffer<end-3){ 124 crc ^= le2me_32(*(const uint32_t*)buffer); buffer+=4; 125 crc = ctx[3*256 + ( crc &0xFF)] 126 ^ctx[2*256 + ((crc>>8 )&0xFF)] 127 ^ctx[1*256 + ((crc>>16)&0xFF)] 128 ^ctx[0*256 + ((crc>>24) )]; 129 } 130 } 131#endif 132 while(buffer<end) 133 crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8); 134 135 return crc; 136} 137 138#ifdef TEST 139#undef printf 140int main(void){ 141 uint8_t buf[1999]; 142 int i; 143 int p[4][3]={{AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04}, 144 {AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0}, 145 {AV_CRC_16_ANSI , 0x8005, 0x1FBB }, 146 {AV_CRC_8_ATM , 0x07, 0xE3 },}; 147 const AVCRC *ctx; 148 149 for(i=0; i<sizeof(buf); i++) 150 buf[i]= i+i*i; 151 152 for(i=0; i<4; i++){ 153 ctx = av_crc_get_table(p[i][0]); 154 printf("crc %08X =%X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf))); 155 } 156 return 0; 157} 158#endif 159