jsimd.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. /*
  2. * jsimd_arm.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, 2022, D. R. Commander.
  7. * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
  8. * Copyright (C) 2019, Google LLC.
  9. * Copyright (C) 2020, Arm Limited.
  10. *
  11. * Based on the x86 SIMD extension for IJG JPEG library,
  12. * Copyright (C) 1999-2006, MIYASAKA Masaru.
  13. * For conditions of distribution and use, see copyright notice in jsimdext.inc
  14. *
  15. * This file contains the interface between the "normal" portions
  16. * of the library and the SIMD implementations when running on a
  17. * 32-bit Arm architecture.
  18. */
  19. #define JPEG_INTERNALS
  20. #include "../../../jinclude.h"
  21. #include "../../../jpeglib.h"
  22. #include "../../../jsimd.h"
  23. #include "../../../jdct.h"
  24. #include "../../../jsimddct.h"
  25. #include "../../jsimd.h"
  26. #include <ctype.h>
  27. static unsigned int simd_support = ~0;
  28. static unsigned int simd_huffman = 1;
  29. #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
  30. #define SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT (1024 * 1024)
  31. LOCAL(int)
  32. check_feature(char *buffer, char *feature)
  33. {
  34. char *p;
  35. if (*feature == 0)
  36. return 0;
  37. if (strncmp(buffer, "Features", 8) != 0)
  38. return 0;
  39. buffer += 8;
  40. while (isspace(*buffer))
  41. buffer++;
  42. /* Check if 'feature' is present in the buffer as a separate word */
  43. while ((p = strstr(buffer, feature))) {
  44. if (p > buffer && !isspace(*(p - 1))) {
  45. buffer++;
  46. continue;
  47. }
  48. p += strlen(feature);
  49. if (*p != 0 && !isspace(*p)) {
  50. buffer++;
  51. continue;
  52. }
  53. return 1;
  54. }
  55. return 0;
  56. }
  57. LOCAL(int)
  58. parse_proc_cpuinfo(int bufsize)
  59. {
  60. char *buffer = (char *)malloc(bufsize);
  61. FILE *fd;
  62. simd_support = 0;
  63. if (!buffer)
  64. return 0;
  65. fd = fopen("/proc/cpuinfo", "r");
  66. if (fd) {
  67. while (fgets(buffer, bufsize, fd)) {
  68. if (!strchr(buffer, '\n') && !feof(fd)) {
  69. /* "impossible" happened - insufficient size of the buffer! */
  70. fclose(fd);
  71. free(buffer);
  72. return 0;
  73. }
  74. if (check_feature(buffer, "neon"))
  75. simd_support |= JSIMD_NEON;
  76. }
  77. fclose(fd);
  78. }
  79. free(buffer);
  80. return 1;
  81. }
  82. #endif
  83. /*
  84. * Check what SIMD accelerations are supported.
  85. *
  86. * FIXME: This code is racy under a multi-threaded environment.
  87. */
  88. LOCAL(void)
  89. init_simd(void)
  90. {
  91. #ifndef NO_GETENV
  92. char env[2] = { 0 };
  93. #endif
  94. #if !defined(__ARM_NEON__) && (defined(__linux__) || defined(ANDROID) || defined(__ANDROID__))
  95. int bufsize = 1024; /* an initial guess for the line buffer size limit */
  96. #endif
  97. if (simd_support != ~0U)
  98. return;
  99. simd_support = 0;
  100. #if defined(__ARM_NEON__)
  101. simd_support |= JSIMD_NEON;
  102. #elif defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
  103. /* We still have a chance to use Neon regardless of globally used
  104. * -mcpu/-mfpu options passed to gcc by performing runtime detection via
  105. * /proc/cpuinfo parsing on linux/android */
  106. while (!parse_proc_cpuinfo(bufsize)) {
  107. bufsize *= 2;
  108. if (bufsize > SOMEWHAT_SANE_PROC_CPUINFO_SIZE_LIMIT)
  109. break;
  110. }
  111. #endif
  112. #ifndef NO_GETENV
  113. /* Force different settings through environment variables */
  114. if (!GETENV_S(env, 2, "JSIMD_FORCENEON") && !strcmp(env, "1"))
  115. simd_support = JSIMD_NEON;
  116. if (!GETENV_S(env, 2, "JSIMD_FORCENONE") && !strcmp(env, "1"))
  117. simd_support = 0;
  118. if (!GETENV_S(env, 2, "JSIMD_NOHUFFENC") && !strcmp(env, "1"))
  119. simd_huffman = 0;
  120. #endif
  121. }
  122. GLOBAL(int)
  123. jsimd_can_rgb_ycc(void)
  124. {
  125. init_simd();
  126. /* The code is optimised for these values only */
  127. if (BITS_IN_JSAMPLE != 8)
  128. return 0;
  129. if (sizeof(JDIMENSION) != 4)
  130. return 0;
  131. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  132. return 0;
  133. if (simd_support & JSIMD_NEON)
  134. return 1;
  135. return 0;
  136. }
  137. GLOBAL(int)
  138. jsimd_can_rgb_gray(void)
  139. {
  140. init_simd();
  141. /* The code is optimised for these values only */
  142. if (BITS_IN_JSAMPLE != 8)
  143. return 0;
  144. if (sizeof(JDIMENSION) != 4)
  145. return 0;
  146. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  147. return 0;
  148. if (simd_support & JSIMD_NEON)
  149. return 1;
  150. return 0;
  151. }
  152. GLOBAL(int)
  153. jsimd_can_ycc_rgb(void)
  154. {
  155. init_simd();
  156. /* The code is optimised for these values only */
  157. if (BITS_IN_JSAMPLE != 8)
  158. return 0;
  159. if (sizeof(JDIMENSION) != 4)
  160. return 0;
  161. if ((RGB_PIXELSIZE != 3) && (RGB_PIXELSIZE != 4))
  162. return 0;
  163. if (simd_support & JSIMD_NEON)
  164. return 1;
  165. return 0;
  166. }
  167. GLOBAL(int)
  168. jsimd_can_ycc_rgb565(void)
  169. {
  170. init_simd();
  171. /* The code is optimised for these values only */
  172. if (BITS_IN_JSAMPLE != 8)
  173. return 0;
  174. if (sizeof(JDIMENSION) != 4)
  175. return 0;
  176. if (simd_support & JSIMD_NEON)
  177. return 1;
  178. return 0;
  179. }
  180. GLOBAL(void)
  181. jsimd_rgb_ycc_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
  182. JSAMPIMAGE output_buf, JDIMENSION output_row,
  183. int num_rows)
  184. {
  185. void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
  186. switch (cinfo->in_color_space) {
  187. case JCS_EXT_RGB:
  188. neonfct = jsimd_extrgb_ycc_convert_neon;
  189. break;
  190. case JCS_EXT_RGBX:
  191. case JCS_EXT_RGBA:
  192. neonfct = jsimd_extrgbx_ycc_convert_neon;
  193. break;
  194. case JCS_EXT_BGR:
  195. neonfct = jsimd_extbgr_ycc_convert_neon;
  196. break;
  197. case JCS_EXT_BGRX:
  198. case JCS_EXT_BGRA:
  199. neonfct = jsimd_extbgrx_ycc_convert_neon;
  200. break;
  201. case JCS_EXT_XBGR:
  202. case JCS_EXT_ABGR:
  203. neonfct = jsimd_extxbgr_ycc_convert_neon;
  204. break;
  205. case JCS_EXT_XRGB:
  206. case JCS_EXT_ARGB:
  207. neonfct = jsimd_extxrgb_ycc_convert_neon;
  208. break;
  209. default:
  210. neonfct = jsimd_extrgb_ycc_convert_neon;
  211. break;
  212. }
  213. neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
  214. }
  215. GLOBAL(void)
  216. jsimd_rgb_gray_convert(j_compress_ptr cinfo, JSAMPARRAY input_buf,
  217. JSAMPIMAGE output_buf, JDIMENSION output_row,
  218. int num_rows)
  219. {
  220. void (*neonfct) (JDIMENSION, JSAMPARRAY, JSAMPIMAGE, JDIMENSION, int);
  221. switch (cinfo->in_color_space) {
  222. case JCS_EXT_RGB:
  223. neonfct = jsimd_extrgb_gray_convert_neon;
  224. break;
  225. case JCS_EXT_RGBX:
  226. case JCS_EXT_RGBA:
  227. neonfct = jsimd_extrgbx_gray_convert_neon;
  228. break;
  229. case JCS_EXT_BGR:
  230. neonfct = jsimd_extbgr_gray_convert_neon;
  231. break;
  232. case JCS_EXT_BGRX:
  233. case JCS_EXT_BGRA:
  234. neonfct = jsimd_extbgrx_gray_convert_neon;
  235. break;
  236. case JCS_EXT_XBGR:
  237. case JCS_EXT_ABGR:
  238. neonfct = jsimd_extxbgr_gray_convert_neon;
  239. break;
  240. case JCS_EXT_XRGB:
  241. case JCS_EXT_ARGB:
  242. neonfct = jsimd_extxrgb_gray_convert_neon;
  243. break;
  244. default:
  245. neonfct = jsimd_extrgb_gray_convert_neon;
  246. break;
  247. }
  248. neonfct(cinfo->image_width, input_buf, output_buf, output_row, num_rows);
  249. }
  250. GLOBAL(void)
  251. jsimd_ycc_rgb_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  252. JDIMENSION input_row, JSAMPARRAY output_buf,
  253. int num_rows)
  254. {
  255. void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY, int);
  256. switch (cinfo->out_color_space) {
  257. case JCS_EXT_RGB:
  258. neonfct = jsimd_ycc_extrgb_convert_neon;
  259. break;
  260. case JCS_EXT_RGBX:
  261. case JCS_EXT_RGBA:
  262. neonfct = jsimd_ycc_extrgbx_convert_neon;
  263. break;
  264. case JCS_EXT_BGR:
  265. neonfct = jsimd_ycc_extbgr_convert_neon;
  266. break;
  267. case JCS_EXT_BGRX:
  268. case JCS_EXT_BGRA:
  269. neonfct = jsimd_ycc_extbgrx_convert_neon;
  270. break;
  271. case JCS_EXT_XBGR:
  272. case JCS_EXT_ABGR:
  273. neonfct = jsimd_ycc_extxbgr_convert_neon;
  274. break;
  275. case JCS_EXT_XRGB:
  276. case JCS_EXT_ARGB:
  277. neonfct = jsimd_ycc_extxrgb_convert_neon;
  278. break;
  279. default:
  280. neonfct = jsimd_ycc_extrgb_convert_neon;
  281. break;
  282. }
  283. neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
  284. }
  285. GLOBAL(void)
  286. jsimd_ycc_rgb565_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  287. JDIMENSION input_row, JSAMPARRAY output_buf,
  288. int num_rows)
  289. {
  290. jsimd_ycc_rgb565_convert_neon(cinfo->output_width, input_buf, input_row,
  291. output_buf, num_rows);
  292. }
  293. GLOBAL(int)
  294. jsimd_can_h2v2_downsample(void)
  295. {
  296. init_simd();
  297. /* The code is optimised for these values only */
  298. if (BITS_IN_JSAMPLE != 8)
  299. return 0;
  300. if (DCTSIZE != 8)
  301. return 0;
  302. if (sizeof(JDIMENSION) != 4)
  303. return 0;
  304. if (simd_support & JSIMD_NEON)
  305. return 1;
  306. return 0;
  307. }
  308. GLOBAL(int)
  309. jsimd_can_h2v1_downsample(void)
  310. {
  311. init_simd();
  312. /* The code is optimised for these values only */
  313. if (BITS_IN_JSAMPLE != 8)
  314. return 0;
  315. if (DCTSIZE != 8)
  316. return 0;
  317. if (sizeof(JDIMENSION) != 4)
  318. return 0;
  319. if (simd_support & JSIMD_NEON)
  320. return 1;
  321. return 0;
  322. }
  323. GLOBAL(void)
  324. jsimd_h2v2_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
  325. JSAMPARRAY input_data, JSAMPARRAY output_data)
  326. {
  327. jsimd_h2v2_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
  328. compptr->v_samp_factor, compptr->width_in_blocks,
  329. input_data, output_data);
  330. }
  331. GLOBAL(void)
  332. jsimd_h2v1_downsample(j_compress_ptr cinfo, jpeg_component_info *compptr,
  333. JSAMPARRAY input_data, JSAMPARRAY output_data)
  334. {
  335. jsimd_h2v1_downsample_neon(cinfo->image_width, cinfo->max_v_samp_factor,
  336. compptr->v_samp_factor, compptr->width_in_blocks,
  337. input_data, output_data);
  338. }
  339. GLOBAL(int)
  340. jsimd_can_h2v2_upsample(void)
  341. {
  342. init_simd();
  343. /* The code is optimised for these values only */
  344. if (BITS_IN_JSAMPLE != 8)
  345. return 0;
  346. if (sizeof(JDIMENSION) != 4)
  347. return 0;
  348. if (simd_support & JSIMD_NEON)
  349. return 1;
  350. return 0;
  351. }
  352. GLOBAL(int)
  353. jsimd_can_h2v1_upsample(void)
  354. {
  355. init_simd();
  356. /* The code is optimised for these values only */
  357. if (BITS_IN_JSAMPLE != 8)
  358. return 0;
  359. if (sizeof(JDIMENSION) != 4)
  360. return 0;
  361. if (simd_support & JSIMD_NEON)
  362. return 1;
  363. return 0;
  364. }
  365. GLOBAL(void)
  366. jsimd_h2v2_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  367. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  368. {
  369. jsimd_h2v2_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
  370. input_data, output_data_ptr);
  371. }
  372. GLOBAL(void)
  373. jsimd_h2v1_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  374. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  375. {
  376. jsimd_h2v1_upsample_neon(cinfo->max_v_samp_factor, cinfo->output_width,
  377. input_data, output_data_ptr);
  378. }
  379. GLOBAL(int)
  380. jsimd_can_h2v2_fancy_upsample(void)
  381. {
  382. init_simd();
  383. /* The code is optimised for these values only */
  384. if (BITS_IN_JSAMPLE != 8)
  385. return 0;
  386. if (sizeof(JDIMENSION) != 4)
  387. return 0;
  388. if (simd_support & JSIMD_NEON)
  389. return 1;
  390. return 0;
  391. }
  392. GLOBAL(int)
  393. jsimd_can_h2v1_fancy_upsample(void)
  394. {
  395. init_simd();
  396. /* The code is optimised for these values only */
  397. if (BITS_IN_JSAMPLE != 8)
  398. return 0;
  399. if (sizeof(JDIMENSION) != 4)
  400. return 0;
  401. if (simd_support & JSIMD_NEON)
  402. return 1;
  403. return 0;
  404. }
  405. GLOBAL(int)
  406. jsimd_can_h1v2_fancy_upsample(void)
  407. {
  408. init_simd();
  409. /* The code is optimised for these values only */
  410. if (BITS_IN_JSAMPLE != 8)
  411. return 0;
  412. if (sizeof(JDIMENSION) != 4)
  413. return 0;
  414. if (simd_support & JSIMD_NEON)
  415. return 1;
  416. return 0;
  417. }
  418. GLOBAL(void)
  419. jsimd_h2v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  420. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  421. {
  422. jsimd_h2v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
  423. compptr->downsampled_width, input_data,
  424. output_data_ptr);
  425. }
  426. GLOBAL(void)
  427. jsimd_h2v1_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  428. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  429. {
  430. jsimd_h2v1_fancy_upsample_neon(cinfo->max_v_samp_factor,
  431. compptr->downsampled_width, input_data,
  432. output_data_ptr);
  433. }
  434. GLOBAL(void)
  435. jsimd_h1v2_fancy_upsample(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  436. JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)
  437. {
  438. jsimd_h1v2_fancy_upsample_neon(cinfo->max_v_samp_factor,
  439. compptr->downsampled_width, input_data,
  440. output_data_ptr);
  441. }
  442. GLOBAL(int)
  443. jsimd_can_h2v2_merged_upsample(void)
  444. {
  445. init_simd();
  446. /* The code is optimised for these values only */
  447. if (BITS_IN_JSAMPLE != 8)
  448. return 0;
  449. if (sizeof(JDIMENSION) != 4)
  450. return 0;
  451. if (simd_support & JSIMD_NEON)
  452. return 1;
  453. return 0;
  454. }
  455. GLOBAL(int)
  456. jsimd_can_h2v1_merged_upsample(void)
  457. {
  458. init_simd();
  459. /* The code is optimised for these values only */
  460. if (BITS_IN_JSAMPLE != 8)
  461. return 0;
  462. if (sizeof(JDIMENSION) != 4)
  463. return 0;
  464. if (simd_support & JSIMD_NEON)
  465. return 1;
  466. return 0;
  467. }
  468. GLOBAL(void)
  469. jsimd_h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  470. JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
  471. {
  472. void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
  473. switch (cinfo->out_color_space) {
  474. case JCS_EXT_RGB:
  475. neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
  476. break;
  477. case JCS_EXT_RGBX:
  478. case JCS_EXT_RGBA:
  479. neonfct = jsimd_h2v2_extrgbx_merged_upsample_neon;
  480. break;
  481. case JCS_EXT_BGR:
  482. neonfct = jsimd_h2v2_extbgr_merged_upsample_neon;
  483. break;
  484. case JCS_EXT_BGRX:
  485. case JCS_EXT_BGRA:
  486. neonfct = jsimd_h2v2_extbgrx_merged_upsample_neon;
  487. break;
  488. case JCS_EXT_XBGR:
  489. case JCS_EXT_ABGR:
  490. neonfct = jsimd_h2v2_extxbgr_merged_upsample_neon;
  491. break;
  492. case JCS_EXT_XRGB:
  493. case JCS_EXT_ARGB:
  494. neonfct = jsimd_h2v2_extxrgb_merged_upsample_neon;
  495. break;
  496. default:
  497. neonfct = jsimd_h2v2_extrgb_merged_upsample_neon;
  498. break;
  499. }
  500. neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
  501. }
  502. GLOBAL(void)
  503. jsimd_h2v1_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
  504. JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf)
  505. {
  506. void (*neonfct) (JDIMENSION, JSAMPIMAGE, JDIMENSION, JSAMPARRAY);
  507. switch (cinfo->out_color_space) {
  508. case JCS_EXT_RGB:
  509. neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
  510. break;
  511. case JCS_EXT_RGBX:
  512. case JCS_EXT_RGBA:
  513. neonfct = jsimd_h2v1_extrgbx_merged_upsample_neon;
  514. break;
  515. case JCS_EXT_BGR:
  516. neonfct = jsimd_h2v1_extbgr_merged_upsample_neon;
  517. break;
  518. case JCS_EXT_BGRX:
  519. case JCS_EXT_BGRA:
  520. neonfct = jsimd_h2v1_extbgrx_merged_upsample_neon;
  521. break;
  522. case JCS_EXT_XBGR:
  523. case JCS_EXT_ABGR:
  524. neonfct = jsimd_h2v1_extxbgr_merged_upsample_neon;
  525. break;
  526. case JCS_EXT_XRGB:
  527. case JCS_EXT_ARGB:
  528. neonfct = jsimd_h2v1_extxrgb_merged_upsample_neon;
  529. break;
  530. default:
  531. neonfct = jsimd_h2v1_extrgb_merged_upsample_neon;
  532. break;
  533. }
  534. neonfct(cinfo->output_width, input_buf, in_row_group_ctr, output_buf);
  535. }
  536. GLOBAL(int)
  537. jsimd_can_convsamp(void)
  538. {
  539. init_simd();
  540. /* The code is optimised for these values only */
  541. if (DCTSIZE != 8)
  542. return 0;
  543. if (BITS_IN_JSAMPLE != 8)
  544. return 0;
  545. if (sizeof(JDIMENSION) != 4)
  546. return 0;
  547. if (sizeof(DCTELEM) != 2)
  548. return 0;
  549. if (simd_support & JSIMD_NEON)
  550. return 1;
  551. return 0;
  552. }
  553. GLOBAL(int)
  554. jsimd_can_convsamp_float(void)
  555. {
  556. return 0;
  557. }
  558. GLOBAL(void)
  559. jsimd_convsamp(JSAMPARRAY sample_data, JDIMENSION start_col,
  560. DCTELEM *workspace)
  561. {
  562. jsimd_convsamp_neon(sample_data, start_col, workspace);
  563. }
  564. GLOBAL(void)
  565. jsimd_convsamp_float(JSAMPARRAY sample_data, JDIMENSION start_col,
  566. FAST_FLOAT *workspace)
  567. {
  568. }
  569. GLOBAL(int)
  570. jsimd_can_fdct_islow(void)
  571. {
  572. init_simd();
  573. /* The code is optimised for these values only */
  574. if (DCTSIZE != 8)
  575. return 0;
  576. if (sizeof(DCTELEM) != 2)
  577. return 0;
  578. if (simd_support & JSIMD_NEON)
  579. return 1;
  580. return 0;
  581. }
  582. GLOBAL(int)
  583. jsimd_can_fdct_ifast(void)
  584. {
  585. init_simd();
  586. /* The code is optimised for these values only */
  587. if (DCTSIZE != 8)
  588. return 0;
  589. if (sizeof(DCTELEM) != 2)
  590. return 0;
  591. if (simd_support & JSIMD_NEON)
  592. return 1;
  593. return 0;
  594. }
  595. GLOBAL(int)
  596. jsimd_can_fdct_float(void)
  597. {
  598. return 0;
  599. }
  600. GLOBAL(void)
  601. jsimd_fdct_islow(DCTELEM *data)
  602. {
  603. jsimd_fdct_islow_neon(data);
  604. }
  605. GLOBAL(void)
  606. jsimd_fdct_ifast(DCTELEM *data)
  607. {
  608. jsimd_fdct_ifast_neon(data);
  609. }
  610. GLOBAL(void)
  611. jsimd_fdct_float(FAST_FLOAT *data)
  612. {
  613. }
  614. GLOBAL(int)
  615. jsimd_can_quantize(void)
  616. {
  617. init_simd();
  618. /* The code is optimised for these values only */
  619. if (DCTSIZE != 8)
  620. return 0;
  621. if (sizeof(JCOEF) != 2)
  622. return 0;
  623. if (sizeof(DCTELEM) != 2)
  624. return 0;
  625. if (simd_support & JSIMD_NEON)
  626. return 1;
  627. return 0;
  628. }
  629. GLOBAL(int)
  630. jsimd_can_quantize_float(void)
  631. {
  632. return 0;
  633. }
  634. GLOBAL(void)
  635. jsimd_quantize(JCOEFPTR coef_block, DCTELEM *divisors, DCTELEM *workspace)
  636. {
  637. jsimd_quantize_neon(coef_block, divisors, workspace);
  638. }
  639. GLOBAL(void)
  640. jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
  641. FAST_FLOAT *workspace)
  642. {
  643. }
  644. GLOBAL(int)
  645. jsimd_can_idct_2x2(void)
  646. {
  647. init_simd();
  648. /* The code is optimised for these values only */
  649. if (DCTSIZE != 8)
  650. return 0;
  651. if (sizeof(JCOEF) != 2)
  652. return 0;
  653. if (BITS_IN_JSAMPLE != 8)
  654. return 0;
  655. if (sizeof(JDIMENSION) != 4)
  656. return 0;
  657. if (sizeof(ISLOW_MULT_TYPE) != 2)
  658. return 0;
  659. if (simd_support & JSIMD_NEON)
  660. return 1;
  661. return 0;
  662. }
  663. GLOBAL(int)
  664. jsimd_can_idct_4x4(void)
  665. {
  666. init_simd();
  667. /* The code is optimised for these values only */
  668. if (DCTSIZE != 8)
  669. return 0;
  670. if (sizeof(JCOEF) != 2)
  671. return 0;
  672. if (BITS_IN_JSAMPLE != 8)
  673. return 0;
  674. if (sizeof(JDIMENSION) != 4)
  675. return 0;
  676. if (sizeof(ISLOW_MULT_TYPE) != 2)
  677. return 0;
  678. if (simd_support & JSIMD_NEON)
  679. return 1;
  680. return 0;
  681. }
  682. GLOBAL(void)
  683. jsimd_idct_2x2(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  684. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  685. JDIMENSION output_col)
  686. {
  687. jsimd_idct_2x2_neon(compptr->dct_table, coef_block, output_buf, output_col);
  688. }
  689. GLOBAL(void)
  690. jsimd_idct_4x4(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  691. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  692. JDIMENSION output_col)
  693. {
  694. jsimd_idct_4x4_neon(compptr->dct_table, coef_block, output_buf, output_col);
  695. }
  696. GLOBAL(int)
  697. jsimd_can_idct_islow(void)
  698. {
  699. init_simd();
  700. /* The code is optimised for these values only */
  701. if (DCTSIZE != 8)
  702. return 0;
  703. if (sizeof(JCOEF) != 2)
  704. return 0;
  705. if (BITS_IN_JSAMPLE != 8)
  706. return 0;
  707. if (sizeof(JDIMENSION) != 4)
  708. return 0;
  709. if (sizeof(ISLOW_MULT_TYPE) != 2)
  710. return 0;
  711. if (simd_support & JSIMD_NEON)
  712. return 1;
  713. return 0;
  714. }
  715. GLOBAL(int)
  716. jsimd_can_idct_ifast(void)
  717. {
  718. init_simd();
  719. /* The code is optimised for these values only */
  720. if (DCTSIZE != 8)
  721. return 0;
  722. if (sizeof(JCOEF) != 2)
  723. return 0;
  724. if (BITS_IN_JSAMPLE != 8)
  725. return 0;
  726. if (sizeof(JDIMENSION) != 4)
  727. return 0;
  728. if (sizeof(IFAST_MULT_TYPE) != 2)
  729. return 0;
  730. if (IFAST_SCALE_BITS != 2)
  731. return 0;
  732. if (simd_support & JSIMD_NEON)
  733. return 1;
  734. return 0;
  735. }
  736. GLOBAL(int)
  737. jsimd_can_idct_float(void)
  738. {
  739. return 0;
  740. }
  741. GLOBAL(void)
  742. jsimd_idct_islow(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  743. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  744. JDIMENSION output_col)
  745. {
  746. jsimd_idct_islow_neon(compptr->dct_table, coef_block, output_buf,
  747. output_col);
  748. }
  749. GLOBAL(void)
  750. jsimd_idct_ifast(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  751. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  752. JDIMENSION output_col)
  753. {
  754. jsimd_idct_ifast_neon(compptr->dct_table, coef_block, output_buf,
  755. output_col);
  756. }
  757. GLOBAL(void)
  758. jsimd_idct_float(j_decompress_ptr cinfo, jpeg_component_info *compptr,
  759. JCOEFPTR coef_block, JSAMPARRAY output_buf,
  760. JDIMENSION output_col)
  761. {
  762. }
  763. GLOBAL(int)
  764. jsimd_can_huff_encode_one_block(void)
  765. {
  766. init_simd();
  767. if (DCTSIZE != 8)
  768. return 0;
  769. if (sizeof(JCOEF) != 2)
  770. return 0;
  771. if (simd_support & JSIMD_NEON && simd_huffman)
  772. return 1;
  773. return 0;
  774. }
  775. GLOBAL(JOCTET *)
  776. jsimd_huff_encode_one_block(void *state, JOCTET *buffer, JCOEFPTR block,
  777. int last_dc_val, c_derived_tbl *dctbl,
  778. c_derived_tbl *actbl)
  779. {
  780. return jsimd_huff_encode_one_block_neon(state, buffer, block, last_dc_val,
  781. dctbl, actbl);
  782. }
  783. GLOBAL(int)
  784. jsimd_can_encode_mcu_AC_first_prepare(void)
  785. {
  786. init_simd();
  787. if (DCTSIZE != 8)
  788. return 0;
  789. if (sizeof(JCOEF) != 2)
  790. return 0;
  791. if (simd_support & JSIMD_NEON)
  792. return 1;
  793. return 0;
  794. }
  795. GLOBAL(void)
  796. jsimd_encode_mcu_AC_first_prepare(const JCOEF *block,
  797. const int *jpeg_natural_order_start, int Sl,
  798. int Al, JCOEF *values, size_t *zerobits)
  799. {
  800. jsimd_encode_mcu_AC_first_prepare_neon(block, jpeg_natural_order_start,
  801. Sl, Al, values, zerobits);
  802. }
  803. GLOBAL(int)
  804. jsimd_can_encode_mcu_AC_refine_prepare(void)
  805. {
  806. init_simd();
  807. if (DCTSIZE != 8)
  808. return 0;
  809. if (sizeof(JCOEF) != 2)
  810. return 0;
  811. if (simd_support & JSIMD_NEON)
  812. return 1;
  813. return 0;
  814. }
  815. GLOBAL(int)
  816. jsimd_encode_mcu_AC_refine_prepare(const JCOEF *block,
  817. const int *jpeg_natural_order_start, int Sl,
  818. int Al, JCOEF *absvalues, size_t *bits)
  819. {
  820. return jsimd_encode_mcu_AC_refine_prepare_neon(block,
  821. jpeg_natural_order_start, Sl,
  822. Al, absvalues, bits);
  823. }