jdmerge.c 14 KB

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