Back to index

tetex-bin  3.0
Defines | Functions | Variables
dvi.c File Reference
#include "dvipng.h"
#include <sys/stat.h>

Go to the source code of this file.

Defines

#define basename   xbasename
#define SLEEP   sleep(1)

Functions

bool DVIFollowToggle ()
static unsigned char fgetc_follow (FILE *fp)
void DVIInit (struct dvi_data *dvi)
struct dvi_dataDVIOpen (char *dviname, char *outname)
unsigned char * DVIGetCommand (struct dvi_data *dvi)
uint32_t CommandLength (unsigned char *command)
void SkipPage (struct dvi_data *dvi)
struct page_listInitPage (struct dvi_data *dvi)
int SeekPage (struct dvi_data *dvi, struct page_list *page)
struct page_listNextPage (struct dvi_data *dvi, struct page_list *page)
struct page_listPrevPage (struct dvi_data *dvi, struct page_list *page)
struct page_listFindPage (struct dvi_data *dvi, int32_t pagenum, bool abspage)
void DelPageList (struct dvi_data *dvi)
void DVIClose (struct dvi_data *dvi)
bool DVIReOpen (struct dvi_data *dvi)

Variables

bool followmode = 0

Define Documentation

#define basename   xbasename

Definition at line 34 of file dvi.c.

#define SLEEP   sleep(1)

Definition at line 36 of file dvi.c.


Function Documentation

uint32_t CommandLength ( unsigned char *  command)

Definition at line 222 of file dvi.c.

