// PCX.C - Routines for displaying PCX-files
// Written by Stefan Pfeiffer, DL1ELY, 941210
// Last modification: 950710
// (C) 1994 by Stefan Pfeiffer, DL1ELY


#include "pcx.h"
#include "egavga.h"
#include "storaxx.h"
#include <mem.h>
#include <alloc.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>

unsigned pcx_load_header(char *fname,FILE **f,struct pcx_header *h)
{
   unsigned error;

   *f = (FILE *)fopen(fname,"rb");
   if(!*f) return(0);
   fread((void *)h,1,PCX_SIZE,*f);
   if(h->id!=10) return(0);
   return(1);
};

void pcx_display(FILE *f,struct pcx_header h)
{
  char *s, *ptr;
  register unsigned char byte, len;
  register unsigned i, zeilen;
  char far *vid;
  unsigned offset, byteline;
  char *buf;
  unsigned pos, last;


  buf = lowalloc(BUFSIZE);
  last = fread(buf,1,BUFSIZE,f);
  last--;
  pos = 0;

  byteline = (xmax+1)/8;
  offset = ((ymax-(h.y2-h.y1))/2)*byteline;
  offset+= ((xmax-(h.x2-h.x1))/2)/8;

  s = lowalloc(h.ebenen*h.byte_per_line);

  for(zeilen=0;zeilen<=(h.y2-h.y1);zeilen++)
  {
    for(i=0;i<h.ebenen*h.byte_per_line;)
    {
      byte = buf[pos++];
      if(pos>last)
      {
        last = fread(buf,1,BUFSIZE,f);
        last--;
        pos = 0;
      };

      if((byte&0xC0)!=0xC0) s[i++] = byte;
      else
      {
        len = byte&0x3F;
        byte = buf[pos++];
        if(pos>last)
        {
          last = fread(buf,1,BUFSIZE,f);
          last--;
          pos = 0;
        };
        memset(s+i,byte,len);
        i+=len;
      };
    };

    ptr = s;
    vid = MK_FP(0xA000,zeilen*byteline+offset);

    for(i=0;i<h.ebenen;i++)
    {
      outp(0x3C4,2);
      outp(0x3C5,1<<i);

      _fmemcpy((void far *)vid,(void far *)ptr,h.byte_per_line);
      ptr+=h.byte_per_line;
    };
  };

  lowfree(s);
  lowfree(buf);
};


