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.
680 lines
24 KiB
680 lines
24 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: MEMORY.C - Code module for memory transfers to O/i Wndw
|
|
MemoryTransfer() and AlignDataforOi()
|
|
Comments: Transfer to O/i window from IMGTwainProcessDCMessage
|
|
|
|
History of Revisions:
|
|
|
|
$Log: S:\products\msprods\oiwh\oitwain\memory.c_v $
|
|
*
|
|
* Rev 1.7 08 May 1996 16:49:42 BG
|
|
* Modified MemoryTransfer() to return an error if the IMGOpenDisplayCGBW()
|
|
* 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.7 08 May 1996 15:16:08 BG
|
|
* Modified MemoryTransfer() to return an error if the IMGOpenDisplayCGBW()
|
|
* 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.6 09 Oct 1995 10:40:14 BG
|
|
*
|
|
* This fix closes bug #4573 against the SCAN OCX!
|
|
* Must init a the ImgParms structure prior to calling IMGSetParmsCGBW!
|
|
* The first page of a scan may have repaint problems if this is not
|
|
* inited to 0. Any subsequent scan will clear the problem, however.
|
|
* This fix is in MEMORY.C and NATIVE.C of OITWA400.DLL.
|
|
*
|
|
* Rev 1.5 20 Sep 1995 15:24:20 BG
|
|
* In Memory.C of IMGTWA400.DLL, a IMGCloseDisplay() was being done
|
|
* in order to fix a bug where no repaints were occuring when no data
|
|
* was transfered from the scanner (paper jam or a quick cancel). This
|
|
* fixed the problem (avoided it is more like it) but caused other problems
|
|
* when the Image Edit OCX tried to Clear the Display Window. A bug was
|
|
* found in the Display repaint code (OIDIS400.DLL) when display is from scan
|
|
* and no data is transfered. This has been fixed, so do not close the display
|
|
* anymore, under any circumstances.
|
|
*
|
|
*
|
|
* // BG 9/20/95 Do not close the Display! This was a fix for repaints when
|
|
* // no image data was transfered, but it caused problems when the Edit OCX
|
|
* // tried to Clear the Display! A bug was found in the repaint code of
|
|
* // OIDIS400.DLL when display data comes from scan and no data was transfered.
|
|
*
|
|
* Rev 1.4 11 Sep 1995 13:21:32 KFS
|
|
* 1. Changed dcRC set or compared to 6, to use TWRC_XFERDONE.
|
|
* 2. Don found the fix for bug 4122 didn't fix scanner failures on paper
|
|
* feeds. Check now to CloseDisplay when any error code and no data, after
|
|
* the display has been openned.
|
|
*
|
|
* Rev 1.3 08 Sep 1995 19:17:52 KFS
|
|
* Found if no data sent to the window, I openned the display but did not close
|
|
* the display when an error occurs, or an abort with no data transferred. Found
|
|
* the code needed to call IMGCloseDisplay for the error with no image data.
|
|
*
|
|
* Rev 1.2 21 Aug 1995 15:49:18 KFS
|
|
* Fix filing with no display for scanning, Paul found same page being
|
|
* written for ea. new page of a multipage file, reason is that the hidden
|
|
* image window not getting cleared. Original code was for one page files so
|
|
* window got cleared and destroyed ea. time, not true for multipage.
|
|
*
|
|
* This fixes TWAIN memory mode transfers, see native.c for fix for TWAIN
|
|
* native mode transfers.
|
|
*
|
|
* Rev 1.1 20 Jul 1995 12:09:08 KFS
|
|
* changed oitwain.h to engoitwa.h and display.h engdisp.h
|
|
*
|
|
* Rev 1.0 20 Jul 1995 10:29:56 KFS
|
|
* Initial entry
|
|
*
|
|
* Rev 1.2 23 Aug 1994 16:19:06 KFS
|
|
* No code change, add vlog comments in file on checkin
|
|
*
|
|
|
|
REV# INITIALS DATE CHANGES
|
|
|
|
1 kfs 03/11/93 Extracted from dca_acq.c
|
|
2 kfs 03/17/93 (1)delete wiissubs.h, (2)added send XFERDONE
|
|
msgs for all returns, (3)used IMAGEINFO
|
|
ImageWidth in place of MEMXFER Columns
|
|
for Fotoman didn't return correct value
|
|
3 kfs 05/28/93 support for scan to file w/o display, and
|
|
fix missing set of MSG_GETCURRENT for
|
|
GetCaps()
|
|
4 kfs 08/27/93 fix for scale being off, attempt to fix
|
|
repaint's from not being received after
|
|
scan on initial scan, (sporadically happens
|
|
on 1st scan w/o an image in display)
|
|
5 kfs 10/19/93 found archive bit not set correctly
|
|
|
|
*************************************************************************/
|
|
|
|
// 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 "oitwain.h" // public function prototypes & defs for OITWAIN
|
|
#include "engoitwa.h" // Prototypes & definitions used by other DLL's
|
|
// Previously called oitwain.h
|
|
#include "internal.h" // non public prototypes & defs for OITWAIN
|
|
#include "dca_acq.h" // contain TWAIN sample support code
|
|
#include "strings.h" // string constants for module
|
|
#include <string.h> // needed for _fmemcopy
|
|
|
|
#include "oifile.h" // O/i definition files
|
|
#include "oidisp.h"
|
|
#include "oiadm.h"
|
|
//#include "oiwind.h" /* removed, need only for OiUICreate update */
|
|
//#include "privwind.h"
|
|
|
|
// Imports - Globals from other modules need here
|
|
extern char szOiTwainProp[];
|
|
extern DSMENTRYPROC lpDSM_Entry; // function pointer to Source Mang. entry
|
|
#ifdef WANG_THUNK
|
|
extern DSMENTRYPROC lpiDSM_Entry; // function pointer to Source Mang. entry
|
|
#else
|
|
#define lpiDSM_Entry lpDSM_Entry
|
|
#endif
|
|
|
|
extern TW_UINT16 DCDSOpen; // access to status for dca_glue.c
|
|
extern HANDLE hLibInst; // current instance
|
|
|
|
// Exports - Globals to other modules
|
|
|
|
// Local Global variables within Module
|
|
|
|
|
|
TW_UINT16 MemoryTransfer(pSTR_OiXFERINFO pXferInfo,
|
|
pTWAIN_SUPPORT pOiSupport,
|
|
pTW_IMAGEINFO pdcImageInfo)
|
|
{
|
|
TW_UINT16 dcRC = TWRC_SUCCESS;
|
|
TW_UINT16 dcCC;
|
|
HANDLE hbm_acq; // handle to image from Source to ret to App
|
|
STR_CAP TwainCap;
|
|
LPSTR pImgBuf = 0L;
|
|
DWORD dwByteCount = 0;
|
|
LPSTR lpbiCreated;
|
|
RGBQUAD far * pRGBQuad;
|
|
HBITMAP hHeader_Table = 0;
|
|
TW_PALETTE8 Palette8;
|
|
char szCaption[MAX_CAPTION_LENGTH];
|
|
TW_BOOL bInvert = FALSE; // CHOCOLATE = 0 = FALSE
|
|
// TW_BOOL bModCaption;
|
|
int nImgType;
|
|
int nPalEntry = 0;
|
|
RGBQUAD far * lpPalTab = NULL;
|
|
IMGPARMS ImgParms;
|
|
WORD wOiImageType;
|
|
WORD wColorUsed;
|
|
WORD wSizeofBiHeader = sizeof(BITMAPINFOHEADER);
|
|
DWORD dwColorTableSize;
|
|
int status;
|
|
PARM_SCROLL_STRUCT Scroll;
|
|
|
|
|
|
TW_SETUPMEMXFER SetupMem;
|
|
TW_IMAGEMEMXFER ImageMemXfer;
|
|
LPBITMAPINFOHEADER lpHeader_Table;
|
|
|
|
// BG 10/9/95 Need to init this struct else repaints may not occur properly
|
|
memset(&ImgParms, 0, sizeof(ImgParms));
|
|
|
|
ImageMemXfer.BytesWritten = 0; // Set to zero to check if aborted
|
|
TwainCap.wMsgState = MSG_GETCURRENT; // for pixel flavor
|
|
|
|
if (dcRC = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_CONTROL,
|
|
DAT_SETUPMEMXFER,
|
|
MSG_GET,
|
|
(TW_MEMREF)&SetupMem))
|
|
{
|
|
// SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, NULL, 0);
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
|
|
// Open Image display can handle only 64k - 1 bytes (0xFFFF)
|
|
if (SetupMem.Preferred >= 0x10000)
|
|
{
|
|
if (SetupMem.MinBufSize < 0x10000)
|
|
ImageMemXfer.Memory.Length = SetupMem.MinBufSize;
|
|
else // 4 bytes short of 64k (on a DWORD boundary)
|
|
ImageMemXfer.Memory.Length = 0xfffc;
|
|
}
|
|
else
|
|
ImageMemXfer.Memory.Length = SetupMem.Preferred;
|
|
|
|
// let's try to get pallette info
|
|
if ((pdcImageInfo->PixelType == TWPT_RGB) ||
|
|
(dcRC = (*lpDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_IMAGE,
|
|
DAT_PALETTE8,
|
|
MSG_GET,
|
|
(TW_MEMREF)&Palette8)))
|
|
{
|
|
dcRC = TWRC_SUCCESS; // Set it back to success
|
|
switch (pdcImageInfo->BitsPerPixel)
|
|
{
|
|
default:
|
|
case 1:
|
|
wColorUsed = 2;
|
|
|
|
TwainCap.ItemType = TWTY_BOOL; // variable type
|
|
TwainCap.wCapType = ICAP_PIXELFLAVOR;
|
|
TwainCap.lpData = (pTW_UINT32)&bInvert;
|
|
// if error, use default value TWPF_CHOCOLATE
|
|
if (IMGTwainGetCaps(pXferInfo->hWnd, &TwainCap, NULL))
|
|
bInvert = TWPF_CHOCOLATE; // use default if fails
|
|
break;
|
|
|
|
case 4:
|
|
wColorUsed = 16;
|
|
break;
|
|
|
|
case 8:
|
|
// Some TWAIN Sources specify 8 for RGB when it should be 24, for
|
|
// ... example the Epson sources
|
|
if (pdcImageInfo->PixelType == TWPT_RGB)
|
|
{
|
|
wColorUsed = 0;
|
|
pdcImageInfo->BitsPerPixel = 24;
|
|
}
|
|
else
|
|
wColorUsed = 256;
|
|
break;
|
|
|
|
case 24:
|
|
// A 24 bitcount DIB has no color table
|
|
wColorUsed = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int m;
|
|
|
|
wColorUsed = Palette8.NumColors;
|
|
|
|
dwColorTableSize = wColorUsed * sizeof(RGBQUAD);
|
|
// Alloc memory to hold BiHeader and color table
|
|
if (hHeader_Table = GlobalAlloc(
|
|
GMEM_NOT_BANKED | GMEM_ZEROINIT | GMEM_MOVEABLE,
|
|
(wSizeofBiHeader + dwColorTableSize)))
|
|
{
|
|
if (!(lpHeader_Table = (LPBITMAPINFOHEADER)GlobalLock(hHeader_Table)))
|
|
{
|
|
GlobalFree(hHeader_Table);
|
|
// SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, NULL, 0);
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, NULL, 0);
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
|
|
pRGBQuad = (RGBQUAD far *)((LPSTR)lpHeader_Table + wSizeofBiHeader);
|
|
|
|
for (m = 0; m < (int)wColorUsed; m++)
|
|
{
|
|
pRGBQuad->rgbRed = (Palette8.Colors[m]).Channel1;
|
|
pRGBQuad->rgbGreen = (Palette8.Colors[m]).Channel2;
|
|
pRGBQuad->rgbBlue = (Palette8.Colors[m]).Channel3;
|
|
pRGBQuad->rgbReserved = 0;
|
|
pRGBQuad++;
|
|
}
|
|
// reset it back to 1st color
|
|
pRGBQuad = (RGBQUAD far *)((LPSTR)lpHeader_Table + wSizeofBiHeader);
|
|
}
|
|
|
|
if (hbm_acq = GlobalAlloc(
|
|
GMEM_NOT_BANKED | GMEM_ZEROINIT | GMEM_MOVEABLE,
|
|
SetupMem.Preferred))
|
|
{
|
|
if (!(lpbiCreated = GlobalLock(hbm_acq)))
|
|
{
|
|
GlobalFree(hbm_acq);
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
GlobalUnlock(hbm_acq);
|
|
hHeader_Table = 0;
|
|
}
|
|
// SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, NULL, 0);
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
hHeader_Table = 0;
|
|
}
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
|
|
switch (pdcImageInfo->PixelType)
|
|
{
|
|
default:
|
|
case TWPT_BW:
|
|
nImgType = ITYPE_BI_LEVEL;
|
|
|
|
TwainCap.ItemType = TWTY_BOOL; // variable type
|
|
TwainCap.wCapType = ICAP_PIXELFLAVOR;
|
|
TwainCap.lpData = (pTW_UINT32)&bInvert;
|
|
if (IMGTwainGetCaps(pXferInfo->hWnd, &TwainCap, NULL))
|
|
bInvert = TWPF_CHOCOLATE; // use default if fails
|
|
wOiImageType = BWFORMAT;
|
|
break;
|
|
|
|
case TWPT_GRAY:
|
|
nImgType = (pdcImageInfo->BitsPerPixel == 4) ? ITYPE_GRAY4 : ITYPE_GRAY8;
|
|
wOiImageType = GRAYFORMAT;
|
|
break;
|
|
|
|
case TWPT_RGB:
|
|
nImgType = ITYPE_RGB24;
|
|
wOiImageType = COLORFORMAT;
|
|
break;
|
|
|
|
case TWPT_PALETTE:
|
|
nImgType = (pdcImageInfo->BitsPerPixel == 8) ? ITYPE_PAL8 : ITYPE_PAL4;
|
|
nPalEntry = wColorUsed;
|
|
lpPalTab = pRGBQuad;
|
|
wOiImageType = COLORFORMAT;
|
|
break;
|
|
|
|
case TWPT_CMY:
|
|
case TWPT_CMYK:
|
|
case TWPT_YUV:
|
|
case TWPT_YUVK:
|
|
case TWPT_CIEXYZ:
|
|
GlobalUnlock(hbm_acq);
|
|
GlobalFree(hbm_acq);
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
GlobalUnlock(hbm_acq);
|
|
hHeader_Table = 0;
|
|
}
|
|
// SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, NULL, 0);
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
|
|
IMGGetFileType(pXferInfo->hWnd, wOiImageType, (LPINT) &ImgParms.file_type, FALSE);
|
|
|
|
if (IMGGetParmsCgbw(pXferInfo->hImageWnd, PARM_SCALE, &ImgParms.image_scale, 0))
|
|
{
|
|
status = IMGGetParmsCgbw(pXferInfo->hImageWnd, PARM_SCALE, &ImgParms.image_scale,
|
|
PARM_WINDOW_DEFAULT | PARM_CONSTANT);
|
|
}
|
|
else
|
|
{ // if image on screen, get parms and clear image, may need
|
|
status = IMGGetParmsCgbw(pXferInfo->hImageWnd, PARM_IMGPARMS, &ImgParms, 0);
|
|
//Remove the if on OI_DONT_REPAINT, need to do it all the time for mult page
|
|
//... cannot count on on close of file, since hidden window can be used again
|
|
//if (pXferInfo->dwDispFlag != OI_DONT_REPAINT) //don't clear it
|
|
// {
|
|
if (status = IMGClearWindow(pXferInfo->hImageWnd))
|
|
{
|
|
GlobalUnlock(hbm_acq);
|
|
GlobalFree(hbm_acq);
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
GlobalUnlock(hbm_acq);
|
|
hHeader_Table = 0;
|
|
}
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, 0, 0);
|
|
return (dcRC = TWRC_FAILURE);
|
|
}
|
|
if (pXferInfo->dwDispFlag != OI_DONT_REPAINT) // set to fit to window
|
|
if (ImgParms.image_scale > 12) // if any value > fit to
|
|
ImgParms.image_scale = 12;
|
|
// }
|
|
}
|
|
|
|
// need to set it for window
|
|
status = IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_SCALE,
|
|
&ImgParms.image_scale, 0);
|
|
|
|
status = IMGOpenDisplayCgbw(pXferInfo->hImageWnd,
|
|
pXferInfo->dwDispFlag,
|
|
pdcImageInfo->ImageLength,
|
|
pdcImageInfo->ImageWidth,
|
|
nImgType,
|
|
nPalEntry,
|
|
lpPalTab);
|
|
// Dont go any farther if display open fails!
|
|
if (status) return status;
|
|
|
|
ImgParms.x_resolut = (unsigned int)(pdcImageInfo->XResolution).Whole;
|
|
ImgParms.y_resolut = (unsigned int)(pdcImageInfo->YResolution).Whole;
|
|
status = IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_RESOLUTION, &ImgParms.x_resolut, 0);
|
|
|
|
if (pXferInfo->pCaption)
|
|
{
|
|
lstrcpy(szCaption, pXferInfo->pCaption);
|
|
// only put up the caption if we get to OpenDisplay
|
|
if (pXferInfo->dwDispFlag != OI_DONT_REPAINT)
|
|
LoadString(hLibInst, IDS_CAP_UNTITLED,
|
|
&szCaption[lstrlen(szCaption)], MAX_CAPTION_LENGTH);
|
|
else // take out " - ", for
|
|
szCaption[lstrlen(szCaption) - 3] = 0; // ... no display up
|
|
|
|
SetWindowText(pXferInfo->hImageWnd, szCaption);
|
|
}
|
|
|
|
if (pdcImageInfo->PixelType == TWPT_PALETTE)
|
|
{
|
|
unsigned int nDispPalette;
|
|
|
|
nDispPalette = DISP_PALETTE_CUSTOM;
|
|
status = IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_DISPLAY_PALETTE, &nDispPalette, 0);
|
|
}
|
|
|
|
// appears, need to set it again after open
|
|
status = IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_SCALE,
|
|
&ImgParms.image_scale, 0);
|
|
|
|
pImgBuf = lpbiCreated;
|
|
|
|
ImageMemXfer.Memory.TheMem = (TW_MEMREF)pImgBuf;
|
|
|
|
ImageMemXfer.Memory.Flags = TWMF_APPOWNS | TWMF_POINTER;
|
|
|
|
while (!dcRC) // if successful continue until xferdone or cancel
|
|
{
|
|
dcRC = (*lpiDSM_Entry)(&pOiSupport->AppID,
|
|
&pOiSupport->DsID,
|
|
DG_IMAGE,
|
|
DAT_IMAGEMEMXFER,
|
|
MSG_GET,
|
|
&ImageMemXfer);
|
|
|
|
if (dcRC == TWRC_XFERDONE) // earliest time can eject page, user need to
|
|
// ... negotiate CAP_CLEARPAGE to use it in state 5
|
|
if (pOiSupport->dwFlags & OI_TWAIN_POSTPREEJECT) // POST PREEJECT
|
|
PostMessage ((pOiSupport->dcUI).hParent, PM_PREEJECT, (WPARAM) hbm_acq, 0);
|
|
else // SEND PREEJECT
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_PREEJECT, (WPARAM) hbm_acq, 0);
|
|
|
|
// get condition code upon failure and its not the End of xfer
|
|
if (dcRC && (dcRC != TWRC_XFERDONE))
|
|
{
|
|
dcCC = DCGetConditionCode(pOiSupport);
|
|
if (lpbiCreated)
|
|
{
|
|
GlobalUnlock(hbm_acq);
|
|
GlobalFree(hbm_acq);
|
|
}
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
hHeader_Table = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Local to ELSE
|
|
|
|
dwByteCount += ImageMemXfer.BytesWritten;
|
|
if (hHeader_Table) // save only for palletized
|
|
lpHeader_Table->biSizeImage += dwByteCount;
|
|
|
|
if ((dcRC == TWRC_XFERDONE) || ((dwByteCount + ImageMemXfer.BytesWritten)
|
|
>= ImageMemXfer.Memory.Length))
|
|
{
|
|
UINT uWriteCount;
|
|
|
|
pImgBuf = lpbiCreated;
|
|
// add parameter to invert for b/w data if
|
|
// ... bInvert is TWPF_VANILLA which is a BOOL TRUE
|
|
// ByteCount is adjusted for alignment
|
|
uWriteCount = AlignDataforOi((char *)pImgBuf, // Starting location of buffer
|
|
pdcImageInfo, // Image info structure
|
|
&ImageMemXfer, // memory transfer structure
|
|
dwByteCount,// Byte count for buffer
|
|
bInvert); // invert data if TWPF_VANILLA
|
|
|
|
status = IMGWriteDisplay(pXferInfo->hImageWnd, pImgBuf, (LPUINT) &uWriteCount);
|
|
|
|
if (dcRC == TWRC_XFERDONE) // end of xfer
|
|
{
|
|
if (hHeader_Table) // if alloc a Header_Table, fill it in
|
|
{
|
|
lpHeader_Table->biSize = (DWORD)wSizeofBiHeader;
|
|
lpHeader_Table->biWidth = ImageMemXfer.Columns;
|
|
lpHeader_Table->biHeight = ImageMemXfer.YOffset
|
|
+ ImageMemXfer.Rows;
|
|
lpHeader_Table->biPlanes = 1;
|
|
lpHeader_Table->biBitCount = pdcImageInfo->BitsPerPixel;
|
|
lpHeader_Table->biCompression = BI_RGB; // no compression
|
|
lpHeader_Table->biClrUsed = wColorUsed;
|
|
}
|
|
if (lpbiCreated)
|
|
{
|
|
GlobalUnlock(hbm_acq);
|
|
// add for O/i
|
|
GlobalFree(hbm_acq);
|
|
}
|
|
if (hHeader_Table)
|
|
{
|
|
GlobalUnlock(hHeader_Table);
|
|
GlobalFree(hHeader_Table);
|
|
hHeader_Table = 0;
|
|
}
|
|
|
|
// Set the values needed, all others 0 or NULL
|
|
ImgParms.cabinet_name[0] = '\0';
|
|
ImgParms.drawer_name[0] = '\0';
|
|
ImgParms.folder_name[0] = '\0';
|
|
ImgParms.doc_name[0] = '\0';
|
|
ImgParms.file_name[0] = '\0';
|
|
IMGGetParmsCgbw(pXferInfo->hImageWnd, PARM_ARCHIVE, &ImgParms.archive, '\0');
|
|
// ImgParms.archive = FALSE;
|
|
ImgParms.page_num = 1;
|
|
ImgParms.total_num_pages = 1;
|
|
|
|
// file_type filled in previously
|
|
// x&y_resolut filled in previously
|
|
status = IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_IMGPARMS, &ImgParms, 0);
|
|
|
|
Scroll.lHorz = Scroll.lVert = 0;
|
|
IMGSetParmsCgbw(pXferInfo->hImageWnd, PARM_SCROLL,
|
|
&Scroll,
|
|
PARM_ABSOLUTE | PARM_REPAINT);
|
|
|
|
// Updates Menu items for IMGCreateWindowXX()
|
|
/* Pull out for not using UIEVENTS for WIN32
|
|
if (pXferInfo->dwDispFlag != OI_DONT_REPAINT) // only if on display
|
|
IMGFileSetDisplay(pXferInfo->hWnd);
|
|
Pull out complete, may cause problem - kfs */
|
|
|
|
// for O/i indicates image up on screen for paints
|
|
SendMessage ((pOiSupport->dcUI).hParent, PM_XFERDONE, (WPARAM) hbm_acq, 0);
|
|
}
|
|
else
|
|
{
|
|
dwByteCount = 0; // set it 0 for next full buffer
|
|
}
|
|
// set to beginning of buffer
|
|
ImageMemXfer.Memory.TheMem = (TW_MEMREF)pImgBuf;
|
|
}
|
|
else
|
|
{
|
|
// increment for next partial buffer
|
|
pImgBuf += ImageMemXfer.BytesWritten;
|
|
ImageMemXfer.Memory.TheMem = (TW_MEMREF)pImgBuf;
|
|
}
|
|
} // End of else of if (dcRC && (dcRC != TWRC_XFERDONE))
|
|
} // End of While Loop
|
|
|
|
// BG 9/20/95 Do not close the Display! This was a fix for repaints when
|
|
// no image data was transfered, but it caused problems when the Edit OCX
|
|
// tried to Clear the Display! A bug was found in the repaint code of
|
|
// OIDIS400.DLL when display data comes from scan and no data was transfered.
|
|
//if (!((dcRC == TWRC_SUCCESS) || (dcRC == TWRC_XFERDONE))
|
|
// && !(dwByteCount || ImageMemXfer.BytesWritten))
|
|
// IMGCloseDisplay(pXferInfo->hImageWnd); // nothing got to display wndw, close it
|
|
|
|
return dcRC;
|
|
|
|
} // end MemoryTransfer()
|
|
|
|
UINT AlignDataforOi(char * pBufStart, // Starting location of buffer
|
|
pTW_IMAGEINFO pdcImageInfo, // Image info structure
|
|
pTW_IMAGEMEMXFER pImageMemXfer, // memory transfer structure
|
|
DWORD dwByteCount, // Byte count for buffer
|
|
BOOL bInvert) // invert for b/w
|
|
{
|
|
LPSTR pGetLine;
|
|
LPSTR pPutLine;
|
|
DWORD dwNoOfDWPerLine;
|
|
WORD wNoOfBitsLeftOut;
|
|
DWORD dwBytesPerImgLine;
|
|
WORD wByteOffSet, nRowsPerBuffer;
|
|
|
|
|
|
// First determine, is alignment necessary
|
|
|
|
// No of double words without remainder
|
|
dwNoOfDWPerLine = pdcImageInfo->ImageWidth * pdcImageInfo->BitsPerPixel / 32;
|
|
|
|
// No of bits not include in DW total above
|
|
wNoOfBitsLeftOut = (WORD)(pdcImageInfo->ImageWidth * pdcImageInfo->BitsPerPixel % 32);
|
|
|
|
// Determine the actual byte count of image
|
|
|
|
// No of bytes for DW total
|
|
dwBytesPerImgLine = dwNoOfDWPerLine * 4; // if remainder 0, this is byte line count
|
|
|
|
// Figure in the remaing bits
|
|
if (wNoOfBitsLeftOut)
|
|
{
|
|
dwBytesPerImgLine++; // add extra byte to count
|
|
if (wNoOfBitsLeftOut >= 9)
|
|
dwBytesPerImgLine++; // add extra byte to count
|
|
if (wNoOfBitsLeftOut >= 17)
|
|
dwBytesPerImgLine++; // add extra byte to count
|
|
if (wNoOfBitsLeftOut >= 25)
|
|
dwBytesPerImgLine++; // add extra byte to count
|
|
}
|
|
|
|
nRowsPerBuffer = (WORD)(dwByteCount / pImageMemXfer->BytesPerRow);
|
|
|
|
// Check with count from pImageMemXfer
|
|
wByteOffSet = (WORD)(pImageMemXfer->BytesPerRow - dwBytesPerImgLine);
|
|
if (wByteOffSet > 3) // Safe Check
|
|
return 0;
|
|
else
|
|
{
|
|
if (wByteOffSet || bInvert)
|
|
{
|
|
WORD n;
|
|
WORD i;
|
|
|
|
if (bInvert)
|
|
{// invert 1st line
|
|
pGetLine = pBufStart;
|
|
for (n = 1; n <= (WORD)dwBytesPerImgLine; n++)
|
|
{
|
|
*pGetLine ^= 0xff;
|
|
pGetLine++;
|
|
}
|
|
}
|
|
// Move n lines to new alignment
|
|
for (n = 1; n <= (nRowsPerBuffer - 1); n++)
|
|
{
|
|
// Set pointers for data move
|
|
pGetLine = pBufStart + (pImageMemXfer->BytesPerRow * n);
|
|
pPutLine = pBufStart + (dwBytesPerImgLine * n);
|
|
|
|
// move dwBytesPerImgLine bytes of data in a line
|
|
// invert data if needed else use _fmemcopy()
|
|
if (bInvert)
|
|
{
|
|
for (i = 1; i <= (WORD)dwBytesPerImgLine; i++)
|
|
{
|
|
*pPutLine = ~(*pGetLine);
|
|
pPutLine++;
|
|
pGetLine++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memcpy(pPutLine, pGetLine, (WORD)dwBytesPerImgLine);
|
|
}
|
|
}
|
|
}
|
|
else // offset is 0, return bytecount given
|
|
return dwByteCount;
|
|
}
|
|
// return the new byte count
|
|
return (UINT)(dwByteCount - (nRowsPerBuffer * wByteOffSet));
|
|
} // end of AlignDataforOi
|
|
|