/media/libjpeg/jdmerge.c

http://github.com/zpao/v8monkey · C · 409 lines · 254 code · 46 blank · 109 comment · 17 complexity · f37af3a74472518e1a28dbd997b5bbb1 MD5 · raw file

  1. /*
  2. * jdmerge.c
  3. *
  4. * Copyright (C) 1994-1996, Thomas G. Lane.
  5. * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
  6. * Copyright (C) 2009, D. R. Commander.
  7. * This file is part of the Independent JPEG Group's software.
  8. * For conditions of distribution and use, see the accompanying README file.
  9. *
  10. * This file contains code for merged upsampling/color conversion.
  11. *
  12. * This file combines functions from jdsample.c and jdcolor.c;
  13. * read those files first to understand what's going on.
  14. *
  15. * When the chroma components are to be upsampled by simple replication
  16. * (ie, box filtering), we can save some work in color conversion by
  17. * calculating all the output pixels corresponding to a pair of chroma
  18. * samples at one time. In the conversion equations
  19. * R = Y + K1 * Cr
  20. * G = Y + K2 * Cb + K3 * Cr
  21. * B = Y + K4 * Cb
  22. * only the Y term varies among the group of pixels corresponding to a pair
  23. * of chroma samples, so the rest of the terms can be calculated just once.
  24. * At typical sampling ratios, this eliminates half or three-quarters of the
  25. * multiplications needed for color conversion.
  26. *
  27. * This file currently provides implementations for the following cases:
  28. * YCbCr => RGB color conversion only.
  29. * Sampling ratios of 2h1v or 2h2v.
  30. * No scaling needed at upsample time.
  31. * Corner-aligned (non-CCIR601) sampling alignment.
  32. * Other special cases could be added, but in most applications these are
  33. * the only common cases. (For uncommon cases we fall back on the more
  34. * general code in jdsample.c and jdcolor.c.)
  35. */
  36. #define JPEG_INTERNALS
  37. #include "jinclude.h"
  38. #include "jpeglib.h"
  39. #include "jsimd.h"
  40. #ifdef UPSAMPLE_MERGING_SUPPORTED
  41. /* Private subobject */
  42. typedef struct {
  43. struct jpeg_upsampler pub; /* public fields */
  44. /* Pointer to routine to do actual upsampling/conversion of one row group */
  45. JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
  46. JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  47. JSAMPARRAY output_buf));
  48. /* Private state for YCC->RGB conversion */
  49. int * Cr_r_tab; /* => table for Cr to R conversion */
  50. int * Cb_b_tab; /* => table for Cb to B conversion */
  51. INT32 * Cr_g_tab; /* => table for Cr to G conversion */
  52. INT32 * Cb_g_tab; /* => table for Cb to G conversion */
  53. /* For 2:1 vertical sampling, we produce two output rows at a time.
  54. * We need a "spare" row buffer to hold the second output row if the
  55. * application provides just a one-row buffer; we also use the spare
  56. * to discard the dummy last row if the image height is odd.
  57. */
  58. JSAMPROW spare_row;
  59. boolean spare_full; /* T if spare buffer is occupied */
  60. JDIMENSION out_row_width; /* samples per output row */
  61. JDIMENSION rows_to_go; /* counts rows remaining in image */
  62. } my_upsampler;
  63. typedef my_upsampler * my_upsample_ptr;
  64. #define SCALEBITS 16 /* speediest right-shift on some machines */
  65. #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
  66. #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  67. /*
  68. * Initialize tables for YCC->RGB colorspace conversion.
  69. * This is taken directly from jdcolor.c; see that file for more info.
  70. */
  71. LOCAL(void)
  72. build_ycc_rgb_table (j_decompress_ptr cinfo)
  73. {
  74. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  75. int i;
  76. INT32 x;
  77. SHIFT_TEMPS
  78. upsample->Cr_r_tab = (int *)
  79. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  80. (MAXJSAMPLE+1) * SIZEOF(int));
  81. upsample->Cb_b_tab = (int *)
  82. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  83. (MAXJSAMPLE+1) * SIZEOF(int));
  84. upsample->Cr_g_tab = (INT32 *)
  85. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  86. (MAXJSAMPLE+1) * SIZEOF(INT32));
  87. upsample->Cb_g_tab = (INT32 *)
  88. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  89. (MAXJSAMPLE+1) * SIZEOF(INT32));
  90. for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  91. /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  92. /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  93. /* Cr=>R value is nearest int to 1.40200 * x */
  94. upsample->Cr_r_tab[i] = (int)
  95. RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  96. /* Cb=>B value is nearest int to 1.77200 * x */
  97. upsample->Cb_b_tab[i] = (int)
  98. RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
  99. /* Cr=>G value is scaled-up -0.71414 * x */
  100. upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
  101. /* Cb=>G value is scaled-up -0.34414 * x */
  102. /* We also add in ONE_HALF so that need not do it in inner loop */
  103. upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
  104. }
  105. }
  106. /*
  107. * Initialize for an upsampling pass.
  108. */
  109. METHODDEF(void)
  110. start_pass_merged_upsample (j_decompress_ptr cinfo)
  111. {
  112. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  113. /* Mark the spare buffer empty */
  114. upsample->spare_full = FALSE;
  115. /* Initialize total-height counter for detecting bottom of image */
  116. upsample->rows_to_go = cinfo->output_height;
  117. }
  118. /*
  119. * Control routine to do upsampling (and color conversion).
  120. *
  121. * The control routine just handles the row buffering considerations.
  122. */
  123. METHODDEF(void)
  124. merged_2v_upsample (j_decompress_ptr cinfo,
  125. JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  126. JDIMENSION in_row_groups_avail,
  127. JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  128. JDIMENSION out_rows_avail)
  129. /* 2:1 vertical sampling case: may need a spare row. */
  130. {
  131. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  132. JSAMPROW work_ptrs[2];
  133. JDIMENSION num_rows; /* number of rows returned to caller */
  134. if (upsample->spare_full) {
  135. /* If we have a spare row saved from a previous cycle, just return it. */
  136. jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
  137. 1, upsample->out_row_width);
  138. num_rows = 1;
  139. upsample->spare_full = FALSE;
  140. } else {
  141. /* Figure number of rows to return to caller. */
  142. num_rows = 2;
  143. /* Not more than the distance to the end of the image. */
  144. if (num_rows > upsample->rows_to_go)
  145. num_rows = upsample->rows_to_go;
  146. /* And not more than what the client can accept: */
  147. out_rows_avail -= *out_row_ctr;
  148. if (num_rows > out_rows_avail)
  149. num_rows = out_rows_avail;
  150. /* Create output pointer array for upsampler. */
  151. work_ptrs[0] = output_buf[*out_row_ctr];
  152. if (num_rows > 1) {
  153. work_ptrs[1] = output_buf[*out_row_ctr + 1];
  154. } else {
  155. work_ptrs[1] = upsample->spare_row;
  156. upsample->spare_full = TRUE;
  157. }
  158. /* Now do the upsampling. */
  159. (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  160. }
  161. /* Adjust counts */
  162. *out_row_ctr += num_rows;
  163. upsample->rows_to_go -= num_rows;
  164. /* When the buffer is emptied, declare this input row group consumed */
  165. if (! upsample->spare_full)
  166. (*in_row_group_ctr)++;
  167. }
  168. METHODDEF(void)
  169. merged_1v_upsample (j_decompress_ptr cinfo,
  170. JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  171. JDIMENSION in_row_groups_avail,
  172. JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  173. JDIMENSION out_rows_avail)
  174. /* 1:1 vertical sampling case: much easier, never need a spare row. */
  175. {
  176. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  177. /* Just do the upsampling. */
  178. (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
  179. output_buf + *out_row_ctr);
  180. /* Adjust counts */
  181. (*out_row_ctr)++;
  182. (*in_row_group_ctr)++;
  183. }
  184. /*
  185. * These are the routines invoked by the control routines to do
  186. * the actual upsampling/conversion. One row group is processed per call.
  187. *
  188. * Note: since we may be writing directly into application-supplied buffers,
  189. * we have to be honest about the output width; we can't assume the buffer
  190. * has been rounded up to an even width.
  191. */
  192. /*
  193. * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
  194. */
  195. METHODDEF(void)
  196. h2v1_merged_upsample (j_decompress_ptr cinfo,
  197. JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  198. JSAMPARRAY output_buf)
  199. {
  200. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  201. register int y, cred, cgreen, cblue;
  202. int cb, cr;
  203. register JSAMPROW outptr;
  204. JSAMPROW inptr0, inptr1, inptr2;
  205. JDIMENSION col;
  206. /* copy these pointers into registers if possible */
  207. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  208. int * Crrtab = upsample->Cr_r_tab;
  209. int * Cbbtab = upsample->Cb_b_tab;
  210. INT32 * Crgtab = upsample->Cr_g_tab;
  211. INT32 * Cbgtab = upsample->Cb_g_tab;
  212. SHIFT_TEMPS
  213. inptr0 = input_buf[0][in_row_group_ctr];
  214. inptr1 = input_buf[1][in_row_group_ctr];
  215. inptr2 = input_buf[2][in_row_group_ctr];
  216. outptr = output_buf[0];
  217. /* Loop for each pair of output pixels */
  218. for (col = cinfo->output_width >> 1; col > 0; col--) {
  219. /* Do the chroma part of the calculation */
  220. cb = GETJSAMPLE(*inptr1++);
  221. cr = GETJSAMPLE(*inptr2++);
  222. cred = Crrtab[cr];
  223. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  224. cblue = Cbbtab[cb];
  225. /* Fetch 2 Y values and emit 2 pixels */
  226. y = GETJSAMPLE(*inptr0++);
  227. outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  228. outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  229. outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  230. outptr += rgb_pixelsize[cinfo->out_color_space];
  231. y = GETJSAMPLE(*inptr0++);
  232. outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  233. outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  234. outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  235. outptr += rgb_pixelsize[cinfo->out_color_space];
  236. }
  237. /* If image width is odd, do the last output column separately */
  238. if (cinfo->output_width & 1) {
  239. cb = GETJSAMPLE(*inptr1);
  240. cr = GETJSAMPLE(*inptr2);
  241. cred = Crrtab[cr];
  242. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  243. cblue = Cbbtab[cb];
  244. y = GETJSAMPLE(*inptr0);
  245. outptr[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  246. outptr[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  247. outptr[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  248. }
  249. }
  250. /*
  251. * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  252. */
  253. METHODDEF(void)
  254. h2v2_merged_upsample (j_decompress_ptr cinfo,
  255. JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  256. JSAMPARRAY output_buf)
  257. {
  258. my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  259. register int y, cred, cgreen, cblue;
  260. int cb, cr;
  261. register JSAMPROW outptr0, outptr1;
  262. JSAMPROW inptr00, inptr01, inptr1, inptr2;
  263. JDIMENSION col;
  264. /* copy these pointers into registers if possible */
  265. register JSAMPLE * range_limit = cinfo->sample_range_limit;
  266. int * Crrtab = upsample->Cr_r_tab;
  267. int * Cbbtab = upsample->Cb_b_tab;
  268. INT32 * Crgtab = upsample->Cr_g_tab;
  269. INT32 * Cbgtab = upsample->Cb_g_tab;
  270. SHIFT_TEMPS
  271. inptr00 = input_buf[0][in_row_group_ctr*2];
  272. inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  273. inptr1 = input_buf[1][in_row_group_ctr];
  274. inptr2 = input_buf[2][in_row_group_ctr];
  275. outptr0 = output_buf[0];
  276. outptr1 = output_buf[1];
  277. /* Loop for each group of output pixels */
  278. for (col = cinfo->output_width >> 1; col > 0; col--) {
  279. /* Do the chroma part of the calculation */
  280. cb = GETJSAMPLE(*inptr1++);
  281. cr = GETJSAMPLE(*inptr2++);
  282. cred = Crrtab[cr];
  283. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  284. cblue = Cbbtab[cb];
  285. /* Fetch 4 Y values and emit 4 pixels */
  286. y = GETJSAMPLE(*inptr00++);
  287. outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  288. outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  289. outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  290. outptr0 += RGB_PIXELSIZE;
  291. y = GETJSAMPLE(*inptr00++);
  292. outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  293. outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  294. outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  295. outptr0 += RGB_PIXELSIZE;
  296. y = GETJSAMPLE(*inptr01++);
  297. outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  298. outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  299. outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  300. outptr1 += RGB_PIXELSIZE;
  301. y = GETJSAMPLE(*inptr01++);
  302. outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  303. outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  304. outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  305. outptr1 += RGB_PIXELSIZE;
  306. }
  307. /* If image width is odd, do the last output column separately */
  308. if (cinfo->output_width & 1) {
  309. cb = GETJSAMPLE(*inptr1);
  310. cr = GETJSAMPLE(*inptr2);
  311. cred = Crrtab[cr];
  312. cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  313. cblue = Cbbtab[cb];
  314. y = GETJSAMPLE(*inptr00);
  315. outptr0[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  316. outptr0[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  317. outptr0[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  318. y = GETJSAMPLE(*inptr01);
  319. outptr1[rgb_red[cinfo->out_color_space]] = range_limit[y + cred];
  320. outptr1[rgb_green[cinfo->out_color_space]] = range_limit[y + cgreen];
  321. outptr1[rgb_blue[cinfo->out_color_space]] = range_limit[y + cblue];
  322. }
  323. }
  324. /*
  325. * Module initialization routine for merged upsampling/color conversion.
  326. *
  327. * NB: this is called under the conditions determined by use_merged_upsample()
  328. * in jdmaster.c. That routine MUST correspond to the actual capabilities
  329. * of this module; no safety checks are made here.
  330. */
  331. GLOBAL(void)
  332. jinit_merged_upsampler (j_decompress_ptr cinfo)
  333. {
  334. my_upsample_ptr upsample;
  335. upsample = (my_upsample_ptr)
  336. (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  337. SIZEOF(my_upsampler));
  338. cinfo->upsample = (struct jpeg_upsampler *) upsample;
  339. upsample->pub.start_pass = start_pass_merged_upsample;
  340. upsample->pub.need_context_rows = FALSE;
  341. upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
  342. if (cinfo->max_v_samp_factor == 2) {
  343. upsample->pub.upsample = merged_2v_upsample;
  344. if (jsimd_can_h2v2_merged_upsample())
  345. upsample->upmethod = jsimd_h2v2_merged_upsample;
  346. else
  347. upsample->upmethod = h2v2_merged_upsample;
  348. /* Allocate a spare row buffer */
  349. upsample->spare_row = (JSAMPROW)
  350. (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  351. (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
  352. } else {
  353. upsample->pub.upsample = merged_1v_upsample;
  354. if (jsimd_can_h2v1_merged_upsample())
  355. upsample->upmethod = jsimd_h2v1_merged_upsample;
  356. else
  357. upsample->upmethod = h2v1_merged_upsample;
  358. /* No spare row needed */
  359. upsample->spare_row = NULL;
  360. }
  361. build_ycc_rgb_table(cinfo);
  362. }
  363. #endif /* UPSAMPLE_MERGING_SUPPORTED */