mirror of https://github.com/lianthony/NT4.0
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.
1013 lines
37 KiB
1013 lines
37 KiB
/***********************************************************************
|
|
TWAIN source code:
|
|
Copyright (C) '92-'93 Wang Laboratories, Inc.:
|
|
All rights reserved.
|
|
|
|
Author: Ken Spina
|
|
Project: TWAIN Scanner Support in O/i Client
|
|
Module: TRANSFER.C - Transfers an image to O/i Window
|
|
Comments: Contains DCTransferImage() & GetCompleteImage()
|
|
|
|
History of Revisions:
|
|
|
|
$Log: S:\products\msprods\oiwh\oitwain\transfer.c_v $
|
|
*
|
|
* Rev 1.16 25 Jun 1996 15:45:08 BG
|
|
* Moved the GetTwainImageInfo call inside the multi image transfer loop.
|
|
* Cameras can transfer images with different resolutions, causing a bug
|
|
* if the same image size and res is used for each transfer. Now we
|
|
* get the image info for each image, instead of just the first.
|
|
*
|
|
* Rev 1.15 19 Jun 1996 10:20:32 BG
|
|
* * Remove testing of Autofeed flag to exit multi image transfer loop.
|
|
* This flag is only set if the device has an ADF. This restricts multi image
|
|
* transfers on devices such as digital cameras, hand helds, data bases...
|
|
* This flag is apparently obsolete.
|
|
*
|
|
* Rev 1.14 08 May 1996 16:50:38 BG
|
|
* Modified DCTransferImage() to return an error if the IMGOpenDisplayCGBW()
|
|
* of MemoryTransfer() or NativeTransfer() call fails. This API has a limitation
|
|
* of 18000 pixels maximum width or height. If this was exceeded by scan,
|
|
* we were ignoring the error and bad things would happen.
|
|
* Now we return the error back to the Scan OCX and result in a
|
|
* "Invalid Option Specified" error. This closes bug #6413.
|
|
*
|
|
* Rev 1.14 08 May 1996 15:19:20 BG
|
|
* Modified DCTransferImage() to return an error if the IMGOpenDisplayCGBW()
|
|
* of MemoryTransfer() or NativeTransfer() call fails. This API has a limitation
|
|
* of 18000 pixels maximum width or height. If this was exceeded by scan,
|
|
* we were ignoring the error and bad things would happen.
|
|
* Now we return the error back to the Scan OCX and result in a
|
|
* "Invalid Option Specified" error. This closes bug #6413.
|
|
*
|
|
* Rev 1.13 22 Apr 1996 14:19:34 BG
|
|
* Do not return an error when a multipage insert or append to a file
|
|
* reaches the PageCount limit. Just stop scanning. If this is attempted
|
|
* and PageCount = ActualPageCount of the file before StartScan, then
|
|
* return ERROR_PAGERANGE. This closes bug #6332 P2.
|
|
*
|
|
* Rev 1.12 16 Apr 1996 15:29:10 BG
|
|
* This close bug #6327. Try to scan an AWD file, but select Color image
|
|
* Sorry, not color, but 4bit Gray! Do this from the TWAIN UI. The scan runtime
|
|
* would detect 4bit pixel depth, but not assign a ImageGroup. This defaulted
|
|
* to 1, so when I did a IMGGetFileType with ImageGroup = 1, it gave me a file
|
|
* type of AWD (should have been TIFF or BMP, whatever was last used for Gray
|
|
* scanning). Now when I go to do the filing with an AWD filetype and BW image
|
|
* group, an error occured because the actual data is really 4bit gray. To fix,
|
|
* just assign the appropriate image group (Gray or Color) if 4 bit pixel depth.
|
|
* Other pixel depths are OK.
|
|
*
|
|
* Rev 1.11 12 Apr 1996 10:34:26 BG
|
|
* Fix for Bug #6283 P2. I inadvertantly made the MultiPage property and
|
|
* the PagesPerFile property redundant. If the PagesPerFile > 1, then I would
|
|
* set MultiPage to TRUE in TRANSFER.C of OITWA400.DLL. This is wrong. Here
|
|
* are the correct relationships between these properties while scanning
|
|
* to file or template:
|
|
* Scan To MP PPF Result
|
|
* =========================================================================
|
|
* File T 7FFF Scan all in the feeder to one file
|
|
* File T X Scan X pages to one file
|
|
* File F 7FFF Scan 1 page to one file (PPF ignored)
|
|
* File F X Scan 1 page to one file (PPF ignored)
|
|
* Template T 7FFF Scan all in feeder to one template file
|
|
* Template T X Scan X pages per file to N template files
|
|
* Template F 7FFF Scan 1 page per file to all template files
|
|
* Template F X Scan 1 page per file to X template files
|
|
* Display NA NA Scan 1 page to display
|
|
*
|
|
*
|
|
* Rev 1.10 04 Apr 1996 14:30:10 BG
|
|
* added a Page Start Event (Page End with a Pagenum of -1) for the
|
|
* Scan OCX.
|
|
*
|
|
* Rev 1.9 25 Mar 1996 16:29:46 BG
|
|
* Fixed P1 Bug #6083. When a 16bit gray image is scanned, it was attempting
|
|
* to compress it as JPEG, which is not supported (error message). This
|
|
* is because of a missing BREAK statement in a case which determined what
|
|
* the image type was (it fell into the 256 bit code).
|
|
*
|
|
* Rev 1.8 22 Mar 1996 15:57:40 BG
|
|
* Changed the IMGGetIMGCodingCGBW() call to get the compression type and
|
|
* options from the registry instead of the window. This is because the
|
|
* Scan OCX no longer writes these preferences to the image window, but to
|
|
* its control window, due to the new Scan Preferences dialog now is no
|
|
* longer attached to a scan method, but can be called at any time.
|
|
*
|
|
* Rev 1.7 21 Mar 1996 11:26:58 BG
|
|
* Must default to uncompressed if scanning to a AWD file. I was doing
|
|
* this for BMP, but forgot AWD.
|
|
*
|
|
* Rev 1.6 06 Mar 1996 10:40:40 BG
|
|
* changed _max_path to MAXFILESPECLENGTH
|
|
*
|
|
* Rev 1.5 05 Mar 1996 15:59:00 BG
|
|
* moved disk full check into the multi image transfer loop. It was only
|
|
* checking on the first scan of a multi image transfer. So it would
|
|
* scan the subsequent pages in a feeder and report the error after a page
|
|
* was scanned. Now it will always report the error prior to scanning any page.
|
|
*
|
|
* Rev 1.4 05 Mar 1996 11:35:32 BG
|
|
* No change.
|
|
*
|
|
* Rev 1.3 05 Mar 1996 11:34:24 BG
|
|
* added support for template scanning. Can now scan multi file, multi page,
|
|
* using multi image TWAIN transfer loop.
|
|
*
|
|
* Rev 1.2 22 Feb 1996 11:32:58 BG
|
|
* Modified TWAIN architecture to do multi image transfers now. Used
|
|
* to do single image transfers in a multi page loop. This would send
|
|
* TWAIN from state 4, to state 5, 6, 7, and then back to 4 again for
|
|
* every image transfered! Now we stay in states 6 and 7 until no more
|
|
* images are available from the data source. This requires that the
|
|
* filing be done now in this tight TWAIN loop within OITWA400.DLL. This
|
|
* includes file type checking, image type checking, page location
|
|
* verification, etc... All this stuff (including the filing) has been moved
|
|
* from OISSQ400.DLL to OITWAIN.DLL (TRANSFER.C and SAVEFILE.C).
|
|
*
|
|
* Rev 1.1 20 Jul 1995 12:05:06 KFS
|
|
* Changed oitwain.h to engoitwa.h and display.h engdisp.h for found
|
|
* in the include directory
|
|
*
|
|
* Rev 1.0 20 Jul 1995 10:28:32 KFS
|
|
* Initial entry
|
|
*
|
|
* Rev 1.1 23 Aug 1994 16:15:18 KFS
|
|
* No code change, add vlog comments to file on checkin
|
|
*
|
|
|
|
REV# INITIALS DATE CHANGES
|
|
|
|
1 kfs 03/11/93 Separated from dca_acq.c
|
|
2 kfs 03/12/93 eliminated O/i include file, now in
|
|
*tranfer()
|
|
3 kfs 03/17/93 needed to put back wiissubs.h and oidisp.h,
|
|
(2) discussion with Epson, found their
|
|
onevalue container is returning both
|
|
xfermech parameters, not just the current,
|
|
work around to use GetCaps, so lpData of
|
|
struct will come back with CURRENTVALUE
|
|
4 kfs 05/28/93 support for scan to file w/o display
|
|
5 kfs 06/04/93 fix for scan to file w/o display with
|
|
child windows and multiple image windows
|
|
6 kfs 07/21/93 use OiControl() to tell us the window for
|
|
image data through new hImageWnd in TWAIN
|
|
property struct (for cabinet)
|
|
7 kfs 10/22/93 cancel from scanner on hp not shutting
|
|
down the scanner properly with PENDINGXFER
|
|
|
|
*************************************************************************/
|
|
|
|
// needed for windows definitions
|
|
#include "nowin.h" // eliminate not used Window definitions
|
|
#include <windows.h> // Windows definitions
|
|
#include "TWAIN.h" // needed for TWAIN definitions
|
|
#include "internal.h" // non public prototypes & defs for OITWAIN
|
|
#include "scandest.h"
|
|
#include "dca_acq.h" // contain TWAIN sample support code
|
|
#include "strings.h" // string constants for module
|
|
|
|
// Imports - Globals from other modules need here
|
|
extern char szOiTwainProp[];
|
|
extern DSMENTRYPROC lpDSM_Entry; // function pointer to Source Mang. entry
|
|
extern TW_UINT16 DCDSOpen; // access to status for dca_glue.c
|
|
extern HANDLE hLibInst; // current instance
|
|
|
|
LPSTR PASCAL lstrchr ( LPSTR, int );
|
|
|
|
// Globals within module
|
|
WORD nTemplateFileCount;
|
|
|
|
// Local Prototypes
|
|
// This original defined in dos.h, need to redo dos21 calls.
|
|
typedef struct tagfind_t {
|
|
char reserved[21];
|
|
char attrib;
|
|
unsigned wr_time;
|
|
unsigned wr_date;
|
|
char name[13];
|
|
long size;
|
|
}find_t;
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
* FUNCTION: GetRegCompression
|
|
*
|
|
* ARGS: pdcImageInfo (pTW_IMAGEINFO)
|
|
*
|
|
* RETURNS: Error if Filetype incompatible with Imagetype or IMGSetImgCodingCgbw
|
|
* fails.
|
|
*
|
|
* COMMENTS: This routine is necessary in order to read the compression
|
|
* type and options from the registry. These were written by the
|
|
* Scan OCX, which does not know the image type prior to scan
|
|
* anymore. Also done here will be a file access check to see if
|
|
* scanning to an existing file.
|
|
*************************************************************************/
|
|
int GetRegCompression(pTW_IMAGEINFO pdcImageInfo, lpTWSCANPAGE lpTWPage, LPSCANDATA sdp)
|
|
{
|
|
int nRetCode = 0;
|
|
WORD wImageGroup = BWFORMAT;
|
|
BOOL bFileDoesntExist;
|
|
BOOL bItsADoc;
|
|
char filter[6]; // filter extension
|
|
char full_path[MAXFILESPECLENGTH/*MAXPATHLENGTH*/];
|
|
unsigned long t;
|
|
char num_str[9];
|
|
HANDLE hff;
|
|
char szFindFirstFile[MAXFILESPECLENGTH];
|
|
BOOL bFoundFile = TRUE;
|
|
WIN32_FIND_DATA target2;
|
|
char filename[MAXVOLNAMELENGTH];
|
|
|
|
bItsADoc = (*sdp->autodoc) || (*sdp->document); // Why do I need this???
|
|
|
|
IMGFileAccessCheck(lpTWPage->hImageWnd, lpTWPage->lpFioInfo->filename, 0, (LPINT)&bFileDoesntExist);
|
|
if (bFileDoesntExist == FALSE) // File exists, overwrite, append or insert
|
|
{
|
|
if (nRetCode = SetFilePageOpts(lpTWPage, bItsADoc))
|
|
{
|
|
lpTWPage->iImageState = DI_IMAGE_NO_FILE;
|
|
return nRetCode;
|
|
}
|
|
if ((short)lpTWPage->lpspecfPage->Page <= 0 )
|
|
lpTWPage->lpspecfPage->Page = lpTWPage->lpcurfPage->Page;
|
|
} // End file exist
|
|
else // It's a new file, page doesn't exist, append
|
|
{
|
|
lpTWPage->lpFioInfoCgbw->page_opts = FIO_NEW_FILE;
|
|
lpTWPage->lpFioInfo->page_number = lpTWPage->lpcurfPage->Page = lpTWPage->lpspecfPage->Page = 1;
|
|
lpTWPage->lpFioInfo->page_count = lpTWPage->lpcurfPage->PagesPer = 0;
|
|
}
|
|
|
|
switch (pdcImageInfo->BitsPerPixel)
|
|
{
|
|
default:
|
|
case 1:
|
|
wImageGroup = BWFORMAT;
|
|
break;
|
|
|
|
case 4:
|
|
if (pdcImageInfo->PixelType == TWPT_GRAY)
|
|
{
|
|
wImageGroup = GRAYFORMAT;
|
|
}
|
|
else wImageGroup = COLORFORMAT; // Not Supported for writes!
|
|
case 8:
|
|
if (pdcImageInfo->PixelType == TWPT_GRAY)
|
|
{
|
|
wImageGroup = GRAYFORMAT;
|
|
}
|
|
else
|
|
{
|
|
wImageGroup = COLORFORMAT;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
wImageGroup = COLORFORMAT;
|
|
}
|
|
|
|
|
|
// see if image type is compatible with file type
|
|
if (nRetCode = IMGGetFileType(lpTWPage->hOrgImgWnd, wImageGroup, (LPINT)(&lpTWPage->lpLocalFileInfo->ftype), FALSE))
|
|
return FIO_UNKNOWN_FILE_TYPE;
|
|
if ((lpTWPage->lpLocalFileInfo->ftype == FIO_AWD) && (wImageGroup != BWFORMAT))
|
|
return FIO_ILLEGAL_IMAGE_FILETYPE;
|
|
|
|
// Check for template scanning. Will need to append the extension.
|
|
// Will also need to check if template files already exist and get the
|
|
// highest template number so we can continue.
|
|
if (lpTWPage->flags & IMG_SJF_SEQFILES)
|
|
{
|
|
switch (lpTWPage->lpLocalFileInfo->ftype) // Get Extension, place it in filter
|
|
{
|
|
case FIO_WIF: /* .WIF (2)*/
|
|
lstrcpy(filter, (LPSTR)".WIF");
|
|
break;
|
|
case FIO_BMP: /* .BMP (4)*/
|
|
lstrcpy(filter, (LPSTR)".BMP");
|
|
break;
|
|
default:
|
|
/* case FIO_PIX: .PIX Not Support yet (1)*/
|
|
/* case FIO_GIF: .GIF Not Supported yet (5)*/
|
|
/* case FIO_UNKNOWN: .UKN (7)*/
|
|
/* case FIO_PCX: .PCX Not Supported for write (8)*/
|
|
/* case FIO_DCX: .DCX Not Supported for write (9)*/
|
|
/* case FIO_TGA: .TGA Not Supported for write 10 */
|
|
/* case FIO_JPG: .JPB Not Supported for write 11 */
|
|
case FIO_TIF: /* .TIF (3)*/
|
|
lstrcpy(filter, (LPSTR)".TIF");
|
|
break;
|
|
case FIO_AWD: /* .AWD (12)*/
|
|
lstrcpy(filter, (LPSTR)".AWD"); // add for awd support
|
|
break;
|
|
}
|
|
// for subsequent files (built in DoFiling())
|
|
lstrcpy(lpTWPage->lpTemplateInfo->extension, filter);
|
|
|
|
// build the template full path now that we have the extension.
|
|
lstrcpy(full_path, lpTWPage->lpTemplateInfo->directory);
|
|
AddSlash(full_path);
|
|
lstrcat(full_path, lpTWPage->lpTemplateInfo->Filename);
|
|
// append the extension
|
|
lstrcat(full_path, lpTWPage->lpTemplateInfo->extension);
|
|
|
|
// See if any files exist already for this template. We want
|
|
// to start at 1 or append at the highest numbered template file.
|
|
lpTWPage->lpTemplateInfo->highest = 0L;
|
|
// New WIN95 Code
|
|
lstrcpy(szFindFirstFile, full_path/*directory*/);
|
|
hff = FindFirstFile(szFindFirstFile, &target2);
|
|
if (!(hff == INVALID_HANDLE_VALUE) )
|
|
{
|
|
// New WIN95 Code - Found a file, continue to find more
|
|
while (bFoundFile != FALSE)
|
|
{
|
|
t = atoul(&target2.cFileName[lpTWPage->lpTemplateInfo->name_length]);
|
|
if (t > lpTWPage->lpTemplateInfo->highest)
|
|
lpTWPage->lpTemplateInfo->highest = t;
|
|
bFoundFile = FindNextFile(hff, &target2);
|
|
}
|
|
|
|
}
|
|
if (++lpTWPage->lpTemplateInfo->highest > lpTWPage->lpTemplateInfo->limit)
|
|
{
|
|
return IMGSE_FILE_LIMIT; /* to many files with that name */
|
|
}
|
|
|
|
// create new filename based on template
|
|
lstrcpy(filename, lpTWPage->lpTemplateInfo->Filename);
|
|
lstrncpy(&filename[lpTWPage->lpTemplateInfo->name_length], "00000000", 8 - lpTWPage->lpTemplateInfo->name_length);
|
|
filename[8] = 0;
|
|
lntoa(lpTWPage->lpTemplateInfo->highest, num_str, 10);
|
|
lstrcpy(&filename[8 - lstrlen(num_str)], num_str);
|
|
|
|
// build the path
|
|
lstrcpy(full_path, lpTWPage->lpTemplateInfo->directory);
|
|
AddSlash(full_path);
|
|
lstrcat(full_path, filename);
|
|
lstrcat(full_path, lpTWPage->lpTemplateInfo->extension);
|
|
|
|
// set new filename
|
|
lstrcpy(lpTWPage->lpFioInfo->filename, full_path);
|
|
}
|
|
|
|
|
|
// Check for file type and multi page request, cannot support for bmp, & wif
|
|
if ((!(lpTWPage->lpLocalFileInfo->ftype == FIO_TIF)) &&
|
|
(!(lpTWPage->lpLocalFileInfo->ftype == FIO_AWD)))
|
|
{ // force single page
|
|
lpTWPage->flags &= ~IMG_SJF_MULTIPAGE;
|
|
}
|
|
|
|
return nRetCode;
|
|
}
|
|
|
|
/*************************************************************************
|
|
* FUNCTION: DCTransferImage
|
|
*
|
|
* ARGS: hWnd
|
|
*
|
|
* RETURNS: none
|
|
*
|
|
* NOTES: 1). delete any bit maps laying around
|
|
* 2). mention those who do not want Native need CAP nego. ICAP_XFERMECH
|
|
* 3). get a little information about image, for form, I do not use it
|
|
* 4). set up a for form loop to pull image(s) from the Source
|
|
* 5). call for GetCompleteImage from Source
|
|
* 6). be sure to send a MSG_ENDXFER as a seperator between images
|
|
* 7). after the images are transfered I like to shut down the Source
|
|
* DCTerminate
|
|
*
|
|
* COMMENTS: Setup for a transfer in the routine called as a response to
|
|
* XFERREADY. Then has a nested loop do/while on the routine which
|
|
* actually pulls in the image or GetCompleteImage. The GetCompleteImage
|
|
* routine also deals with the cancel, xferdone, success messages from
|
|
* Source.
|
|
*/
|
|
VOID DCTransferImage(LP_TWAIN_SCANDATA lpTwainInfo, pTWAIN_SUPPORT pOiSupport,
|
|
lpTWSCANPAGE lpTWPage, LPSCANDATA sdp)
|
|
|
|
{
|
|
// TW information
|
|
TW_PENDINGXFERS dcPendingXfer;
|
|
TW_UINT16 dcRC;
|
|
TW_IMAGEINFO dcImageInfo;
|
|
TW_UINT16 dcRCPEND;
|
|
HWND hWnd;
|
|
int nRetCode = 0;
|
|
DWORD dwSectorsPerCluster, dwBytesPerSector;
|
|
DWORD dwFreeClusters, dwClusters;
|
|
DWORD dwFreeDiskSpace;
|
|
DWORD dwImageSize;
|
|
LPSTR lpszColon;
|
|
LPSTR lpszRoot;
|
|
char szRoot[4];
|
|
BOOL bMultiPageStop = FALSE;
|
|
|
|
hWnd = lpTwainInfo->hMainWnd;
|
|
nTemplateFileCount = 0;
|
|
|
|
// explicitly initialize the transfer count
|
|
dcPendingXfer.Count = 0;
|
|
lpTwainInfo->hOverRun = 0;
|
|
|
|
// only do file acces check, ect.. if scanning to a file
|
|
if (lpTWPage->lpFioInfo) nRetCode = GetRegCompression(&dcImageInfo, lpTWPage, sdp);
|
|
if (nRetCode)
|
|
{
|
|
// error occured, possible filetype/imagetype mismatch, not enough disk
|
|
// space, etc... return error and abort scan
|
|
lpTWPage->OIFileError = nRetCode;
|
|
//Reset and stop scan. This will get us to state 5!
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_RESET,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
}
|
|
else
|
|
{
|
|
// BG 8/3/95 Execute the Scan OCX callback for the page start event
|
|
// BG 9/12/95 This used to be after the scan but before the file. Moved
|
|
// it to after the file in case a filing error occured.
|
|
if (lpTWPage->OCXCallbackAddr)
|
|
{
|
|
(*lpTWPage->OCXCallbackAddr) ((WORD) -1);
|
|
}
|
|
|
|
// Ask Source if more images are coming.
|
|
do
|
|
{
|
|
// Get the image information, nice to know a little about the image the Source
|
|
// will be sending
|
|
(*lpDSM_Entry) (&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_IMAGE,
|
|
DAT_IMAGEINFO,
|
|
MSG_GET,
|
|
(TW_MEMREF)&dcImageInfo);
|
|
|
|
if (lpTWPage->lpFioInfo)
|
|
{
|
|
// first see if there is enough space to scan this UNCOMPRESSED image.
|
|
// If not, consider it an error and return, even if compression is
|
|
// going to be done.
|
|
lpszColon = lstrchr(sdp->filename, ':');
|
|
// extract the root
|
|
if (lpszColon) lpszRoot = lstrcpyn(szRoot, sdp->filename, 4);
|
|
else // default to current drive
|
|
lpszRoot = 0; // Null string
|
|
|
|
nRetCode = GetDiskFreeSpace(lpszRoot, &dwSectorsPerCluster,
|
|
&dwBytesPerSector, &dwFreeClusters, &dwClusters);
|
|
if (nRetCode) // got valid disk data
|
|
{
|
|
dwFreeDiskSpace = dwSectorsPerCluster * dwBytesPerSector * dwFreeClusters;
|
|
// Now determine the size of the uncompressed image in bytes
|
|
dwImageSize = (dcImageInfo.ImageWidth * dcImageInfo.ImageLength
|
|
* dcImageInfo.BitsPerPixel) / 8;
|
|
if (dwImageSize >= dwFreeDiskSpace)
|
|
{
|
|
lpTWPage->OIFileError = IMGSE_OUT_OF_DISK_SPACE;
|
|
//Reset and stop scan. This will get us to state 5!
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_RESET,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
lpTwainInfo->hOverRun = 0; // So cancel will work
|
|
|
|
dcRC = GetCompleteImage (hWnd, pOiSupport, &dcImageInfo);
|
|
|
|
switch (dcRC)
|
|
{
|
|
case TWRC_SUCCESS:
|
|
// Entire image should have been xfered, should not get here
|
|
break;
|
|
|
|
case TWRC_XFERDONE:
|
|
// BG 1/16/96 This is where I need to do the filing!
|
|
if (lpTWPage->lpFioInfo) DoOIFiling(lpTwainInfo, lpTWPage, sdp);
|
|
// MSG_ENDXFER Required for proper 6<->7 state transitions
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_ENDXFER,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
|
|
// Set stop flag if not multipage file and not template scanning
|
|
// or if not multipage file and template scanning reaches pagesperfile limit
|
|
if (!(lpTWPage->flags & IMG_SJF_MULTIPAGE))
|
|
{
|
|
if (!(lpTWPage->flags & IMG_SJF_SEQFILES))
|
|
{
|
|
bMultiPageStop = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (nTemplateFileCount >= lpTWPage->lpspecfPage->PagesPer)
|
|
{
|
|
bMultiPageStop = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if not a multipage file or if STOP hit, lets stop this multi image transfer
|
|
// Also check for error filing last image. Dont continue if true.
|
|
if (((bMultiPageStop) || (sdp->stat_pause) ||
|
|
(lpTWPage->lpcurfPage->Page > lpTWPage->lpspecfPage->PagesPer) ||
|
|
(lpTWPage->OIFileError)) &&
|
|
// BG 6/17/96 Do not check AUTOFEED flag anymore! Will not work with devices
|
|
// which do not have an ADF but do transfer multiple images: Cameras, CD, Database...
|
|
// (lpTWPage->OIFileError) ||
|
|
// (!(lpTWPage->flags & IMG_SJF_AUTOFEED))) &&
|
|
(dcPendingXfer.Count != 0))
|
|
{
|
|
//Reset and stop scan. This will get us to state 5!
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_RESET,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
dcPendingXfer.Count = 0; // just in case
|
|
// do not flag this as an error during scan, just stop scanning
|
|
// only flag as an error prior to scan (the user is attempting to
|
|
// scan past the end of a file page range and that range is at its max
|
|
// before the start of scan).
|
|
if (lpTWPage->OIFileError == ERROR_PAGERANGE) lpTWPage->OIFileError = 0;
|
|
}
|
|
break;
|
|
|
|
case TWRC_CANCEL:
|
|
//Reset and stop scan if cancel hit
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_ENDXFER,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
if (dcPendingXfer.Count != 0) // 0 means state 5, else still in state 6
|
|
{
|
|
//Reset and stop scan if cancel hit. This will get us to state 5!
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_RESET,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
dcPendingXfer.Count = 0; // just in case
|
|
}
|
|
break;
|
|
|
|
case TWRC_FAILURE:
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_ENDXFER,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
dcPendingXfer.Count = 0; // just in case
|
|
break;
|
|
|
|
default:
|
|
// unkown return code
|
|
dcRCPEND = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_PENDINGXFERS,
|
|
MSG_ENDXFER,
|
|
(TW_MEMREF)&dcPendingXfer);
|
|
dcPendingXfer.Count = 0; // just in case
|
|
lpTWPage->OIFileError = dcRC; // return display errors here
|
|
break;
|
|
}
|
|
|
|
} while (dcPendingXfer.Count != 0);
|
|
}
|
|
return;
|
|
} // DCTransferImage
|
|
|
|
/*************************************************************************
|
|
* FUNCTION: GetCompleteImage
|
|
*
|
|
* ARGS: hWnd handle to window
|
|
*
|
|
* RETURNS: dcRC
|
|
*
|
|
* NOTES: 1). ask the Source to start sending the pending image. We
|
|
* were told about this by receipt of a XFERREADY message
|
|
* from the Source.
|
|
*
|
|
* COMMENTS: Only transfer in memory buffered mode, at present
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
TW_UINT16 GetCompleteImage (HWND hWnd, pTWAIN_SUPPORT pOiSupport,
|
|
pTW_IMAGEINFO pdcImageInfo)
|
|
{
|
|
TW_UINT16 dcRC = TWRC_SUCCESS;
|
|
STR_CAP TwainCap;
|
|
TW_UINT16 CurrentCap;
|
|
HANDLE hImgBuf = 0;
|
|
LPSTR pImgBuf = 0L;
|
|
DWORD dwByteCount = 0;
|
|
LPSTR pBMImage = 0L;
|
|
HBITMAP hHeader_Table = 0;
|
|
char szCaption[MAX_CAPTION_LENGTH];
|
|
LPSTR lpDash;
|
|
WORD i = 0;
|
|
int k = 0;
|
|
TW_BOOL bInvert = FALSE; // CHOCOLATE = 0 = FALSE
|
|
TW_BOOL bModCaption;
|
|
int nPalEntry = 0;
|
|
RGBQUAD far * lpPalTab = NULL;
|
|
WORD wSizeofBiHeader = sizeof(BITMAPINFOHEADER);
|
|
STR_OiXFERINFO XferInfo; // defined for Oi transfer functions
|
|
TW_UINT16 Mech[3];
|
|
|
|
XferInfo.hWnd = hWnd; // Set Wndw handle into Oi XferInfo Struct
|
|
if (pOiSupport->hImageWnd)
|
|
XferInfo.hImageWnd = pOiSupport->hImageWnd;
|
|
else
|
|
XferInfo.hImageWnd = hWnd;
|
|
|
|
if (pOiSupport->dwFlags & OI_TWAIN_ALTIMGWND) // if this bit set get as many as asked
|
|
{
|
|
if (!(XferInfo.hImageWnd = GetWindow(hWnd, GW_CHILD)))
|
|
XferInfo.hImageWnd = pOiSupport->hImageWnd;
|
|
else
|
|
{ // verify window
|
|
HANDLE hProp;
|
|
BOOL bFoundProp = FALSE;
|
|
|
|
do
|
|
{ // find out which window we need to use
|
|
if (!(hProp = IMGGetProp(XferInfo.hImageWnd, "Scanner")))
|
|
{
|
|
XferInfo.hImageWnd = GetNextWindow(XferInfo.hImageWnd, GW_HWNDNEXT);
|
|
}
|
|
else
|
|
bFoundProp = TRUE;
|
|
|
|
} while (!bFoundProp && XferInfo.hImageWnd);
|
|
if (!bFoundProp)
|
|
XferInfo.hImageWnd = pOiSupport->hImageWnd;
|
|
}
|
|
}
|
|
|
|
// Setup Display Parameter for O/i
|
|
switch (pOiSupport->dwFlags & OI_TWAIN_DISPMASK) // define display method
|
|
{
|
|
case OI_DISP_WINDOW: /* removed from OIDISP.H - 7/06/95 */
|
|
case OI_DISP_SCROLL:
|
|
case OI_DISP_NO:
|
|
case OI_DONT_REPAINT:
|
|
case OI_NOSCROLL:
|
|
XferInfo.dwDispFlag = pOiSupport->dwFlags & OI_TWAIN_DISPMASK;
|
|
break;
|
|
// not a supported value, will use OI_DISP_NO
|
|
default:
|
|
XferInfo.dwDispFlag = OI_DISP_NO;
|
|
}
|
|
|
|
// Setup window caption
|
|
// if caption is to be modified
|
|
if (bModCaption = !(pOiSupport->dwFlags & OI_TWAIN_NOUNTITLED))
|
|
{
|
|
GetWindowText(XferInfo.hImageWnd, szCaption, MAX_CAPTION_LENGTH);
|
|
if (lpDash = lstrchr(szCaption, '-'))
|
|
{
|
|
if (*(lpDash - 1) == 0x20)
|
|
*(lpDash + 2) = 0;
|
|
else
|
|
{ // not the correct dash to separate file(doc) from user text
|
|
do
|
|
{
|
|
if (lpDash = lstrchr(lpDash + 1, '-'))
|
|
{
|
|
if (*(lpDash - 1) == 0x20)
|
|
{
|
|
*(lpDash + 2) = 0;
|
|
break; // got it, need to break
|
|
}
|
|
if (lpDash == NULL)
|
|
lstrcat(szCaption, " - "); // it's zero, will break
|
|
}
|
|
else
|
|
lstrcat(szCaption, " - "); // no other dash, 0 will will break loop
|
|
} while (lpDash != NULL);
|
|
}
|
|
}
|
|
else
|
|
lstrcat(szCaption, " - ");
|
|
XferInfo.pCaption = szCaption;
|
|
}
|
|
else
|
|
XferInfo.pCaption = NULL;
|
|
|
|
TwainCap.ItemIndex = 0;
|
|
TwainCap.ItemType = TWTY_UINT16; // variable type
|
|
TwainCap.wCapType = ICAP_XFERMECH;
|
|
TwainCap.wMsgState = MSG_GETCURRENT;
|
|
TwainCap.lpData = (pTW_UINT16)(&CurrentCap);
|
|
|
|
if (!lstrcmp(pOiSupport->DsID.ProductName, "Epson Scanners"))
|
|
{ // this should get the CurrentCap for epson, bug in OneValue
|
|
TwainCap.wMsgState = MSG_GET;
|
|
dcRC = IMGTwainGetCaps(hWnd, &TwainCap, &Mech[0]);
|
|
}
|
|
else
|
|
{
|
|
dcRC = IMGTwainGetCaps(hWnd, &TwainCap, NULL);
|
|
}
|
|
|
|
//CurrentCap = TWSX_MEMORY;
|
|
|
|
if (!dcRC) // IF SUCCESSFUL, CONTINUE
|
|
{
|
|
switch ((TW_UINT16)CurrentCap)
|
|
{
|
|
default:
|
|
case TWSX_MEMORY:
|
|
dcRC = MemoryTransfer(&XferInfo, pOiSupport, pdcImageInfo);
|
|
break;
|
|
|
|
case TWSX_FILE:
|
|
// Will not support at this time
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, (WPARAM) NULL, 0);
|
|
dcRC = TWRC_FAILURE;
|
|
break;
|
|
|
|
case TWSX_NATIVE:
|
|
dcRC = NativeTransfer(&XferInfo, pOiSupport, pdcImageInfo);
|
|
break;
|
|
}
|
|
|
|
} // end of dcRC = GetCaps
|
|
|
|
return dcRC;
|
|
} // GetCompleteImage
|
|
|
|
|
|
|
|
/*******************************************************************************************/
|
|
/* BG 1/17/96 This routine added so Norway scanning could be more compliant with */
|
|
/* TWAIN. Multi image transfers are now supported as opposed to single, and this is */
|
|
/* where the filing is done. It used to occur in TWINIF.C of OISSQ400.DLL. */
|
|
/*******************************************************************************************/
|
|
|
|
VOID PASCAL DoOIFiling(LP_TWAIN_SCANDATA lpTwainInfo, lpTWSCANPAGE lpTWPage, LPSCANDATA sdp)
|
|
{
|
|
WORD page_num;
|
|
WORD wImageGroup = BWFORMAT;
|
|
unsigned int nImgType; // Image type, eg. is ITYPE_BI_LEVEL
|
|
int ret_stat = IMGSE_SUCCESS;
|
|
int real_ret = IMGSE_SUCCESS;
|
|
LPSTR file_ptr[2];
|
|
BOOL bItsADoc;
|
|
char filename[MAXVOLNAMELENGTH];
|
|
char num_str[9];
|
|
char fullpath[MAXFILESPECLENGTH];
|
|
|
|
bItsADoc = (*sdp->autodoc) || (*sdp->document); // Why do I need this???
|
|
|
|
if (lpTWPage->lpFioInfo)
|
|
{
|
|
file_ptr[0] = lpTWPage->lpFioInfo->filename;
|
|
page_num = lpTWPage->lpFioInfo->page_number; // Page No. in LP_FIO_INFORMATION
|
|
}
|
|
|
|
if (lpTWPage->bEnableSuccess)
|
|
{
|
|
switch ((lpTwainInfo->dcImageInfo).BitsPerPixel)
|
|
{
|
|
default:
|
|
case 1:
|
|
wImageGroup = BWFORMAT;
|
|
nImgType = ITYPE_BI_LEVEL;
|
|
break;
|
|
|
|
case 4:
|
|
nImgType = ITYPE_GRAY4;
|
|
if ((lpTwainInfo->dcImageInfo).PixelType == TWPT_GRAY)
|
|
{
|
|
wImageGroup = GRAYFORMAT;
|
|
}
|
|
else
|
|
{
|
|
wImageGroup = COLORFORMAT;
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
if ((lpTwainInfo->dcImageInfo).PixelType == TWPT_GRAY)
|
|
{
|
|
wImageGroup = GRAYFORMAT;
|
|
nImgType = ITYPE_GRAY8;
|
|
}
|
|
else
|
|
{
|
|
wImageGroup = COLORFORMAT;
|
|
nImgType = ITYPE_PAL8;
|
|
}
|
|
break;
|
|
|
|
case 24:
|
|
// A 24 bitcount DIB has no color table
|
|
nImgType = ITYPE_RGB24; // color
|
|
wImageGroup = COLORFORMAT;
|
|
}
|
|
|
|
// Force compression to uncompressed if BMP or AWD file
|
|
if ((lpTWPage->lpLocalFileInfo->ftype == FIO_BMP) ||
|
|
(lpTWPage->lpLocalFileInfo->ftype == FIO_AWD))
|
|
{
|
|
lpTWPage->lpLocalFileInfo->wCEPType = FIO_0D;
|
|
lpTWPage->lpLocalFileInfo->wCEPOpt = 0;
|
|
}
|
|
else // not a BMP or AWD. Must be TIFF w/any image type
|
|
{
|
|
if ((nImgType == ITYPE_BI_LEVEL) || (nImgType == ITYPE_GRAY8) ||
|
|
(nImgType == ITYPE_RGB24))
|
|
{
|
|
ret_stat = IMGGetImgCodingCgbw(lpTWPage->hOrgImgWnd, wImageGroup,
|
|
(LPWORD)(&lpTWPage->lpLocalFileInfo->wCEPType),
|
|
(LPWORD)(&lpTWPage->lpLocalFileInfo->wCEPOpt),
|
|
TRUE);
|
|
}
|
|
else // No compression supported for image type
|
|
{
|
|
lpTWPage->lpLocalFileInfo->wCEPType = FIO_0D;
|
|
lpTWPage->lpLocalFileInfo->wCEPOpt = 0;
|
|
}
|
|
}
|
|
|
|
/****** Get File Type ***************/
|
|
// for O/i 3.5 use GetFileType
|
|
ret_stat = IMGGetFileType(lpTWPage->hOrgImgWnd, wImageGroup, (LPINT)(&lpTWPage->lpLocalFileInfo->ftype), FALSE);
|
|
|
|
if (lpTWPage->open_disp_flags == OI_DISP_NO) // if it's display after need to make
|
|
{ // ... sure we display it
|
|
IMGSetParmsCgbw(lpTWPage->hImageWnd, PARM_SCALE,
|
|
(void far *)&conv_array[sdp->cmd_scale+4], PARM_REPAINT);
|
|
}
|
|
|
|
if (real_ret == IMGSE_ABORT) // if it's abort, it's been set to no file
|
|
goto exit1;
|
|
else
|
|
lpTWPage->iImageState = DI_IMAGE_EXISTS;
|
|
}
|
|
else
|
|
{
|
|
if (lpTWPage->bAutoMode)
|
|
{
|
|
|
|
/* PortTool v2.2 5/1/1995 16:38 */
|
|
/* Found : FAR */
|
|
/* Issue : Win32 is non-segmented, thus FAR == NEAR == nothing! */
|
|
// ret_stat = IMGScannerStatus(hScancb, &scan_stat, &JLoc, (DWORD *)&lValid);
|
|
// if (!(ret_stat || (lValid & scan_stat & IMG_STAT_PAPER)))
|
|
// {
|
|
// ret_stat = IMGSE_NO_PAPER;
|
|
// }
|
|
}
|
|
else
|
|
ret_stat = IMGSE_START_SCAN;
|
|
goto exit1;
|
|
}
|
|
|
|
if (ret_stat == IMGSE_ABORT)
|
|
goto exit1;
|
|
|
|
if (file_ptr[0]) // do this if filing as document or file
|
|
{
|
|
ret_stat = HighLevelSavetoFile(lpTWPage,
|
|
sdp,
|
|
1,
|
|
&real_ret);
|
|
// on failure with no display, close it now
|
|
if (real_ret && (lpTWPage->open_disp_flags & OI_DONT_REPAINT))
|
|
IMGCloseDisplay(lpTWPage->hImageWnd);
|
|
|
|
if (real_ret)
|
|
lpTWPage->iImageState = DI_IMAGE_NO_FILE;
|
|
}
|
|
|
|
if (real_ret)
|
|
{
|
|
if (lpTWPage->flags & IMG_SJF_SEQFILES)
|
|
{
|
|
if (real_ret == IMGSE_FILE_EXISTS)
|
|
{
|
|
if (lpTWPage->lpTemplateInfo->highest > lpTWPage->lpTemplateInfo->limit)
|
|
{
|
|
real_ret = IMGSE_FILE_LIMIT;
|
|
}
|
|
}
|
|
}
|
|
ret_stat = real_ret;
|
|
goto exit1;
|
|
}
|
|
|
|
// BG 8/3/95 Execute the Scan OCX callback for the page end event
|
|
// BG 9/12/95 This used to be after the scan but before the file. Moved
|
|
// it to after the file in case a filing error occured.
|
|
if (real_ret == IMGSE_SUCCESS && (lpTWPage->OCXCallbackAddr))
|
|
{
|
|
ret_stat = (*lpTWPage->OCXCallbackAddr) ((WORD) page_num);
|
|
}
|
|
|
|
//BG 1/18/96 This stuff is from the bottom of SCANDEST loop!
|
|
if ((lpTWPage->flags & IMG_SJF_MULTIPAGE) && (lpTWPage->lpcurfPage->Page < OISCAN_DEF_MAXPAGESPERFILE))
|
|
{
|
|
++lpTWPage->lpcurfPage->Page;
|
|
|
|
// BG 8/25/95 Must check for one page scanned to a new file. Returns 0 in PagesPerFile if we dont.
|
|
// The next page will be set to two, skipping over the Page = 1 case.
|
|
//if (lpScanFile) // need to return current page information
|
|
// lpScanFile->PagesPerFile = curfPage.PagesPer;
|
|
if (lpTWPage->lpScanFile) // need to return current page information
|
|
{
|
|
if (lpTWPage->lpcurfPage->PagesPer == 0)
|
|
{
|
|
lpTWPage->lpScanFile->PagesPerFile = 1;
|
|
}
|
|
else
|
|
{
|
|
lpTWPage->lpScanFile->PagesPerFile = lpTWPage->lpcurfPage->PagesPer;
|
|
}
|
|
}
|
|
|
|
// BG 6/17/96 Do not check AUTOFEED flag anymore! Will not work with devices
|
|
// which do not have an ADF but do transfer multiple images: Cameras, CD, Database...
|
|
// if (lpTWPage->flags & IMG_SJF_AUTOFEED)
|
|
// {
|
|
ret_stat = SetFilePageOpts(lpTWPage, bItsADoc);
|
|
|
|
// BG 9/18/95 This is a cludge to fix a bug when the AutoFeed flag is on and the user
|
|
// is rescanning the last page of a multipage file. If this occurs, the above routine
|
|
// (SetFilePageOpts()) will return an error because the page count was updated for the
|
|
// last page after it was scanned and filed. Next it is checked and determined to be out
|
|
// of bounds. This is not true, however. So lets just flag this case and reset the error
|
|
// to success instead of fixing the real problem and potentially breaking something else.
|
|
if ((ret_stat == ERROR_PAGERANGE) && (lpTWPage->lpcurfPage->Page > lpTWPage->lpspecfPage->PagesPer)) ret_stat = 0;
|
|
// }
|
|
}
|
|
|
|
if (lpTWPage->lpScanFile) // need to return page information if given
|
|
lpTWPage->lpScanFile->FilePage = lpTWPage->lpcurfPage->Page;
|
|
|
|
// If we are doing template scanning, see if its time to
|
|
// generate a new file
|
|
if (lpTWPage->flags & IMG_SJF_SEQFILES)
|
|
{ // If multipage page count met or NOT multipage, reset
|
|
if ((!(lpTWPage->flags & IMG_SJF_MULTIPAGE)) ||
|
|
(lpTWPage->lpcurfPage->Page > lpTWPage->lpspecfPage->PagesPer))
|
|
{
|
|
lpTWPage->lpcurfPage->Page = 1; // reset for next file
|
|
|
|
if (++lpTWPage->lpTemplateInfo->highest > lpTWPage->lpTemplateInfo->limit)
|
|
{
|
|
/* too many files with that name */
|
|
ret_stat = IMGSE_FILE_LIMIT;
|
|
goto exit1;
|
|
}
|
|
|
|
// must keep track of file count if not multipage
|
|
if (!(lpTWPage->flags & IMG_SJF_MULTIPAGE)) nTemplateFileCount += 1;
|
|
|
|
// create new filename based on template
|
|
lstrcpy(filename, lpTWPage->lpTemplateInfo->Filename);
|
|
lstrncpy(&filename[lpTWPage->lpTemplateInfo->name_length], "00000000", 8 - lpTWPage->lpTemplateInfo->name_length);
|
|
filename[8] = 0;
|
|
lntoa(lpTWPage->lpTemplateInfo->highest, num_str, 10);
|
|
lstrcpy(&filename[8 - lstrlen(num_str)], num_str);
|
|
|
|
// build the path
|
|
lstrcpy(fullpath, lpTWPage->lpTemplateInfo->directory);
|
|
AddSlash(fullpath);
|
|
lstrcat(fullpath, filename);
|
|
lstrcat(fullpath, lpTWPage->lpTemplateInfo->extension);
|
|
|
|
// set new filename
|
|
lstrcpy(lpTWPage->lpFioInfo->filename, fullpath);
|
|
}
|
|
}
|
|
|
|
|
|
exit1:
|
|
lpTWPage->OIFileError = ret_stat;
|
|
|
|
}
|