|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
pfbdump.c
Abstract:
dump out PFB files as ASCII text Revision History:
12/30/96 -davidx- Created it.
--*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
#include <string.h>
char *progname; char hexdigits[] = "0123456789ABCDEF"; PBYTE pOutputBuffer;
#define MAX_OUTPUT_SIZE 0x400000
PVOID MapFileIntoMemory( PSTR pFilename, PDWORD pFileSize )
{ HANDLE hFile, hFileMap; PVOID pData;
// Open a handle to the specified file
hFile = CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return NULL;
// Obtain the file size if requested
if (pFileSize != NULL) { *pFileSize = GetFileSize(hFile, NULL);
if (*pFileSize == 0xFFFFFFFF) { CloseHandle(hFile); return NULL; } }
// Map the file into memory
hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hFileMap != NULL) { pData = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); CloseHandle(hFileMap); } else pData = NULL;
// We can safely close both the file mapping object and the file object itself.
CloseHandle(hFile);
return pData; }
BOOL WriteOutputData( PSTR pFilename, PBYTE pData, DWORD size )
{ HANDLE hFile;
// open a handle to the specified file
hFile = CreateFile(pFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { fprintf(stderr, "last error = %d\n", GetLastError()); return FALSE; }
// write data to file
if (WriteFile(hFile, pData, size, &size, NULL)) { CloseHandle(hFile); return TRUE; } else { CloseHandle(hFile); DeleteFile(pFilename); return FALSE; } }
BOOL DecodePFBData( PBYTE pInput, DWORD inputSize, PBYTE pOutput, PDWORD pOutputSize )
{ PBYTE pin, pend, pout;
pin = pInput; pend = pInput + inputSize; pout = pOutput;
while (pin < pend) { INT seglen, index; BYTE segtype;
// each segment must start with 0x80
if ((pend - pin) < 2 || *pin++ != 128) return FALSE;
// check segment type
segtype = *pin++; if (segtype == 3) // EOF segment
break;
if ((pend - pin) < 4) return FALSE; seglen = ((DWORD) pin[0] ) | ((DWORD) pin[1] << 8) | ((DWORD) pin[2] << 16) | ((DWORD) pin[3] << 24);
pin += 4; if ((pend - pin) < seglen) return FALSE;
if (segtype == 1) // ASCII segment
{ // copy input data to output and
// convert CR to CR/LF combination
while (seglen--) { if ((*pout++ = *pin++) == '\r') *pout++ = '\n'; } } else if (segtype == 2) // binary segment
{ // copy binary data to hex
for (index=1; index <= seglen; index++) { *pout++ = hexdigits[*pin >> 4]; *pout++ = hexdigits[*pin & 15]; pin++;
if (index%32 == 0 || index == seglen) { *pout++ = '\r'; *pout++ = '\n'; } } } else return FALSE; }
*pOutputSize = (pout - pOutput); return TRUE; }
BOOL PFBDump( PSTR pFilename )
{ BOOL result = FALSE; PBYTE pInputData = NULL; CHAR outputFilenameBuffer[MAX_PATH]; PSTR p, pEnd; DWORD inputDataSize, outputDataSize;
// make sure the input filename ends with .pfb extension
if ((p = strrchr(pFilename, '.')) == NULL || _stricmp(p, ".pfb") != 0) { fprintf(stderr, "%s: file '%s' ignored because it doesn't have .PFB extension\n", progname, pFilename);
return FALSE; }
// map the input file into memory
if (! (pInputData = MapFileIntoMemory(pFilename, &inputDataSize))) { fprintf(stderr, "%s: couldn't open input file '%s'\n", progname, pFilename);
return FALSE; }
// decode PFB data
if (! DecodePFBData(pInputData, inputDataSize, pOutputBuffer, &outputDataSize)) { fprintf(stderr, "%s: file '%s' doesn't seem to contain valid PFB data\n", progname, pFilename);
goto exitdump; }
if (outputDataSize > MAX_OUTPUT_SIZE) { fprintf(stderr, "%s: choked on '%s' because the output file is too big\n", progname, pFilename);
exit(-1); }
// name the output file with /FontName information in the PFB file
// is there something similar to strstr() for searching a memory block?
p = pOutputBuffer; pEnd = p + outputDataSize;
while (p < pEnd) { if ((*p++ == '/') && (pEnd - p) >= 8 && memcmp(p, "FontName", 8) == 0) { p += 8;
while (p < pEnd && isspace(*p)) p++; if (p < pEnd && *p++ == '/') { PSTR s; INT len;
for (s=p; s < pEnd && !isspace(*s); s++) ;
len = s - p;
if (len > 0 && len < MAX_PATH) { CopyMemory(outputFilenameBuffer, p, len); outputFilenameBuffer[len] = '\0'; break; } }
p = pEnd; } }
if (p == pEnd) { fprintf(stderr, "%s: couldn't find FontName in PFB file '%s'\n", progname, pFilename);
goto exitdump; }
// write data to output file
if (! (result = WriteOutputData(outputFilenameBuffer, pOutputBuffer, outputDataSize))) { fprintf(stderr, "%s: couldn't write to output file '%s'\n", progname, outputFilenameBuffer); }
exitdump:
UnmapViewOfFile(pInputData); return result; }
int _cdecl main( int argc, char **argv )
{ progname = *argv++; argc--;
if (argc == 0) { fprintf(stderr, "usage: %s filename ...\n", progname); return -1; }
if (! (pOutputBuffer = malloc(MAX_OUTPUT_SIZE))) { fprintf(stderr, "%s: not enough memory\n"); return -1; }
while (argc--) PFBDump(*argv++);
free(pOutputBuffer); return 0; }
|