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.

325 lines
9.0 KiB

  1. #include <stdlib.h>
  2. #include "common.h"
  3. #include "score.h"
  4. #include "runnet.h"
  5. #include "jaws.h"
  6. #include "fugu.h"
  7. #include "sole.h"
  8. #include "nnet.h"
  9. extern LOCRUN_INFO g_locRunInfo;
  10. // validates the header of the Jaws net
  11. BOOL CheckJawsNetHeader (void *pData)
  12. {
  13. NNET_HEADER *pHeader = (NNET_HEADER *)pData;
  14. // wrong magic number
  15. ASSERT (pHeader->dwFileType == JAWS_FILE_TYPE);
  16. if (pHeader->dwFileType != JAWS_FILE_TYPE)
  17. {
  18. return FALSE;
  19. }
  20. // check version
  21. ASSERT(pHeader->iFileVer >= JAWS_OLD_FILE_VERSION);
  22. ASSERT(pHeader->iMinCodeVer <= JAWS_CUR_FILE_VERSION);
  23. ASSERT ( !memcmp ( pHeader->adwSignature,
  24. g_locRunInfo.adwSignature,
  25. sizeof (pHeader->adwSignature)
  26. )
  27. );
  28. ASSERT (pHeader->cSpace == 1);
  29. if ( pHeader->iFileVer >= JAWS_OLD_FILE_VERSION &&
  30. pHeader->iMinCodeVer <= JAWS_CUR_FILE_VERSION &&
  31. !memcmp ( pHeader->adwSignature,
  32. g_locRunInfo.adwSignature,
  33. sizeof (pHeader->adwSignature)
  34. ) &&
  35. pHeader->cSpace == 1
  36. )
  37. {
  38. return TRUE;
  39. }
  40. else
  41. {
  42. return FALSE;
  43. }
  44. }
  45. BOOL JawsLoadPointer(JAWS_LOAD_INFO *pJaws)
  46. {
  47. NNET_SPACE_HEADER *pSpaceHeader;
  48. if (!CheckJawsNetHeader (pJaws->info.pbMapping))
  49. return FALSE;
  50. // point to the one and only space header
  51. pSpaceHeader = (NNET_SPACE_HEADER *)(pJaws->info.pbMapping + sizeof (NNET_HEADER));
  52. if ( restoreLocalConnectNet ( pJaws->info.pbMapping + pSpaceHeader->iDataOffset,
  53. 0, &pJaws->net
  54. ) == NULL
  55. )
  56. {
  57. return FALSE;
  58. }
  59. pJaws->iNetSize =
  60. getRunTimeNetMemoryRequirements (pJaws->info.pbMapping + pSpaceHeader->iDataOffset);
  61. if (pJaws->iNetSize <= 0)
  62. {
  63. return FALSE;
  64. }
  65. return TRUE;
  66. }
  67. ///////////////////////////////////////
  68. //
  69. // JawsLoadFile
  70. //
  71. // Load otter/fugu/sole combiner from file
  72. //
  73. // Parameters:
  74. // pInfo: [out] Information about the mapped file
  75. // wszPath: [in] Path to load from
  76. //
  77. // Return values:
  78. // TRUE on successful, FALSE otherwise.
  79. //
  80. //////////////////////////////////////
  81. BOOL JawsLoadFile(JAWS_LOAD_INFO *pJaws, wchar_t *wszPath)
  82. {
  83. wchar_t wszFile[_MAX_PATH];
  84. // Generate path to file.
  85. FormatPath(wszFile, wszPath, (wchar_t *)0, (wchar_t *)0, (wchar_t *)0, L"jaws.bin");
  86. if (!DoOpenFile(&pJaws->info, wszFile))
  87. {
  88. return FALSE;
  89. }
  90. return JawsLoadPointer(pJaws);
  91. }
  92. ///////////////////////////////////////
  93. //
  94. // JawsUnloadFile
  95. //
  96. // Load otter/fugu/sole combiner from file
  97. //
  98. // Parameters:
  99. // pInfo: [out] File to unmap
  100. //
  101. // Return values:
  102. // TRUE on successful, FALSE otherwise.
  103. //
  104. //////////////////////////////////////
  105. BOOL JawsUnloadFile(JAWS_LOAD_INFO *pJaws)
  106. {
  107. return DoCloseFile(&pJaws->info);
  108. }
  109. BOOL JawsLoadRes(JAWS_LOAD_INFO *pJaws, HINSTANCE hInst, int nResID, int nType)
  110. {
  111. if (DoLoadResource(&pJaws->info, hInst, nResID, nType) == NULL)
  112. {
  113. return FALSE;
  114. }
  115. return JawsLoadPointer(pJaws);
  116. }
  117. // describe the codepoint
  118. RREAL *CodePointFlags(ALC alc, RREAL *pFeat)
  119. {
  120. *(pFeat++) = ((alc & ALC_NUMERIC) ? 65535 : 0);
  121. *(pFeat++) = ((alc & ALC_ALPHA) ? 65535 : 0);
  122. *(pFeat++) = ((alc & (ALC_PUNC | ALC_NUMERIC_PUNC | ALC_OTHER)) ? 65535 : 0);
  123. *(pFeat++) = ((alc & (ALC_HIRAGANA | ALC_JAMO | ALC_BOPOMOFO)) ? 65535 : 0);
  124. *(pFeat++) = ((alc & (ALC_KATAKANA | ALC_HANGUL_ALL)) ? 65535 : 0);
  125. *(pFeat++) = ((alc & (ALC_KANJI_ALL)) ? 65535 : 0);
  126. return pFeat;
  127. }
  128. // Given an alt list with dense and possibly folded codes in it, run through it
  129. // and expand the folded lists. The unfolded alt list is returned in place.
  130. // This function assumes that the list begins with better alternates, as those
  131. // later in the list will get dropped if we run out of space.
  132. static void UnfoldCodes(ALT_LIST *pAltList, LOCRUN_INFO *pLocRunInfo, CHARSET *cs)
  133. {
  134. int i, cOut=0;
  135. ALT_LIST newAltList; // This will be where the new alt list is constructed.
  136. // For each alternate in the input list and while we have space in the output list
  137. for (i=0; i<(int)pAltList->cAlt && (int)cOut<MAX_ALT_LIST; i++) {
  138. // Check if the alternate is a folded coded
  139. if (LocRunIsFoldedCode(pLocRunInfo,pAltList->awchList[i])) {
  140. int kndex;
  141. // If it is a folded code, look up the folding set
  142. wchar_t *pFoldingSet = LocRunFolded2FoldingSet(pLocRunInfo, pAltList->awchList[i]);
  143. // Run through the folding set, adding non-NUL items to the output list
  144. // (until the output list is full)
  145. for (kndex = 0;
  146. kndex < LOCRUN_FOLD_MAX_ALTERNATES && pFoldingSet[kndex] != 0 && (int)cOut<MAX_ALT_LIST;
  147. kndex++) {
  148. if (IsAllowedChar(pLocRunInfo, cs, pFoldingSet[kndex]))
  149. {
  150. newAltList.awchList[cOut]=pFoldingSet[kndex];
  151. newAltList.aeScore[cOut]=pAltList->aeScore[i];
  152. cOut++;
  153. #ifdef DISABLE_UNFOLDING
  154. // If unfolding is disabled, then stop after producing one unfolded code.
  155. // This way we don't push results later in the alt list out of the alt
  156. // list, while still allowing the recognizer to return unicodes for each
  157. // alternate.
  158. break;
  159. #endif
  160. }
  161. }
  162. } else {
  163. // Dense codes that are not folded get added directly
  164. newAltList.awchList[cOut]=pAltList->awchList[i];
  165. newAltList.aeScore[cOut]=pAltList->aeScore[i];
  166. cOut++;
  167. }
  168. }
  169. // Store the length of the output list
  170. newAltList.cAlt=cOut;
  171. // Copy the output list over the input.
  172. *pAltList=newAltList;
  173. }
  174. int JawsFeaturize(FUGU_LOAD_INFO *pFugu, SOLE_LOAD_INFO *pSole, LOCRUN_INFO *pLocRunInfo,
  175. GLYPH *pGlyph, RECT *pGuide,
  176. CHARSET *pCharSet, RREAL *pFeat, ALT_LIST *pAltList,
  177. BOOL *pfAgree)
  178. {
  179. int i;
  180. ALT_LIST altListFugu;
  181. ALT_LIST altListSole;
  182. wchar_t wchSoleTop1;
  183. float flSoleTop1;
  184. if (FuguMatch(&pFugu->fugu, &altListFugu, MAX_ALT_LIST, pGlyph, NULL, pCharSet, pLocRunInfo) < 0)
  185. {
  186. return -1;
  187. }
  188. UnfoldCodes(&altListFugu, pLocRunInfo, pCharSet);
  189. altListSole = altListFugu;
  190. if (SoleMatchRescore(pSole, &wchSoleTop1, &flSoleTop1, &altListSole, MAX_ALT_LIST,
  191. pGlyph, pGuide, pCharSet, pLocRunInfo) < 0)
  192. {
  193. return -1;
  194. }
  195. *pAltList = altListSole;
  196. if (altListFugu.cAlt > 0 && wchSoleTop1 == altListFugu.awchList[0])
  197. {
  198. *pfAgree = TRUE;
  199. }
  200. else
  201. {
  202. *pfAgree = FALSE;
  203. if (altListFugu.cAlt > JAWS_NUM_ALTERNATES)
  204. {
  205. pAltList->cAlt = JAWS_NUM_ALTERNATES;
  206. }
  207. for (i = 0; i < JAWS_NUM_ALTERNATES; i++)
  208. {
  209. extern UNIGRAM_INFO g_unigramInfo;
  210. if (i < (int) altListFugu.cAlt)
  211. {
  212. *(pFeat++) = (int) (altListFugu.aeScore[i] * 65535);
  213. *(pFeat++) = (int) (altListSole.aeScore[i] * 65535);
  214. *(pFeat++) = (int) (-UnigramCost(&g_unigramInfo, altListFugu.awchList[i]) * 100 * 256);
  215. pFeat = CodePointFlags(LocRun2ALC(pLocRunInfo, altListFugu.awchList[i]), pFeat);
  216. }
  217. else
  218. {
  219. *(pFeat++) = 0;
  220. *(pFeat++) = 0;
  221. *(pFeat++) = (int) (-UnigramCost(&g_unigramInfo, 0xFFFE) * 100 * 256);
  222. pFeat = CodePointFlags(0, pFeat);
  223. }
  224. }
  225. *(pFeat++) = (CframeGLYPH(pGlyph) - 1) * 65535;
  226. }
  227. return pAltList->cAlt;
  228. }
  229. ///////////////////////////////////////
  230. //
  231. // JawsMatch
  232. //
  233. // Invoke Fugu/Otter/Sole combiner on a character.
  234. //
  235. // Parameters:
  236. // pFugu: [in] Fugu database to use
  237. // pAltList: [in/out] Alt list to rewrite the scores of
  238. // cAlt: [in] The maximum number of alternates to return
  239. // pGlyph: [in] The ink to recognize
  240. // pGuide: [in] Guide to scale ink to
  241. // pCharSet: [in] Filter for the characters to be returned
  242. // pLocRunInfo: [in] Pointer to the locale database
  243. //
  244. // Return values:
  245. // Returned the number of items in the alt list, or -1 if there is an error
  246. //
  247. //////////////////////////////////////
  248. int JawsMatch(JAWS_LOAD_INFO *pJaws, FUGU_LOAD_INFO *pFugu, SOLE_LOAD_INFO *pSole,
  249. ALT_LIST *pAltList, int cAlt, GLYPH *pGlyph, RECT *pGuide,
  250. CHARSET *pCharSet, LOCRUN_INFO *pLocRunInfo)
  251. {
  252. int i;
  253. RREAL *pNetOut;
  254. int iWinner, cOut;
  255. BOOL fAgree;
  256. RREAL *pFeat = (RREAL *) ExternAlloc(pJaws->iNetSize * sizeof(RREAL));
  257. if (pFeat == NULL)
  258. {
  259. return -1;
  260. }
  261. if (JawsFeaturize(pFugu, pSole, pLocRunInfo, pGlyph, pGuide, pCharSet, pFeat, pAltList, &fAgree) < 0)
  262. {
  263. ExternFree(pFeat);
  264. return -1;
  265. }
  266. if (!fAgree)
  267. {
  268. pNetOut = runLocalConnectNet(&pJaws->net, pFeat, &iWinner, &cOut);
  269. if (cOut < (int) pAltList->cAlt)
  270. {
  271. pAltList->cAlt = cOut;
  272. }
  273. for (i = 0; i < (int) pAltList->cAlt; i++)
  274. {
  275. pAltList->aeScore[i] = (float) *(pNetOut++) / (float) SOFT_MAX_UNITY;
  276. }
  277. }
  278. for (i = 0; i < (int) pAltList->cAlt; i++)
  279. {
  280. pAltList->aeScore[i] = ((float) -ProbToScore(pAltList->aeScore[i])) / (float) 256.0;
  281. }
  282. SortAltList(pAltList);
  283. ExternFree(pFeat);
  284. return pAltList->cAlt;
  285. }