OneOCR Dev commited on
Commit
feff106
·
1 Parent(s): 366e8c3

fix: self-contained Colab notebook - inline C source, no git dependency

Browse files
Files changed (1) hide show
  1. test_wine_colab.ipynb +286 -179
test_wine_colab.ipynb CHANGED
@@ -5,20 +5,20 @@
5
  "id": "d603dd1d",
6
  "metadata": {},
7
  "source": [
8
- "# OneOCR — Wine Bridge Test na Linux\n",
9
  "\n",
10
- "Test czy `oneocr.dll` działa na Linuxie przez Wine → **100% accuracy**.\n",
11
  "\n",
12
  "**Kroki:**\n",
13
- "1. Instalacja Wine + MinGW na Ubuntu (Colab)\n",
14
- "2. Clone repo + **ręczny upload DLL** do `ocr_data/`\n",
15
- "3. Kompilacja C loadera\n",
16
- "4. Uruchomienie DLL przez Wine → OCR na obrazach testowych\n",
17
- "\n",
18
- "**Potrzebne pliki** (wrzuć po komórce 4):\n",
19
- "- `oneocr.dll` (40 MB)\n",
20
- "- `oneocr.onemodel` (56 MB)\n",
21
- "- `onnxruntime.dll` (13 MB)"
22
  ]
23
  },
24
  {
@@ -28,23 +28,13 @@
28
  "metadata": {},
29
  "outputs": [],
30
  "source": [
31
- "# 1. Install Wine + MinGW (use WineHQ repo for latest stable)\n",
32
- "import subprocess, os\n",
33
- "\n",
34
- "# Add WineHQ repo for latest stable Wine (Ubuntu's stock is old)\n",
35
- "cmds = [\n",
36
- " 'dpkg --add-architecture i386',\n",
37
- " 'mkdir -pm755 /etc/apt/keyrings',\n",
38
- " 'wget -qO /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key 2>/dev/null || true',\n",
39
- " 'apt-get update -qq',\n",
40
- " 'apt-get install -y -qq wine64 mingw-w64 > /dev/null 2>&1',\n",
41
- "]\n",
42
- "for cmd in cmds:\n",
43
- " subprocess.run(cmd, shell=True, capture_output=True)\n",
44
- "\n",
45
- "# Show Wine version\n",
46
  "!wine64 --version\n",
47
- "!x86_64-w64-mingw32-gcc --version | head -1"
 
48
  ]
49
  },
50
  {
@@ -54,15 +44,13 @@
54
  "metadata": {},
55
  "outputs": [],
56
  "source": [
57
- "# 2. Initialize Wine prefix (64-bit, suppress noise)\n",
58
  "import os\n",
59
  "os.environ['WINEDEBUG'] = '-all'\n",
60
  "os.environ['WINEPREFIX'] = '/root/.wine'\n",
61
  "os.environ['WINEARCH'] = 'win64'\n",
62
  "!wineboot --init 2>/dev/null\n",
63
- "!echo \"Wine prefix initialized\"\n",
64
- "# Verify Wine can run basic exe\n",
65
- "!echo 'int main(){return 0;}' > /tmp/test.c && x86_64-w64-mingw32-gcc -o /tmp/test.exe /tmp/test.c && wine64 /tmp/test.exe && echo \"Wine runs MinGW executables OK\""
66
  ]
67
  },
68
  {
@@ -72,14 +60,13 @@
72
  "metadata": {},
73
  "outputs": [],
74
  "source": [
75
- "# 3. Clone repo from HuggingFace\n",
76
- "!pip install -q huggingface_hub 2>/dev/null\n",
77
- "!git lfs install\n",
78
- "!git clone https://huggingface.co/MattyMroz/oneocr /content/oneocr 2>/dev/null || (cd /content/oneocr && git pull)\n",
79
  "!mkdir -p /content/oneocr/ocr_data\n",
80
- "!ls -la /content/oneocr/tools/\n",
81
- "print(\"\\n--- ocr_data/ contents ---\")\n",
82
- "!ls -la /content/oneocr/ocr_data/ 2>/dev/null || echo \"ocr_data/ is empty — upload DLLs in next cell\""
83
  ]
84
  },
