jdcol565.c 12 KB

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