jsimd.c 17 KB

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