85
  {
@@ -89,70 +76,42 @@
89
  "metadata": {},
90
  "outputs": [],
91
  "source": [
92
- "# 4. ⬆️ UPLOAD DLL FILES HERE ⬆️\n",
93
- "# \n",
94
- "# Opcja A: Upload przez Colab (kliknij \"Files\" po lewej Upload)\n",
95
- "# Wrzuć: oneocr.dll, oneocr.onemodel, onnxruntime.dll\n",
96
- "# Potem uruchom komórkę żeby przenieść do ocr_data/\n",
97
  "#\n",
98
- "# Opcja B: Jeśli masz na Google Drive:\n",
99
  "# from google.colab import drive\n",
100
  "# drive.mount('/content/drive')\n",
101
- "# !cp /content/drive/MyDrive/ścieżka/{oneocr.dll,oneocr.onemodel,onnxruntime.dll} /content/oneocr/ocr_data/\n",
102
  "\n",
103
- "import shutil, os\n",
104
  "from pathlib import Path\n",
105
  "\n",
106
  "ocr_data = Path('/content/oneocr/ocr_data')\n",
107
- "needed = {\n",
108
- " 'oneocr.dll': 40_000_000, # ~40 MB\n",
109
- " 'oneocr.onemodel': 50_000_000, # ~56 MB \n",
110
- " 'onnxruntime.dll': 10_000_000, # ~13 MB\n",
111
- "}\n",
112
  "\n",
113
- "# Search multiple possible locations\n",
114
- "search_dirs = [Path('/content'), Path('/root'), Path('/tmp')]\n",
115
- "\n",
116
- "for f, min_size in needed.items():\n",
117
  " dst = ocr_data / f\n",
118
- " if dst.exists() and dst.stat().st_size > min_size:\n",
119
- " print(f' ✅ Już jest: {f} ({dst.stat().st_size / 1e6:.1f} MB)')\n",
120
- " continue\n",
121
- " \n",
122
- " # Find the file\n",
123
- " found = False\n",
124
- " for d in search_dirs:\n",
125
- " src = d / f\n",
126
- " if src.exists() and src.stat().st_size > min_size:\n",
127
- " shutil.copy2(str(src), str(dst))\n",
128
- " print(f' ✅ Skopiowano: {f} ({dst.stat().st_size / 1e6:.1f} MB)')\n",
129
- " found = True\n",
130
- " break\n",
131
- " \n",
132
- " if not found:\n",
133
- " if dst.exists():\n",
134
- " size = dst.stat().st_size\n",
135
- " if size < 1000:\n",
136
- " # Likely git LFS pointer\n",
137
- " print(f' ❌ {f} — to git LFS pointer ({size} B)! Wrzuć prawdziwy plik.')\n",
138
- " with open(dst) as fh:\n",
139
- " print(f' Zawartość: {fh.read(100)[:80]}...')\n",
140
- " else:\n",
141
- " print(f' ⚠️ {f} istnieje ale mały ({size / 1e6:.1f} MB) — sprawdź!')\n",
142
  " else:\n",
143
- " print(f' ❌ BRAK: {f} wrzuć plik!')\n",
 
 
144
  "\n",
145
- "# Final check\n",
146
- "print()\n",
147
- "all_ok = True\n",
148
- "for f, min_size in needed.items():\n",
149
- " dst = ocr_data / f\n",
150
- " if not dst.exists() or dst.stat().st_size < min_size:\n",
151
- " all_ok = False\n",
152
- "if all_ok:\n",
153
- " print('🎉 Wszystkie pliki na miejscu!')\n",
154
- "else:\n",
155
- " print('⚠️ Brakuje plików — wrzuć je i uruchom tę komórkę ponownie.')"
156
  ]
157
  },
158
  {
@@ -173,11 +132,174 @@
173
  "metadata": {},
174
  "outputs": [],
175
  "source": [
176
- "# 6. Compile BOTH loaders: debug + normal\n",
177
- "!x86_64-w64-mingw32-gcc -O2 -o /content/oneocr/tools/oneocr_debug.exe /content/oneocr/tools/oneocr_debug.c\n",
178
- "!x86_64-w64-mingw32-gcc -O2 -o /content/oneocr/tools/oneocr_loader.exe /content/oneocr/tools/oneocr_loader.c\n",
179
- "!ls -la /content/oneocr/tools/*.exe\n",
180
- "print('✅ Both loaders compiled')"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  ]
182
  },
183
  {
@@ -187,46 +309,47 @@
187
  "metadata": {},
188
  "outputs": [],
189
  "source": [
190
- "# 7. 🔍 DIAGNOSTYKA Run debug loader to find exact failure point\n",
191
  "import subprocess, os\n",
192
  "\n",
193
  "os.environ['WINEDEBUG'] = '-all'\n",
 
 
194
  "\n",
195
- "# Convert path for Wine\n",
196
- "dll_dir_wine = 'Z:\\\\content\\\\oneocr\\\\ocr_data'\n",
197
- "\n",
198
- "print(\"=\" * 60)\n",
199
- "print(\"DIAGNOSTYKA: Testowanie komponentów pod Wine\")\n",
200
- "print(\"=\" * 60)\n",
201
- "\n",
202
- "# Run debug loader\n",
203
- "result = subprocess.run(\n",
204
- " ['wine64', '/content/oneocr/tools/oneocr_debug.exe', dll_dir_wine],\n",
205
- " capture_output=True, text=True, timeout=120,\n",
206
- " env={**os.environ, 'WINEDEBUG': '-all'}\n",
207
- ")\n",
208
- "\n",
209
- "print(result.stdout)\n",
210
- "if result.stderr:\n",
211
- " print(\"--- STDERR ---\")\n",
212
- " print(result.stderr[:1000])\n",
213
- "\n",
214
- "# Also run with Wine debug channels for bcrypt/ntdll\n",
215
- "print(\"\\n\" + \"=\" * 60)\n",
216
- "print(\"EXTRA: Wine debug trace (bcrypt + module loading)\")\n",
217
- "print(\"=\" * 60)\n",
218
- "result2 = subprocess.run(\n",
219
- " ['wine64', '/content/oneocr/tools/oneocr_debug.exe', dll_dir_wine],\n",
220
- " capture_output=True, text=True, timeout=120,\n",
221
- " env={**os.environ, 'WINEDEBUG': '+bcrypt,+loaddll'}\n",
222
- ")\n",
223
- "# Only show relevant debug lines (not all the noise)\n",
224
- "for line in result2.stderr.split('\\n'):\n",
225
- " if any(kw in line.lower() for kw in ['bcrypt', 'cfb', 'fail', 'err:', 'fixme:', 'oneocr', 'onnxruntime', 'not implemented', 'not supported']):\n",
226
- " print(line)\n",
227
- "if result2.stdout != result.stdout:\n",
228
- " print(\"\\nDiagnostic output:\")\n",
229
- " print(result2.stdout[-500:])"
230
  ]
231
  },
