factory.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. {
  2. Free Pascal port of the Hermes C library.
  3. Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
  4. Original C version by Christian Nentwich ([email protected])
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. }
  17. Var
  18. Processor : Integer;
  19. Procedure Hermes_Factory_Init;
  20. Var
  21. res : Integer;
  22. Begin
  23. res := 0;
  24. Processor := PROC_GENERIC;
  25. {$IFDEF I386_ASSEMBLER}
  26. Processor := Processor Or PROC_X86_PENTIUM;{There are no others at the moment}
  27. res := Hermes_X86_CPU;
  28. If (res And $800000) <> 0 Then
  29. Begin
  30. // Writeln('mmx disabled for debugging');
  31. Processor := Processor Or PROC_MMX_PENTIUM;
  32. { Writeln('mmx!');}
  33. End;
  34. {$ENDIF I386_ASSEMBLER}
  35. End;
  36. Function Hermes_Factory_getClearer(bits : int32) : PHermesClearer;
  37. Var
  38. tmp : PHermesClearer;
  39. Begin
  40. { Try different processors in order of priority..
  41. Note that for this to work, an MMX processor has to have both MMX and
  42. X86 flags }
  43. tmp := malloc(SizeOf(THermesClearer));
  44. If tmp = Nil Then
  45. Begin
  46. Hermes_Factory_getClearer := Nil;
  47. Exit;
  48. End;
  49. tmp^.bits := bits;
  50. Hermes_Factory_getClearer := tmp;
  51. {$IFDEF I386_ASSEMBLER}
  52. If (Processor And PROC_MMX_PENTIUM) <> 0 Then
  53. Case bits Of
  54. 32 : Begin
  55. tmp^.func := @ClearMMX_32;
  56. Exit;
  57. End;
  58. 24 : ;
  59. 16 : Begin
  60. tmp^.func := @ClearMMX_16;
  61. Exit;
  62. End;
  63. 8 : Begin
  64. tmp^.func := @ClearMMX_8;
  65. Exit;
  66. End;
  67. End;
  68. If (Processor And PROC_X86_PENTIUM) <> 0 Then
  69. Case bits Of
  70. 32 : Begin
  71. tmp^.func := @ClearX86_32;
  72. Exit;
  73. End;
  74. 24 : ;
  75. 16 : Begin
  76. tmp^.func := @ClearX86_16;
  77. Exit;
  78. End;
  79. 8 : Begin
  80. tmp^.func := @ClearX86_8;
  81. Exit;
  82. End;
  83. End;
  84. {$ENDIF I386_ASSEMBLER}
  85. Case bits Of
  86. 32 : Begin
  87. tmp^.func := @ClearP_32;
  88. Exit;
  89. End;
  90. 24 : Begin
  91. tmp^.func := @ClearP_24;
  92. Exit;
  93. End;
  94. 16 : Begin
  95. tmp^.func := @ClearP_16;
  96. Exit;
  97. End;
  98. 8 : Begin
  99. tmp^.func := @ClearP_8;
  100. Exit;
  101. End;
  102. Else
  103. Begin
  104. free(tmp);
  105. Hermes_Factory_getClearer := Nil;
  106. End;
  107. End;
  108. End;
  109. Function Hermes_Factory_getConverter(source, dest : PHermesFormat) : PHermesConverter;
  110. Var
  111. tmp : PHermesConverter;
  112. i : Integer;
  113. found : Boolean;
  114. Begin
  115. found := False;
  116. tmp := malloc(SizeOf(THermesConverter));
  117. If tmp = Nil Then
  118. Begin
  119. Hermes_Factory_getConverter := Nil;
  120. Exit;
  121. End;
  122. { Set all conversion routines to nil }
  123. tmp^.loopnormal := Nil;
  124. tmp^.loopstretch := Nil;
  125. tmp^.normal := Nil;
  126. tmp^.stretch := Nil;
  127. tmp^.dither := Nil;
  128. tmp^.ditherstretch := Nil;
  129. tmp^.flags := 0;
  130. If source^.indexed Then
  131. { For 8 bit indexed, just look at the destination bit depth and check
  132. if the converter's processor is a subset of our processor }
  133. For i := 0 To Factory_NumConverters - 1 Do
  134. If (Factory_Converters[i].d_bits = dest^.bits) And
  135. (Factory_Converters[i].s_idx And
  136. ((processor And Factory_Converters[i].processor) <> 0)) Then
  137. Begin
  138. { If any routines are unassigned, assign them now }
  139. If tmp^.loopnormal = Nil Then
  140. Begin
  141. tmp^.loopnormal := Factory_Converters[i].loopnormal;
  142. found := True;
  143. End;
  144. If tmp^.normal = Nil Then
  145. Begin
  146. tmp^.normal := Factory_Converters[i].normal;
  147. found := True;
  148. End;
  149. If tmp^.loopstretch = Nil Then
  150. Begin
  151. tmp^.loopstretch := Factory_Converters[i].loopstretch;
  152. found := True;
  153. End;
  154. If tmp^.stretch = Nil Then
  155. Begin
  156. tmp^.stretch := Factory_Converters[i].stretch;
  157. found := True;
  158. End;
  159. End Else
  160. Else
  161. { Otherwise we need to compare everything, including bitmasks }
  162. For i := 0 To Factory_NumConverters - 1 Do
  163. If (Factory_Converters[i].d_bits = dest^.bits) And
  164. (Factory_Converters[i].d_r = dest^.r) And
  165. (Factory_Converters[i].d_g = dest^.g) And
  166. (Factory_Converters[i].d_b = dest^.b) And
  167. (Factory_Converters[i].d_a = dest^.a) And
  168. (Factory_Converters[i].d_idx = dest^.indexed) And
  169. (Factory_Converters[i].s_bits = source^.bits) And
  170. (Factory_Converters[i].s_r = source^.r) And
  171. (Factory_Converters[i].s_g = source^.g) And
  172. (Factory_Converters[i].s_b = source^.b) And
  173. (Factory_Converters[i].s_a = source^.a) And
  174. (Factory_Converters[i].s_idx = source^.indexed) And
  175. ((processor And Factory_Converters[i].processor) <> 0) Then
  176. Begin
  177. { If any routines are unassigned, assign them now }
  178. If (tmp^.loopnormal = Nil) And
  179. (Factory_Converters[i].loopnormal <> Nil) Then
  180. Begin
  181. tmp^.loopnormal := Factory_Converters[i].loopnormal;
  182. found := True;
  183. End;
  184. If (tmp^.normal = Nil) And
  185. (Factory_Converters[i].normal <> Nil) Then
  186. Begin
  187. tmp^.normal := Factory_Converters[i].normal;
  188. found := True;
  189. End;
  190. If (tmp^.loopstretch = Nil) And
  191. (Factory_Converters[i].loopstretch <> Nil) Then
  192. Begin
  193. tmp^.loopstretch := Factory_Converters[i].loopstretch;
  194. found := True;
  195. End;
  196. If (tmp^.stretch = Nil) And
  197. (Factory_Converters[i].stretch <> Nil) Then
  198. Begin
  199. tmp^.stretch := Factory_Converters[i].stretch;
  200. found := True;
  201. End;
  202. If (tmp^.dither = Nil) And
  203. (Factory_Converters[i].dither <> Nil) Then
  204. Begin
  205. tmp^.dither := Factory_Converters[i].dither;
  206. found := True;
  207. End;
  208. If (tmp^.ditherstretch = Nil) And
  209. (Factory_Converters[i].ditherstretch <> Nil) Then
  210. Begin
  211. tmp^.ditherstretch := Factory_Converters[i].ditherstretch;
  212. found := True;
  213. End;
  214. { In the rare event of having everything assigned, pull the emergency
  215. break. Otherwise we need to continue looking (might be stretching
  216. routines somewhere :)
  217. Do I sound like a stewardess? }
  218. If (tmp^.loopnormal <> Nil) And (tmp^.normal <> Nil) And
  219. (tmp^.loopstretch <> Nil) And (tmp^.stretch <> Nil) And
  220. (tmp^.dither <> Nil) And (tmp^.ditherstretch <> Nil) Then
  221. Break;
  222. End;
  223. If found Then
  224. Begin
  225. Hermes_FormatCopy(source, @tmp^.source);
  226. Hermes_FormatCopy(dest, @tmp^.dest);
  227. Hermes_Factory_getConverter := tmp;
  228. End
  229. Else
  230. Begin
  231. free(tmp);
  232. Hermes_Factory_getConverter := Nil;
  233. End;
  234. End;
  235. Function Hermes_Factory_getEqualConverter(bits : Integer) : PHermesConverter;
  236. Var
  237. found : Boolean;
  238. tmp : PHermesConverter;
  239. asm_found : Integer;
  240. c_found : Integer;
  241. Begin
  242. found := False;
  243. tmp := malloc(SizeOf(THermesConverter));
  244. If tmp = Nil Then
  245. Begin
  246. Hermes_Factory_getEqualConverter := Nil;
  247. Exit;
  248. End;
  249. { Set all conversion routines to null }
  250. tmp^.loopnormal := Nil;
  251. tmp^.loopstretch := Nil;
  252. tmp^.normal := Nil;
  253. tmp^.stretch := Nil;
  254. tmp^.dither := Nil;
  255. tmp^.ditherstretch := Nil;
  256. {$IFDEF I386_ASSEMBLER}
  257. { Try MMX routines }
  258. If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
  259. (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
  260. If (processor And PROC_MMX_PENTIUM) <> 0 Then
  261. { Case bits Of
  262. End};
  263. { Try X86 routines }
  264. If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
  265. (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
  266. If (processor And PROC_X86_PENTIUM) <> 0 Then
  267. Begin
  268. asm_found := 0;
  269. Case bits Of
  270. 32 : Begin
  271. tmp^.normal := @CopyX86p_4byte; asm_found := 1;
  272. End;
  273. 24 : ;
  274. 16 : Begin
  275. tmp^.normal := @CopyX86p_2byte; asm_found := 1;
  276. End;
  277. 8 : Begin
  278. tmp^.normal := @CopyX86p_1byte; asm_found := 1;
  279. End;
  280. End;
  281. If (asm_found And 1) <> 0 Then
  282. Begin
  283. tmp^.loopnormal := @ConvertX86;
  284. found := True;
  285. End;
  286. End;
  287. {$ENDIF I386_ASSEMBLER}
  288. If (tmp^.loopnormal = Nil) Or (tmp^.normal = Nil) Or
  289. (tmp^.loopstretch = Nil) Or (tmp^.stretch = Nil) Then
  290. Begin
  291. c_found := 0;
  292. Case bits Of
  293. 32 : Begin
  294. If tmp^.normal = Nil Then
  295. Begin
  296. tmp^.normal := @CopyP_4byte; c_found := c_found Or 1;
  297. End;
  298. If tmp^.stretch = Nil Then
  299. Begin
  300. tmp^.stretch := @CopyP_4byte_S; c_found := c_found Or 2;
  301. End;
  302. End;
  303. 24 : Begin
  304. If tmp^.normal = Nil Then
  305. Begin
  306. tmp^.normal := @CopyP_3byte; c_found := c_found Or 1;
  307. End;
  308. If tmp^.stretch = Nil Then
  309. Begin
  310. tmp^.stretch := @CopyP_3byte_S; c_found := c_found Or 2;
  311. End;
  312. End;
  313. 16 : Begin
  314. If tmp^.normal = Nil Then
  315. Begin
  316. tmp^.normal := @CopyP_2byte; c_found := c_found Or 1;
  317. End;
  318. If tmp^.stretch = Nil Then
  319. Begin
  320. tmp^.stretch := @CopyP_2byte_S; c_found := c_found Or 2;
  321. End;
  322. End;
  323. 8 : Begin
  324. If tmp^.normal = Nil Then
  325. Begin
  326. tmp^.normal := @CopyP_1byte; c_found := c_found Or 1;
  327. End;
  328. If tmp^.stretch = Nil Then
  329. Begin
  330. tmp^.stretch := @CopyP_1byte_S; c_found := c_found Or 2;
  331. End;
  332. End;
  333. End;
  334. If (c_found And 1) <> 0 Then
  335. Begin
  336. tmp^.loopnormal := @ConvertP; found := True;
  337. End;
  338. If (c_found And 2) <> 0 Then
  339. Begin
  340. tmp^.loopstretch := @ConvertPStretch; found := True;
  341. End;
  342. End;
  343. If found Then
  344. Hermes_Factory_getEqualConverter := tmp
  345. Else
  346. Begin
  347. free(tmp);
  348. Hermes_Factory_getEqualConverter := Nil;
  349. End;
  350. End;