/* bits.c * Bit manipulations for Kexis * NOTE: This code is Buggy for a number of cases, and is DEFINATELY broke * on 64 bit, or big edian machines. (read: just about everything but intel) * Copyright (C) 2000 Wayde Milas (wmilas@rarcoa.com) * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "types.h" #include "bits.h" #include "encode.h" #include "kexis.h" /* This is just an function used to dump raw bits so I can see what the hell * is going on when debugging. */ void print_bits(long bits, int len, unsigned long print) { int loop=len-1; int hold=0; if(DEBUG == 1 && (print>DEBUG_POS-DEBUG_DOWN && print= 0) { hold = 1< 32) { printf("\nbitCounter: %d length: %ld\n", kexisBlock->bitCounter, length); sprintf(options->errorString, "Bit Overflow in push_bits!"); handle_error(options); } //if(DEBUG==1 && (kexisBlock->debugBlockCount>DEBUG_POS-DEBUG_DOWN && kexisBlock->debugBlockCountbitCounter, length, outBits, kexisBlock->debugBlockCount); // Handle the most common case where there is no boundy issue. if(kexisBlock->bitCounter + length < 32) { // Loading outBits into the assembly. assembly = outBits; //print_bits(assembly, 32, kexisBlock->debugBlockCount); // shifting assembly into top word, packing tight based on // biitkexisBlock->debugBlockCounter. assembly <<= ((32 - kexisBlock->bitCounter) - length); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // Move bits into transfer kexisBlock->bitBucket |= assembly; //print_bits(kexisBlock->bitBucket, 32, kexisBlock->debugBlockCount); // adjust bitCounter length; // check and see if we are right at the end kexisBlock->bitCounter += length; } else if(kexisBlock->bitCounter + length == 32) { // Loading outBits into the assembly. assembly = outBits; //print_bits(assembly, 32, kexisBlock->debugBlockCount); // shifting assembly into top word, packing tight based on // biitkexisBlock->debugBlockCounter. assembly <<= ((32 - kexisBlock->bitCounter) - length); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // Move bits into data stream kexisBlock->data[kexisBlock->dataPosition] = kexisBlock->bitBucket | assembly; //print_bits(kexisBlock->data[kexisBlock->dataPosition], 32, //kexisBlock->debugBlockCount); //zer the bit bucket; kexisBlock->bitBucket = 0; // increment the kexisBlock->debugBlockCounter kexisBlock->dataPosition++; kexisBlock->bitCounter = 0; // If the stream is full, dump it to disk. if(kexisBlock->dataPosition == options->frameSize/2){ write_kexisblock(options, kexisBlock, pcmBlock); kexisBlock->dataPosition = 0; } } // There is a boundry issue else { // Loading outBits into the assembly. assembly = outBits; //print_bits(assembly, 32, kexisBlock->debugBlockCount); // shift the assembly over so we get the fontmost bits. assembly >>= (length - (32 - kexisBlock->bitCounter)); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // We only want 32 - kexisBlock->bitCounter bits, Mask he rest out. assembly &= ((1<<(32-kexisBlock->bitCounter)) -1); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // combine assembly and bitbucket and put it in the out stream; kexisBlock->data[kexisBlock->dataPosition] = kexisBlock->bitBucket | assembly; //print_bits(kexisBlock->data[kexisBlock->dataPosition], 32, //kexisBlock->debugBlockCount); // adjsut the data Position; kexisBlock->dataPosition++; // If the stream is full, dump it to disk. if(kexisBlock->dataPosition == options->frameSize/2){ write_kexisblock(options, kexisBlock, pcmBlock); kexisBlock->dataPosition = 0; } // put in the data again. assembly = outBits; //print_bits(assembly, 32, kexisBlock->debugBlockCount); // mask out the front most bits we have already saved. assembly &= ((1<<(length - (32-kexisBlock->bitCounter))) -1); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // shift it all the way to the front assembly <<= (32 - (length - (32-kexisBlock->bitCounter))); //print_bits(assembly, 32, kexisBlock->debugBlockCount); // transfer it into bit bucket. kexisBlock->bitBucket = assembly; //print_bits(kexisBlock->bitBucket, 32, kexisBlock->debugBlockCount); // increment bit kexisBlock->debugBlockCounter; kexisBlock->bitCounter = length - (32 - kexisBlock->bitCounter); } } void cleanup_bits(KEXISBLOCKSTRUCT *kexisBlock, OPTIONSTRUCT *options, PCMBLOCKSTRUCT *pcmBlock) { kexisBlock->data[kexisBlock->dataPosition] = kexisBlock->bitBucket; kexisBlock->dataPosition++; write_kexisblock(options, kexisBlock, pcmBlock); } long bit_suck(KEXISBLOCKSTRUCT *kexisBlock, long len, PCMBLOCKSTRUCT *pcmBlock, OPTIONSTRUCT *options) { unsigned long holdData=0; unsigned long holdData2=0; size_t holdRead; //if(DEBUG==1 && (kexisBlock->debugBlockCount>DEBUG_POS-DEBUG_DOWN && kexisBlock->debugBlockCountsubBlockPointer, //len, kexisBlock->debugBlockCount); // check and see if we the data we need is gonna be past a boundry. if(kexisBlock->subBlockPointer + len < 32) { // assign holdData holdData = kexisBlock->data[kexisBlock->blockPointer]; //print_bits(holdData, 32, kexisBlock->debugBlockCount); //shift the bits we want all the way to the right holdData >>= (32 - (kexisBlock->subBlockPointer + len)); //print_bits(holdData, 32, kexisBlock->debugBlockCount); // mask those bits. holdData &= ((1<debugBlockCount); // increment our kexisBlock->debugBlockCounters. kexisBlock->subBlockPointer += len; // return it return holdData; } else if(kexisBlock->subBlockPointer + len == 32) { // assign holdData holdData = kexisBlock->data[kexisBlock->blockPointer]; //print_bits(holdData, 32, kexisBlock->debugBlockCount); //shift the bits we want all the way to the right holdData >>= (32 - (kexisBlock->subBlockPointer + len)); //print_bits(holdData, 32, kexisBlock->debugBlockCount); // mask those bits. holdData &= ((1<debugBlockCount); // increment subblock. kexisBlock->subBlockPointer =0; kexisBlock->blockPointer++; // see if we need to read in more date. if(kexisBlock->blockPointer == (options->frameSize/2)){ holdRead = fread(kexisBlock->data, sizeof(long), options->frameSize/2, options->inFileStream); if(holdRead <= 0) { sprintf(options->errorString, "In Error reading from %s!", options->inFileName); handle_error(options); } kexisBlock->blockPointer=0; } return holdData; } // else we need to cross a boundry else { // assign holdData holdData = kexisBlock->data[kexisBlock->blockPointer]; //print_bits(holdData, 32, kexisBlock->debugBlockCount); // mask lowest bits we need only. holdData &= ((1<<(32 - kexisBlock->subBlockPointer)) -1); //print_bits(holdData, 32, kexisBlock->debugBlockCount); //shift em left. to make room for the remainder. holdData <<= (len-(32-kexisBlock->subBlockPointer)); //print_bits(holdData, 32, kexisBlock->debugBlockCount); kexisBlock->blockPointer++; // read in more data if we need it. if(kexisBlock->blockPointer == (options->frameSize/2)){ holdRead = fread(kexisBlock->data, sizeof(long), options->frameSize/2, options->inFileStream); if(holdRead <= 0) { sprintf(options->errorString, "In Error reading from %s!", options->inFileName); handle_error(options); } kexisBlock->blockPointer=0; } // grab the second word. holdData2 = kexisBlock->data[kexisBlock->blockPointer]; //print_bits(holdData2, 32, kexisBlock->debugBlockCount); //shift the part we want all the way from the left to teh right. holdData2 >>= (32 - (len - (32 - kexisBlock->subBlockPointer))); //print_bits(holdData2, 32, kexisBlock->debugBlockCount); // mask out any bits we dont need. holdData2 &= ((1<<(len -(32 - kexisBlock->subBlockPointer))) -1); //print_bits(holdData2, 32, kexisBlock->debugBlockCount); // combine the two together. holdData = holdData | holdData2; //print_bits(holdData, 32, kexisBlock->debugBlockCount); // increment the sub block pointer. kexisBlock->subBlockPointer = len - (32 - kexisBlock->subBlockPointer); return holdData; } }