232
  {
@@ -236,48 +359,41 @@
236
  "metadata": {},
237
  "outputs": [],
238
  "source": [
239
- "# 8. 🧪 TEST: Run C loader via Wine on a single image\n",
240
  "import subprocess, json, os\n",
241
  "from PIL import Image\n",
242
  "from pathlib import Path\n",
243
  "\n",
244
  "os.environ['WINEDEBUG'] = '-all'\n",
245
  "\n",
246
- "# Convert test image to BMP\n",
247
  "test_img = '/content/oneocr/working_space/input/ocr_test (1).png'\n",
248
  "bmp_path = '/tmp/test.bmp'\n",
249
  "img = Image.open(test_img).convert('RGBA')\n",
250
  "img.save(bmp_path, format='BMP')\n",
251
  "print(f'Image: {img.size}')\n",
252
  "\n",
253
- "# Model key\n",
254
  "key = b'kj)TGtrK>f]b[Piow.gU+nC@s\\x22\\x22\\x22\\x22\\x22\\x224'\n",
255
  "key_hex = key.hex()\n",
256
  "\n",
257
- "# Convert paths to Wine Z: format\n",
258
- "dll_dir = 'Z:\\\\content\\\\oneocr\\\\ocr_data'\n",
259
- "bmp_wine = 'Z:\\\\tmp\\\\test.bmp'\n",
260
- "\n",
261
- "cmd = ['wine64', '/content/oneocr/tools/oneocr_loader.exe', dll_dir, bmp_wine, key_hex]\n",
262
- "print(f'Running: wine64 oneocr_loader.exe ...')\n",
263
- "\n",
264
- "result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)\n",
265
  "\n",
266
  "print(f'Return code: {result.returncode}')\n",
267
- "if result.stderr:\n",
268
- " print(f'Stderr: {result.stderr[:500]}')\n",
269
- "\n",
270
  "if result.returncode == 0 and result.stdout.strip():\n",
271
  " data = json.loads(result.stdout.strip())\n",
272
- " print(f'\\n✅ SUCCESS!')\n",
273
- " print(f'Text angle: {data[\"text_angle\"]}')\n",
274
  " for line in data['lines']:\n",
275
  " words = ' | '.join(f\"{w['text']} ({w['confidence']:.0%})\" for w in line['words'])\n",
276
- " print(f' Line: {words}')\n",
277
- " print(f'\\nTotal lines: {len(data[\"lines\"])}')\n",
278
  "else:\n",
279
- " print('FAILED')\n",
280
- " print(result.stdout[:500] if result.stdout else 'No stdout')"
 
281
  ]
282
  },
283
  {
@@ -287,49 +403,43 @@
287
  "metadata": {},
288
  "outputs": [],
289
  "source": [
290
- "# 9. 🧪 FULL TEST: Run on ALL 19 test images\n",
291
  "import time\n",
292
  "\n",
293
  "test_dir = Path('/content/oneocr/working_space/input')\n",
294
  "images = sorted(test_dir.glob('*.png'))\n",
295
- "print(f'Testing {len(images)} images via Wine bridge...\\n')\n",
296
  "\n",
297
- "success = 0\n",
298
  "fail = 0\n",
299
- "\n",
300
  "for img_path in images:\n",
301
  " try:\n",
302
  " img = Image.open(img_path).convert('RGBA')\n",
303
  " img.save(bmp_path, format='BMP')\n",
304
- "\n",
305
  " t0 = time.time()\n",
306
- " result = subprocess.run(\n",
307
- " ['wine64', '/content/oneocr/tools/oneocr_loader.exe',\n",
308
  " 'Z:\\\\content\\\\oneocr\\\\ocr_data', 'Z:\\\\tmp\\\\test.bmp', key_hex],\n",
309
  " capture_output=True, text=True, timeout=120,\n",
310
  " env={**os.environ, 'WINEDEBUG': '-all'}\n",
311
  " )\n",
312
  " dt = time.time() - t0\n",
313
- "\n",
314
- " if result.returncode == 0 and result.stdout.strip():\n",
315
- " data = json.loads(result.stdout.strip())\n",
316
- " n_lines = len(data['lines'])\n",
317
- " text = ' | '.join(l['text'] for l in data['lines'][:3])\n",
318
- " print(f' ✅ {img_path.name:25s} | {dt:.1f}s | {n_lines}L | {text[:50]}')\n",
319
- " success += 1\n",
320
  " else:\n",
321
- " print(f' {img_path.name:25s} | {result.stderr[:100]}')\n",
322
  " fail += 1\n",
323
  " except Exception as e:\n",
324
- " print(f' {img_path.name:25s} | {e}')\n",
325
  " fail += 1\n",
326
  "\n",
327
- "print(f'\\n{\"=\" * 60}')\n",
328
- "print(f'Result: {success}/{success+fail} OK ({success/(success+fail)*100:.0f}%)')\n",
329
  "if fail == 0:\n",
330
- " print('🎉 Wine bridge on Linux: WORKS! 100% accuracy identical to Windows DLL.')\n",
331
- "else:\n",
332
- " print(f'⚠️ {fail} failures — check diagnostic output (cell 7) for details')"
333
  ]
334
  },
