ftp.nice.ch/pub/next/tools/cdrom/pCD.0.34.N.bs.tar.gz#/pCD0.3.4/hpcdtoppm.0.4/format.c

This is format.c in view mode; [Download] [Up]

/* hpcdtoppm (Hadmut's pcdtoppm) v0.4
*  Copyright (c) 1992, 1993 by Hadmut Danisch (danisch@ira.uka.de).
*  Permission to use and distribute this software and its
*  documentation for noncommercial use and without fee is hereby granted,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation. It is not allowed to sell this software in 
*  any way. This software is not public domain.
*/

#include "hpcdtoppm.h"

struct pcdquad { uBYTE len,highseq,lowseq,key;};
struct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
struct myhqt { unsigned long seq,mask,len; uBYTE key; };


#define E ((unsigned long) 1)


static void readhqtsub(quelle,ziel,anzahl)
  struct pcdhqt *quelle;
  struct myhqt *ziel;
  int *anzahl;
 {int i;
  struct pcdquad *sub;
  struct myhqt *help;
  *anzahl=(quelle->entries)+1;

  for(i=0;i<*anzahl;i++)
   {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
    help=ziel+i;

    help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
    help->len = ((unsigned long) sub->len) +1;
    help->key = sub->key;

#ifdef DEBUGhuff
   fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
          *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
          help->seq,help->len,sizeof(uBYTE));
#endif

    if(help->len > 16) error(E_HUFF);

    help->mask = ~ ( (E << (32-help->len)) -1); 

  }
#ifdef DEBUG
  for(i=0;i<*anzahl;i++)
   {help=ziel+i;
    fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
        i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
        help->seq & (~help->mask));
   }
#endif

}

#undef E





static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
static int          myhufflen0=0,myhufflen1=0,myhufflen2=0;

void readhqt(w,h,n)
  dim w,h;
  int n;
 {
  uBYTE *ptr;

  melde("readhqt\n");
  EREADBUF;
  ptr = sbuffer;

  readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);

  if(n<2) return;
  ptr+= 1 + 4* myhufflen0;
  readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);

  if(n<3) return;
  ptr+= 1 + 4* myhufflen1;
  readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);

}







#ifdef FASTHUFF

static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
static void inithuff(hlen,ptr,TAB)
  int hlen;
  struct myhqt *ptr,*TAB[];
 {int i,n;
  long seq,len;
  struct myhqt *help;

  for(i=0;i<0x10000;i++) TAB[i]=0;

  for(n=0;n<hlen;n++)
   {help=ptr+n;
    seq=(help->seq)>>16;
    len=help->len;

    for(i=0;i<(1<<(16-len));i++)
      TAB[seq | i] = help;
   }
 }
#endif




static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};


void decode(w,h,f,f1,f2,autosync)
  dim w,h;
  implane *f,*f1,*f2;
  int autosync;
 {int htlen,sum,do_inform,part;
  unsigned long sreg,maxwidth;
  unsigned int inh,n,zeile,segment,ident;
  struct myhqt *hp;

  uBYTE *nptr;
  uBYTE *lptr;

#define nextbuf  {  nptr=sbuffer;  EREADBUF; }
#define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
#define shiftout(n){ sreg<<=n; inh-=n; \
                     while (inh<=24) \
                      {checkbuf; \
                       sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
                       inh+=8;\
                      }\
                    }  
#define issync     ((sreg & 0xffffff00) == 0xfffffe00) 
#define brutesync  ((sreg & 0x00fff000) == 0x00fff000) 
#define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}

#ifdef FASTHUFF
  struct myhqt **HTAB;
  HTAB=0;
  inithuff(myhufflen0,myhuff0,HTAB0);
  inithuff(myhufflen1,myhuff1,HTAB1);
  inithuff(myhufflen2,myhuff2,HTAB2);
#define SETHUFF0 HTAB=HTAB0;
#define SETHUFF1 HTAB=HTAB1;
#define SETHUFF2 HTAB=HTAB2;
#define FINDHUFF(x) {x=HTAB[sreg>>16];}

#else

  int i;
  struct myhqt *htptr;
  htptr=0;
#define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
#define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
#define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
#define FINDHUFF(x)  {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
                      if(i>=htlen) x=0;}
