public bool GetHalftoneBuffer(ScannedSide side, short xCoord, short yCoord, short width, short height, MemoryBlock image) { short absX = xCoord; short absY = yCoord; if (side == 0) { absX += _scannerConfig.WorkZone.SideTopX; absY += _scannerConfig.WorkZone.SideTopY; } else { absX += _scannerConfig.WorkZone.SideBottomX; absY += _scannerConfig.WorkZone.SideBottomY; } short bufferId; _scanner.GetHalftoneBuffer(side, absX, absY, width, height, image, out bufferId); Logger.LogVerbose(Message.ScannerManagerGetHalftone, side, xCoord, yCoord, width, height, bufferId); return true; }
public void RunRecognize(MemoryBlock pdImage0, MemoryBlock pdImage1, int nLineWidth0, int nLineWidth1, int nNumOfLines0, int nNumOfLines1) { lock (s_runSync) { s_runRecCount++; // увеличиваю количество вызовов функции if (pdImage0 == null || pdImage1 == null) { SetError(ErrorCode.IllegalUse, "RunRecognize: переданы нулевые указатели на изображения"); throw new OcrException("RunRecognize: переданы нулевые указатели на изображения"); } IntPtr buffer0 = pdImage0.ToPointer(); IntPtr buffer1 = pdImage1.ToPointer(); if (buffer0 == IntPtr.Zero || buffer1 == IntPtr.Zero) { SetError(ErrorCode.UnexpectedError, "RunRecognize: получены нулевые указатели на изображения"); throw new OcrException("RunRecognize: получены нулевые указатели на изображения"); } _side0.all_bin_buf = IntPtr.Zero; _side0.bin_buf = buffer0; _side0.bin_size = (uint) (nNumOfLines0*nLineWidth0); _side0.ByteImageWidth = nLineWidth0; _side0.ImageWidth = nLineWidth0*8; _side0.ActualScanNumber = nNumOfLines0; _side0.tone_buf = IntPtr.Zero; _side0.bin_width = 0; _side0.size = 0; _side0.tone_size = 0; _side0.g_p0.len = 0; _side0.g_p0.start = 0; _side0.g_p1.len = 0; _side0.g_p1.start = 0; _side0.g_p2.len = 0; _side0.g_p2.start = 0; _side0.flag = 0; _side0.ScanCounter = 0; _side0.OutFlag = 0; _side0.LineCount = 0; _side0.xl = 0; _side0.yl = 0; _side0.xr = 0; _side0.yr = 0; _side1.bin_size = (uint) (nNumOfLines1*nLineWidth1); _side1.bin_buf = buffer1; _side1.ImageWidth = nLineWidth1*8; _side1.ByteImageWidth = nLineWidth1; _side1.ActualScanNumber = nNumOfLines1; _side1.tone_buf = IntPtr.Zero; _side1.bin_width = 0; _side1.size = 0; _side1.tone_size = 0; _side1.g_p0.len = 0; _side1.g_p0.start = 0; _side1.g_p1.len = 0; _side1.g_p1.start = 0; _side1.g_p2.len = 0; _side1.g_p2.start = 0; _side1.flag = 0; _side1.ScanCounter = 0; _side1.OutFlag = 0; _side1.LineCount = 0; _side1.xl = 0; _side1.yl = 0; _side1.xr = 0; _side1.yr = 0; _pollResults.Clear(); try { if (_isRunningNow) { EndRecognition(0, 0, 0); } else { _isRunningNow = true; } _bulletinNumber = -1; int res = StartRecognition(ref _side0, ref _side1); if (res < 0) { SetError(ErrorCode.StartRecognitionFailed, "Не удалось начать распознавание: " + res); throw new OcrException("Не удалось начать распознавание: " + res); } StartOnLineTesting(ref _side0, ref _side1, GetFrameDist_mm()); } catch (Exception ex) { SetError(ErrorCode.UnexpectedError, "RunRecognize: " + ex); throw; } } }
public unsafe void GetHalftoneBuffer( ScannedSide side, short x, short y, short w, short h, MemoryBlock iMemory, out short id) { if (side == ScannedSide.Undefined) throw new ArgumentException("Сторона не определена"); var sideIndex = (int)side; var ptr = _sh.HalftoneBuffer[sideIndex]; if (side == ScannedSide.Top) { ptr = HalfToneBuffer0.ToPointer(); } else if (side == ScannedSide.Bottom) { ptr = HalfToneBuffer1.ToPointer(); } var sourceBuffer = (byte*)ptr.ToPointer(); x -= _x[sideIndex]; y -= _y[sideIndex]; if (x < 0) { throw new Exception("недопустимое значение левой границы"); } if (y < 0) { throw new Exception("недопустимое значение верхней границы"); } if (h < 0) { throw new Exception("отрицательная высота"); } if (w < 0) { throw new Exception("отрицательная ширина"); } if (x + w > _currentConfiguration.DotsOneSide || y + h > _currentConfiguration.MaxLines) { throw new Exception("запрашиваемое изображение выходит за границы отсканированной области"); } if (x % DOTS_PER_BYTE_HALFTONE != 0) { throw new Exception("начальная координата не попадает на границу байта!"); } if (w % DOTS_PER_BYTE_HALFTONE != 0) { throw new Exception("ширина запрошенной области содерит не целое число байт!"); } ptr = iMemory.ToPointer(); if (ptr == IntPtr.Zero) { throw new Exception("нет буфера для записи изображения!"); } var destination = (byte*)ptr.ToPointer(); var lengthLine = _currentConfiguration.DotsOneSide / DOTS_PER_BYTE_HALFTONE; var lengthCopy = w / DOTS_PER_BYTE_HALFTONE; var shift = (side == 0 ? 0 : _currentConfiguration.DotsOneSide); if (x == y && y == 0 && lengthCopy == lengthLine) { if (!WhiteCoeffApplyed[sideIndex]) { var wcPtr = _whiteCoeffU.ToPointer(); if ((_currentConfiguration.Options & HardwareOptions.RightToLeftHalftone) > 0) { if (!_halftoneFlipped[sideIndex]) { FlipBufferVertically(sourceBuffer, lengthCopy, h); _halftoneFlipped[sideIndex] = true; } applyWhiteCoeffs(sourceBuffer, destination, (byte*)wcPtr.ToPointer() + shift, lengthCopy, h); } else { applyWhiteCoeffs(sourceBuffer, destination, (byte*)wcPtr.ToPointer() + shift, lengthCopy, h); } } else { } } else { int wcX = x; var wcInc = 1; if (!_halftoneFlipped[sideIndex] && (_currentConfiguration.Options & HardwareOptions.RightToLeftHalftone) > 0) { wcX = x + w - 1; wcInc = -1; x = (short)(_currentConfiguration.DotsOneSide - x - w); } var startLine = sourceBuffer + // начало буфера y * lengthLine + // число байт в первых y-строках x / BaseSharedMemory.DotsPerByteHalftone; // число байт в первых x-точках var p = destination; for (var i = 0; i < h; i++) { var source = startLine; for (int j = 0, wcJ = wcX; j < lengthCopy; j++, wcJ += wcInc) { *p++ = whiteCoeffTable.whiteCoeff[(*source++ << 8) + _whiteCoeff[shift + wcJ]]; } startLine += lengthLine; } if (!_halftoneFlipped[sideIndex] && (_currentConfiguration.Options & HardwareOptions.RightToLeftHalftone) > 0) { FlipBufferVertically(destination, w, h); } } id = 0; }
int OcrCallBackHandler(OcrCallBackType cbType, IntPtr data, int size) { try { DebugOut("CALLBACK: " + cbType + " [" + data.ToInt32().ToString("X") + ", " + size + "]"); switch (cbType) { case OcrCallBackType.ModelSave: { if (size <= 0 || data == IntPtr.Zero) { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": неверные или неожиданные параметры [" + data.ToInt32().ToString("X") + ", " + size + "]"); return -3; } try { if (File.Exists(ModelFilePath)) File.Delete(ModelFilePath); var modelData = new byte[size + 1]; Marshal.Copy(data, modelData, 0, size); using (FileStream fs = File.Create(ModelFilePath)) { fs.Write(modelData, 0, size); fs.Flush(); } return 1; } catch (Exception ex) { SetError(ErrorCode.UnexpectedError, "CALLBACK: " + cbType + ": " + ex); return -2; } } case OcrCallBackType.GetModelFileSize: { try { var fi = new FileInfo(ModelFilePath); return (int)fi.Length; } catch (Exception ex) { SetError(ErrorCode.UnexpectedError, "CALLBACK: " + cbType + ": " + ex); return -2; } } case OcrCallBackType.ModelRestore: { int retval = 1; var fi = new FileInfo(ModelFilePath); if (fi.Length == size) { var modelData = new byte[size + 1]; using (FileStream fs = File.OpenRead(ModelFilePath)) { fs.Read(modelData, 0, size); } Marshal.Copy(modelData, 0, data, size); } else { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": длина файла не соответствует ожидаемой"); retval = -1; } return retval; } case OcrCallBackType.DataSave: break; case OcrCallBackType.DataRestore: break; case OcrCallBackType.GetStamp: return GetStamp(size); case OcrCallBackType.GetStampCount: return GetStampCount(); case OcrCallBackType.GetStampMinLineWidth: return GetStampMinLineWidth(); case OcrCallBackType.GetStampMaxLineWidth: return GetStampMaxLineWidth(); case OcrCallBackType.GetStampTestLevel: return GetStampTestLevel(); case OcrCallBackType.GetSideResolution: { if (data == IntPtr.Zero) { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": неверные или неожиданные параметры [" + data.ToInt32().ToString("X") + ", " + size + "]"); return -1; } var s = (Resolution)Marshal.PtrToStructure(data, typeof(Resolution)); if (s.side == 0) { s.x = _dpiX0; s.y = _dpiY0; Marshal.StructureToPtr(s, data, true); } else if (s.side == 1) { s.x = _dpiX1; s.y = _dpiY1; Marshal.StructureToPtr(s, data, true); } else { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": неверные или неожиданные параметры [" + data.ToInt32().ToString("X") + ", " + size + "]"); return -1; } } break; case OcrCallBackType.PutBulletinNumber: PutBulletinNumber(size); break; case OcrCallBackType.PutResults: { var s = (OcrResult)Marshal.PtrToStructure(data, typeof(OcrResult)); DebugOut("s.IsValid = " + s.IsValid + ", s.numChecked = " + s.numChecked + ", s.PollNum = " + s.PollNum); if (! PutResult(s)) { SetError(ErrorCode.UnexpectedError, "CALLBACK: " + cbType + ": не удалось сохранить результат распознавания"); return -1; } } break; case OcrCallBackType.GetPath2Data: { if(string.IsNullOrEmpty(_bstrPath2RecognitionData)) { data = IntPtr.Zero; } else { Marshal.Copy(_bstrPath2RecognitionData.ToCharArray(), 0, data, _bstrPath2RecognitionData.Length); } } break; case OcrCallBackType.GetDigitSquares: return 0; case OcrCallBackType.UnloadDigitOcrResult: return -1; case OcrCallBackType.GetGrayRectBuffSize: if(data == IntPtr.Zero || (size != 0 && size != 1)) { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": неверные или неожиданные параметры [" + data.ToInt32().ToString("X") + ", " + size + "]"); return -1; } var r = (AlRect) Marshal.PtrToStructure(data, typeof (AlRect)); if (r.y < 0 || r.h < 0 || r.x < 0 || r.w < 0) { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": Запрошен недопустимый размер буфера полутона: x=" + r.x + ", y=" + r.y + ", w=" + r.w + ", h=" + r.h); return -1; } var bufSize = r.h * r.w; // количество пиксел DebugOut("Вычислен размер полутонового буфера: size=" + bufSize); return bufSize; case OcrCallBackType.GetGrayRectImage: if (data == IntPtr.Zero || (size != 0 && size != 1)) { return -1; } var alSubf = (AlSubf) Marshal.PtrToStructure(data, typeof (AlSubf)); if (_events != null) { var piMem = new MemoryBlock(alSubf.@base); try { long nSize = _events.GetHalfToneBuffer(this, (short) size, alSubf.x, alSubf.y, alSubf.ys, alSubf.xs, piMem); if (nSize == -1) { DebugOut("GetGrayRectImage: Unable to get image"); return -1; } } catch (Exception ex) { SetError(ErrorCode.UnexpectedError, "CALLBACK: " + cbType + ": " + ex); return -1; } } else { SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": не установлен обработчик события GetHalfToneBuffer"); return -1; } alSubf.width = alSubf.xs; return 1; case OcrCallBackType.GetBinThreshold: if (size == 0 || size == 1) { try { if (_events != null) { int nThr = _events.GetBinaryThreshold(this, (short)size); return nThr; } SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": не установлен обработчик события GetBinaryThreshold"); return -1; } catch (Exception ex) { SetError(ErrorCode.UnexpectedError, "CALLBACK: " + cbType + ": " + ex); return -1; } } SetError(ErrorCode.IllegalUse, "CALLBACK: " + cbType + ": неверные или неожиданные параметры [" + data.ToInt32().ToString("X") + ", " + size + "]"); return -1; case OcrCallBackType.ReportProgress: DebugOut("Progress: " + size); break; default: SetError(ErrorCode.IllegalUse, "CALLBACK: не распознанный код " + cbType); break; } } catch(Exception ex) { try { SetError(ErrorCode.UnexpectedError, "CALLBACK: ERROR [" + cbType + ", " + data.ToInt32().ToString("X") + ", " + size + "] => " + ex); } catch(Exception exOnSetError) { SetError(ErrorCode.UnexpectedError, "CALLBACK: ERROR [" + cbType + "] => " + ex); SetError(ErrorCode.UnexpectedError, "CALLBACK: SETERROR => " + exOnSetError); } } return 1; }
public int GetHalfToneBuffer(IOcr ocr, short side, int x, int y, int height, int width, MemoryBlock image) { if (!_config.Ocr.GrayAnalysis.Enabled) return -1; try { var res = _scannerManager.GetHalftoneBuffer( (ScannedSide)side, (short)x, (short)y, (short)width, (short)height, image); if (res && _config.DebugImageSaving.Squares) { var imageDirectoryPath = _fileSystemManager.GetDataDirectoryPath(FileType.ScanningImage); long requiredSize = width * height; if (ReserveSpaceForImage(requiredSize)) { var filePathSb = GetImageFileName("SQ"); filePathSb.Insert(0, imageDirectoryPath + '/'); filePathSb.AppendFormat("_S{0}_X{1}_Y{2}_W{3}_H{4}.tif", side, x, y, width, height); TiffImageHelper.SaveToFile(filePathSb.ToString(), ImageType.Halftone, image, width, height); } } return res ? width * height : -1; } catch (Exception ex) { Logger.LogError(Message.RecognizerGetBufferError, ex); return -1; } }