335
  {
@@ -339,22 +449,19 @@
339
  "metadata": {},
340
  "outputs": [],
341
  "source": [
342
- "# 10. 🧪 TEST: Unified engine (auto-selects Wine backend on Linux)\n",
343
  "import sys\n",
344
  "sys.path.insert(0, '/content/oneocr')\n",
345
- "\n",
346
  "from ocr.engine_unified import OcrEngineUnified\n",
347
  "\n",
348
  "engine = OcrEngineUnified()\n",
349
- "print(f'Backend selected: {engine.backend_name}')\n",
350
  "\n",
351
  "img = Image.open('/content/oneocr/working_space/input/ocr_test (10).png')\n",
352
  "result = engine.recognize_pil(img)\n",
353
- "\n",
354
  "print(f'Text: {result.text}')\n",
355
  "print(f'Lines: {len(result.lines)}')\n",
356
- "print(f'Confidence: {result.average_confidence:.1%}')\n",
357
- "print(f'\\n🎉 OneOCR DLL works on Linux via Wine! Same 100% accuracy as Windows.')"
358
  ]
359
  }
360
  ],
 
5
  "id": "d603dd1d",
6
  "metadata": {},
7
  "source": [
8
+ "# OneOCR — Wine Bridge Test na Linux (Colab)\n",
9
  "\n",
10
+ "Test czy `oneocr.dll` działa na Linuxie przez Wine.\n",
11
  "\n",
12
  "**Kroki:**\n",
13
+ "1. Instalacja Wine + MinGW\n",
14
+ "2. Clone repo + upload DLL\n",
15
+ "3. Diagnostyka Wine (debug loader)\n",
16
+ "4. Test OCR przez Wine\n",
17
+ "\n",
18
+ "**Potrzebne pliki** (wrzuć w komórce 4):\n",
19
+ "- `oneocr.dll` (~40 MB)\n",
20
+ "- `oneocr.onemodel` (~56 MB)\n",
21
+ "- `onnxruntime.dll` (~13 MB)"
22
  ]
23
  },
24
  {
 
28
  "metadata": {},
29
  "outputs": [],
30
  "source": [
31
+ "# 1. Install Wine + MinGW\n",
32
+ "!dpkg --add-architecture i386\n",
33
+ "!apt-get update -qq 2>/dev/null\n",
34
+ "!apt-get install -y -qq wine64 mingw-w64 2>&1 | tail -1\n",
 
 
 
 
 
 
 
 
 
 
 
35
  "!wine64 --version\n",
36
+ "!x86_64-w64-mingw32-gcc --version 2>&1 | head -1\n",
37
+ "print(\"OK\")"
38
  ]
39
  },
40
  {
 
44
  "metadata": {},
45
  "outputs": [],
46
  "source": [
47
+ "# 2. Initialize Wine prefix\n",
48
  "import os\n",
49
  "os.environ['WINEDEBUG'] = '-all'\n",
50
  "os.environ['WINEPREFIX'] = '/root/.wine'\n",
51
  "os.environ['WINEARCH'] = 'win64'\n",
52
  "!wineboot --init 2>/dev/null\n",
53
+ "print(\"Wine prefix OK\")"
 
 
54
  ]
55
  },
56
  {
 
60
  "metadata": {},
61
  "outputs": [],
62
  "source": [
63
+ "# 3. Clone repo\n",
64
+ "!rm -rf /content/oneocr\n",
65
+ "!git lfs install 2>/dev/null\n",
66
+ "!git clone https://huggingface.co/MattyMroz/oneocr /content/oneocr\n",
67
  "!mkdir -p /content/oneocr/ocr_data\n",
68
+ "!ls /content/oneocr/tools/*.c\n",
69
+ "print(\"Repo OK\")"
 
70
  ]
71
  },
72
  {
 
76
  "metadata": {},
77
  "outputs": [],
78
  "source": [
79
+ "# 4. UPLOAD DLL FILES\n",
80
+ "#\n",
81
+ "# Kliknij \"Files\" po lewej w Colab -> Upload\n",
82
+ "# Wrzuc: oneocr.dll, oneocr.onemodel, onnxruntime.dll\n",
83
+ "# Potem uruchom te komorke\n",
84
  "#\n",
85
+ "# Albo z Google Drive:\n",
86
  "# from google.colab import drive\n",
87
  "# drive.mount('/content/drive')\n",
88
+ "# !cp /content/drive/MyDrive/path/{oneocr.dll,oneocr.onemodel,onnxruntime.dll} /content/oneocr/ocr_data/\n",
89
  "\n",
90
+ "import shutil\n",
91
  "from pathlib import Path\n",
92
  "\n",
93
  "ocr_data = Path('/content/oneocr/ocr_data')\n",
94
+ "needed = {'oneocr.dll': 40e6, 'oneocr.onemodel': 50e6, 'onnxruntime.dll': 10e6}\n",
 
 
 
 
95
  "\n",
96
+ "for f, minsize in needed.items():\n",
 
 
 
97
  " dst = ocr_data / f\n",
98
+ " # szukaj w /content/ (domyslny upload Colab)\n",
99
+ " src = Path(f'/content/{f}')\n",
100
+ " if src.exists() and not dst.exists():\n",
101
+ " shutil.move(str(src), str(dst))\n",
102
+ " if dst.exists():\n",
103
+ " sz = dst.stat().st_size\n",
104
+ " if sz > minsize:\n",
105
+ " print(f' OK: {f} ({sz/1e6:.1f} MB)')\n",
106
+ " elif sz < 1000:\n",
107
+ " print(f' BLAD: {f} to git LFS pointer! Wrzuc prawdziwy plik.')\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  " else:\n",
109
+ " print(f' UWAGA: {f} maly ({sz/1e6:.1f} MB)')\n",
110
+ " else:\n",
111
+ " print(f' BRAK: {f} - wrzuc plik!')\n",
112
  "\n",
113
+ "ok = all((ocr_data / f).exists() and (ocr_data / f).stat().st_size > s for f, s in needed.items())\n",
114
+ "print(f'\\n{\"Wszystkie pliki OK!\" if ok else \"BRAK PLIKOW - wrzuc i uruchom ponownie\"}')"
 
 
 
 
 
 
 
 
 
115
  ]
116
  },
