jsimd.c 21 KB

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