static int	ofm_load_file(const char *filename, TFMInfo *info)
{
	int	lf, lh, bc, ec, nw, nh, nd;
	int	i, n;
	Int32	*tfm;
	Uchar	*ptr;
	int	size;
	FILE	*in;
	Int32	*cb;
	Int32	*charinfo;
	Int32	*widths;
	Int32	*heights;
	Int32	*depths;
	Uint32	checksum;
	int	olevel;
	int	nwords;

	in = fopen(filename, "rb");
	if(in == NULL)
		return -1;

	/* not a checksum, but serves a similar purpose */
	checksum = 0;
	
	/* get the counters */
	/* get file level */
	olevel = fsget2(in);
	if(olevel != 0)
		goto bad_tfm;
	olevel = fsget2(in);
	if(olevel != 0) {
		DEBUG((DBG_FONTS, "(mt) reading Level-1 OFM file `%s'\n", 
			filename));
		/* we handle level-1 files separately */
		if(ofm1_load_file(in, info) < 0)
			goto bad_tfm;
		return 0;
	}

	DEBUG((DBG_FONTS, "(mt) reading Level-0 OFM file `%s'\n", filename));
	nwords = 14;
	lf = fuget4(in); checksum  = nwords;
	lh = fuget4(in); checksum += lh;
	bc = fuget4(in); 
	ec = fuget4(in); checksum += 2 * (ec - bc + 1);
	nw = fuget4(in); checksum += nw;
	nh = fuget4(in); checksum += nh;
	nd = fuget4(in); checksum += nd;
	checksum +=   fuget4(in); /* skip italics correction count */
	checksum += 2*fuget4(in); /* skip lig/kern table size */
	checksum +=   fuget4(in); /* skip kern table size */
	checksum += 2*fuget4(in); /* skip extensible recipe count */
	checksum +=   fuget4(in); /* skip # of font parameters */

	/* I have found several .ofm files that seem to have the 
	 * font-direction word missing, so we try to detect that here */
	if(checksum == lf + 1) {
		DEBUG((DBG_FONTS, "(mt) font direction missing in `%s'\n",
			filename));
		checksum--;
		nwords--;
	} else {
		/* skip font direction */
		fuget4(in);
	}

	if(checksum != lf || bc > ec + 1 || ec > 65535)
		goto bad_tfm;

	/* now we're at the header */

	/* get the checksum */
	info->checksum = fuget4(in);
	/* get the design size */
	info->design = fuget4(in);

	/* get the coding scheme */
	if(lh > 2) {
		/* get the coding scheme */
		i = n = fsget1(in);
		if(n < 0 || n > 39) {
			mdvi_warning(_("%s: font coding scheme truncated to 40 bytes\n"),
				     filename);
			n = 39;
		}
		fread(info->coding, 39, 1, in);
		info->coding[n] = 0;
	} else
		strcpy(info->coding, "FontSpecific");
	/* get the font family */
	if(lh > 12) {
		n = fsget1(in);
		if(n > 0) {
			i = Max(n, 63);
			fread(info->family, i, 1, in);
			info->family[i] = 0;
		} else
			strcpy(info->family, "unspecified");
	}

	/* now skip anything else in the header */
	fseek(in, 4L*(nwords + lh), SEEK_SET);
	/* and read everything at once */
	size = 2*(ec - bc + 1) + nw + nh + nd;
	tfm = xnalloc(Int32, size * sizeof(Int32));
	if(fread(tfm, 4, size, in) != size) {
		mdvi_free(tfm);
		goto bad_tfm;
	}
	/* byte-swap all the tables at once */
#ifdef WORD_LITTLE_ENDIAN
	swap_array((Uint32 *)tfm, size);
#endif
	cb = tfm;
	charinfo = cb; cb += 2*(ec - bc + 1);
	widths   = cb; cb += nw;
	heights  = cb; cb += nh;
	depths   = cb;

	if(widths[0] || heights[0] || depths[0]) {
	   	mdvi_free(tfm);
		goto bad_tfm;
	}

	/* from this point on, no error checking is done */
	
	/* we don't need this anymore */
	fclose(in);

	/* now we don't read from `ptr' anymore */
	
	info->loc = bc;
	info->hic = ec;
	info->type = DviFontTFM;

	/* allocate characters */
	info->chars = xnalloc(TFMChar, size);

	/* get the relevant data */
	ptr = (Uchar *)charinfo;
	for(i = bc; i <= ec; ptr += 4, i++) {
		int	ndx;

		ndx = muget2(ptr);
		info->chars[i-bc].advance = widths[ndx];
		/* TFM files lack this information */
		info->chars[i-bc].left = 0;
		info->chars[i-bc].right = widths[ndx];
		info->chars[i-bc].present = (ndx != 0);
		ndx = muget1(ptr);
		info->chars[i-bc].height = heights[ndx];
		ndx = muget1(ptr);
		info->chars[i-bc].depth = depths[ndx];
	}

	mdvi_free(tfm);
	return 0;

bad_tfm:
	mdvi_error(_("%s: File corrupted, or not a TFM file\n"), filename);
	fclose(in);
	return -1;	
}