117
  {
 
132
  "metadata": {},
133
  "outputs": [],
134
  "source": [
135
+ "# 6. Compile C loaders (source written INLINE - no git dependency)\n",
136
+ "import subprocess, os\n",
137
+ "\n",
138
+ "# ========== DEBUG LOADER SOURCE ==========\n",
139
+ "DEBUG_C = r\"\"\"\n",
140
+ "#include <stdio.h>\n",
141
+ "#include <stdlib.h>\n",
142
+ "#include <string.h>\n",
143
+ "#include <windows.h>\n",
144
+ "typedef void* BCRYPT_ALG_HANDLE;\n",
145
+ "typedef void* BCRYPT_KEY_HANDLE;\n",
146
+ "typedef long NTSTATUS;\n",
147
+ "typedef NTSTATUS (*fn_Open)(BCRYPT_ALG_HANDLE*, const wchar_t*, const wchar_t*, unsigned long);\n",
148
+ "typedef NTSTATUS (*fn_SetP)(BCRYPT_ALG_HANDLE, const wchar_t*, unsigned char*, unsigned long, unsigned long);\n",
149
+ "typedef NTSTATUS (*fn_GenK)(BCRYPT_ALG_HANDLE, BCRYPT_KEY_HANDLE*, unsigned char*, unsigned long, unsigned char*, unsigned long, unsigned long);\n",
150
+ "typedef NTSTATUS (*fn_Dec)(BCRYPT_KEY_HANDLE, unsigned char*, unsigned long, void*, unsigned char*, unsigned long, unsigned char*, unsigned long, unsigned long*, unsigned long);\n",
151
+ "typedef NTSTATUS (*fn_Close)(BCRYPT_ALG_HANDLE, unsigned long);\n",
152
+ "typedef NTSTATUS (*fn_DestK)(BCRYPT_KEY_HANDLE);\n",
153
+ "typedef long long (*fn_CrInit)(long long*);\n",
154
+ "typedef long long (*fn_SetDL)(long long, char);\n",
155
+ "typedef long long (*fn_CrPipe)(const char*, const char*, long long, long long*);\n",
156
+ "typedef void (*fn_RelInit)(long long);\n",
157
+ "typedef void (*fn_RelPipe)(long long);\n",
158
+ "\n",
159
+ "int main(int argc, char** argv) {\n",
160
+ " if (argc < 2) { fprintf(stderr, \"Usage: %s <dll_dir> [key_hex]\\n\", argv[0]); return 1; }\n",
161
+ " const char* dd = argv[1];\n",
162
+ " const char* kh = argc>2 ? argv[2] : \"6b6a29544774724b3e665d625b50696f772e67552b6e43407322222222222234\";\n",
163
+ " char p[MAX_PATH];\n",
164
+ "\n",
165
+ " printf(\"=== TEST 1: File Access ===\\n\");\n",
166
+ " const char* files[] = {\"oneocr.onemodel\", \"oneocr.dll\", \"onnxruntime.dll\", NULL};\n",
167
+ " for (int i=0; files[i]; i++) {\n",
168
+ " snprintf(p, sizeof(p), \"%s\\\\%s\", dd, files[i]);\n",
169
+ " HANDLE h = CreateFileA(p, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\n",
170
+ " if (h != INVALID_HANDLE_VALUE) {\n",
171
+ " LARGE_INTEGER sz; GetFileSizeEx(h, &sz);\n",
172
+ " printf(\" OK: %s (%.1f MB)\\n\", files[i], sz.QuadPart/1e6);\n",
173
+ " if (sz.QuadPart < 1000000 && i==0) {\n",
174
+ " char buf[200]={0}; DWORD r; ReadFile(h,buf,100,&r,NULL);\n",
175
+ " if(strstr(buf,\"git-lfs\")) printf(\" *** GIT LFS POINTER! Not real file! ***\\n\");\n",
176
+ " }\n",
177
+ " CloseHandle(h);\n",
178
+ " } else {\n",
179
+ " printf(\" FAIL: %s (error %lu)\\n\", files[i], GetLastError());\n",
180
+ " }\n",
181
+ " }\n",
182
+ "\n",
183
+ " printf(\"\\n=== TEST 2: DLL Loading ===\\n\");\n",
184
+ " SetDllDirectoryA(dd);\n",
185
+ " snprintf(p, sizeof(p), \"%s\\\\onnxruntime.dll\", dd);\n",
186
+ " HMODULE hort = LoadLibraryA(p);\n",
187
+ " printf(\" onnxruntime.dll: %s\\n\", hort ? \"OK\" : \"FAIL\");\n",
188
+ " snprintf(p, sizeof(p), \"%s\\\\oneocr.dll\", dd);\n",
189
+ " HMODULE hmod = LoadLibraryA(p);\n",
190
+ " printf(\" oneocr.dll: %s\\n\", hmod ? \"OK\" : \"FAIL\");\n",
191
+ " if (hmod) {\n",
192
+ " const char* ex[] = {\"CreateOcrInitOptions\",\"CreateOcrPipeline\",\"RunOcrPipeline\",\"ReleaseOcrResult\",\"ReleaseOcrPipeline\",NULL};\n",
193
+ " for(int i=0;ex[i];i++) printf(\" %s: %s\\n\", ex[i], GetProcAddress(hmod,ex[i])?\"OK\":\"MISSING\");\n",
194
+ " }\n",
195
+ "\n",
196
+ " printf(\"\\n=== TEST 3: bcrypt AES-256-CFB ===\\n\");\n",
197
+ " HMODULE hbc = LoadLibraryA(\"bcrypt.dll\");\n",
198
+ " if (!hbc) { printf(\" FAIL: bcrypt.dll not loaded\\n\"); }\n",
199
+ " else {\n",
200
+ " fn_Open pO=(fn_Open)GetProcAddress(hbc,\"BCryptOpenAlgorithmProvider\");\n",
201
+ " fn_SetP pS=(fn_SetP)GetProcAddress(hbc,\"BCryptSetProperty\");\n",
202
+ " fn_GenK pG=(fn_GenK)GetProcAddress(hbc,\"BCryptGenerateSymmetricKey\");\n",
203
+ " fn_Dec pD=(fn_Dec)GetProcAddress(hbc,\"BCryptDecrypt\");\n",
204
+ " fn_Close pC=(fn_Close)GetProcAddress(hbc,\"BCryptCloseAlgorithmProvider\");\n",
205
+ " fn_DestK pDK=(fn_DestK)GetProcAddress(hbc,\"BCryptDestroyKey\");\n",
206
+ " BCRYPT_ALG_HANDLE hA=NULL;\n",
207
+ " NTSTATUS st=pO(&hA,L\"AES\",NULL,0);\n",
208
+ " printf(\" OpenAlgorithm(AES): 0x%08lx %s\\n\",st,st==0?\"OK\":\"FAIL\");\n",
209
+ " if(st==0){\n",
210
+ " wchar_t cfb[]=L\"ChainingModeCFB\";\n",
211
+ " st=pS(hA,L\"ChainingMode\",(unsigned char*)cfb,sizeof(cfb),0);\n",
212
+ " printf(\" SetProperty(CFB): 0x%08lx %s\\n\",st,st==0?\"OK\":\"FAIL\");\n",
213
+ " if(st!=0){\n",
214
+ " printf(\" *** CFB NOT SUPPORTED! Trying others... ***\\n\");\n",
215
+ " wchar_t cbc[]=L\"ChainingModeCBC\"; wchar_t ecb[]=L\"ChainingModeECB\"; wchar_t gcm[]=L\"ChainingModeGCM\";\n",
216
+ " printf(\" CBC: 0x%08lx\\n\",pS(hA,L\"ChainingMode\",(unsigned char*)cbc,sizeof(cbc),0));\n",
217
+ " printf(\" ECB: 0x%08lx\\n\",pS(hA,L\"ChainingMode\",(unsigned char*)ecb,sizeof(ecb),0));\n",
218
+ " printf(\" GCM: 0x%08lx\\n\",pS(hA,L\"ChainingMode\",(unsigned char*)gcm,sizeof(gcm),0));\n",
219
+ " }\n",
220
+ " if(st==0){\n",
221
+ " unsigned char tk[32]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};\n",
222
+ " BCRYPT_KEY_HANDLE hK=NULL; st=pG(hA,&hK,NULL,0,tk,32,0);\n",
223
+ " printf(\" GenerateKey: 0x%08lx %s\\n\",st,st==0?\"OK\":\"FAIL\");\n",
224
+ " if(st==0&&hK){\n",
225
+ " unsigned char iv[16]={0},ct[16]={65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80},pt[16]={0};\n",
226
+ " unsigned long cb=0; st=pD(hK,ct,16,NULL,iv,16,pt,16,&cb,0);\n",
227
+ " printf(\" Decrypt: 0x%08lx %s (%lu bytes)\\n\",st,st==0?\"OK\":\"FAIL\",cb);\n",
228
+ " pDK(hK);\n",
229
+ " }\n",
230
+ " }\n",
231
+ " pC(hA,0);\n",
232
+ " }\n",
233
+ " FreeLibrary(hbc);\n",
234
+ " }\n",
235
+ "\n",
236
+ " printf(\"\\n=== TEST 4: CreateOcrPipeline ===\\n\");\n",
237
+ " if(!hmod){\n",
238
+ " SetDllDirectoryA(dd);\n",
239
+ " snprintf(p,sizeof(p),\"%s\\\\oneocr.dll\",dd);\n",
240
+ " hmod=LoadLibraryA(p);\n",
241
+ " }\n",
242
+ " if(!hmod){printf(\" SKIP: DLL not loaded\\n\");}\n",
243
+ " else{\n",
244
+ " fn_CrInit pCI=(fn_CrInit)GetProcAddress(hmod,\"CreateOcrInitOptions\");\n",
245
+ " fn_SetDL pSD=(fn_SetDL)GetProcAddress(hmod,\"OcrInitOptionsSetUseModelDelayLoad\");\n",
246
+ " fn_CrPipe pCP=(fn_CrPipe)GetProcAddress(hmod,\"CreateOcrPipeline\");\n",
247
+ " fn_RelInit pRI=(fn_RelInit)GetProcAddress(hmod,\"ReleaseOcrInitOptions\");\n",
248
+ " fn_RelPipe pRP=(fn_RelPipe)GetProcAddress(hmod,\"ReleaseOcrPipeline\");\n",
249
+ " if(!pCI||!pCP){printf(\" FAIL: Missing functions\\n\");}\n",
250
+ " else{\n",
251
+ " long long io=0,r2=pCI(&io);\n",
252
+ " printf(\" CreateOcrInitOptions: %lld %s\\n\",r2,r2==0?\"OK\":\"FAIL\");\n",
253
+ " if(pSD){r2=pSD(io,1);printf(\" SetDelayLoad(1): %lld %s\\n\",r2,r2==0?\"OK\":\"FAIL\");}\n",
254
+ " snprintf(p,sizeof(p),\"%s\\\\oneocr.onemodel\",dd);\n",
255
+ " int kl=(int)strlen(kh)/2; char key[64]={0};\n",
256
+ " for(int i=0;i<kl&&i<63;i++) sscanf(kh+i*2,\"%2hhx\",(unsigned char*)&key[i]);\n",
257
+ " printf(\" Model: %s\\n Key: %d bytes\\n\",p,kl);\n",
258
+ " fflush(stdout);\n",
259
+ " long long pipe=0;\n",
260
+ " r2=pCP(p,key,io,&pipe);\n",
261
+ " printf(\" CreateOcrPipeline: %lld %s\\n\",r2,r2==0?\"OK\":\"FAIL\");\n",
262
+ " if(r2==0){printf(\" *** SUCCESS! Pipeline works under Wine! ***\\n\");pRP(pipe);}\n",
263
+ " else{printf(\" *** FAILED with code %lld ***\\n\",r2);}\n",
264
+ " pRI(io);\n",
265
+ " }\n",
266
+ " FreeLibrary(hmod);\n",
267
+ " }\n",
268
+ " if(hort)FreeLibrary(hort);\n",
269
+ " printf(\"\\n=== DONE ===\\n\");\n",
270
+ " return 0;\n",
271
+ "}\n",
272
+ "\"\"\"\n",
273
+ "\n",
274
+ "# Write and compile debug loader\n",
275
+ "with open('/tmp/oneocr_debug.c', 'w') as f:\n",
276
+ " f.write(DEBUG_C)\n",
277
+ "\n",
278
+ "r = subprocess.run(\n",
279
+ " ['x86_64-w64-mingw32-gcc', '-O2', '-o', '/tmp/oneocr_debug.exe', '/tmp/oneocr_debug.c'],\n",
280
+ " capture_output=True, text=True\n",
281
+ ")\n",
282
+ "if r.returncode != 0:\n",
283
+ " print(\"COMPILE ERROR (debug):\")\n",
284
+ " print(r.stderr)\n",
285
+ "else:\n",
286
+ " sz = os.path.getsize('/tmp/oneocr_debug.exe')\n",
287
+ " print(f\" OK: oneocr_debug.exe ({sz} bytes)\")\n",
288
+ "\n",
289
+ "# Also compile the main loader from repo (if source exists)\n",
290
+ "loader_c = '/content/oneocr/tools/oneocr_loader.c'\n",
291
+ "if os.path.exists(loader_c):\n",
292
+ " r2 = subprocess.run(\n",
293
+ " ['x86_64-w64-mingw32-gcc', '-O2', '-o', '/tmp/oneocr_loader.exe', loader_c],\n",
294
+ " capture_output=True, text=True\n",
295
+ " )\n",
296
+ " if r2.returncode != 0:\n",
297
+ " print(\"COMPILE ERROR (loader):\")\n",
298
+ " print(r2.stderr)\n",
299
+ " else:\n",
300
+ " print(f\" OK: oneocr_loader.exe ({os.path.getsize('/tmp/oneocr_loader.exe')} bytes)\")\n",
301
+ "else:\n",
302
+ " print(f\" SKIP: {loader_c} not found\")"
303
  ]
304
  },
