jsimd_arm64.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * jsimd_arm64.c
  3. *
  4. * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  5. * Copyright (C) 2009-2011, 2013-2014, 2016, D. R. Commander.
  6. * Copyright (C) 2015-2016, Matthieu Darbois.
  7. *
  8. * Based on the x86 SIMD extension for IJG JPEG library,
  9. * Copyright (C) 1999-2006, MIYASAKA Masaru.
  10. * For conditions of distribution and use, see copyright notice in jsimdext.inc
  11. *
  12. * This file contains the interface between the "normal" portions
  13. * of the library and the SIMD implementations when running on a
  14. * 64-bit ARM architecture.
  15. */
  16. #define JPEG_INTERNALS
  17. #include "../jinclude.h"
  18. #include "../jpeglib.h"
  19. #include "../jsimd.h"
  20. #include "../jdct.h"
  21. #include "../jsimddct.h"
  22. #include "jsimd.h"
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #define JSIMD_FASTLD3 1
  27. #define JSIMD_FASTST3 2
  28. #define JSIMD_FASTTBL 4
  29. static unsigned int simd_support = ~0;
  30. static unsigned int simd_huffman = 1;
  31. static unsigned int simd_features = JSIMD_FASTLD3 | JSIMD_FASTST3 |
  32. JSIMD_FASTTBL;
  33. #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
  34. #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
  35. LOCAL(int)
  36. check_cpuinfo (char *buffer, const char *field, char *value)
  37. {
  38. char *p;
  39. if (*value == 0)
  40. return 0;
  41. if (strncmp(buffer, field, strlen(field)) != 0)
  42. return 0;
  43. buffer += strlen(field);
  44. while (isspace(*buffer))
  45. buffer++;
  46. /* Check if 'value' is present in the buffer as a separate word */
  47. while ((p = strstr(buffer, value))) {
  48. if (p > buffer && !isspace(*(p - 1))) {
  49. buffer++;
  50. continue;
  51. }
  52. p += strlen(value);
  53. if (*p != 0 && !isspace(*p)) {
  54. buffer++;
  55. continue;
  56. }
  57. return 1;
  58. }
  59. return 0;
  60. }
  61. LOCAL(int)
  62. parse_proc_cpuinfo (int bufsize)
  63. {
  64. char *buffer = (char *)malloc(bufsize);
  65. FILE *fd;
  66. if (!buffer)
  67. return 0;
  68. fd = fopen("/proc/cpuinfo", "r");
  69. if (fd) {
  70. while (fgets(buffer, bufsize, fd)) {
  71. if (!strchr(buffer, '\n') && !feof(fd)) {
  72. /* "impossible" happened - insufficient size of the buffer! */
  73. fclose(fd);
  74. free(buffer);
  75. return 0;
  76. }
  77. if (check_cpuinfo(buffer, "CPU part", "0xd03") ||
  78. check_cpuinfo(buffer, "CPU part", "0xd07"))
  79. /* The Cortex-A53 has a slow tbl implementation. We can gain a few
  80. percent speedup by disabling the use of that instruction. The
  81. speedup on Cortex-A57 is more subtle but still measurable. */
  82. simd_features &= ~JSIMD_FASTTBL;
  83. else if (check_cpuinfo(buffer, "CPU part", "0x0a1"))
  84. /* The SIMD version of Huffman encoding is slower than the C version on
  85. Cavium ThunderX. Also, ld3 and st3 are abyssmally slow on that
  86. CPU. */
  87. simd_huffman = simd_features = 0;
  88. }
  89. fclose(fd);
  90. }
  91. free(buffer);
  92. return 1;
  93. }
  94. #endif
  95. /*
  96. * Check what SIMD accelerations are supported.
  97. *
  98. * FIXME: This code is racy under a multi-threaded environment.
  99. */
  100. /*
  101. * ARMv8 architectures support NEON extensions by default.
  102. * It is no longer optional as it was with ARMv7.
  103. */
  104. LOCAL(void)
  105. init_simd (void)
  106. {
  107. char *env = NULL;
  108. #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
  109. int bufsize = 1024; /* an initial guess for the line buffer size limit */
  110. #endif
  111. if (simd_support != ~0U)
  112. return;
  113. simd_support = 0;
  114. simd_support |= JSIMD_ARM_NEON;
  115. #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
  116. while (!parse_proc_cpuinfo(bufsize)) {
  117. bufsize *= 2;
  118. if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
  119. break;
  120. }
  121. #endif
  122. /* Force different settings through environment variables */
  123. env = getenv("JSIMD_FORCENEON");
  124. if ((env != NULL) && (strcmp(env, "1") == 0))
  125. simd_support = JSIMD_ARM_NEON;
  126. env = getenv("JSIMD_FORCENONE");
  127. if ((env != NULL) && (strcmp(env, "1") == 0))
  128. simd_support = 0;
  129. env = getenv("JSIMD_NOHUFFENC");
  130. if ((env != NULL) && (strcmp(env, "1") == 0))
  131. simd_huffman = 0;
  132. env = getenv("JSIMD_FASTLD3");
  133. if ((env != NULL) && (strcmp(env, "1") == 0))
  134. simd_features |= JSIMD_FASTLD3;
  135. if ((env != NULL) && (strcmp(env, "0") == 0))
  136. simd_features &= ~JSIMD_FASTLD3;
  137. env = getenv("JSIMD_FASTST3");
  138. if ((env != NULL) && (strcmp(env, "1") == 0))
  139. simd_features |= JSIMD_FASTST3;
  140. if ((env != NULL) && (strcmp(env, "0") == 0))
  141. simd_features &= ~JSIMD_FASTST3;
  142. }
  143. GLOBAL(int)
  144. jsimd_can_rgb_ycc (void)
  145. {
  146. init_simd();
  147. /* The code is optimised for these values only */
  148. if (BITS_IN_JSAMPLE != 8)
  149. return 0;
  150. if (sizeof(JDIMENSION) != 4)
  151. return 0;
  152. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  153. return 0;
  154. if (simd_support & JSIMD_ARM_NEON)
  155. return 1;
  156. return 0;
  157. }
  158. GLOBAL(int)
  159. jsimd_can_rgb_gray (void)
  160. {
  161. init_simd();
  162. return 0;
  163. }
  164. GLOBAL(int)
  165. jsimd_can_ycc_rgb (void)
  166. {
  167. init_simd();
  168. /* The code is optimised for these values only */
  169. if (BITS_IN_JSAMPLE != 8)
  170. return 0;
  171. if (sizeof(JDIMENSION) != 4)
  172. return 0;
  173. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  174. return 0;
  175. if (simd_support & JSIMD_ARM_NEON)
  176. return 1;
  177. return 0;
  178. }
  179. GLOBAL(int)
  180. jsimd_can_ycc_rgb565 (void)
  181. {
  182. init_simd();
  183. /* The code is optimised for these values only */
  184. if (BITS_IN_JSAMPLE != 8)
  185. return 0;
  186. if (sizeof(JDIMENSION) != 4)
  187. return 0;
  188. if (simd_support & JSIMD_ARM_NEON)
  189. return 1;
  190. return 0;
  191. }
  192. GLOBAL(void)
  193. jsimd_rgb_ycc_convert (j_compress_ptr cinfo,
  194. JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
  195. JDIMENSION output_row, int num_rows)
  196. {
  197. void (*neonfct)(JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
  198. switch(cinfo->in_color_space) {
  199. case JCS_EXT_RGB:
  200. if (simd_features & JSIMD_FASTLD3)
  201. neonfct=jsimd_extrgb_ycc_convert_neon;
  202. else
  203. neonfct=jsimd_extrgb_ycc_convert_neon_slowld3;
  204. break;
  205. case JCS_EXT_RGBX:
  206. case JCS_EXT_RGBA:
  207. neonfct=jsimd_extrgbx_ycc_convert_neon;
  208. break;
  209. case JCS_EXT_BGR:
  210. if (simd_features & JSIMD_FASTLD3)
  211. neonfct=jsimd_extbgr_ycc_convert_neon;
  212. else
  213. neonfct=jsimd_extbgr_ycc_convert_neon_slowld3;
  214. break;
  215. case JCS_EXT_BGRX:
  216. case JCS_EXT_BGRA:
  217. neonfct=jsimd_extbgrx_ycc_convert_neon;
  218. break;
  219. case JCS_EXT_XBGR:
  220. case JCS_EXT_ABGR:
  221. neonfct=jsimd_extxbgr_ycc_convert_neon;
  222. break;
  223. case JCS_EXT_XRGB:
  224. case JCS_EXT_ARGB:
  225. neonfct=jsimd_extxrgb_ycc_convert_neon;
  226. break;
  227. default:
  228. if (simd_features & JSIMD_FASTLD3)
  229. neonfct=jsimd_extrgb_ycc_convert_neon;
  230. else
  231. neonfct=jsimd_extrgb_ycc_convert_neon_slowld3;
  232. break;
  233. }
  234. neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
  235. }
  236. GLOBAL(void)
  237. jsimd_rgb_gray_convert (j_compress_ptr cinfo,
  238. JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
  239. JDIMENSION output_row, int num_rows)
  240. {
  241. }
  242. GLOBAL(void)
  243. jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
  244. JSAMPIMAGE input_buf, JDIMENSION input_row,
  245. JSAMPARRAY output_buf, int num_rows)
  246. {
  247. void (*neonfct)(JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
  248. switch(cinfo->out_color_space) {
  249. case JCS_EXT_RGB:
  250. if (simd_features & JSIMD_FASTST3)
  251. neonfct=jsimd_ycc_extrgb_convert_neon;
  252. else
  253. neonfct=jsimd_ycc_extrgb_convert_neon_slowst3;
  254. break;
  255. case JCS_EXT_RGBX:
  256. case JCS_EXT_RGBA:
  257. neonfct=jsimd_ycc_extrgbx_convert_neon;
  258. break;
  259. case JCS_EXT_BGR:
  260. if (simd_features & JSIMD_FASTST3)
  261. neonfct=jsimd_ycc_extbgr_convert_neon;
  262. else
  263. neonfct=jsimd_ycc_extbgr_convert_neon_slowst3;
  264. break;
  265. case JCS_EXT_BGRX:
  266. case JCS_EXT_BGRA:
  267. neonfct=jsimd_ycc_extbgrx_convert_neon;
  268. break;
  269. case JCS_EXT_XBGR:
  270. case JCS_EXT_ABGR:
  271. neonfct=jsimd_ycc_extxbgr_convert_neon;
  272. break;
  273. case JCS_EXT_XRGB:
  274. case JCS_EXT_ARGB:
  275. neonfct=jsimd_ycc_extxrgb_convert_neon;
  276. break;
  277. default:
  278. if (simd_features & JSIMD_FASTST3)
  279. neonfct=jsimd_ycc_extrgb_convert_neon;
  280. else
  281. neonfct=jsimd_ycc_extrgb_convert_neon_slowst3;
  282. break;
  283. }
  284. neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
  285. }
  286. GLOBAL(void)
  287. jsimd_ycc_rgb565_convert (j_decompress_ptr cinfo,
  288. JSAMPIMAGE input_buf, JDIMENSION input_row,
  289. JSAMPARRAY output_buf, int num_rows)
  290. {
  291. jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
  292. output_buf, num_rows);
  293. }
  294. GLOBAL(int)
  295. jsimd_can_h2v2_downsample (void)
  296. {
  297. init_simd();
  298. /* The code is optimised for these values only */
  299. if (BITS_IN_JSAMPLE != 8)
  300. return 0;
  301. if (DCTSIZE != 8)
  302. return 0;
  303. if (sizeof(JDIMENSION) != 4)
  304. return 0;
  305. if (simd_support & JSIMD_ARM_NEON)
  306. return 1;
  307. return 0;
  308. }
  309. GLOBAL(int)
  310. jsimd_can_h2v1_downsample (void)
  311. {
  312. init_simd();
  313. /* The code is optimised for these values only */
  314. if (BITS_IN_JSAMPLE != 8)
  315. return 0;
  316. if (DCTSIZE != 8)
  317. return 0;
  318. if (sizeof(JDIMENSION) != 4)
  319. return 0;
  320. if (simd_support & JSIMD_ARM_NEON)
  321. return 1;
  322. return 0;
  323. }
  324. GLOBAL(void)
  325. jsimd_h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
  326. JSAMPARRAY input_data, JSAMPARRAY output_data)
  327. {
  328. jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
  329. compptr->v_samp_factor, compptr->width_in_blocks,
  330. input_data, output_data);
  331. }
  332. GLOBAL(void)
  333. jsimd_h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
  334. JSAMPARRAY input_data, JSAMPARRAY output_data)
  335. {
  336. jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
  337. compptr->v_samp_factor, compptr->width_in_blocks,
  338. input_data, output_data);
  339. }
  340. GLOBAL(int)
  341. jsimd_can_h2v2_upsample (void)
  342. {
  343. init_simd();
  344. return 0;
  345. }
  346. GLOBAL(int)
  347. jsimd_can_h2v1_upsample (void)
  348. {
  349. init_simd();
  350. return 0;
  351. }
  352. GLOBAL(void)
  353. jsimd_h2v2_upsample (j_decompress_ptr cinfo,
  354. jpeg_component_info *compptr,
  355. JSAMPARRAY input_data,
  356. JSAMPARRAY *output_data_ptr)
  357. {
  358. }
  359. GLOBAL(void)
  360. jsimd_h2v1_upsample (j_decompress_ptr cinfo,
  361. jpeg_component_info *compptr,
  362. JSAMPARRAY input_data,
  363. JSAMPARRAY *output_data_ptr)
  364. {
  365. }
  366. GLOBAL(int)
  367. jsimd_can_h2v2_fancy_upsample (void)
  368. {
  369. init_simd();
  370. return 0;
  371. }
  372. GLOBAL(int)
  373. jsimd_can_h2v1_fancy_upsample (void)
  374. {
  375. init_simd();
  376. return 0;
  377. }
  378. GLOBAL(void)
  379. jsimd_h2v2_fancy_upsample (j_decompress_ptr cinfo,
  380. jpeg_component_info *compptr,
  381. JSAMPARRAY input_data,
  382. JSAMPARRAY *output_data_ptr)
  383. {
  384. }
  385. GLOBAL(void)
  386. jsimd_h2v1_fancy_upsample (j_decompress_ptr cinfo,
  387. jpeg_component_info *compptr,
  388. JSAMPARRAY input_data,
  389. JSAMPARRAY *output_data_ptr)
  390. {
  391. }
  392. GLOBAL(int)
  393. jsimd_can_h2v2_merged_upsample (void)
  394. {
  395. init_simd();
  396. return 0;
  397. }
  398. GLOBAL(int)
  399. jsimd_can_h2v1_merged_upsample (void)
  400. {
  401. init_simd();
  402. return 0;
  403. }
  404. GLOBAL(void)
  405. jsimd_h2v2_merged_upsample (j_decompress_ptr cinfo,
  406. JSAMPIMAGE input_buf,
  407. JDIMENSION in_row_group_ctr,
  408. JSAMPARRAY output_buf)
  409. {
  410. }
  411. GLOBAL(void)
  412. jsimd_h2v1_merged_upsample (j_decompress_ptr cinfo,
  413. JSAMPIMAGE input_buf,
  414. JDIMENSION in_row_group_ctr,
  415. JSAMPARRAY output_buf)
  416. {
  417. }
  418. GLOBAL(int)
  419. jsimd_can_convsamp (void)
  420. {
  421. init_simd();
  422. /* The code is optimised for these values only */
  423. if (DCTSIZE != 8)
  424. return 0;
  425. if (BITS_IN_JSAMPLE != 8)
  426. return 0;
  427. if (sizeof(JDIMENSION) != 4)
  428. return 0;
  429. if (sizeof(DCTELEM) != 2)
  430. return 0;
  431. if (simd_support & JSIMD_ARM_NEON)
  432. return 1;
  433. return 0;
  434. }
  435. GLOBAL(int)
  436. jsimd_can_convsamp_float (void)
  437. {
  438. init_simd();
  439. return 0;
  440. }
  441. GLOBAL(void)
  442. jsimd_convsamp (JSAMPARRAY sample_data, JDIMENSION start_col,
  443. DCTELEM *workspace)
  444. {
  445. jsimd_convsamp_neon(sample_data, start_col, workspace);
  446. }
  447. GLOBAL(void)
  448. jsimd_convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col,
  449. FAST_FLOAT *workspace)
  450. {
  451. }
  452. GLOBAL(int)
  453. jsimd_can_fdct_islow (void)
  454. {
  455. init_simd();
  456. /* The code is optimised for these values only */
  457. if (DCTSIZE != 8)
  458. return 0;
  459. if (sizeof(DCTELEM) != 2)
  460. return 0;
  461. if (simd_support & JSIMD_ARM_NEON)
  462. return 1;
  463. return 0;
  464. }
  465. GLOBAL(int)
  466. jsimd_can_fdct_ifast (void)
  467. {
  468. init_simd();
  469. /* The code is optimised for these values only */
  470. if (DCTSIZE != 8)
  471. return 0;
  472. if (sizeof(DCTELEM) != 2)
  473. return 0;
  474. if (simd_support & JSIMD_ARM_NEON)
  475. return 1;
  476. return 0;
  477. }
  478. GLOBAL(int)
  479. jsimd_can_fdct_float (void)
  480. {
  481. init_simd();
  482. return 0;
  483. }
  484. GLOBAL(void)
  485. jsimd_fdct_islow (DCTELEM *data)
  486. {
  487. jsimd_fdct_islow_neon(data);
  488. }
  489. GLOBAL(void)
  490. jsimd_fdct_ifast (DCTELEM *data)
  491. {
  492. jsimd_fdct_ifast_neon(data);
  493. }
  494. GLOBAL(void)
  495. jsimd_fdct_float (FAST_FLOAT *data)
  496. {
  497. }
  498. GLOBAL(int)
  499. jsimd_can_quantize (void)
  500. {
  501. init_simd();
  502. /* The code is optimised for these values only */
  503. if (DCTSIZE != 8)
  504. return 0;
  505. if (sizeof(JCOEF) != 2)
  506. return 0;
  507. if (sizeof(DCTELEM) != 2)
  508. return 0;
  509. if (simd_support & JSIMD_ARM_NEON)
  510. return 1;
  511. return 0;
  512. }
  513. GLOBAL(int)
  514. jsimd_can_quantize_float (void)
  515. {
  516. init_simd();
  517. return 0;
  518. }
  519. GLOBAL(void)
  520. jsimd_quantize (JCOEFPTR coef_block, DCTELEM *divisors,
  521. DCTELEM *workspace)
  522. {
  523. jsimd_quantize_neon(coef_block, divisors, workspace);
  524. }
  525. GLOBAL(void)
  526. jsimd_quantize_float (JCOEFPTR coef_block, FAST_FLOAT *divisors,
  527. FAST_FLOAT *workspace)
  528. {
  529. }
  530. GLOBAL(int)
  531. jsimd_can_idct_2x2 (void)
  532. {
  533. init_simd();
  534. /* The code is optimised for these values only */
  535. if (DCTSIZE != 8)
  536. return 0;
  537. if (sizeof(JCOEF) != 2)
  538. return 0;
  539. if (BITS_IN_JSAMPLE != 8)
  540. return 0;
  541. if (sizeof(JDIMENSION) != 4)
  542. return 0;
  543. if (sizeof(ISLOW_MULT_TYPE) != 2)
  544. return 0;
  545. if (simd_support & JSIMD_ARM_NEON)
  546. return 1;
  547. return 0;
  548. }
  549. GLOBAL(int)
  550. jsimd_can_idct_4x4 (void)
  551. {
  552. init_simd();
  553. /* The code is optimised for these values only */
  554. if (DCTSIZE != 8)
  555. return 0;
  556. if (sizeof(JCOEF) != 2)
  557. return 0;
  558. if (BITS_IN_JSAMPLE != 8)
  559. return 0;
  560. if (sizeof(JDIMENSION) != 4)
  561. return 0;
  562. if (sizeof(ISLOW_MULT_TYPE) != 2)
  563. return 0;
  564. if (simd_support & JSIMD_ARM_NEON)
  565. return 1;
  566. return 0;
  567. }
  568. GLOBAL(void)
  569. jsimd_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info *compptr,
  570. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  571. JDIMENSION output_col)
  572. {
  573. jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf,
  574. output_col);
  575. }
  576. GLOBAL(void)
  577. jsimd_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info *compptr,
  578. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  579. JDIMENSION output_col)
  580. {
  581. jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf,
  582. output_col);
  583. }
  584. GLOBAL(int)
  585. jsimd_can_idct_islow (void)
  586. {
  587. init_simd();
  588. /* The code is optimised for these values only */
  589. if (DCTSIZE != 8)
  590. return 0;
  591. if (sizeof(JCOEF) != 2)
  592. return 0;
  593. if (BITS_IN_JSAMPLE != 8)
  594. return 0;
  595. if (sizeof(JDIMENSION) != 4)
  596. return 0;
  597. if (sizeof(ISLOW_MULT_TYPE) != 2)
  598. return 0;
  599. if (simd_support & JSIMD_ARM_NEON)
  600. return 1;
  601. return 0;
  602. }
  603. GLOBAL(int)
  604. jsimd_can_idct_ifast (void)
  605. {
  606. init_simd();
  607. /* The code is optimised for these values only */
  608. if (DCTSIZE != 8)
  609. return 0;
  610. if (sizeof(JCOEF) != 2)
  611. return 0;
  612. if (BITS_IN_JSAMPLE != 8)
  613. return 0;
  614. if (sizeof(JDIMENSION) != 4)
  615. return 0;
  616. if (sizeof(IFAST_MULT_TYPE) != 2)
  617. return 0;
  618. if (IFAST_SCALE_BITS != 2)
  619. return 0;
  620. if (simd_support & JSIMD_ARM_NEON)
  621. return 1;
  622. return 0;
  623. }
  624. GLOBAL(int)
  625. jsimd_can_idct_float (void)
  626. {
  627. init_simd();
  628. return 0;
  629. }
  630. GLOBAL(void)
  631. jsimd_idct_islow (j_decompress_ptr cinfo, jpeg_component_info *compptr,
  632. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  633. JDIMENSION output_col)
  634. {
  635. jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
  636. output_col);
  637. }
  638. GLOBAL(void)
  639. jsimd_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info *compptr,
  640. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  641. JDIMENSION output_col)
  642. {
  643. jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
  644. output_col);
  645. }
  646. GLOBAL(void)
  647. jsimd_idct_float (j_decompress_ptr cinfo, jpeg_component_info *compptr,
  648. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  649. JDIMENSION output_col)
  650. {
  651. }
  652. GLOBAL(int)
  653. jsimd_can_huff_encode_one_block (void)
  654. {
  655. init_simd();
  656. if (DCTSIZE != 8)
  657. return 0;
  658. if (sizeof(JCOEF) != 2)
  659. return 0;
  660. if (simd_support & JSIMD_ARM_NEON && simd_huffman)
  661. return 1;
  662. return 0;
  663. }
  664. GLOBAL(JOCTET*)
  665. jsimd_huff_encode_one_block (void *state, JOCTET *buffer, JCOEFPTR block,
  666. int last_dc_val, c_derived_tbl *dctbl,
  667. c_derived_tbl *actbl)
  668. {
  669. if (simd_features & JSIMD_FASTTBL)
  670. return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
  671. dctbl, actbl);
  672. else
  673. return jsimd_huff_encode_one_block_neon_slowtbl(state, buffer, block,
  674. last_dc_val, dctbl, actbl);
  675. }