Leaked source code of windows server 2003
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

/*++
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);
}