Home › Forums › TWAIN Classic › Lost in Buffered Memory Transfer
- This topic has 2 replies, 2 voices, and was last updated 18 years ago by clandestino.
- AuthorPosts
Hi everybody.
I’m working on my own TWAIN Data Source, which should open files from my hard disk and transfers it into any TWAIN-supporting application. Since it took me already some time to get it working, I think I can say I have at least a bare idea of what the TWAIN protocol does. But I don’t know anything on image processing, so I’m using a library called paintlib (you can grab it here http://www.paintlib.de/paintlib/) for the opening and format converting stuff – so lets assume I ony work on Windows Bitmaps. My source works fine on native transfer (DG_IMAGE | DAT_IMAGENATIVEXFER | MSG_GET). The library opens the picture, returns a handle to a copy in global memory, i pass it to the application and thats it.My problem is the buffered transfer (DG_IMAGE | DAT_IMAGEMEMXFER | MSG_GET), but first things first: I thought, just because my source is only pretending to be a scanner I could return to most of the request dummy data. I provide only mandatory capabilities (mandatory in TWAIN 1.6), the source does not allow to set xy resolution or an image layout, but it returns a layout that more or less fits the layout of the image that is ready to scan.
As long as the application wants to scan native data everything works fine. I only experience problems when the application switches to buffered transfer. Please have a look at these screenshots (See also the code I’m reffering to at the end of this posting):
screenshot from GIMP
These ones are produced by Gimp and Acrobat Reader, and I don’t know where to start fixing the error. I thought passing the memory to the application whould be as straight forward as the native mode. I request enough memory for at least one whole line, max. the entire picture, preferred 10 lines. My code copies the lines from a line array presented by my PAINTLIB library and flips the red and blue color channel if required (this is set in an extern config-file). The scanning process terminates fine but in most cases i recieve these crashed results like shown on the screenshots.How has experienced the same results during developing a twain source or how knows what i am doing wrong? am i missing something? I don’t get it, please give me some hints. Well, at least thank you very much for reading up to this line. I would appreciate it when you could drop me a line what you think of my problem.
with kind regards,
F.Michels
TW_UINT16 CTW_TransferManager::processMemoryTransfer(TWMSG& msg)
{
CmfctwainApp* pParent =NULL;
GET_PARENT(pParent);
ASSERT(pParent != NULL);
pTW_IMAGEMEMXFER pXfer =(pTW_IMAGEMEMXFER)msg.pData;
BITMAPINFOHEADER* pBMIH;
if(pParent->pStatusMgr->getState() == CTW_StatusManager::STATE6)
{
if(pBmp != NULL)
{
pParent->pStatusMgr->setConditionCode(CTW_StatusManager::OPERATIONERROR);
return TWRC_FAILURE;
}
/*
#ifdef _DEBUG
// check what transfer mode we are in
AfxMessageBox("DG_IMAGE | DAT_IMAGEMEMXFER | MSG_GETnImage Buffer Transfer", MB_OK);
#endif
*/
// Bild öffnen
PLAnyPicDecoder decoder;
//pBmp =new PLWinBmp;
pDib =new PLDIBSection;
t_transfer_job job =jobQueue.front(); // get current job
#ifdef _DEBUG
decoder.SetTraceConfig(3, NULL);
#endif
//decoder.MakeBmpFromFile(job.strPath, pBmp);
// do we have to switch color channels RGB to BGR ??
iPixelformat =atoi(pParent->pXmlConfig->getProperty(XMLCFG_PROPERTY_PIXELFORMAT));
// open 32-bit bitmap
decoder.MakeBmpFromFile(job.strPath, pDib);
decoder.Close();
rowCount =0;
buffer.NewTransfer(pDib);
// Status ändern
pParent->pStatusMgr->setState(CTW_StatusManager::STATE7);
}
// the buffer class takes care of the passed TW_IMAGEMEMXFER structure
// locks memory and fills in the requested fields
buffer.AttachBuffer(pXfer);
BYTE* pDestRow;
PLPixel32** lineArray =pDib->GetLineArray32();
for(int rowIndex=buffer.YOffset(); buffer.GetWriteRowPtr(pDestRow); rowIndex++)
{
PLPixel32* pSrcRow =lineArray[rowIndex];
size_t length =(pDib->GetBitsPerPixel() * pDib->GetWidth() + 7) / 8;
memcpy(pDestRow, pSrcRow, length);
// flip color channels if required (RGB -> BGR!)
if(iPixelformat == XMLCFG_PF_BGRx)
{
BYTE* pbuf =pDestRow;
for (int n = pDib->GetWidth(); n--; pbuf += 4)
{
BYTE t = pbuf[2];
pbuf[2] = pbuf[0];
pbuf[0] = t;
}
}
}
// unlock memory
buffer.DetachBuffer();
pXfer->Columns =pXfer->Columns;
if(buffer.XferDone())
{
// clean up
delete pDib;
finishImageTransfer(&jobQueue.front());
return TWRC_XFERDONE;
}
else
return TWRC_SUCCESS;
}
what was the solution?
set the pixel type wrong (PLANARCHUNKY) and paintlib provided wired samples per pixel (the library reports 3 samples per pixel, but when i copy the memory, every pixel has a forth sample….)
- AuthorPosts