Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
6.4 KiB

  1. //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation. All rights reserved.
  4. //
  5. // Module:
  6. // volcano/dll/brknet.c
  7. //
  8. // Description:
  9. // Functions to implement the functionality of the break Neural net that
  10. // modifies the lattice structure to correct segmentation errors.
  11. //
  12. // Author:
  13. // ahmadab 11/05/01
  14. //
  15. //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  16. #include "common.h"
  17. #include "volcanop.h"
  18. #include "lattice.h"
  19. #include "runnet.h"
  20. #include "brknet.h"
  21. #include "segm.h"
  22. #include "nnet.h"
  23. // the size and structure representing the Breaking net used in Free mode
  24. // if the is not available for a particular configuration, s_iBrkNetSize will be zero
  25. static int s_iBrkNetSize = 0;
  26. static LOCAL_NET s_BrkNet;
  27. // validates the header of the brknet
  28. BOOL CheckBrkNetHeader (void *pData)
  29. {
  30. NNET_HEADER *pHeader = (NNET_HEADER *)pData;
  31. // wrong magic number
  32. ASSERT (pHeader->dwFileType == BRKNET_FILE_TYPE);
  33. if (pHeader->dwFileType != BRKNET_FILE_TYPE)
  34. {
  35. return FALSE;
  36. }
  37. // check version
  38. ASSERT(pHeader->iFileVer >= BRKNET_OLD_FILE_VERSION);
  39. ASSERT(pHeader->iMinCodeVer <= BRKNET_CUR_FILE_VERSION);
  40. ASSERT ( !memcmp ( pHeader->adwSignature,
  41. g_locRunInfo.adwSignature,
  42. sizeof (pHeader->adwSignature)
  43. )
  44. );
  45. ASSERT (pHeader->cSpace == 1);
  46. if ( pHeader->iFileVer >= BRKNET_OLD_FILE_VERSION &&
  47. pHeader->iMinCodeVer <= BRKNET_CUR_FILE_VERSION &&
  48. !memcmp ( pHeader->adwSignature,
  49. g_locRunInfo.adwSignature,
  50. sizeof (pHeader->adwSignature)
  51. ) &&
  52. pHeader->cSpace == 1
  53. )
  54. {
  55. return TRUE;
  56. }
  57. else
  58. {
  59. return FALSE;
  60. }
  61. }
  62. // does the necessary preparations for a net to be used later
  63. static LOCAL_NET *PrepareBrkNet(BYTE *pData, int *piNetSize, LOCAL_NET *pNet)
  64. {
  65. NNET_SPACE_HEADER *pSpaceHeader;
  66. if (!pData)
  67. {
  68. return FALSE;
  69. }
  70. // check the header info
  71. if (!CheckBrkNetHeader (pData))
  72. {
  73. return NULL;
  74. }
  75. // point to the one and only space that we have
  76. pSpaceHeader = (NNET_SPACE_HEADER *)(pData + sizeof (NNET_HEADER));
  77. // point to the actual data
  78. pData = pData + pSpaceHeader->iDataOffset;
  79. // restore the connections
  80. if (!(pNet = restoreLocalConnectNet(pData, 0, pNet)) )
  81. {
  82. return NULL;
  83. }
  84. // compute the run time memory requirements of the net
  85. (*piNetSize) = getRunTimeNetMemoryRequirements(pData);
  86. if ((*piNetSize) <= 0)
  87. {
  88. return NULL;
  89. }
  90. return pNet;
  91. }
  92. // load the brk net from resources
  93. BOOL LoadBrkNetFromFile(wchar_t *pwszRecogDir, LOAD_INFO *pLoadInfo)
  94. {
  95. BYTE *pData;
  96. wchar_t awszFileName[MAX_PATH];
  97. // init the size to zero, in case we fail
  98. s_iBrkNetSize = 0;
  99. swprintf (awszFileName, L"%s\\brknet.bin", pwszRecogDir);
  100. // memory map the file
  101. pData = DoOpenFile (pLoadInfo, awszFileName);
  102. if (!pData)
  103. {
  104. return FALSE;
  105. }
  106. // prepare Brk net
  107. if (!PrepareBrkNet(pData, &s_iBrkNetSize, &s_BrkNet))
  108. {
  109. return FALSE;
  110. }
  111. return TRUE;
  112. }
  113. // load the brk net from resources
  114. BOOL LoadBrkNetFromResource (HINSTANCE hInst, int nResID, int nType)
  115. {
  116. BYTE *pData;
  117. LOAD_INFO LoadInfo;
  118. // init the size to zero, in case we fail
  119. s_iBrkNetSize = 0;
  120. pData = DoLoadResource (&LoadInfo, hInst, nResID, nType);
  121. if (!pData)
  122. {
  123. return FALSE;
  124. }
  125. // prepare the net
  126. if (!PrepareBrkNet(pData, &s_iBrkNetSize, &s_BrkNet))
  127. {
  128. return FALSE;
  129. }
  130. return TRUE;
  131. }
  132. // update the lattice by running the BRK-NET on all the possible break points.
  133. // Currently only one segmentation survives which is the one suggested by the BRK-NET
  134. // returns the number of charcaters in the updated lattice on success, -1 upon failure
  135. int UpdateLattice (LATTICE *pLat)
  136. {
  137. int iPos,
  138. iStrk,
  139. cStrk,
  140. iWinner,
  141. cOut,
  142. cBrk;
  143. BOOL *pIsBreak = NULL;
  144. BRKPT *pBrk = NULL;
  145. RREAL *pNetMem = NULL,
  146. *pNetOut;
  147. int iRet = -1,
  148. iBrk;
  149. // if the net has not been successfully loaded, we'll fail
  150. if (s_iBrkNetSize <= 0)
  151. {
  152. goto exit;
  153. }
  154. // alloc memory for the Net's running buffer
  155. pNetMem = (RREAL *) ExternAlloc (s_iBrkNetSize * sizeof (*pNetMem));
  156. if (!pNetMem)
  157. {
  158. goto exit;
  159. }
  160. // create the break pts structure
  161. cStrk = pLat->nStrokes;
  162. pBrk = CreateBrkPtList (pLat);
  163. // if we have succeeded, lets process these break points
  164. if (pBrk)
  165. {
  166. // allocate a boolean struct to mark ON break points
  167. pIsBreak = (BOOL *) ExternAlloc (cStrk * sizeof (*pIsBreak));
  168. if (!pIsBreak)
  169. {
  170. goto exit;
  171. }
  172. // for all break points
  173. for (iStrk = 0, cBrk = 0; iStrk < cStrk; iStrk++)
  174. {
  175. int iFeat, cFeat, aFeat[MAX_BRK_NET_FEAT];
  176. // featurize for this break point
  177. cFeat = FeaturizeBrkPt (pLat, pBrk + iStrk, aFeat);
  178. ASSERT (cFeat <= MAX_BRK_NET_FEAT);
  179. // prepare the nets input
  180. for (iFeat = 0; iFeat < cFeat; iFeat++)
  181. {
  182. pNetMem[iFeat] = aFeat[iFeat];
  183. }
  184. // run the net
  185. pNetOut = runLocalConnectNet (&s_BrkNet, pNetMem, &iWinner, &cOut);
  186. ASSERT (cOut == 2);
  187. // this is considered a hard break point if the net's output is higher than the threshold
  188. pIsBreak[iStrk] = pNetOut[1] >= (BREAKING_THRESHOLD);
  189. // mark it a as a breakpoint
  190. if (pIsBreak[iStrk])
  191. {
  192. cBrk++;
  193. }
  194. // copy the score in the lattice
  195. pLat->pAltList[iStrk].iBrkNetScore = pNetOut[1];
  196. }
  197. ASSERT (cBrk <= cStrk);
  198. // make sure there is a break point always at the end,
  199. if (!pIsBreak[cStrk - 1])
  200. {
  201. pIsBreak[cStrk - 1] = TRUE;
  202. cBrk++;
  203. }
  204. // clear out all the existing alternate lists at every stroke
  205. for (iStrk = 0; iStrk < cStrk; iStrk++)
  206. {
  207. ClearAltList (pLat->pAltList + iStrk);
  208. }
  209. // change the lattice to reflect the new segmentation
  210. for (iBrk = iStrk = 0; iBrk < cBrk; iBrk++)
  211. {
  212. iPos = iStrk;
  213. // find the next break point
  214. while (!pIsBreak[iStrk] && iStrk < cStrk)
  215. {
  216. iStrk++;
  217. }
  218. // build the alt list at the the ending stroke with the
  219. // current stroke being the starting one
  220. //BuildStrokeCountRecogAlts(pLat, iStrk, iStrk - iPos + 1);
  221. if (!ProcessLatticeRange (pLat, iPos, iStrk))
  222. {
  223. goto exit;
  224. }
  225. UpdateSegmentations (pLat, iPos, iStrk);
  226. iStrk++;
  227. }
  228. // Mark the best path through the lattice
  229. //iRet = FindFullPath (pLat);
  230. FixupBackPointers (pLat);
  231. }
  232. exit:
  233. // free the local buffers if had been allocated
  234. if (pBrk)
  235. {
  236. FreeBreaks (cStrk, pBrk);
  237. }
  238. if (pIsBreak)
  239. {
  240. ExternFree (pIsBreak);
  241. }
  242. if (pNetMem)
  243. {
  244. ExternFree (pNetMem);
  245. }
  246. return iRet;
  247. }
  248. void BrkNetUnloadfile (LOAD_INFO *pLoadInfo)
  249. {
  250. if (s_iBrkNetSize != 0)
  251. {
  252. DoCloseFile (pLoadInfo);
  253. }
  254. }