305
  {
 
309
  "metadata": {},
310
  "outputs": [],
311
  "source": [
312
+ "# 7. DIAGNOSTYKA - testuje kazdy komponent pod Wine osobno\n",
313
  "import subprocess, os\n",
314
  "\n",
315
  "os.environ['WINEDEBUG'] = '-all'\n",
316
+ "exe = '/tmp/oneocr_debug.exe'\n",
317
+ "dll_dir = 'Z:\\\\content\\\\oneocr\\\\ocr_data'\n",
318
  "\n",
319
+ "# Verify exe exists\n",
320
+ "if not os.path.exists(exe):\n",
321
+ " print(f\"BLAD: {exe} nie istnieje! Uruchom komorke 6 najpierw.\")\n",
322
+ "else:\n",
323
+ " print(f\"EXE: {exe} ({os.path.getsize(exe)} bytes)\")\n",
324
+ " print(f\"DLL dir: {dll_dir}\")\n",
325
+ " print(\"=\" * 60)\n",
326
+ "\n",
327
+ " # Run diagnostic\n",
328
+ " result = subprocess.run(\n",
329
+ " ['wine64', exe, dll_dir],\n",
330
+ " capture_output=True, text=True, timeout=120,\n",
331
+ " env={**os.environ, 'WINEDEBUG': '-all'}\n",
332
+ " )\n",
333
+ "\n",
334
+ " if result.stdout:\n",
335
+ " print(result.stdout)\n",
336
+ " if result.stderr:\n",
337
+ " print(\"--- WINE STDERR ---\")\n",
338
+ " print(result.stderr[:2000])\n",
339
+ "\n",
340
+ " # Second run with Wine debug channels\n",
341
+ " print(\"\\n\" + \"=\" * 60)\n",
342
+ " print(\"Wine debug trace (bcrypt + loaddll):\")\n",
343
+ " print(\"=\" * 60)\n",
344
+ " r2 = subprocess.run(\n",
345
+ " ['wine64', exe, dll_dir],\n",
346
+ " capture_output=True, text=True, timeout=120,\n",
347
+ " env={**os.environ, 'WINEDEBUG': '+bcrypt,+loaddll,-other'}\n",
348
+ " )\n",
349
+ " for line in r2.stderr.split('\\n'):\n",
350
+ " lo = line.lower()\n",
351
+ " if any(k in lo for k in ['bcrypt','cfb','fail','err:','fixme:','oneocr','onnxruntime','not impl','not supp']):\n",
352
+ " print(line[:200])"
 
353
  ]
354
  },