#endif

  melde("decode\n");

  if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);

  htlen=sreg=maxwidth=0;
  zeile=0;
  nextbuf;
  inh=32;
  lptr=0;
  part=do_inform=0;
  shiftout(16);
  shiftout(16);

  if(autosync) seeksync;

  n=0;
  for(;;)
   {
    if (issync)
     {shiftout(24);
      ident=sreg>>16;
      shiftout(16);

      zeile=(ident>>1) & 0x1fff;
      segment=ident>>14;
      if(do_inform) {fprintf(stderr,"Synchron mark found Line %u\n",zeile);do_inform=0;}
#ifdef DEBUG
      fprintf(stderr,"Id %4x Zeile: %6u Seg %3d Pix bisher: %5d  Position: %8lx+%5lx=%8x\n",
          ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
#endif


      if(lptr && (n!=maxwidth)) 
       {if(!do_rep)error(E_SEQ1);
        else fprintf(stderr,"Line %u in %s : wrong length of last line (%u)\n",zeile,pn[part],n);
       }
      n=0;

      if(zeile==h) {RPRINT; return; }
      if(zeile >h) error(E_SEQ2);

      switch(segment)
       {
        case 0: if((!f) && autosync) {seeksync; break;}
                if(!f) error(E_SEQ7);
                lptr=f->im + zeile*f->mwidth;
                maxwidth=f->iwidth;
                SETHUFF0;
                part=0;
                break;

        case 2: if((!f1) && autosync) {seeksync; break;}
                if(!f1) return;
                if(!f1) error(E_SEQ7);
                lptr=f1->im + (zeile>>1)*f1->mwidth;
                maxwidth=f1->iwidth;
                SETHUFF1;
                part=1;
                break;
 
        case 3: if((!f2) && autosync) {seeksync; break;}
                if(!f2) return;
                if(!f2) error(E_SEQ7);
                lptr=f2->im + (zeile>>1)*f2->mwidth;
                maxwidth=f2->iwidth;
                SETHUFF2;
                part=2;
                break;

        default:error(E_SEQ3);
	}
     }
    else
     {


      if(!lptr)      error(E_SEQ6);
      if(n>maxwidth) 
        {
#ifdef DEBUG
         fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
#endif
         if (!do_rep) error(E_SEQ4);
         else { fprintf(stderr,"Missing synchron mark in %s line %u\n",pn[part],zeile);
                seeksync;
                do_inform=1;
                n=maxwidth;
              }
       }
      else
       {FINDHUFF(hp);
        if(!hp) error(E_SEQ5);

        sum=((int)(*lptr)) + ((sBYTE)hp->key);
        NORM(sum);
        *(lptr++) = sum;

        n++; 
        shiftout(hp->len);
       }
     }

   }


#undef nextbuf  
#undef checkbuf 
#undef shiftout
#undef issync
#undef seeksync

 }








enum ERRORS readplain(fpcd,w,h,l,c1,c2)
  FILE *fpcd;
  dim w,h;
  implane *l,*c1,*c2;
 {dim i;
  uBYTE *pl=0,*pc1=0,*pc2=0;
  melde("readplain\n");

  if(l)
   { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
     l->iwidth=w;
     l->iheight=h;
     pl=l->im;
   }

  if(c1)
   { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
     c1->iwidth=w/2;
     c1->iheight=h/2;
     pc1=c1->im;
   }

  if(c2)
   { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
     c2->iwidth=w/2;
     c2->iheight=h/2;
     pc2=c2->im;
   }

  for(i=0;i<h/2;i++)
   {
    if(pl)
     { 
       if(fread(pl,w,1,fpcd)<1) return(E_READ);
       pl+= l->mwidth;

       if(fread(pl,w,1,fpcd)<1) return(E_READ);
       pl+= l->mwidth;
     }
    else SKIPr(2*w);
     
    if(pc1)
     { if(fread(pc1,w/2,1,fpcd)<1) return(E_READ);
       pc1+= c1->mwidth;
     }
    else SKIPr(w/2);
     
    if(pc2)
     { if(fread(pc2,w/2,1,fpcd)<1) return(E_READ);
       pc2+= c2->mwidth;
     }
    else SKIPr(w/2);


   }
  RPRINT;
  return E_NONE;
 }

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.