L_RedirectIO

#include "l_bitmap.h"

L_LTKRN_API L_VOID L_RedirectIO(pfnOpen, pfnRead, pfnWrite, pfnSeek, pfnClose, pUserData)

REDIRECTOPEN pfnOpen;

/* far pointer to an open procedure */

REDIRECTREAD pfnRead;

/* far pointer to a read procedure */

REDIRECTWRITE pfnWrite;

/* far pointer to a write procedure */

REDIRECTSEEK pfnSeek;

/* far pointer to a seek procedure */

REDIRECTCLOSE pfnClose;

/* far pointer to a close procedure */

L_VOID* pUserData;

/* pointer to additional parameters */

Lets you replace the LEADTOOLS input/output functions for opening, reading, writing, seeking, and closing files.

Parameter

Description

pfnOpen

Far pointer to an open procedure. Use NULL to reset to the default. For a description of the callback function syntax, refer to REDIRECTOPEN Callback Function.

pfnRead

Far pointer to a read procedure. Use NULL to reset to the default. For a description of the callback function syntax, refer to REDIRECTREAD Callback Function.

pfnWrite

Far pointer to a write procedure. Use NULL to reset to the default For a description of the callback function syntax, refer to REDIRECTWRITE Callback Function.

pfnSeek

Far pointer to a seek procedure. Use NULL to reset to the default. For a description of the callback function syntax, refer to REDIRECTSEEK Callback Function.

pfnClose

Far pointer to a close procedure. Use NULL to reset to the default. For a description of the callback function syntax, refer to REDIRECTCLOSE Callback Function.

pUserData

A void pointer that you can use to access a variable or structure containing data that your callback function needs. This gives you a way to receive data indirectly from the function that uses this callback function. (This is the same pointer that you pass in the pUserData parameter of the calling function.)

 

Keep in mind that this is a void pointer, which must be cast to the appropriate data type within your callback function.

Returns

None.

Comments

For example, you can redirect all of the LEADTOOLS I/O functions by using the multimedia extensions, or you can redirect all the toolkit I/O functions to your own I/O functions.

Use a NULL argument to reset an I/O function to its default setting. The redefinition of the I/O process is left to you to define.

This function cannot be used in combination with L_FeedLoad, L_LoadBitmapMemory, L_LoadMemory, L_StartFeedLoad, L_StopFeedLoad, L_SaveBitmapMemory, and L_SaveFileMemory.

Note:

Redirected IO is not supported for some file formats.  For more information, refer to File Formats for Which Redirected IO is Not Supported.

Required DLLs and Libraries

LTKRN

For a listing of the exact DLLs and Libraries needed, based on the toolkit version, refer to Files To Be Included With Your Application.

Platforms

Windows 2000 / XP/Vista, Windows CE.

See Also

Topics:

Raster Image Functions: Input and Output

 

Annotation Functions: Input and Output

Example

This example loads a file using redirected input and output. Refer to the individual callback function descriptions to see how they are implemented.

/************************** Global Declarations **********************************/
typedef struct tagDATA
{
   BITMAPHANDLE   BitmapHandle;     /* BITMAP HANDLE to hold the image. */
} DATA;

typedef struct tagUSERDATA
{
   L_SIZE_T dwSize;       /* Size of the buffer. */
   L_SIZE_T dwUsed;       /* Number of bytes used. */
   L_UCHAR *pData;        /* Pointer to the actual buffer. */
   L_UCHAR *pCurData;     /* Current pointer location. */
} USERDATA, * LPUSERDATA;

DATA     Data;       /* Pointer to DATA structure */
HANDLE   hBuf;       /* Handle for globally allocated memory */
USERDATA UserData;   /* User structure for I/O operation */

/* my own I/O callback functions */
L_HFILE EXT_CALLBACK WindowsOpen(L_TCHAR* pFile,
                                 L_INT nMode,
                                 L_INT nShare,
                                 L_VOID* pUserData);

L_INT EXT_CALLBACK MyClose (L_HFILE FD, L_VOID* pUserData)
{
   /* we already have the file in memory so do nothing */
   UNREFERENCED_PARAMETER (FD);
   LPUSERDATA pData = (LPUSERDATA)pUserData;

   pData->pCurData = pData->pData;
   pData->dwUsed = 0;
   return (TRUE);
}

