/* * This file has been modified for the cdrkit suite. * * The behaviour and appearence of the program code below can differ to a major * extent from the version distributed by the original author(s). * * For details, see Changelog file distributed with the cdrkit package. If you * received this file from another source then ask the distributing person for * a log of modifications. * */ /* @(#)crc16.c 1.6 04/03/02 Copyright 1998-2004 J. Schilling */ /* * Q-subchannel CRC subroutines * * Polynom is: p(x) = x ** 16 + x ** 12 + x ** 5 + 1 * If computed over 12 bytes, the result must be zero. * On the disk the CRC bits are inverted. * * Copyright (c) 1998-2003 J. Schilling */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * 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; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "crc16.h" static UInt16_t updcrc(Uint p_crc, UInt8_t *cp, Uint cnt); UInt16_t calcCRC(Uchar *buf, Uint bsize); UInt16_t fillcrc(Uchar *buf, Uint bsize); UInt16_t flip_crc_error_corr(Uchar *b, Uint bsize, Uint p_crc); /* number of bits in CRC: don't change it. */ #define BPW 16 /* this the number of bits per char: don't change it. */ #define BPB 8 static UInt16_t crctab[1< 0) { crc = (crc<>(BPW-BPB)) ^ (*cp++)]; } return (crc); } /*static UInt16_t*/ UInt16_t calcCRC(Uchar *buf, Uint bsize) { return (updcrc(0x0000, (UInt8_t *)buf, bsize)); } /* * CRC für Q-Sub füllen */ UInt16_t fillcrc(Uchar *buf, Uint bsize) { UInt16_t crc = calcCRC(buf, bsize-2); /* * Invert CRC bits for RED Book compliance. */ crc = crc ^ 0xFFFF; buf[bsize-2] = (crc >> 8) & 0xFF; buf[bsize-1] = crc & 0xFF; return (crc); } static UInt8_t fliptab[BPB] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, }; UInt16_t flip_crc_error_corr(Uchar *b, Uint bsize, Uint p_crc) { register UInt16_t crc = p_crc; register Uint btsize = bsize * BPB; if (crc != 0) { int i; for (i = 0; i < btsize; i++) { UInt8_t c; c = fliptab[i % BPB]; b[i / BPB] ^= c; if ((crc = calcCRC(b, bsize)) == 0) { return (crc); } b[i / BPB] ^= c; } } return (crc & 0xffff); }