355
  {
 
359
  "metadata": {},
360
  "outputs": [],
361
  "source": [
362
+ "# 8. TEST: Single image OCR via Wine\n",
363
  "import subprocess, json, os\n",
364
  "from PIL import Image\n",
365
  "from pathlib import Path\n",
366
  "\n",
367
  "os.environ['WINEDEBUG'] = '-all'\n",
368
  "\n",
 
369
  "test_img = '/content/oneocr/working_space/input/ocr_test (1).png'\n",
370
  "bmp_path = '/tmp/test.bmp'\n",
371
  "img = Image.open(test_img).convert('RGBA')\n",
372
  "img.save(bmp_path, format='BMP')\n",
373
  "print(f'Image: {img.size}')\n",
374
  "\n",
 
375
  "key = b'kj)TGtrK>f]b[Piow.gU+nC@s\\x22\\x22\\x22\\x22\\x22\\x224'\n",
376
  "key_hex = key.hex()\n",
377
  "\n",
378
+ "result = subprocess.run(\n",
379
+ " ['wine64', '/tmp/oneocr_loader.exe',\n",
380
+ " 'Z:\\\\content\\\\oneocr\\\\ocr_data', 'Z:\\\\tmp\\\\test.bmp', key_hex],\n",
381
+ " capture_output=True, text=True, timeout=120,\n",
382
+ " env={**os.environ, 'WINEDEBUG': '-all'}\n",
383
+ ")\n",
 
 
384
  "\n",
385
  "print(f'Return code: {result.returncode}')\n",
 
 
 
386
  "if result.returncode == 0 and result.stdout.strip():\n",
387
  " data = json.loads(result.stdout.strip())\n",
388
+ " print(f'\\nSUCCESS!')\n",
 
389
  " for line in data['lines']:\n",
390
  " words = ' | '.join(f\"{w['text']} ({w['confidence']:.0%})\" for w in line['words'])\n",
391
+ " print(f' {words}')\n",
392
+ " print(f'Total lines: {len(data[\"lines\"])}')\n",
393
  "else:\n",
394
+ " print('FAILED')\n",
395
+ " if result.stderr: print(f'Stderr: {result.stderr[:500]}')\n",
396
+ " if result.stdout: print(f'Stdout: {result.stdout[:500]}')"
397
  ]
398
  },
