jdcol565.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /*
  2. * jdcol565.c
  3. *
  4. * This file was part of the Independent JPEG Group's software:
  5. * Copyright (C) 1991-1997, Thomas G. Lane.
  6. * Modifications:
  7. * Copyright (C) 2013, Linaro Limited.
  8. * Copyright (C) 2014, D. R. Commander.
  9. * For conditions of distribution and use, see the accompanying README file.
  10. *
  11. * This file contains output colorspace conversion routines.
  12. */
  13. /* This file is included by jdcolor.c */
  14. INLINE
  15. LOCAL(void)
  16. ycc_rgb565_convert_internal (j_decompress_ptr cinfo,
  17. JSAMPIMAGE input_buf, JDIMENSION input_row,
  18. JSAMPARRAY output_buf, int num_rows)
  19. {
  20. my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
  21. register int y, cb, cr;
  22. register JSAMPROW outptr;
  23. register JSAMPROW inptr0, inptr1, inptr2;
  24. register JDIMENSION col;
  25. JDIMENSION num_cols = cinfo->output_width;
  26. /* copy these pointers into registers if possible */
  27. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  28. register int * Crrtab = cconvert->Cr_r_tab;
  29. register int * Cbbtab = cconvert->Cb_b_tab;
  30. register INT32 * Crgtab = cconvert->Cr_g_tab;
  31. register INT32 * Cbgtab = cconvert->Cb_g_tab;
  32. SHIFT_TEMPS
  33. while (--num_rows >= 0) {
  34. INT32 rgb;
  35. unsigned int r, g, b;
  36. inptr0 = input_buf[0][input_row];
  37. inptr1 = input_buf[1][input_row];
  38. inptr2 = input_buf[2][input_row];
  39. input_row++;
  40. outptr = *output_buf++;
  41. if (PACK_NEED_ALIGNMENT(outptr)) {
  42. y = GETJSAMPLE(*inptr0++);
  43. cb = GETJSAMPLE(*inptr1++);
  44. cr = GETJSAMPLE(*inptr2++);
  45. r = range_limit[y + Crrtab[cr]];
  46. g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  47. SCALEBITS))];
  48. b = range_limit[y + Cbbtab[cb]];
  49. rgb = PACK_SHORT_565(r, g, b);
  50. *(INT16*)outptr = rgb;
  51. outptr += 2;
  52. num_cols--;
  53. }
  54. for (col = 0; col < (num_cols >> 1); col++) {
  55. y = GETJSAMPLE(*inptr0++);
  56. cb = GETJSAMPLE(*inptr1++);
  57. cr = GETJSAMPLE(*inptr2++);
  58. r = range_limit[y + Crrtab[cr]];
  59. g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  60. SCALEBITS))];
  61. b = range_limit[y + Cbbtab[cb]];
  62. rgb = PACK_SHORT_565(r, g, b);
  63. y = GETJSAMPLE(*inptr0++);
  64. cb = GETJSAMPLE(*inptr1++);
  65. cr = GETJSAMPLE(*inptr2++);
  66. r = range_limit[y + Crrtab[cr]];
  67. g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  68. SCALEBITS))];
  69. b = range_limit[y + Cbbtab[cb]];
  70. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  71. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  72. outptr += 4;
  73. }
  74. if (num_cols & 1) {
  75. y = GETJSAMPLE(*inptr0);
  76. cb = GETJSAMPLE(*inptr1);
  77. cr = GETJSAMPLE(*inptr2);
  78. r = range_limit[y + Crrtab[cr]];
  79. g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  80. SCALEBITS))];
  81. b = range_limit[y + Cbbtab[cb]];
  82. rgb = PACK_SHORT_565(r, g, b);
  83. *(INT16*)outptr = rgb;
  84. }
  85. }
  86. }
  87. INLINE
  88. LOCAL(void)
  89. ycc_rgb565D_convert_internal (j_decompress_ptr cinfo,
  90. JSAMPIMAGE input_buf, JDIMENSION input_row,
  91. JSAMPARRAY output_buf, int num_rows)
  92. {
  93. my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
  94. register int y, cb, cr;
  95. register JSAMPROW outptr;
  96. register JSAMPROW inptr0, inptr1, inptr2;
  97. register JDIMENSION col;
  98. JDIMENSION num_cols = cinfo->output_width;
  99. /* copy these pointers into registers if possible */
  100. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  101. register int * Crrtab = cconvert->Cr_r_tab;
  102. register int * Cbbtab = cconvert->Cb_b_tab;
  103. register INT32 * Crgtab = cconvert->Cr_g_tab;
  104. register INT32 * Cbgtab = cconvert->Cb_g_tab;
  105. INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  106. SHIFT_TEMPS
  107. while (--num_rows >= 0) {
  108. INT32 rgb;
  109. unsigned int r, g, b;
  110. inptr0 = input_buf[0][input_row];
  111. inptr1 = input_buf[1][input_row];
  112. inptr2 = input_buf[2][input_row];
  113. input_row++;
  114. outptr = *output_buf++;
  115. if (PACK_NEED_ALIGNMENT(outptr)) {
  116. y = GETJSAMPLE(*inptr0++);
  117. cb = GETJSAMPLE(*inptr1++);
  118. cr = GETJSAMPLE(*inptr2++);
  119. r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
  120. g = range_limit[DITHER_565_G(y +
  121. ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  122. SCALEBITS)), d0)];
  123. b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
  124. rgb = PACK_SHORT_565(r, g, b);
  125. *(INT16*)outptr = rgb;
  126. outptr += 2;
  127. num_cols--;
  128. }
  129. for (col = 0; col < (num_cols >> 1); col++) {
  130. y = GETJSAMPLE(*inptr0++);
  131. cb = GETJSAMPLE(*inptr1++);
  132. cr = GETJSAMPLE(*inptr2++);
  133. r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
  134. g = range_limit[DITHER_565_G(y +
  135. ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  136. SCALEBITS)), d0)];
  137. b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
  138. d0 = DITHER_ROTATE(d0);
  139. rgb = PACK_SHORT_565(r, g, b);
  140. y = GETJSAMPLE(*inptr0++);
  141. cb = GETJSAMPLE(*inptr1++);
  142. cr = GETJSAMPLE(*inptr2++);
  143. r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
  144. g = range_limit[DITHER_565_G(y +
  145. ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  146. SCALEBITS)), d0)];
  147. b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
  148. d0 = DITHER_ROTATE(d0);
  149. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  150. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  151. outptr += 4;
  152. }
  153. if (num_cols & 1) {
  154. y = GETJSAMPLE(*inptr0);
  155. cb = GETJSAMPLE(*inptr1);
  156. cr = GETJSAMPLE(*inptr2);
  157. r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
  158. g = range_limit[DITHER_565_G(y +
  159. ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
  160. SCALEBITS)), d0)];
  161. b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
  162. rgb = PACK_SHORT_565(r, g, b);
  163. *(INT16*)outptr = rgb;
  164. }
  165. }
  166. }
  167. INLINE
  168. LOCAL(void)
  169. rgb_rgb565_convert_internal (j_decompress_ptr cinfo,
  170. JSAMPIMAGE input_buf, JDIMENSION input_row,
  171. JSAMPARRAY output_buf, int num_rows)
  172. {
  173. register JSAMPROW outptr;
  174. register JSAMPROW inptr0, inptr1, inptr2;
  175. register JDIMENSION col;
  176. JDIMENSION num_cols = cinfo->output_width;
  177. SHIFT_TEMPS
  178. while (--num_rows >= 0) {
  179. INT32 rgb;
  180. unsigned int r, g, b;
  181. inptr0 = input_buf[0][input_row];
  182. inptr1 = input_buf[1][input_row];
  183. inptr2 = input_buf[2][input_row];
  184. input_row++;
  185. outptr = *output_buf++;
  186. if (PACK_NEED_ALIGNMENT(outptr)) {
  187. r = GETJSAMPLE(*inptr0++);
  188. g = GETJSAMPLE(*inptr1++);
  189. b = GETJSAMPLE(*inptr2++);
  190. rgb = PACK_SHORT_565(r, g, b);
  191. *(INT16*)outptr = rgb;
  192. outptr += 2;
  193. num_cols--;
  194. }
  195. for (col = 0; col < (num_cols >> 1); col++) {
  196. r = GETJSAMPLE(*inptr0++);
  197. g = GETJSAMPLE(*inptr1++);
  198. b = GETJSAMPLE(*inptr2++);
  199. rgb = PACK_SHORT_565(r, g, b);
  200. r = GETJSAMPLE(*inptr0++);
  201. g = GETJSAMPLE(*inptr1++);
  202. b = GETJSAMPLE(*inptr2++);
  203. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  204. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  205. outptr += 4;
  206. }
  207. if (num_cols & 1) {
  208. r = GETJSAMPLE(*inptr0);
  209. g = GETJSAMPLE(*inptr1);
  210. b = GETJSAMPLE(*inptr2);
  211. rgb = PACK_SHORT_565(r, g, b);
  212. *(INT16*)outptr = rgb;
  213. }
  214. }
  215. }
  216. INLINE
  217. LOCAL(void)
  218. rgb_rgb565D_convert_internal (j_decompress_ptr cinfo,
  219. JSAMPIMAGE input_buf, JDIMENSION input_row,
  220. JSAMPARRAY output_buf, int num_rows)
  221. {
  222. register JSAMPROW outptr;
  223. register JSAMPROW inptr0, inptr1, inptr2;
  224. register JDIMENSION col;
  225. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  226. JDIMENSION num_cols = cinfo->output_width;
  227. INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  228. SHIFT_TEMPS
  229. while (--num_rows >= 0) {
  230. INT32 rgb;
  231. unsigned int r, g, b;
  232. inptr0 = input_buf[0][input_row];
  233. inptr1 = input_buf[1][input_row];
  234. inptr2 = input_buf[2][input_row];
  235. input_row++;
  236. outptr = *output_buf++;
  237. if (PACK_NEED_ALIGNMENT(outptr)) {
  238. r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
  239. g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
  240. b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
  241. rgb = PACK_SHORT_565(r, g, b);
  242. *(INT16*)outptr = rgb;
  243. outptr += 2;
  244. num_cols--;
  245. }
  246. for (col = 0; col < (num_cols >> 1); col++) {
  247. r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
  248. g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
  249. b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
  250. d0 = DITHER_ROTATE(d0);
  251. rgb = PACK_SHORT_565(r, g, b);
  252. r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
  253. g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
  254. b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
  255. d0 = DITHER_ROTATE(d0);
  256. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
  257. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  258. outptr += 4;
  259. }
  260. if (num_cols & 1) {
  261. r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
  262. g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
  263. b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
  264. rgb = PACK_SHORT_565(r, g, b);
  265. *(INT16*)outptr = rgb;
  266. }
  267. }
  268. }
  269. INLINE
  270. LOCAL(void)
  271. gray_rgb565_convert_internal (j_decompress_ptr cinfo,
  272. JSAMPIMAGE input_buf, JDIMENSION input_row,
  273. JSAMPARRAY output_buf, int num_rows)
  274. {
  275. register JSAMPROW inptr, outptr;
  276. register JDIMENSION col;
  277. JDIMENSION num_cols = cinfo->output_width;
  278. while (--num_rows >= 0) {
  279. INT32 rgb;
  280. unsigned int g;
  281. inptr = input_buf[0][input_row++];
  282. outptr = *output_buf++;
  283. if (PACK_NEED_ALIGNMENT(outptr)) {
  284. g = *inptr++;
  285. rgb = PACK_SHORT_565(g, g, g);
  286. *(INT16*)outptr = rgb;
  287. outptr += 2;
  288. num_cols--;
  289. }
  290. for (col = 0; col < (num_cols >> 1); col++) {
  291. g = *inptr++;
  292. rgb = PACK_SHORT_565(g, g, g);
  293. g = *inptr++;
  294. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
  295. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  296. outptr += 4;
  297. }
  298. if (num_cols & 1) {
  299. g = *inptr;
  300. rgb = PACK_SHORT_565(g, g, g);
  301. *(INT16*)outptr = rgb;
  302. }
  303. }
  304. }
  305. INLINE
  306. LOCAL(void)
  307. gray_rgb565D_convert_internal (j_decompress_ptr cinfo,
  308. JSAMPIMAGE input_buf, JDIMENSION input_row,
  309. JSAMPARRAY output_buf, int num_rows)
  310. {
  311. register JSAMPROW inptr, outptr;
  312. register JDIMENSION col;
  313. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  314. JDIMENSION num_cols = cinfo->output_width;
  315. INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
  316. while (--num_rows >= 0) {
  317. INT32 rgb;
  318. unsigned int g;
  319. inptr = input_buf[0][input_row++];
  320. outptr = *output_buf++;
  321. if (PACK_NEED_ALIGNMENT(outptr)) {
  322. g = *inptr++;
  323. g = range_limit[DITHER_565_R(g, d0)];
  324. rgb = PACK_SHORT_565(g, g, g);
  325. *(INT16*)outptr = rgb;
  326. outptr += 2;
  327. num_cols--;
  328. }
  329. for (col = 0; col < (num_cols >> 1); col++) {
  330. g = *inptr++;
  331. g = range_limit[DITHER_565_R(g, d0)];
  332. rgb = PACK_SHORT_565(g, g, g);
  333. d0 = DITHER_ROTATE(d0);
  334. g = *inptr++;
  335. g = range_limit[DITHER_565_R(g, d0)];
  336. rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
  337. d0 = DITHER_ROTATE(d0);
  338. WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
  339. outptr += 4;
  340. }
  341. if (num_cols & 1) {
  342. g = *inptr;
  343. g = range_limit[DITHER_565_R(g, d0)];
  344. rgb = PACK_SHORT_565(g, g, g);
  345. *(INT16*)outptr = rgb;
  346. }
  347. }
  348. }