changeset 30:664e2d2b92b9 libavutil

generic crc calculation code
author michael
date Mon, 06 Mar 2006 14:13:01 +0000
parents 68bda919ab25
children 7b1170d0da89
files Makefile crc.c crc.h
diffstat 3 files changed, 96 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Feb 22 10:28:44 2006 +0000
+++ b/Makefile	Mon Mar 06 14:13:01 2006 +0000
@@ -15,6 +15,7 @@
       integer.o \
       rational.o \
       intfloat_readwrite.o \
+      crc.o \
 
 HEADERS = avutil.h common.h mathematics.h integer.h rational.h \
           intfloat_readwrite.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crc.c	Mon Mar 06 14:13:01 2006 +0000
@@ -0,0 +1,80 @@
+#include "common.h"
+#include "crc.h"
+
+AVCRC *av_crcEDB88320;
+AVCRC *av_crc04C11DB7;
+AVCRC *av_crc8005    ;
+AVCRC *av_crc07      ;
+
+/**
+ * Inits a crc table.
+ * @param ctx must be an array of sizeof(AVCRC)*257 or sizeof(AVCRC)*1024
+ * @param cts_size size of ctx in bytes
+ * @return <0 on failure
+ */
+int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){
+    int i, j;
+    uint32_t c;
+
+    if (bits < 8 || bits > 32 || poly >= (1LL<<bits))
+        return -1;
+    if (ctx_size != sizeof(AVCRC)*257 && ctx_size != sizeof(AVCRC)*1024)
+        return -1;
+
+    for (i = 0; i < 256; i++) {
+        if (le) {
+            for (c = i, j = 0; j < 8; j++)
+                c = (c>>1)^(poly & (-(c&1)));
+            ctx[i] = c;
+        } else {
+            for (c = i << 24, j = 0; j < 8; j++)
+                c = (c<<1) ^ ((poly<<(32-bits)) & (((int32_t)c)>>31) );
+            ctx[i] = bswap_32(c);
+        }
+    }
+    ctx[256]=1;
+    if(ctx_size >= sizeof(AVCRC)*1024)
+        for (i = 0; i < 256; i++)
+            for(j=0; j<3; j++)
+                ctx[256*(j+1) + i]= (ctx[256*j + i]>>8) ^ ctx[ ctx[256*j + i]&0xFF ];
+
+    return 0;
+}
+
+uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length){
+    const uint8_t *end= buffer+length;
+
+    if(!ctx[256])
+        while(buffer<end-3){
+            crc ^= le2me_32(*(uint32_t*)buffer); buffer+=4;
+            crc =  ctx[3*256 + ( crc     &0xFF)]
+                  ^ctx[2*256 + ((crc>>8 )&0xFF)]
+                  ^ctx[1*256 + ((crc>>16)&0xFF)]
+                  ^ctx[0*256 + ((crc>>24)     )];
+        }
+    while(buffer<end)
+        crc = ctx[((uint8_t)crc) ^ *buffer++] ^ (crc >> 8);
+
+    return crc;
+}
+
+#ifdef TEST
+#undef printf
+main(){
+    uint8_t buf[1999];
+    int i;
+    int p[4][4]={{1, 32, 0xedb88320L, 0x3D5CDD04},
+                 {0, 32, 0x04c11db7L, 0xC0F5BAE0},
+                 {0, 16, 0x8005     , 0x1FBB    },
+                 {0,  8, 0x07       , 0xE3      },};
+    AVCRC ctx[1 ? 1024:257];
+
+    for(i=0; i<sizeof(buf); i++)
+        buf[i]= i+i*i;
+
+    for(i=0; i<4; i++){
+        av_crc_init(ctx, p[i][0], p[i][1], p[i][2], sizeof(ctx));
+        printf("crc %08X =%X\n", p[i][2], av_crc(ctx, 0, buf, sizeof(buf)));
+    }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crc.h	Mon Mar 06 14:13:01 2006 +0000
@@ -0,0 +1,15 @@
+#ifndef CRC_H
+#define CRC_H
+
+typedef uint32_t AVCRC;
+
+extern AVCRC *av_crcEDB88320;
+extern AVCRC *av_crc04C11DB7;
+extern AVCRC *av_crc8005    ;
+extern AVCRC *av_crc07      ;
+
+int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size);
+uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length);
+
+#endif /* CRC_H */
+