Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Wednesday, December 23, 2015 5:19:03 AM(UTC)

sfirouz  
sfirouz

Groups: Registered
Posts: 6


I need to save a Multi-page TIFF file using L_SaveFileOffset because I need to make sure no other process including Windows itself can access the file in the middle of saving pages and as far as I know L_SaveFileOffset is the only API for saving in <strong>LeadTools</strong> that allows saving the image using a file handle. The problem is, no matter what I do, only the last page gets saved. Please Help.<br /><br />
<pre>
HANDLE hFile = ::CreateFile(L"ColorMaps.tif", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if(NULL != hFile)
{
const wchar_t pathTemplate[] = {L"ColorMap%d.bmp"};
wchar_t tPath[sizeof(pathTemplate) / sizeof(pathTemplate[0])];
FILEINFO PageInfo;
SAVEFILEOPTION so;
LOADFILEOPTION tlo;
int i;
HDC hDc;
BITMAPHANDLE tBmp;
__int64 tSize;

memset(&tlo, 0, sizeof(LOADFILEOPTION));
tlo.uStructSize = sizeof(LOADFILEOPTION);
L_GetDefaultLoadFileOption(&tlo, sizeof(LOADFILEOPTION));
tlo.Flags |= ELO_ROTATED;
hDc = ::GetDC(NULL);
tlo.XResolution = ::GetDeviceCaps(hDc, LOGPIXELSX);
tlo.YResolution = ::GetDeviceCaps(hDc, LOGPIXELSY);
::ReleaseDC(NULL, hDc);
memset(&so, 0, sizeof(SAVEFILEOPTION));
so.uStructSize = sizeof(SAVEFILEOPTION);
so.Flags = ESO_INSERTPAGE;

memset(&tBmp, 0, sizeof(BITMAPHANDLE));
tBmp.uStructSize = sizeof(BITMAPHANDLE);
for(i = 1; i &lt 7; i++)
{
::StringCbPrintf(tPath, sizeof(tPath), pathTemplate, i);
L_FileInfo(tPath, &PageInfo, sizeof(FILEINFO), 0, &tlo);
L_LoadBitmap(tPath, &tBmp, sizeof(BITMAPHANDLE), 0, ORDER_RGBORGRAY, &tlo, &PageInfo);
if (TOP_LEFT != tBmp.ViewPerspective)
L_ChangeBitmapViewPerspective(NULL, &tBmp, sizeof(BITMAPHANDLE), TOP_LEFT);
L_SaveFileOffset((L_HFILE)hFile, 0, &tSize, &tBmp, FILE_TIF_PACKBITS, PageInfo.BitsPerPixel, 0, SAVEFILE_MULTIPAGE, NULL, NULL, &so);
so.PageNumber = i + 1;
}
::CloseHandle(hFile);
}
</pre>
<br />
The above is just an example and there might be 1000's of pages being saved into the TIFF file.<br />
The problem shows itself if a user opens <strong>Windows Explorer</strong> and navigates to the directory were the file is being saved, you can see that windows is trying to repaint the icon for the file in between each page save and if I use L_SaveBitmap or L_SaveFile, sometimes they return <strong><em>-14</em></strong> because windows is reading the file and <strong>LeadTools</strong> cannot get a lock on it.<br />
P.S. L_SaveFileOffset returns <strong>1</strong> (<em>SUCCESS</em>) for all the pages and I am using <strong>LeadTools Documents imaging version 17.5</strong>.<br />
Thank you
 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

#2 Posted : Sunday, December 27, 2015 6:09:17 AM(UTC)

Amin  
Amin

Groups: Manager, Tech Support
Posts: 367

Was thanked: 1 time(s) in 1 post(s)

One way to have total control over the file handle is to use redirected IO. The code needed to lock the TIFF file for the whole 6 pages will be something like this:

// 2 global variables
L_HFILE hFileMyTiff = NULL;
bool reallyClose = false;
L_HFILE EXT_CALLBACK MyOpen(L_TCHAR* pFile, L_INT nMode, L_INT nShare, L_VOID* pUserData)
{
   if(!hFileMyTiff) //only open the file if it's not already open
      hFileMyTiff = (L_HFILE)::CreateFile(pFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
   return hFileMyTiff;
}
L_UINT EXT_CALLBACK MyRead(L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID *pUserData)
{
   DWORD dwRead = 0;
   ::ReadFile(FD, pBuf, uCount, &dwRead, NULL);
   return dwRead;
}
L_UINT EXT_CALLBACK MyWrite(L_HFILE FD, L_UCHAR * pBuf, L_UINT uCount, L_VOID* pUserData)
{
   DWORD dwWritten = 0;
   ::WriteFile(FD, pBuf, uCount, &dwWritten, NULL);
   return dwWritten;
}
L_SSIZE_T EXT_CALLBACK MySeek(L_HFILE FD, L_SSIZE_T nPos, L_INT nOrigin, L_VOID* pUserData)
{
   return ::SetFilePointer(FD, nPos, NULL, nOrigin);
}
L_INT EXT_CALLBACK MyClose (L_HFILE FD, L_VOID* pUserData)
{
   if(reallyClose)
   {
      ::CloseHandle(FD);
      hFileMyTiff = NULL;
   }
   else
      ::SetFilePointer(FD, 0, NULL, FILE_BEGIN);
   return TRUE;
}
void tst()
{
   const wchar_t pathTemplate[] = {L"ColorMap%d.bmp"};
   wchar_t tPath[sizeof(pathTemplate) / sizeof(pathTemplate[0])];
   FILEINFO PageInfo;
   LOADFILEOPTION tlo;
   int i;
   HDC hDc;
   BITMAPHANDLE tBmp;
   __int64 tSize;

   memset(&tlo, 0, sizeof(LOADFILEOPTION));
   tlo.uStructSize = sizeof(LOADFILEOPTION);
   L_GetDefaultLoadFileOption(&tlo, sizeof(LOADFILEOPTION));
   tlo.Flags |= ELO_ROTATED;
   hDc = ::GetDC(NULL);
   tlo.XResolution = ::GetDeviceCaps(hDc, LOGPIXELSX);
   tlo.YResolution = ::GetDeviceCaps(hDc, LOGPIXELSY);
   ::ReleaseDC(NULL, hDc);

   memset(&tBmp, 0, sizeof(BITMAPHANDLE));
   tBmp.uStructSize = sizeof(BITMAPHANDLE);
   for(i = 1; i < 7; i++)
   {
      ::StringCbPrintf(tPath, sizeof(tPath), pathTemplate, i);
      L_FileInfo(tPath, &PageInfo, sizeof(FILEINFO), 0, &tlo);
      L_LoadBitmap(tPath, &tBmp, sizeof(BITMAPHANDLE), 0, ORDER_RGBORGRAY, &tlo, &PageInfo);
      if (TOP_LEFT != tBmp.ViewPerspective)
         L_ChangeBitmapViewPerspective(NULL, &tBmp, sizeof(BITMAPHANDLE), TOP_LEFT);

      if(i==6) //only allow closing after the last page is saved
         reallyClose = true;
      else
         reallyClose = false;
      L_RedirectIO(MyOpen, MyRead, MyWrite, MySeek, MyClose, NULL); //use our own file I/O functions
      L_SaveFile(L"ColorMaps.tif", &tBmp, FILE_TIF_PACKBITS, PageInfo.BitsPerPixel, 0, SAVEFILE_MULTIPAGE, NULL, NULL, NULL);
      L_RedirectIO(NULL, NULL, NULL, NULL, NULL, NULL); //reset to default I/O so as not affect loading
   }
}


Note the use of 2 global variables for simplicity. A cleaner approach might be to define your own data structure and pass its address in the pUserData parameter of L_RedirectIO.
Amin Dodin

Senior Support Engineer
LEAD Technologies, Inc.
LEAD Logo
 
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2024, Yet Another Forum.NET
This page was generated in 0.092 seconds.