/************************************************************/
/*         File Name: MIS.c                                 */
/*         Package:   NIST Multiple Image Set Utilities     */
/*                                                          */
/*         Contents:  Extractmis()                          */
/*                    Fragmis()                             */
/*                    Freemis()                             */
/*                    Readmisfile()                         */
/*                    Xtrctmis()                            */
/************************************************************/
#include <stdio.h>
#include <sys/param.h>
#include <memory.h>
#include <sys/types.h>
#include <ihead.h>
#include <mis.h>

/************************************************************/
unsigned char *extractmis(mis,n)
MIS *mis;
int n;
{
   unsigned char *rbuf;
   char index[BUFSIZ];
   int depth, entlen, mislen;

   if ((n < 0) || (n >= mis->ent_num)){
        sprintf(index,"%d",n);
	fatalerr("extractmis","bad index",index);
   }

   if (mis->misw != mis->entw){
	sprintf(index,"mis width %d != image width %d", mis->misw, mis->entw);
	fatalerr("extractmis",index,(char *)NULL);
   }

   if (mis->mish != mis->ent_alloc * mis->enth)
	fatalerr("extractmis",
              "mis height != mis entries*image height",(char *)NULL);
   sscanf(mis->head->depth, "%d", &depth);
   entlen = SizeFromDepth(mis->entw,mis->enth,depth);
   mislen = SizeFromDepth(mis->misw,n*mis->enth,depth);
   if (entlen < 1)
      fatalerr("extractmis","size < 1",NULL);
   rbuf = (u_char *) malloc((u_int)entlen);
   if (rbuf == (u_char *) NULL)
	syserr("extractmis","malloc","rbuf");
   memcpy(rbuf,mis->data+mislen,entlen);
   return(rbuf);
}

/************************************************************/
void fragmis(misfile,rootname)
char *misfile, *rootname;
{ 
  MIS *mis;
  char filename[MAXPATHLEN];
  IHEAD itemhead;
  unsigned char *itemdata;
  int i;
  
  mis = readmisfile(misfile);

  memcpy(&itemhead,mis->head,sizeof(IHEAD));
  sprintf(itemhead.width,"%d",mis->entw);
  sprintf(itemhead.height,"%d",mis->enth);
  *(itemhead.parent) = NULL;
  sprintf(itemhead.par_x,"0");
  sprintf(itemhead.par_y,"0");
  sprintf(itemhead.compress, "%d", UNCOMP);
  sprintf(itemhead.complen,"0");
  for(i = 0; i < mis->ent_num; i++){
     sprintf(filename, "%s_%03d.pct", rootname, i);
     itemdata = extractmis(mis, i);
     if(strlen(filename) >= BUFSIZE)
        fatalerr("fragmis","Output file overflow", filename);
     strcpy(itemhead.id,filename);
     strcpy(itemhead.created,current_time());
     writeihdrfile(filename,&itemhead,itemdata);
     free(itemdata);
  }
  freemis(mis);
}

/************************************************************/
void freemis(mis)
MIS *mis;
{
  free((char *)mis->head);
  free((char *)mis->data);
  free((char *)mis);
}

/************************************************************/
MIS *readmisfile(file)
char *file;
{
   MIS *mis;
   IHEAD *head;
   unsigned char *buf;
   int misw, mish, misd, entw, enth, ent_num;

   readihdrfile(file,&head,&buf,&misw,&mish,&misd);
   if (sscanf(head->par_x,"%d",&entw) != 1)
	fatalerr("readmisfile",file,"cannot read entry width from par_x field");
   if (sscanf(head->par_y,"%d",&enth) != 1)
	fatalerr("readmisfile",file,"cannot read entry height from par_y field");
   if ((misw <= 0) || (mish <= 0))
	fatalerr("readmisfile",file,"bad MIS dimension(s)");
   if ((entw <= 0) || (enth <= 0))
	fatalerr("readmisfile",file,"bad entry dimension(s)");
   if (entw != misw)
	fatalerr("readmisfile",file,"MIS width != entry width");
   if (mish % enth != 0)
	fatalerr("readmisfile",file,"MIS height not a multiplt of entry height");
   ent_num = mish / enth;
   if((mis = (MIS *)malloc(sizeof(MIS))) == NULL)
      syserr("readmisfile","malloc","mis");
   mis->head = head;
   mis->data = buf;
   mis->misw = misw;
   mis->mish = mish;
   mis->entw = entw;
   mis->enth = enth;
   mis->ent_num = ent_num;
   mis->ent_alloc = ent_num;
   return(mis);
}

/************************************************************/
void xtrctmis(misfile, outfile, index)
char *misfile, *outfile;
int index;
{ 
  MIS *mis;
  IHEAD itemhead;
  unsigned char *itemdata;
  
  mis = readmisfile(misfile);

  memcpy(&itemhead,mis->head,sizeof(IHEAD));
  sprintf(itemhead.width,"%d",mis->entw);
  sprintf(itemhead.height,"%d",mis->enth);
  *(itemhead.parent) = NULL;
  sprintf(itemhead.par_x,"0");
  sprintf(itemhead.par_y,"0");
  sprintf(itemhead.compress, "%d", UNCOMP);
  sprintf(itemhead.complen,"0");
  itemdata = extractmis(mis, index);
  if(strlen(outfile) >= BUFSIZE)
     fatalerr("xtrctmis","Output file overflow", outfile);
  strcpy(itemhead.id,outfile);
  strcpy(itemhead.created,current_time());
  writeihdrfile(outfile,&itemhead,itemdata);
  free(itemdata);
  freemis(mis);
}
