Files
2025-09-12 18:55:25 +09:00

89 lines
2.3 KiB
C

#include <stdio.h>
#define NWK 20
#define JTRY(j,k,m) ((long)((((double)(k))*((double)(j)))/((double)(m))))
typedef struct {
unsigned long *ilob,*iupb,*ncumfq,jdif,nc,minint,nch,ncum,nrad;
} arithcode;
void arcode(ich,codep,lcode,lcd,isign,acode)
arithcode *acode;
int isign;
unsigned char **codep;
unsigned long *ich,*lcd,*lcode;
{
char *realloc();
void arcsum();
void nrerror();
int j,k;
unsigned long ihi,ja,jh,jl,m;
if (!isign) {
acode->jdif=acode->nrad-1;
for (j=NWK;j>=1;j--) {
acode->iupb[j]=acode->nrad-1;
acode->ilob[j]=0;
acode->nc=j;
if (acode->jdif > acode->minint) return;
acode->jdif=(acode->jdif+1)*acode->nrad-1;
}
nrerror("NWK too small in arcode.");
} else {
if (isign > 0) {
if (*ich > acode->nch) nrerror("bad ich in arcode.");
}
else {
ja=(*codep)[*lcd]-acode->ilob[acode->nc];
for (j=acode->nc+1;j<=NWK;j++) {
ja *= acode->nrad;
ja += ((*codep)[*lcd+j-acode->nc]-acode->ilob[j]);
}
ihi=acode->nch+1;
*ich=0;
while (ihi-(*ich) > 1) {
m=(*ich+ihi)>>1;
if (ja >= JTRY(acode->jdif,acode->ncumfq[m+1],acode->ncum))
*ich=m;
else ihi=m;
}
if (*ich == acode->nch) return;
}
jh=JTRY(acode->jdif,acode->ncumfq[*ich+2],acode->ncum);
jl=JTRY(acode->jdif,acode->ncumfq[*ich+1],acode->ncum);
acode->jdif=jh-jl;
arcsum(acode->ilob,acode->iupb,jh,NWK,acode->nrad,acode->nc);
arcsum(acode->ilob,acode->ilob,jl,NWK,acode->nrad,acode->nc);
for (j=acode->nc;j<=NWK;j++) {
if (*ich != acode->nch && acode->iupb[j] != acode->ilob[j]) break;
if (*lcd > *lcode) {
fprintf(stderr,"Reached the end of the 'code' array.\n");
fprintf(stderr,"Attempting to expand its size.\n");
*lcode += *lcode/2;
if ((*codep=(unsigned char *)realloc(*codep,
(unsigned)(*lcode*sizeof(unsigned char)))) == NULL) {
nrerror("Size expansion failed");
}
}
if (isign > 0) (*codep)[*lcd]=(unsigned char)acode->ilob[j];
++(*lcd);
}
if (j > NWK) return;
acode->nc=j;
for(j=0;acode->jdif<acode->minint;j++)
acode->jdif *= acode->nrad;
if (acode->nc-j < 1) nrerror("NWK too small in arcode.");
if (j) {
for (k=acode->nc;k<=NWK;k++) {
acode->iupb[k-j]=acode->iupb[k];
acode->ilob[k-j]=acode->ilob[k];
}
}
acode->nc -= j;
for (k=NWK-j+1;k<=NWK;k++) acode->iupb[k]=acode->ilob[k]=0;
}
return;
}
#undef NWK
#undef JTRY