You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
403 lines
12 KiB
403 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tx_thrd.c
|
|
|
|
Abstract:
|
|
|
|
This module implements MMR->MR and MMR->MH conversion in a separate thread.
|
|
|
|
Author:
|
|
|
|
Rafael Lisitsa (RafaelL) 14-Aug-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
|
|
|
|
#include "prep.h"
|
|
|
|
#include "efaxcb.h"
|
|
#include "t30.h"
|
|
#include "hdlc.h"
|
|
#include "debug.h"
|
|
|
|
#include "tiff.h"
|
|
|
|
#include "glbproto.h"
|
|
#include "t30gl.h"
|
|
|
|
// Don't want to limit time to transmit page
|
|
#define WAIT_FOR_NEXT_STRIP_TX_TIMEOUT INFINITE
|
|
|
|
// Max size for converted page
|
|
#define MAX_CONVERTED_SIZE 3000000
|
|
|
|
DWORD
|
|
TiffConvertThread
|
|
(
|
|
PThrdGlbl pTG
|
|
)
|
|
{
|
|
DWORD tiffCompression = pTG->TiffConvertThreadParams.tiffCompression;
|
|
BOOL NegotHiRes = pTG->TiffConvertThreadParams.HiRes;
|
|
BOOL SrcHiRes = pTG->SrcHiRes;
|
|
char OutFileName[_MAX_FNAME];
|
|
HANDLE OutFileHandle;
|
|
DWORD *lpdwOutputBuffer = NULL;
|
|
DWORD dwBytesWritten;
|
|
DWORD dwSizeOutputBuffer = 500000;
|
|
DWORD dwUsedSizeOutputBuffer;
|
|
DWORD StripDataSize;
|
|
DWORD NumHandles=2;
|
|
HANDLE HandlesArray[2];
|
|
DWORD WaitResult;
|
|
DWORD RetCode = FALSE;
|
|
BOOL fOutFileNeedsBeClosed = 0;
|
|
BOOL fResScan = 0;
|
|
|
|
DEBUG_FUNCTION_NAME(_T("TiffConvertThread"));
|
|
|
|
HandlesArray[0] = pTG->AbortReqEvent;
|
|
HandlesArray[1] = pTG->ThrdSignal;
|
|
|
|
lpdwOutputBuffer = (DWORD *) VirtualAlloc(
|
|
NULL,
|
|
dwSizeOutputBuffer,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
|
|
if (! lpdwOutputBuffer)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "lpdwOutputBuffer can't VirtualAlloc");
|
|
goto l_exit;
|
|
}
|
|
|
|
//
|
|
// Set the appropriate PRTY for this thread
|
|
// I/O threads run at 15. TIFF - at 9...11
|
|
//
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"NegotHiRes=%d SrcHiRes=%d Started",
|
|
NegotHiRes,
|
|
SrcHiRes);
|
|
|
|
if (! SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST) )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SetThreadPriority HIGHEST failed le=%x",
|
|
GetLastError() );
|
|
goto l_exit;
|
|
}
|
|
|
|
// need test below to make sure that pTG is still valid
|
|
if (pTG->ReqTerminate)
|
|
{
|
|
goto l_exit;
|
|
}
|
|
|
|
//
|
|
// TIFF file was already opened in FaxDevSendA
|
|
// in order to get the YResolution tag to negotiate resolution.
|
|
//
|
|
pTG->CurrentOut = 1;
|
|
|
|
//
|
|
// loop thru all pages
|
|
//
|
|
|
|
do
|
|
{
|
|
pTG->fTiffPageDone = 0;
|
|
|
|
_fmemcpy (OutFileName, gT30.TmpDirectory, gT30.dwLengthTmpDirectory);
|
|
_fmemcpy (&OutFileName[gT30.dwLengthTmpDirectory], pTG->TiffConvertThreadParams.lpszLineID, 8);
|
|
sprintf( &OutFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->CurrentOut);
|
|
|
|
if ( ( OutFileHandle = CreateFileA( OutFileName,
|
|
GENERIC_WRITE,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
0,
|
|
NULL) ) == INVALID_HANDLE_VALUE )
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"ec: %lx CREATING file %s",
|
|
GetLastError(),
|
|
OutFileName);
|
|
goto l_exit;
|
|
}
|
|
|
|
fOutFileNeedsBeClosed = 1;
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Page %d started",
|
|
pTG->CurrentOut);
|
|
|
|
if (! TiffSeekToPage( pTG->Inst.hfile, pTG->CurrentOut, FILLORDER_LSB2MSB ) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "seeking to page");
|
|
goto l_exit;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_MSG, "TIFF_TX: Tiff seeking to page -OK");
|
|
}
|
|
|
|
//
|
|
// check the current page dimensions. Add memory if needed.
|
|
//
|
|
|
|
TiffGetCurrentPageData( pTG->Inst.hfile,
|
|
NULL,
|
|
&StripDataSize,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (StripDataSize > 1500000)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"Tiff CONVERTING %d page StripSize = %d",
|
|
pTG->CurrentOut,
|
|
StripDataSize);
|
|
goto l_exit;
|
|
}
|
|
|
|
// convert-reallocate loop
|
|
do
|
|
{
|
|
dwUsedSizeOutputBuffer = dwSizeOutputBuffer;
|
|
|
|
if (tiffCompression == TIFF_COMPRESSION_MR)
|
|
{
|
|
if (NegotHiRes == SrcHiRes)
|
|
{
|
|
fResScan = ConvMmrPageToMrSameRes ( pTG->Inst.hfile,
|
|
lpdwOutputBuffer,
|
|
&dwUsedSizeOutputBuffer,
|
|
NegotHiRes);
|
|
}
|
|
else
|
|
{
|
|
fResScan = ConvMmrPageHiResToMrLoRes ( pTG->Inst.hfile,
|
|
lpdwOutputBuffer,
|
|
&dwUsedSizeOutputBuffer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fResScan = ConvMmrPageToMh ( pTG->Inst.hfile,
|
|
lpdwOutputBuffer,
|
|
&dwUsedSizeOutputBuffer,
|
|
NegotHiRes,
|
|
SrcHiRes);
|
|
}
|
|
if (!fResScan)
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
|
|
if ((dwLastError==ERROR_INSUFFICIENT_BUFFER) && (dwSizeOutputBuffer < MAX_CONVERTED_SIZE))
|
|
{
|
|
// Buffer was too small, reallocate bigger buffer
|
|
if (!VirtualFree(lpdwOutputBuffer, 0 , MEM_RELEASE))
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "VirtualFree failed, LE=%d", GetLastError());
|
|
goto l_exit;
|
|
}
|
|
lpdwOutputBuffer = NULL;
|
|
|
|
dwSizeOutputBuffer += 500000;
|
|
DebugPrintEx(DEBUG_MSG, "CONVERTING %d page, LE=%d, reallocating %d bytes",
|
|
pTG->CurrentOut, dwLastError, dwSizeOutputBuffer);
|
|
|
|
lpdwOutputBuffer = (DWORD *) VirtualAlloc(
|
|
NULL,
|
|
dwSizeOutputBuffer,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
if (! lpdwOutputBuffer)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"lpdwOutputBuffer can't VirtualAlloc %d",
|
|
dwSizeOutputBuffer);
|
|
goto l_exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "CONVERTING %d page, LE=%d", pTG->CurrentOut, dwLastError);
|
|
goto l_exit;
|
|
}
|
|
}
|
|
} while (!fResScan);
|
|
|
|
|
|
if ( ( ! WriteFile(OutFileHandle, (BYTE *) lpdwOutputBuffer, dwUsedSizeOutputBuffer, &dwBytesWritten, NULL) ) ||
|
|
(dwUsedSizeOutputBuffer != dwBytesWritten ) )
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "Tiff writing file %s", OutFileName);
|
|
goto l_exit;
|
|
}
|
|
|
|
if ( ! CloseHandle(OutFileHandle) )
|
|
{
|
|
fOutFileNeedsBeClosed = 0;
|
|
DebugPrintEx(DEBUG_ERR, "Tiff closing file %s", OutFileName);
|
|
goto l_exit;
|
|
}
|
|
|
|
fOutFileNeedsBeClosed = 0;
|
|
|
|
pTG->fTiffPageDone = 1;
|
|
|
|
if (!SetEvent(pTG->FirstPageReadyTxSignal))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SetEvent(0x%lx) returns failure code: %ld",
|
|
(ULONG_PTR)pTG->FirstPageReadyTxSignal,
|
|
(long) GetLastError());
|
|
RetCode = FALSE;
|
|
goto l_exit;
|
|
}
|
|
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Done page %d size=%d",
|
|
pTG->CurrentOut,
|
|
dwUsedSizeOutputBuffer);
|
|
|
|
if (!pTG->FirstOut)
|
|
{
|
|
pTG->FirstOut = 1;
|
|
}
|
|
|
|
pTG->LastOut++;
|
|
|
|
//
|
|
// check to see if we are done
|
|
//
|
|
if (pTG->LastOut >= pTG->TiffInfo.PageCount)
|
|
{
|
|
DebugPrintEx( DEBUG_MSG,
|
|
"Done whole document Last page %d size=%d",
|
|
pTG->CurrentOut,
|
|
dwUsedSizeOutputBuffer);
|
|
pTG->fTiffDocumentDone = 1;
|
|
|
|
goto good_exit;
|
|
}
|
|
|
|
//
|
|
// we want to maintain 2 pages ahead
|
|
//
|
|
|
|
if (pTG->LastOut - pTG->CurrentIn >= 2)
|
|
{
|
|
WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, WAIT_FOR_NEXT_STRIP_TX_TIMEOUT);
|
|
|
|
if (WaitResult == WAIT_TIMEOUT)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR, "WaitForMultipleObjects TIMEOUT");
|
|
goto l_exit;
|
|
}
|
|
|
|
if (WaitResult == WAIT_FAILED)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"WaitForMultipleObjects FAILED le=%lx",
|
|
GetLastError());
|
|
}
|
|
|
|
if (pTG->ReqTerminate)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"Received TERMINATE request");
|
|
goto good_exit;
|
|
}
|
|
else if (pTG->ReqStartNewPage)
|
|
{
|
|
DebugPrintEx(DEBUG_MSG,"Received START NEW PAGE request");
|
|
pTG->AckStartNewPage = 1;
|
|
pTG->ReqStartNewPage = 0;
|
|
}
|
|
else
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"Received WRONG request");
|
|
WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, WAIT_FOR_NEXT_STRIP_TX_TIMEOUT);
|
|
|
|
if (WaitResult == WAIT_TIMEOUT)
|
|
{
|
|
DebugPrintEx(DEBUG_ERR,"WaitForMultipleObjects TIMEOUT");
|
|
goto l_exit;
|
|
}
|
|
|
|
if (WaitResult == WAIT_FAILED)
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"WaitForMultipleObjects FAILED le=%lx",
|
|
GetLastError());
|
|
}
|
|
}
|
|
}
|
|
|
|
pTG->CurrentOut++;
|
|
DebugPrintEx(DEBUG_MSG,"Start page %d", pTG->CurrentOut);
|
|
|
|
}
|
|
while (1);
|
|
|
|
good_exit:
|
|
if (pTG->fTiffOpenOrCreated)
|
|
{
|
|
TiffClose( pTG->Inst.hfile);
|
|
pTG->fTiffOpenOrCreated = 0;
|
|
}
|
|
|
|
RetCode = TRUE;
|
|
|
|
|
|
l_exit:
|
|
|
|
if (fOutFileNeedsBeClosed)
|
|
{
|
|
CloseHandle(OutFileHandle);
|
|
}
|
|
|
|
if (lpdwOutputBuffer)
|
|
{
|
|
VirtualFree(lpdwOutputBuffer, 0 , MEM_RELEASE);
|
|
// Nothing to do if it fails...
|
|
lpdwOutputBuffer = NULL;
|
|
}
|
|
|
|
pTG->AckTerminate = 1;
|
|
pTG->fOkToResetAbortReqEvent = 1;
|
|
|
|
if (!SetEvent(pTG->ThrdAckTerminateSignal))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SetEvent(0x%lx) returns failure code: %ld",
|
|
(ULONG_PTR)pTG->ThrdAckTerminateSignal,
|
|
(long) GetLastError());
|
|
RetCode = FALSE;
|
|
}
|
|
if (!SetEvent(pTG->FirstPageReadyTxSignal))
|
|
{
|
|
DebugPrintEx( DEBUG_ERR,
|
|
"SetEvent(0x%lx) returns failure code: %ld",
|
|
(ULONG_PTR)pTG->FirstPageReadyTxSignal,
|
|
(long) GetLastError());
|
|
RetCode = FALSE;
|
|
}
|
|
|
|
DebugPrintEx(DEBUG_MSG,"EXITs");
|
|
return (RetCode);
|
|
}
|
|
|