Beispiel #1
0
static void ICC_Async_InvertBuffer(uint32_t size, unsigned char *buffer)
{
	uint32_t i;
	cs_debug_mask(D_IFD, "%s: size=%u buf[0]=%02x", __func__, size, buffer[0]);
	for(i = 0; i < size; i++)
		{ buffer[i] = ~(INVERT_BYTE(buffer[i])); }
}
Beispiel #2
0
static void ICC_Async_InvertBuffer (uint32_t size, BYTE * buffer)
{
	uint32_t i;

	for (i = 0; i < size; i++)
		buffer[i] = ~(INVERT_BYTE (buffer[i]));
}
Beispiel #3
0
/*---------------------------------------------------------------------------*/
static int TTWAIN_MemoryXferHandler(void)
{
	TW_IMAGEMEMXFER *imageMemXfer = 0;
	TW_HANDLE imageMemXferH = 0;
	TW_HANDLE transferBufferH = 0;
	TW_SETUPMEMXFER setup;
	TW_IMAGEINFO info;
	TW_IMAGELAYOUT imageLayout;
	TUINT32 nTransferDone;
	TW_INT16 rc1, rc2, rc3, rc4, twRC2;
	int ret = FALSE;
	int stopScanning = 0;
	UCHAR *transferBuffer = 0;
	UCHAR *sourceBuffer = 0;
	UCHAR *targetBuffer = 0;
	unsigned int rows;
	double pixSize;
	int extraX = 0;
	int extraY = 0;
	TW_UINT32 rowsToCopy = 0;
	TW_UINT32 rowsRemaining = 0;
	TW_UINT32 bytesToCopy = 0;
	TW_UINT32 bytesToWrap = 0;
	TW_UINT32 memorySize = 0;
	int imgInfoOk; /* on Mac often (always) is impossible to get the imageinfo
										 about the transfer... so no I can't prealloc memory 
										 and do other checks about size etc...
									*/

	/*printf("%s\n", __PRETTY_FUNCTION__);*/

	memset(&info, 0, sizeof(TW_IMAGEINFO));
	rc1 = TTWAIN_DS(DG_IMAGE, DAT_IMAGEINFO, MSG_GET, (TW_MEMREF)&info);
	imgInfoOk = (rc1 == TWRC_SUCCESS);

	/*printf("get image info returns %d\n", imgInfoOk);*/

	rc4 = TTWAIN_DS(DG_IMAGE, DAT_IMAGELAYOUT, MSG_GET, &imageLayout);

	/* determine the transfer buffer size */
	rc2 = TTWAIN_DS(DG_CONTROL, DAT_SETUPMEMXFER, MSG_GET, (TW_MEMREF)&setup);
	transferBufferH = GLOBAL_ALLOC(GMEM_FIXED, setup.Preferred);
	if (!transferBufferH)
		return FALSE;
	transferBuffer = (UCHAR *)GLOBAL_LOCK(transferBufferH);

	if (imgInfoOk) {
		pixSize = info.BitsPerPixel / 8.0;
		memorySize = info.ImageLength * CEIL(info.ImageWidth * pixSize);
	} else {
		/* we need to allocate incrementally the memory needs to store the image*/
		memorySize = setup.Preferred; /* start using the setupmemxfer.preferred size*/
		pixSize = 3;
	}

	if (TTwainData.transferInfo.usageMode == TTWAIN_MODE_UNLEASHED) {
		/*
  TTwainData.transferInfo = GLOBAL_ALLOC(GMEM_FIXED, memorySize); 
*/
		TTwainData.transferInfo.memoryBuffer = (UCHAR *)malloc(memorySize);

		if (!TTwainData.transferInfo.memoryBuffer) {
			/*tmsg_error("unable to allocate memory!");*/
			return FALSE;
		}
		if (imgInfoOk) {
			TTwainData.transferInfo.memorySize = memorySize;
			TTwainData.transferInfo.preferredLx = info.ImageWidth;
			TTwainData.transferInfo.preferredLy = info.ImageLength;
		} else {
			TTwainData.transferInfo.memorySize = setup.Preferred;
			TTwainData.transferInfo.preferredLx = 0;
			TTwainData.transferInfo.preferredLy = 0;
		}
	}

	extraX = info.ImageWidth - TTwainData.transferInfo.preferredLx;
	extraY = info.ImageLength - TTwainData.transferInfo.preferredLy;

	rowsRemaining = MIN(TTwainData.transferInfo.preferredLy, info.ImageLength);

	targetBuffer = TTwainData.transferInfo.memoryBuffer;

	/*clean-up the buffer
memset(targetBuffer, 0xff, TTwainData.transferInfo.memorySize);
*/

	imageMemXferH = GLOBAL_ALLOC(GMEM_FIXED, sizeof(TW_IMAGEMEMXFER));
	if (!imageMemXferH)
		return FALSE;

	imageMemXfer = (TW_IMAGEMEMXFER *)GLOBAL_LOCK(imageMemXferH);

	imageMemXfer->Memory.TheMem = (char *)transferBuffer;
	imageMemXfer->Memory.Length = setup.Preferred;
	imageMemXfer->Memory.Flags = TWMF_APPOWNS | TWMF_POINTER;
	TTwainData.transferInfo.pendingXfers.Count = 0;
	/* transfer the data -- loop until done or canceled */
	nTransferDone = 0;
	do {
		rc3 = TTWAIN_DS(DG_IMAGE, DAT_IMAGEMEMXFER, MSG_GET, (TW_MEMREF)imageMemXfer);
		nTransferDone++;
		switch (rc3) {
		case TWRC_SUCCESS:
			PRINTF("IMAGEMEMXFER, GET, returns SUCCESS\n");
			if (imgInfoOk) {
				TW_UINT32 colsToCopy;
				rowsToCopy = MIN(imageMemXfer->Rows, rowsRemaining);
				colsToCopy = MIN(imageMemXfer->Columns, (unsigned long)TTwainData.transferInfo.preferredLx);
				bytesToCopy = CEIL(colsToCopy * pixSize);
				bytesToWrap = CEIL(TTwainData.transferInfo.preferredLx * pixSize);
			} else {
				TW_UINT32 newMemorySize;
				rowsToCopy = imageMemXfer->Rows;
				bytesToCopy = imageMemXfer->BytesPerRow;
				bytesToWrap = bytesToCopy;
				newMemorySize = (TTwainData.transferInfo.preferredLy + imageMemXfer->Rows) * imageMemXfer->BytesPerRow;
				if (TTwainData.transferInfo.memorySize < newMemorySize) {
					TTwainData.transferInfo.memoryBuffer = (UCHAR *)realloc(TTwainData.transferInfo.memoryBuffer, newMemorySize);
					TTwainData.transferInfo.memorySize = newMemorySize;
					targetBuffer = TTwainData.transferInfo.memoryBuffer + (TTwainData.transferInfo.preferredLy * imageMemXfer->BytesPerRow);
				}
				TTwainData.transferInfo.preferredLy += rowsToCopy;
				if ((int)imageMemXfer->Columns > TTwainData.transferInfo.preferredLx)
					TTwainData.transferInfo.preferredLx = imageMemXfer->Columns;
			}

			sourceBuffer = (UCHAR *)imageMemXfer->Memory.TheMem;
			if (TTwainData.transferInfo.nextImageNeedsToBeInverted)
				INVERT_BYTE(sourceBuffer, bytesToCopy)

			for (rows = 0; rows < rowsToCopy; rows++) {
				memcpy(targetBuffer, sourceBuffer, bytesToCopy);
				targetBuffer += bytesToWrap;
				sourceBuffer += imageMemXfer->BytesPerRow;
			}
			rowsRemaining -= rowsToCopy;
			break;

		case TWRC_XFERDONE:
			PRINTF("IMAGEMEMXFER, GET, returns XFERDONE\n");
			/*copy the last transfer data*/
			if (imgInfoOk) {
				TW_UINT32 colsToCopy;
				rowsToCopy = MIN(imageMemXfer->Rows, rowsRemaining);
				colsToCopy = MIN(imageMemXfer->Columns, (unsigned long)TTwainData.transferInfo.preferredLx);
				bytesToCopy = CEIL(colsToCopy * pixSize);
				bytesToWrap = CEIL(TTwainData.transferInfo.preferredLx * pixSize);
			} else {
				TW_UINT32 newMemorySize;
				rowsToCopy = imageMemXfer->Rows;
				bytesToCopy = imageMemXfer->BytesPerRow;
				bytesToWrap = bytesToCopy;
				newMemorySize = (TTwainData.transferInfo.preferredLy + imageMemXfer->Rows) * imageMemXfer->BytesPerRow;
				if (TTwainData.transferInfo.memorySize < newMemorySize) {
					TTwainData.transferInfo.memoryBuffer = (UCHAR *)realloc(TTwainData.transferInfo.memoryBuffer, newMemorySize);
					TTwainData.transferInfo.memorySize = newMemorySize;
					targetBuffer = TTwainData.transferInfo.memoryBuffer + (TTwainData.transferInfo.preferredLy * imageMemXfer->BytesPerRow);
				}
				TTwainData.transferInfo.preferredLy += rowsToCopy;
				if ((int)imageMemXfer->Columns > TTwainData.transferInfo.preferredLx)
					TTwainData.transferInfo.preferredLx = imageMemXfer->Columns;
			}
			sourceBuffer = (UCHAR *)imageMemXfer->Memory.TheMem;
			if (TTwainData.transferInfo.nextImageNeedsToBeInverted)
				INVERT_BYTE(sourceBuffer, bytesToCopy)

			for (rows = 0; rows < rowsToCopy; rows++) {
				memcpy(targetBuffer, sourceBuffer, bytesToCopy);
				targetBuffer += bytesToWrap;
				sourceBuffer += imageMemXfer->BytesPerRow;
			}
			rowsRemaining -= rowsToCopy;
			PRINTF("get pending xfers\n");
			twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
							  (TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
			if (twRC2 != TWRC_SUCCESS) {
				printf("pending xfers != success");
				ret = FALSE;
				goto done;
			}
			PRINTF(" pending count = %d\n", TTwainData.transferInfo.pendingXfers.Count);
			if (TTwainData.transferInfo.pendingXfers.Count == 0) {
				ret = TRUE;
				goto done;
			}
			if (TTwainData.transferInfo.pendingXfers.Count == 0xffff) {
				ret = TRUE;
				goto done;
			}
			if (TTwainData.transferInfo.pendingXfers.Count == 0xfffe) {
				ret = TRUE;
				goto done;
			}
			ret = TRUE;
			goto done;

		case TWRC_CANCEL:
			TTWAIN_RecordError();
			twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
							  (TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
			if (twRC2 != TWRC_SUCCESS) {
				ret = FALSE;
				goto done;
			}
			if (TTwainData.transferInfo.pendingXfers.Count == 0) {
				ret = FALSE;
				goto done;
			}
			break;

		case TWRC_FAILURE:
			PRINTF("IMAGEMEMXFER, GET, returns FAILURE\n");
			TTWAIN_RecordError();
			twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
							  (TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
			if (twRC2 != TWRC_SUCCESS) {
				ret = FALSE;
				goto done;
			}
			if (TTwainData.transferInfo.pendingXfers.Count == 0) {
				ret = FALSE;
				goto done;
			}
			break;

		default:
			PRINTF("IMAGEMEMXFER, GET, returns ?!? Default handler called\n");
			/* Abort the image */
			TTWAIN_RecordError();
			twRC2 = TTWAIN_DS(DG_CONTROL, DAT_PENDINGXFERS, MSG_ENDXFER,
							  (TW_MEMREF)&TTwainData.transferInfo.pendingXfers);
			if (twRC2 != TWRC_SUCCESS) {
				ret = FALSE;
				goto done;
			}
			if (TTwainData.transferInfo.pendingXfers.Count == 0) {
				ret = FALSE;
				goto done;
			}
		}
	} while (rc3 == TWRC_SUCCESS);

done:
	if (ret == TRUE) {
		if (TTwainData.callback.onDoneCb) {
			float xdpi, ydpi;
			TTWAIN_PIXTYPE pixType;
			xdpi = TTWAIN_Fix32ToFloat(info.XResolution);
			ydpi = TTWAIN_Fix32ToFloat(info.YResolution);

			if (imgInfoOk) {
				xdpi = TTWAIN_Fix32ToFloat(info.XResolution);
				ydpi = TTWAIN_Fix32ToFloat(info.YResolution);
				switch (BB(info.PixelType, info.BitsPerPixel)) {
				case BB(TWPT_BW, 1):
					pixType = TTWAIN_BW;
					break;
				case BB(TWPT_GRAY, 8):
					pixType = TTWAIN_GRAY8;
					break;
				case BB(TWPT_RGB, 24):
					pixType = TTWAIN_RGB24;
					break;
				default:
					pixType = TTWAIN_RGB24;
					break;
				}
			} else {
				float lx = TTWAIN_Fix32ToFloat(imageLayout.Frame.Right) - TTWAIN_Fix32ToFloat(imageLayout.Frame.Left);
				float ly = TTWAIN_Fix32ToFloat(imageLayout.Frame.Bottom) - TTWAIN_Fix32ToFloat(imageLayout.Frame.Top);

				xdpi = (float)TTwainData.transferInfo.preferredLx / lx;
				ydpi = (float)TTwainData.transferInfo.preferredLy / ly;

				switch (imageMemXfer->BytesPerRow / TTwainData.transferInfo.preferredLx) {
				case 1:
					pixType = TTWAIN_GRAY8;
					break;
				case 3:
					pixType = TTWAIN_RGB24;
					break;
				default: {
					double b = (imageMemXfer->BytesPerRow /
								(double)TTwainData.transferInfo.preferredLx);
					if ((b >= 0.125) && (b < 8))
						pixType = TTWAIN_BW;
					else {
						printf("unable to det pix type assume RGB24\n");
						pixType = TTWAIN_RGB24;
					}
					break;
				}
				}
			}
			stopScanning = !TTwainData.callback.onDoneCb(
				TTwainData.transferInfo.memoryBuffer,
				pixType,
				TTwainData.transferInfo.preferredLx,
				TTwainData.transferInfo.preferredLy,
				TTwainData.transferInfo.preferredLx,
				xdpi, ydpi,
				TTwainData.callback.onDoneArg);
#ifdef MACOSX
			PRINTF("stopScanning = %d\n", stopScanning);
			exitTwainSession();
#endif
		}
	} else /*ret == FALSE*/
	{
		if (TTwainData.callback.onErrorCb) {
			TTwainData.callback.onErrorCb(TTwainData.callback.onErrorArg, 0);
		}
	}

	if (imageMemXferH) {
		GLOBAL_UNLOCK(imageMemXferH);
		GLOBAL_FREE(imageMemXferH);
	}

	if (transferBufferH) {
		GLOBAL_UNLOCK(transferBuffer);
		GLOBAL_FREE(transferBufferH);
	}
	return ret && !stopScanning;
}