L_SSIZE_T EXT_CALLBACK MySeek (L_HFILE FD, L_SSIZE_T nPos, L_INT nOrigin, L_VOID* pUserData)
{
   /* see in the memory buffer */
   UNREFERENCED_PARAMETER (FD);
   LPUSERDATA pData = (LPUSERDATA)pUserData;

   switch (nOrigin)
   {
   case 0:                     /* SEEK_SET */
      pData->pCurData = pData->pData + nPos;
      pData->dwUsed = nPos;
      break;
   case 1:                     /* SEEK_CUR */
      pData->pCurData += nPos;
      pData->dwUsed += nPos;
      break;
   case 2:                     /* SEEK_END */
      if (0 <= nPos)           /* Positive value, but at the end, so go to
                                   the end. */
         nPos = 0;
      else
         nPos = -(nPos);      /* Seek backwards from the end of the buffer. */
      pData->pCurData = pData->pData + pData->dwSize - nPos;
      pData->dwUsed = pData->dwSize - nPos;
      break;
   }
   return (pData->pCurData - pData->pData);
}

L_UINT EXT_CALLBACK MyWrite (L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID* pUserData)
{
   /* this is a read example, do nothing for write */
   UNREFERENCED_PARAMETER (FD);
   UNREFERENCED_PARAMETER (pBuf);
   UNREFERENCED_PARAMETER (pUserData);
   return (uCount);
}

L_UINT EXT_CALLBACK MyRead (L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID* pUserData)
{
   /* read by copying from the memory buffer */
   UNREFERENCED_PARAMETER (FD);
   LPUSERDATA pData = (LPUSERDATA)pUserData;

   /* reading past end of file? */
   if(pData->pCurData >= pData->pData + pData->dwSize)
      return 0;

   /* Is the request for more data than is left in memory? */
   if (uCount + pData->pCurData >
       pData->pData + pData->dwSize)
      uCount = (L_UINT) (pData->dwSize - pData->dwUsed);   /* adjust request */

   /* Copy data to the buffer of the caller.  We can use _fmemcpy (even with
      BORLAND) because LEADTOOLS will never request more than 64k. */
   _fmemcpy (pBuf, pData->pCurData, uCount);

   /* Adjust internal data. */
   pData->pCurData += uCount;
   pData->dwUsed += uCount;
   return (uCount);
}

L_HFILE EXT_CALLBACK MyOpen(L_TCHAR* pFile, L_INT nMode, L_INT nShare, L_VOID* pUserData)
{
   /* we already have the file in memory so do nothing */
   LPUSERDATA pData = (LPUSERDATA)pUserData;
   UNREFERENCED_PARAMETER (pFile);
   UNREFERENCED_PARAMETER (nMode);
   UNREFERENCED_PARAMETER (nShare);
   pData->pCurData = pData->pData;
   pData->dwUsed = 0;
   return (L_HFILE)5;
}

/***************************************************************************************/
L_INT RedirectIOExample(L_VOID)
{
   L_SIZE_T lSizeToRead;
   HANDLE hFile;
   L_INT nRet;

   /* We will allocate a buffer of the image size and read the image into it,
   then all of our I/O operations will be operate on this buffer */

   hFile = CreateFile(TEXT("%UserProfile%\\My Documents\\LEADTOOLS Images\\image1.cmp"), GENERIC_READ , 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

   UserData.dwSize =  GetFileSize(hFile, NULL);
   /* Allocate a buffer to hold the file. */
   hBuf = GlobalAlloc (GMEM_MOVEABLE, UserData.dwSize);
   UserData.pData = (L_UCHAR *)GlobalLock (hBuf);
   UserData.pCurData = UserData.pData;
   UserData.dwUsed = 0;
   lSizeToRead = 0;
   /* Read the file in a loop, because the file could be larger than a single
      read can request. */
   memset(UserData.pData, 0x44, UserData.dwSize);

   while (lSizeToRead < UserData.dwSize)
   {
      if ( !ReadFile(hFile, (L_VOID *) UserData.pCurData, (DWORD)min (UserData.dwSize - lSizeToRead, 32000), (LPDWORD)&nRet, NULL))
      {
         GlobalUnlock (hBuf);
         GlobalFree (hBuf);
         CloseHandle (hFile);
         return (FALSE);        /* Failure on creation! */
      }
      else
      {
         lSizeToRead += nRet;
         UserData.pCurData += nRet;
      }
   }
   UserData.pCurData = UserData.pData;
   CloseHandle(hFile);

   /* Use our own routines to replace the internal I/O calls */
   L_RedirectIO (MyOpen, MyRead, MyWrite, MySeek, MyClose, &UserData);

   /* Load the bitmap as an 8 bit */
   nRet = L_LoadBitmap (TEXT("rubbish"), &Data.BitmapHandle, sizeof(BITMAPHANDLE), 8, ORDER_RGB, NULL, NULL);
   if(nRet != SUCCESS)
      return nRet;
   /* Reset the I/O routines to the default ones. */
   L_RedirectIO (NULL, NULL, NULL, NULL, NULL, NULL);

   /* free the bitmap when we are done */
   L_FreeBitmap(&Data.BitmapHandle);
   GlobalUnlock (hBuf);
   GlobalFree (hBuf);
   return SUCCESS;
}