/*
 * DATlib   Copyright (c) 1995-1996 Marcus Meissner &
 *          Friedrich-Alexander Universitaet Erlangen-Nuernberg (FAU), IMMD4
 *          All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by Marcus Meissner
 *    at the Friedrich-Alexander Universitaet Erlangen-Nuernberg (FAU), IMMD4
 *
 * 4. The name of the University or the author may not be used
 *    to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND THE AUTHOR ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR THE AUTHOR BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* $Id: 32k_encode.c,v 1.1 1997/03/16 20:29:34 msmeissn Exp $
 *
 * $Log: 32k_encode.c,v $
 * Revision 1.1  1997/03/16 20:29:34  msmeissn
 * Initial revision
 *
 *
 * 32k_encode.c: Generate tables for 32k encode/decode
 */

#define __IN_32K_ENCODE_C
#include <string.h>
#include <stdio.h>
#include "32k_encode.h"

#define bzero(x,l) memset(x,'\0',l)
#define DATASIZE	1920*3

int
da_c_12_to_16(int arg) {
	int	cnv;
	cnv=arg;
	if (cnv>=0x800)
		cnv=arg-0x1000;
	if (cnv>=1792)	return (cnv-1536)*64;
	if (cnv>=1536)	return (cnv-1280)*32;
	if (cnv>=1280)	return (cnv-1024)*16;
	if (cnv>=1024)	return (cnv-768)*8;
	if (cnv>=768)	return (cnv-512)*4;
	if (cnv>=512)	return (cnv-256)*2;
	if (cnv>=0) 	return cnv;
	if (cnv>=-512)	return cnv;
	if (cnv>=-768)	return (cnv+256)*2;
	if (cnv>=-1024)	return (cnv+512)*4;
	if (cnv>=-1280)	return (cnv+768)*8;
	if (cnv>=-1536)	return (cnv+1024)*16;
	if (cnv>=-1792)	return (cnv+1280)*32;
	return (cnv+1536)*64;
}

int
da_c_16_to_12(int arg) {
	int	cnv;

	cnv=arg;
	if (cnv>0x8000)
		cnv=cnv-0x10000;
	if (cnv>=0x4000)	return cnv/64+1536;
	if (cnv>=0x2000)	return cnv/32+1280;
	if (cnv>=0x1000)	return cnv/16+1024;
	if (cnv>=0x0800)	return cnv/8+768;
	if (cnv>=0x0400)	return cnv/4+512;
	if (cnv>=0x0200)	return cnv/2+256;
	if (cnv>=-0x0200)	return cnv;
	if (cnv>=-0x0400)	return (cnv+1)/2-257;
	if (cnv>=-0x0800)	return (cnv+1)/4-513;
	if (cnv>=-0x1000)	return (cnv+1)/8-769;
	if (cnv>=-0x2000)	return (cnv+1)/16-1025;
	if (cnv>=-0x4000)	return (cnv+1)/32-1281;
				return (cnv+1)/64-1537;
}

void
da_init_tables(void) {
	short	X,Y,Z,datbuf[2][128][32];
	int	i,xx[DATASIZE];

	bzero(da_c_44_to_32lp,1920*3);
	bzero(da_c_32lp_to_44,1920*3);
	bzero(datbuf,2*128*32*sizeof(datbuf[0][0][0]));

	for (i=1920*3;i--;) xx[i]=i;
/* now it gets a bit complex. we've got 4 bytes right, 4 bytes shifted
 * by 3840 byte. we have to translate this into our 12->16 mapping so
 * we can save time. that means we've got 3 bytes right, 3 bytes shifted
 * by 3840*3/4 = 2880 etc. so we need to apply this AFTER the 44k->32lp map
 */
 	/* only need to process half of the array (/2) */
	for (i=1920*3/2;i--;) { 
		if ((i%6)>=3) {
			int	tmp;

			tmp=xx[i];
			xx[i]=xx[i+2880];
			xx[i+2880]=tmp;
		}
	}
	for (i=0;i<1440*4;i++) {
#define CODE_44\
		int	I,A,U;\
		I=i/4;\
		U=1-(i%2);\
		A=((i&2)/2);\
		X=A%2;\
		Y=(I%52)+75*(I%2)+(I/832);\
		Z=2*(U+(I/52))-((I/52)%2)-32*(I/832);

		CODE_44;
		datbuf[X][Y][Z]=i;
	}
	for (i=0;i<3*1920;i++) {
		int	A,U,I,J,S;

		S=i%3;
		I=i/3;

		A=I/960;
		U=(3*(I/2)+S)%2;
		J=2*((3*(I/2)+S)/2)+(I%2)-(1440*A);
		X=(A+J)%2;
		Y=(J%52)+75*(J%2)+J/832;
		Z=2*(U+(J/52))-((J/52)%2)-32*(J/832);

		da_c_44_to_32lp[xx[i]]=datbuf[X][Y][Z];
	}
	/* reverse mapping ... */
	for (i=0;i<1440*4;i++)
		da_c_32lp_to_44[da_c_44_to_32lp[i]]=i;

	for (i=0;i<4096;i++)
		da_conv_12_to_16[i]=da_c_12_to_16(i);
	for (i=0;i<65536;i++)
		da_conv_16_to_12[i]=da_c_16_to_12(i);
}