{ 
  /* generally 2^32+5 bytes max, but in practice 32 bit numbers suffice */
  uint32_t length=0;

  length = dvi_commandlength[*command];
  switch (*command)  {
  case XXX1: case XXX2: case XXX3: case XXX4: 
    length += UNumRead(command + 1,length - 1);
    break;
  case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: 
    length += *(command + length - 1) + *(command + length - 2);
    break;
  case PRE: 
    length += *(command + length - 1);
    break;
  }
  return(length);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void DelPageList ( struct dvi_data dvi)

Definition at line 394 of file dvi.c.

{
  struct page_list* temp;
  
  /* Delete the page list */

  temp=dvi->pagelistp;
  while(temp!=NULL) {
    dvi->pagelistp=dvi->pagelistp->next;
    free(temp);
    temp=dvi->pagelistp;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void DVIClose ( struct dvi_data dvi)

Definition at line 408 of file dvi.c.

{
  if (dvi!=NULL) {
    fclose(dvi->filep);
    DelPageList(dvi);
    free(dvi->outname);
    free(dvi->name);
    free(dvi);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 42 of file dvi.c.

{
  return followmode = ! followmode;
}

Here is the caller graph for this function:

unsigned char* DVIGetCommand ( struct dvi_data dvi)

Definition at line 167 of file dvi.c.

{ 
  static unsigned char command[STRSIZE];
  static unsigned char* lcommand = command;
  unsigned char *current = command;
  int length;
  uint32_t strlength=0;

  DEBUG_PRINT(DEBUG_DVI,("\n@%ld ", ftell(dvi->filep)));
  *(current++) = fgetc_follow(dvi->filep);
  length = dvi_commandlength[*command];
  if (length < 0)
    Fatal("undefined DVI op-code %d",*command);
  while(current < command+length) 
    *(current++) = fgetc_follow(dvi->filep);
  switch (*command)  {
  case XXX4:
    strlength =                   *(current - 4);
  case XXX3:
    strlength = strlength * 256 + *(current - 3);
  case XXX2: 
    strlength = strlength * 256 + *(current - 2);
  case XXX1:
    strlength = strlength * 256 + *(current - 1);
    break;
  case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
    strlength = *(current - 1) + *(current - 2);
    break;
  case PRE: 
    strlength = *(current - 1);
    break;
  }
  if (strlength > 0) { /* Read string */
    if (lcommand!=command) {
      free(lcommand);
      lcommand=command;
    }
    if (strlength + (uint32_t)length >  (uint32_t)STRSIZE) {
      /* string + command length exceeds that of buffer */
      if ((lcommand=malloc(length+strlength+1))==NULL) 
       Fatal("cannot allocate memory for DVI command");
      memcpy(lcommand,command,length);
      current = lcommand + length;
    }
    while(current < lcommand+length+strlength) 
      *(current++) = fgetc_follow(dvi->filep);
    return(lcommand);
  } else
    return(command);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void DVIInit ( struct dvi_data dvi)

Definition at line 60 of file dvi.c.

{
  int     k;
  unsigned char* pre;
  struct stat stat;

  fseek(dvi->filep,0,SEEK_SET);
  pre=DVIGetCommand(dvi);
  if (*pre != PRE) {
    Fatal("PRE doesn't occur first--are you sure this is a DVI file?\n\n");
  }
  k = UNumRead(pre+1,1);
  DEBUG_PRINT(DEBUG_DVI,("DVI START:\tPRE %d",k));
  if (k != DVIFORMAT) {
    Fatal("DVI format = %d, can only process DVI format %d files\n\n",
         k, DVIFORMAT);
  }
  dvi->num = UNumRead(pre+2, 4);
  dvi->den = UNumRead(pre+6, 4);
  DEBUG_PRINT(DEBUG_DVI,(" %d/%d",dvi->num,dvi->den));
  dvi->mag = UNumRead(pre+10, 4); /*FIXME, see font.c*/
  DEBUG_PRINT(DEBUG_DVI,(" %d",dvi->mag));
  if ( usermag > 0 && usermag != dvi->mag ) {
    Warning("DVI magnification of %d over-ridden by user (%ld)",
           (long)dvi->mag, usermag );
    dvi->mag = usermag;
  }
  dvi->conv = (1.0/(((double)dvi->num / (double)dvi->den) *
                  ((double)dvi->mag / 1000.0) *
                  ((double)dpi*shrinkfactor/254000.0)))+0.5;
  DEBUG_PRINT(DEBUG_DVI,(" (%d)",dvi->conv));
  k = UNumRead(pre+14,1);
  DEBUG_PRINT(DEBUG_DVI,(" '%.*s'",k,pre+15));
  Message(BE_VERBOSE,"'%.*s' -> %s\n",k,pre+15,dvi->outname);
  fstat(fileno(dvi->filep), &stat);
  dvi->mtime = stat.st_mtime;
  dvi->pagelistp=NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct dvi_data* DVIOpen ( char *  dviname,
char *  outname 
) [read]

Definition at line 99 of file dvi.c.

{
  char* tmpstring;
  struct dvi_data* dvi;

  if ((dvi = calloc(1,sizeof(struct dvi_data)))==NULL)
    Fatal("cannot allocate memory for dvi struct");

  dvi->type = DVI_TYPE;
  dvi->fontnump=NULL;

  dvi->name = malloc(strlen(dviname)+5);
  if (dvi->name==NULL)
    Fatal("cannot allocate space for DVI filename");
  strcpy(dvi->name, dviname);
  tmpstring = strrchr(dvi->name, '.');
  if (tmpstring == NULL || strcmp(tmpstring,".dvi") != 0) 
    strcat(dvi->name, ".dvi");
  
  if (outname==NULL) { 
    dvi->outname = malloc(strlen(basename(dviname))+7);
    if (dvi->outname==NULL) {
      free(dvi->name);
      free(dvi);
      Fatal("cannot allocate space for output filename");
    }
    strcpy(dvi->outname,basename(dviname));
    tmpstring = strrchr(dvi->outname, '.');
    if (tmpstring != NULL) 
      *tmpstring = '\0';
    strcat(dvi->outname, "%d.png");
  } else {
    dvi->outname = malloc(strlen(outname)+1);
    if (dvi->outname==NULL) {
      free(dvi->name);
      free(dvi);
      Fatal("cannot allocate space for output filename");
    }
    strcpy(dvi->outname,outname);
  }

  if ((dvi->filep = fopen(dvi->name,"rb")) == NULL) {
    /* do not insist on .dvi */
    tmpstring = strrchr(dvi->name, '.');
    *tmpstring='\0';
    dvi->filep = fopen(dvi->name,"rb");
  }
  while((dvi->filep == NULL) && followmode) {
    SLEEP;
    *tmpstring='.';
    if ((dvi->filep = fopen(dvi->name,"rb")) == NULL) {
      /* do not insist on .dvi */
      *tmpstring='\0';
      dvi->filep = fopen(dvi->name,"rb");
    }
  }
  if (dvi->filep == NULL) {
    free(dvi->name);
    free(dvi->outname);
    free(dvi);
    perror(dviname);
    exit (EXIT_FAILURE);
  }
  DEBUG_PRINT(DEBUG_DVI,("OPEN FILE\t%s", dvi->name));
  DVIInit(dvi);
  return(dvi);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool DVIReOpen ( struct dvi_data dvi)

Definition at line 419 of file dvi.c.

{
  struct stat stat;
  fstat(fileno(dvi->filep), &stat);
  if (dvi->mtime != stat.st_mtime) {
    fclose(dvi->filep);
    dvi->filep=NULL;
    DelPageList(dvi);
    while(((dvi->filep = fopen(dvi->name,"rb")) == NULL) && followmode) {
      SLEEP;
    }
    if (dvi->filep == NULL) {
      perror(dvi->name);
      exit(EXIT_FAILURE);
    }
    Message(PARSE_STDIN,"Reopened file\n");
    DEBUG_PRINT(DEBUG_DVI,("\nREOPEN FILE\t%s", dvi->name));
    DVIInit(dvi);
    return(true);
  }
  return(false);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char fgetc_follow ( FILE fp) [static]

Definition at line 47 of file dvi.c.

{
  int got=fgetc(fp);

  while(followmode && got==EOF) {
    SLEEP;
    got=fgetc(fp);
  }
  if (got==EOF)
    Fatal("DVI file ends prematurely");
  return (unsigned char)got;
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct page_list* FindPage ( struct dvi_data dvi,
int32_t  pagenum,
bool  abspage 
) [read]

Definition at line 375 of file dvi.c.

{
  struct page_list* page=NextPage(dvi, NULL);
  
  if (pagenum==PAGE_LASTPAGE || pagenum==PAGE_POST) {
    while(page!=NULL && page->count[0]!=PAGE_POST)
      page=NextPage(dvi,page);
    if (pagenum==PAGE_LASTPAGE)
      page=PrevPage(dvi,page);
  } else
    if (pagenum!=PAGE_FIRSTPAGE) 
      while(page != NULL && pagenum != page->count[abspage ? 0 : 10])
       page=NextPage(dvi,page);
  return(page);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct page_list* InitPage ( struct dvi_data dvi) [read]

Definition at line 274 of file dvi.c.

{
  /* Find page start, return pointer to page_list entry if found */
  struct page_list* tpagelistp=NULL;
  unsigned char* command;           

  command=DVIGetCommand(dvi);
  /* Skip until page start or postamble */
  while((*command != BOP) && (*command != POST)) {
    switch(*command) {
    case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
      DEBUG_PRINT(DEBUG_DVI,("NOPAGE CMD:\t%s", dvi_commands[*command]));
      FontDef(command,dvi);
      break;
    case NOP:
      DEBUG_PRINT(DEBUG_DVI,("NOPAGE CMD:\tNOP"));
      break;
    default:
      Fatal("%s occurs outside page", dvi_commands[*command]);
    }
    command=DVIGetCommand(dvi);
  }
  if ((tpagelistp = 
       malloc(sizeof(struct page_list)+(csp+1-2)*sizeof(struct dvi_color)))==NULL)
    Fatal("cannot allocate memory for new page entry");
  tpagelistp->next = NULL;
  if ( *command == BOP ) {  /*  Init page */
    int i;
    DEBUG_PRINT(DEBUG_DVI,("PAGE START:\tBOP"));
    StoreColorStack(tpagelistp);
    tpagelistp->offset = ftell(dvi->filep)-45;
    for (i = 0; i <= 9; i++) {
      tpagelistp->count[i] = UNumRead(command + 1 + i*4, 4);
      DEBUG_PRINT(DEBUG_DVI,(" %d",tpagelistp->count[i]));
    }
    if (dvi->pagelistp==NULL) 
      tpagelistp->count[10] = 1;
    else
      tpagelistp->count[10] = dvi->pagelistp->count[10]+1;
    DEBUG_PRINT(DEBUG_DVI,(" (%d)", tpagelistp->count[10]));
  } else {
    DEBUG_PRINT(DEBUG_DVI,("DVI END:\tPOST"));
    tpagelistp->offset = ftell(dvi->filep)-1;
    tpagelistp->count[0] = PAGE_POST; /* POST */
    tpagelistp->count[10] = PAGE_POST; /* POST */
  }
  return(tpagelistp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct page_list* NextPage ( struct dvi_data dvi,
struct page_list page 
) [read]

Definition at line 331 of file dvi.c.

{
  struct page_list* tpagelistp;

  /* if page points to POST there is no next page */
  if (page!=NULL && page->count[0]==PAGE_POST) 
    return(NULL);

  /* If we have read past the last page in our current list or the
   *  list is empty, sneak a look at the next page
   */
  if (dvi->pagelistp==NULL
      || dvi->pagelistp->offset+45L < ftell(dvi->filep)) {
    tpagelistp=dvi->pagelistp;
    dvi->pagelistp=InitPage(dvi);
    dvi->pagelistp->next=tpagelistp;
  }

  if (page!=dvi->pagelistp) {
    /* also works if page==NULL, we'll get the first page then */
    tpagelistp=dvi->pagelistp;
    while(tpagelistp!=NULL && tpagelistp->next!=page)
      tpagelistp=tpagelistp->next;
  } else {
    /* dvi->pagelistp points to the last page we've read so far,
     * the last page that we know where it is, so to speak
     * So look at the next
     */
    (void)SeekPage(dvi,dvi->pagelistp);
    SkipPage(dvi);
    tpagelistp=dvi->pagelistp;
    dvi->pagelistp=InitPage(dvi);
    dvi->pagelistp->next=tpagelistp;
    tpagelistp=dvi->pagelistp;
  }
  return(tpagelistp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct page_list* PrevPage ( struct dvi_data dvi,
struct page_list page 
) [read]

Definition at line 369 of file dvi.c.

{
  return(page->next);
}

Here is the caller graph for this function:

int SeekPage ( struct dvi_data dvi,
struct page_list page 
)

Definition at line 323 of file dvi.c.

{
  ReadColorStack(page);
  return(fseek(dvi->filep, 
              page->offset+((page->count[0]==PAGE_POST) ? 1L : 45L),
              SEEK_SET));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SkipPage ( struct dvi_data dvi)

Definition at line 242 of file dvi.c.

{ 
  /* Skip present page */
  unsigned char* command;           

  command=DVIGetCommand(dvi);
  while (*command != EOP)  {
    switch (*command)  {
    case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4:
      DEBUG_PRINT(DEBUG_DVI,("NOSKIP CMD:\t%s", dvi_commands[*command]));
      FontDef(command,dvi);
      break;
    case XXX1: case XXX2: case XXX3: case XXX4:
      DEBUG_PRINT(DEBUG_DVI,("NOSKIP CMD:\t%s %d", dvi_commands[*command],
                          UNumRead(command+1, dvi_commandlength[*command]-1)));
      SetSpecial((char*)command + dvi_commandlength[*command], 
               UNumRead(command+1, dvi_commandlength[*command]-1),
               0,0);
      break;
    case BOP: case PRE: case POST: case POST_POST:
      Fatal("%s occurs within page", dvi_commands[*command]);
      break;
#ifdef DEBUG
    default:
      DEBUG_PRINT(DEBUG_DVI,("SKIP CMD:\t%s", dvi_commands[*command]));
#endif
    }
    command=DVIGetCommand(dvi);
  } /* while */
  DEBUG_PRINT(DEBUG_DVI,("SKIP CMD:\t%s", dvi_commands[*command]));
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 40 of file dvi.c.