399
  {
 
403
  "metadata": {},
404
  "outputs": [],
405
  "source": [
406
+ "# 9. FULL TEST: All 19 images\n",
407
  "import time\n",
408
  "\n",
409
  "test_dir = Path('/content/oneocr/working_space/input')\n",
410
  "images = sorted(test_dir.glob('*.png'))\n",
411
+ "print(f'Testing {len(images)} images...\\n')\n",
412
  "\n",
413
+ "ok = 0\n",
414
  "fail = 0\n",
 
415
  "for img_path in images:\n",
416
  " try:\n",
417
  " img = Image.open(img_path).convert('RGBA')\n",
418
  " img.save(bmp_path, format='BMP')\n",
 
419
  " t0 = time.time()\n",
420
+ " r = subprocess.run(\n",
421
+ " ['wine64', '/tmp/oneocr_loader.exe',\n",
422
  " 'Z:\\\\content\\\\oneocr\\\\ocr_data', 'Z:\\\\tmp\\\\test.bmp', key_hex],\n",
423
  " capture_output=True, text=True, timeout=120,\n",
424
  " env={**os.environ, 'WINEDEBUG': '-all'}\n",
425
  " )\n",
426
  " dt = time.time() - t0\n",
427
+ " if r.returncode == 0 and r.stdout.strip():\n",
428
+ " data = json.loads(r.stdout.strip())\n",
429
+ " txt = ' | '.join(l['text'] for l in data['lines'][:3])\n",
430
+ " print(f' OK {img_path.name:25s} | {dt:.1f}s | {len(data[\"lines\"])}L | {txt[:60]}')\n",
431
+ " ok += 1\n",
 
 
432
  " else:\n",
433
+ " print(f' FAIL {img_path.name:25s} | {r.stderr[:80]}')\n",
434
  " fail += 1\n",
435
  " except Exception as e:\n",
436
+ " print(f' FAIL {img_path.name:25s} | {e}')\n",
437
  " fail += 1\n",
438
  "\n",
439
+ "print(f'\\n{\"=\"*60}')\n",
440
+ "print(f'Result: {ok}/{ok+fail} ({ok/(ok+fail)*100:.0f}%)')\n",
441
  "if fail == 0:\n",
442
+ " print('Wine bridge DZIALA! 100% taki sam wynik jak DLL na Windows.')"
 
 
443
  ]
444
  },
445
  {
 
449
  "metadata": {},
450
  "outputs": [],
451
  "source": [
452
+ "# 10. Unified engine test\n",
453
  "import sys\n",
454
  "sys.path.insert(0, '/content/oneocr')\n",
 
455
  "from ocr.engine_unified import OcrEngineUnified\n",
456
  "\n",
457
  "engine = OcrEngineUnified()\n",
458
+ "print(f'Backend: {engine.backend_name}')\n",
459
  "\n",
460
  "img = Image.open('/content/oneocr/working_space/input/ocr_test (10).png')\n",
461
  "result = engine.recognize_pil(img)\n",
 
462
  "print(f'Text: {result.text}')\n",
463
  "print(f'Lines: {len(result.lines)}')\n",
464
+ "print(f'Confidence: {result.average_confidence:.1%}')"
 
465
  ]
466
  }
467
  ],