aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/crc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crc32.c')
-rwxr-xr-xsrc/crc32.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/crc32.c b/src/crc32.c
new file mode 100755
index 0000000..bd68609
--- /dev/null
+++ b/src/crc32.c
@@ -0,0 +1,130 @@
+/* crc32.c - the crc check algorithm for cksfv modified by oliver for easytag
+
+ Copyright (C) 2000 Bryan Call <bc@fodder.org>
+ Copyright (C) 2003 Oliver Schinagl <oliver@are-b.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "crc32.h"
+
+/*
+ * Initial crc32 function
+ * This function was renamed from crc32(...) to crc32_easytag(...) to avoid a
+ * strange problem with some gtk theme that may use the same name of function.
+ */
+int crc32_easytag(register int fd, unsigned long *main_val)
+{
+ char buf[BUFFERSIZE], *p;
+ int nr;
+ unsigned long crc = ~0, crc32_total = ~0;
+
+ while ((nr = read(fd, &buf, sizeof(buf))) > 0)
+ for (p = buf; nr--; ++p)
+ {
+ crc = (crc >> 8) ^ crctable[(crc ^ *p) & 0xff];
+ crc32_total = (crc >> 8) ^ crctable[(crc32_total ^ *p) & 0xff];
+ }
+ if (nr < 0)
+ return 1;
+
+ *main_val = ~crc;
+
+ return 0;
+}
+
+
+
+/*
+ * Calculate the CRC-32 value of audio data (doesn't read the ID3v2 and ID3v1 tags).
+ * Return 0 if OK
+ */
+int crc32_file_with_ID3_tag(char *filename, unsigned long *main_val)
+{
+ char buf[BUFFERSIZE], *p;
+ int nr;
+ unsigned long crc = ~0, crc32_total = ~0;
+ FILE *fd;
+ unsigned char tmp_id3[4];
+ int id3v2size = 0;
+ struct stat statbuf;
+ unsigned long size = 0;
+ int has_id3v1 = 0;
+
+
+ if (!filename)
+ return 1;
+
+ stat(filename,&statbuf);
+ size = statbuf.st_size;
+
+ if ( (fd = fopen(filename,"r"))==NULL )
+ return 1;
+
+ // Check if there is an ID3v1 tag...
+ fseek(fd, -128, SEEK_END);
+ if (fread(tmp_id3, 1, 3, fd) != 3)
+ return 1;
+ if (tmp_id3[0] == 'T' && tmp_id3[1] == 'A' && tmp_id3[2] == 'G')
+ has_id3v1 = 1;
+
+
+ // Check if there is an ID3v2 tag...
+ fseek(fd, 0L, SEEK_SET);
+ if (fread(tmp_id3, 1, 4, fd) != 4)
+ return 1;
+ // Calculate ID3v2 length
+ if (tmp_id3[0] == 'I' && tmp_id3[1] == 'D' && tmp_id3[2] == '3' && tmp_id3[3] < 0xFF)
+ {
+ // id3v2 tag skipeer $49 44 33 yy yy xx zz zz zz zz [zz size]
+ fseek(fd, 2, SEEK_CUR); // Size is 6-9 position
+ if (fread(tmp_id3, 1, 4, fd) != 4)
+ return 1;
+ id3v2size = 10 + ( (long)(tmp_id3[3]) | ((long)(tmp_id3[2]) << 7)
+ | ((long)(tmp_id3[1]) << 14) | ((long)(tmp_id3[0]) << 21) );
+
+ fseek(fd, id3v2size, SEEK_SET);
+ size = size - id3v2size;
+ }else
+ {
+ fseek(fd, 0L, SEEK_SET);
+ }
+
+ while ((nr = fread(buf, sizeof(char), sizeof(buf), fd)) > 0)
+ {
+ if (has_id3v1 && nr <= 128) // We are reading end of ID3v1 tag
+ break;
+ if ( has_id3v1 && ((size=size-nr) < 128) ) // ID3v1 tag is in the current buf
+ nr = nr - 128 + size;
+
+ for (p = buf; nr--; ++p)
+ {
+ crc = (crc >> 8) ^ crctable[(crc ^ *p) & 0xff];
+ crc32_total = (crc >> 8) ^ crctable[(crc32_total ^ *p) & 0xff];
+ }
+ }
+
+ fclose(fd);
+
+ if (nr < 0)
+ return 1;
+
+ *main_val = ~crc;
+
+ return 0;
+}