2025-04-27 07:49:33 -04:00

237 lines
5.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
faxdump.c
Abstract:
Extract a single page out of the fax driver output file
Environment:
Fax driver, utility
Revision History:
01/11/96 -davidx-
Created it.
mm/dd/yy -author-
description
--*/
#include "faxlib.h"
typedef PVOID PDEVDATA;
#include "faxtiff.h"
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#define ErrorExit(arg) { printf arg; exit(-1); }
VOID usage(CHAR *);
INT _cdecl
main(
INT argc,
CHAR **argv
)
{
CHAR *pProgramName, *pInputFilename, *pChar;
INT pageNumber, pageIndex;
INT infile, outfile;
CHAR outputFilename[MAX_PATH], *pOutputFilenameSuffix;
DWORD nextIFDOffset;
TIFFFILEHEADER tiffFileHeader;
pProgramName = *argv++;
argc--;
pageNumber = 1;
//
// Parse command line options
//
while (argc && (**argv == '-' || **argv == '/')) {
pChar = (*argv) + 1;
argv++; argc--;
if (isdigit(*pChar)) {
pageNumber = atoi(pChar);
} else {
usage(pProgramName);
}
}
if (argc != 1)
usage(pProgramName);
pInputFilename = *argv;
//
// Generate output filename
//
strcpy(outputFilename, pInputFilename);
pChar = outputFilename;
pOutputFilenameSuffix = NULL;
while (*pChar) {
if (*pChar == '.')
pOutputFilenameSuffix = pChar;
pChar++;
}
if (pOutputFilenameSuffix == NULL)
pOutputFilenameSuffix = pChar;
//
// Open the input file
//
if ((infile = _open(pInputFilename, O_BINARY|O_RDONLY, 0)) == -1)
ErrorExit(("Failed to open input file: %s\n", pInputFilename));
//
// Read the TIFF file header information
//
if (_read(infile, &tiffFileHeader, sizeof(tiffFileHeader)) != sizeof(tiffFileHeader) ||
tiffFileHeader.magic1 != TIFF_MAGIC1 ||
tiffFileHeader.magic2 != TIFF_MAGIC2 ||
tiffFileHeader.signature != DRIVER_SIGNATURE)
{
ErrorExit(("Not an NT fax driver output file: %s\n", pInputFilename));
}
pageIndex = 1;
nextIFDOffset = tiffFileHeader.firstIFD;
do {
FAXIFD faxIFD;
//
// Read the IFD information
//
if (_lseek(infile, nextIFDOffset - offsetof(FAXIFD, wIFDEntries), SEEK_SET) == -1)
ErrorExit(("Couldn't locate the next IFD\n"));
if (_read(infile, &faxIFD, sizeof(faxIFD)) != sizeof(faxIFD))
ErrorExit(("Couldn't read IFD entries\n"));
if (faxIFD.wIFDEntries != NUM_IFD_ENTRIES ||
faxIFD.filler != DRIVER_SIGNATURE && faxIFD.filler != 0)
{
ErrorExit(("Not an NT fax driver output file\n"));
}
nextIFDOffset = faxIFD.nextIFDOffset;
//
// Create an output TIFF file if the page number matches what's specified
//
if (pageNumber == 0 || pageNumber == LOWORD(faxIFD.ifd[IFD_PAGENUMBER].value)+1) {
LONG offset, compressedBytes, compressedDataOffset;
PBYTE pBuffer;
//
// Generate output filename
//
sprintf(pOutputFilenameSuffix, "%d.tif", pageIndex);
outfile = _open(outputFilename, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, _S_IWRITE);
if (outfile == -1)
ErrorExit(("Failed to create output file: %s\n", outputFilename));
//
// Output TIFF file header information
//
tiffFileHeader.firstIFD = sizeof(tiffFileHeader) + offsetof(FAXIFD, wIFDEntries);
if (_write(outfile, &tiffFileHeader, sizeof(tiffFileHeader)) != sizeof(tiffFileHeader))
ErrorExit(("Couldn't write TIFF file header information\n"));
//
// Munge the IFD information read from the input file
// and calculate new offsets for composite values
//
offset = sizeof(tiffFileHeader);
compressedBytes = faxIFD.ifd[IFD_STRIPBYTECOUNTS].value;
compressedDataOffset = faxIFD.ifd[IFD_STRIPOFFSETS].value;
faxIFD.ifd[IFD_PAGENUMBER].value = 0;
faxIFD.ifd[IFD_STRIPOFFSETS].value = offset + sizeof(faxIFD);
faxIFD.ifd[IFD_XRESOLUTION].value = offset + offsetof(FAXIFD, xresNum);
faxIFD.ifd[IFD_YRESOLUTION].value = offset + offsetof(FAXIFD, yresNum);
faxIFD.ifd[IFD_SOFTWARE].value = offset + offsetof(FAXIFD, software);
faxIFD.nextIFDOffset = faxIFD.filler = 0;
//
// Write new IFD information to the output file
//
if (_write(outfile, &faxIFD, sizeof(faxIFD)) != sizeof(faxIFD))
ErrorExit(("Couldn't write TIFF IFD information\n"));
//
// Copy the compressed bitmap data to the output file
//
if ((pBuffer = malloc(compressedBytes)) == NULL ||
_lseek(infile, compressedDataOffset, SEEK_SET) == -1 ||
_read(infile, pBuffer, compressedBytes) != compressedBytes ||
_write(outfile, pBuffer, compressedBytes) != compressedBytes)
{
ErrorExit(("Couldn't copy compressed bitmap data\n"));
}
free(pBuffer);
_close(outfile);
}
} while (nextIFDOffset && pageIndex++ != pageNumber);
_close(infile);
return 0;
}
VOID
usage(
CHAR *pProgramName
)
{
printf("usage: %s -N filename\n", pProgramName);
printf(" where N is the page number to be extracted\n");
printf(" use 0 to specify all pages in the file\n");
exit(-1);
}