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])); } }
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])); }
/*---------------------------------------------------------------------------*/ 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; }