jdsample.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. {$IFNDEF FPC_DOTTEDUNITS}
  2. Unit JdSample;
  3. {$ENDIF FPC_DOTTEDUNITS}
  4. { Original: jdsample.c; Copyright (C) 1991-1996, Thomas G. Lane. }
  5. { This file contains upsampling routines.
  6. Upsampling input data is counted in "row groups". A row group
  7. is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
  8. sample rows of each component. Upsampling will normally produce
  9. max_v_samp_factor pixel rows from each row group (but this could vary
  10. if the upsampler is applying a scale factor of its own).
  11. An excellent reference for image resampling is
  12. Digital Image Warping, George Wolberg, 1990.
  13. Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.}
  14. interface
  15. {$I jconfig.inc}
  16. {$IFDEF FPC_DOTTEDUNITS}
  17. uses
  18. System.Jpeg.Jmorecfg,
  19. System.Jpeg.Jinclude,
  20. System.Jpeg.Jutils,
  21. System.Jpeg.Jpeglib,
  22. System.Jpeg.Jdeferr,
  23. System.Jpeg.Jerror;
  24. {$ELSE FPC_DOTTEDUNITS}
  25. uses
  26. jmorecfg,
  27. jinclude,
  28. jutils,
  29. jpeglib,
  30. jdeferr,
  31. jerror;
  32. {$ENDIF FPC_DOTTEDUNITS}
  33. { Pointer to routine to upsample a single component }
  34. type
  35. upsample1_ptr = procedure (cinfo : j_decompress_ptr;
  36. compptr : jpeg_component_info_ptr;
  37. input_data : JSAMPARRAY;
  38. var output_data_ptr : JSAMPARRAY);
  39. { Module initialization routine for upsampling. }
  40. {GLOBAL}
  41. procedure jinit_upsampler (cinfo : j_decompress_ptr);
  42. implementation
  43. { Private subobject }
  44. type
  45. my_upsample_ptr = ^my_upsampler;
  46. my_upsampler = record
  47. pub : jpeg_upsampler; { public fields }
  48. { Color conversion buffer. When using separate upsampling and color
  49. conversion steps, this buffer holds one upsampled row group until it
  50. has been color converted and output.
  51. Note: we do not allocate any storage for component(s) which are full-size,
  52. ie do not need rescaling. The corresponding entry of color_buf[] is
  53. simply set to point to the input data array, thereby avoiding copying.}
  54. color_buf : array[0..MAX_COMPONENTS-1] of JSAMPARRAY;
  55. { Per-component upsampling method pointers }
  56. methods : array[0..MAX_COMPONENTS-1] of upsample1_ptr;
  57. next_row_out : int; { counts rows emitted from color_buf }
  58. rows_to_go : JDIMENSION; { counts rows remaining in image }
  59. { Height of an input row group for each component. }
  60. rowgroup_height : array[0..MAX_COMPONENTS-1] of int;
  61. { These arrays save pixel expansion factors so that int_expand need not
  62. recompute them each time. They are unused for other upsampling methods.}
  63. h_expand : array[0..MAX_COMPONENTS-1] of UINT8 ;
  64. v_expand : array[0..MAX_COMPONENTS-1] of UINT8 ;
  65. end;
  66. { Initialize for an upsampling pass. }
  67. {METHODDEF}
  68. procedure start_pass_upsample (cinfo : j_decompress_ptr); far;
  69. var
  70. upsample : my_upsample_ptr;
  71. begin
  72. upsample := my_upsample_ptr (cinfo^.upsample);
  73. { Mark the conversion buffer empty }
  74. upsample^.next_row_out := cinfo^.max_v_samp_factor;
  75. { Initialize total-height counter for detecting bottom of image }
  76. upsample^.rows_to_go := cinfo^.output_height;
  77. end;
  78. { Control routine to do upsampling (and color conversion).
  79. In this version we upsample each component independently.
  80. We upsample one row group into the conversion buffer, then apply
  81. color conversion a row at a time. }
  82. {METHODDEF}
  83. procedure sep_upsample (cinfo : j_decompress_ptr;
  84. input_buf : JSAMPIMAGE;
  85. var in_row_group_ctr : JDIMENSION;
  86. in_row_groups_avail : JDIMENSION;
  87. output_buf : JSAMPARRAY;
  88. var out_row_ctr : JDIMENSION;
  89. out_rows_avail : JDIMENSION); far;
  90. var
  91. upsample : my_upsample_ptr;
  92. ci : int;
  93. compptr : jpeg_component_info_ptr;
  94. num_rows : JDIMENSION;
  95. begin
  96. upsample := my_upsample_ptr (cinfo^.upsample);
  97. { Fill the conversion buffer, if it's empty }
  98. if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then
  99. begin
  100. compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  101. for ci := 0 to pred(cinfo^.num_components) do
  102. begin
  103. { Invoke per-component upsample method. Notice we pass a POINTER
  104. to color_buf[ci], so that fullsize_upsample can change it. }
  105. upsample^.methods[ci] (cinfo, compptr,
  106. JSAMPARRAY(@ input_buf^[ci]^
  107. [in_row_group_ctr * upsample^.rowgroup_height[ci]]),
  108. upsample^.color_buf[ci]);
  109. Inc(compptr);
  110. end;
  111. upsample^.next_row_out := 0;
  112. end;
  113. { Color-convert and emit rows }
  114. { How many we have in the buffer: }
  115. num_rows := JDIMENSION (cinfo^.max_v_samp_factor - upsample^.next_row_out);
  116. { Not more than the distance to the end of the image. Need this test
  117. in case the image height is not a multiple of max_v_samp_factor: }
  118. if (num_rows > upsample^.rows_to_go) then
  119. num_rows := upsample^.rows_to_go;
  120. { And not more than what the client can accept: }
  121. Dec(out_rows_avail, out_row_ctr);
  122. if (num_rows > out_rows_avail) then
  123. num_rows := out_rows_avail;
  124. cinfo^.cconvert^.color_convert (cinfo,
  125. JSAMPIMAGE(@(upsample^.color_buf)),
  126. JDIMENSION (upsample^.next_row_out),
  127. JSAMPARRAY(@(output_buf^[out_row_ctr])),
  128. int (num_rows));
  129. { Adjust counts }
  130. Inc(out_row_ctr, num_rows);
  131. Dec(upsample^.rows_to_go, num_rows);
  132. Inc(upsample^.next_row_out, num_rows);
  133. { When the buffer is emptied, declare this input row group consumed }
  134. if (upsample^.next_row_out >= cinfo^.max_v_samp_factor) then
  135. Inc(in_row_group_ctr);
  136. end;
  137. { These are the routines invoked by sep_upsample to upsample pixel values
  138. of a single component. One row group is processed per call. }
  139. { For full-size components, we just make color_buf[ci] point at the
  140. input buffer, and thus avoid copying any data. Note that this is
  141. safe only because sep_upsample doesn't declare the input row group
  142. "consumed" until we are done color converting and emitting it. }
  143. {METHODDEF}
  144. procedure fullsize_upsample (cinfo : j_decompress_ptr;
  145. compptr : jpeg_component_info_ptr;
  146. input_data : JSAMPARRAY;
  147. var output_data_ptr : JSAMPARRAY); far;
  148. begin
  149. output_data_ptr := input_data;
  150. end;
  151. { This is a no-op version used for "uninteresting" components.
  152. These components will not be referenced by color conversion. }
  153. {METHODDEF}
  154. procedure noop_upsample (cinfo : j_decompress_ptr;
  155. compptr : jpeg_component_info_ptr;
  156. input_data : JSAMPARRAY;
  157. var output_data_ptr : JSAMPARRAY); far;
  158. begin
  159. output_data_ptr := NIL; { safety check }
  160. end;
  161. { This version handles any integral sampling ratios.
  162. This is not used for typical JPEG files, so it need not be fast.
  163. Nor, for that matter, is it particularly accurate: the algorithm is
  164. simple replication of the input pixel onto the corresponding output
  165. pixels. The hi-falutin sampling literature refers to this as a
  166. "box filter". A box filter tends to introduce visible artifacts,
  167. so if you are actually going to use 3:1 or 4:1 sampling ratios
  168. you would be well advised to improve this code. }
  169. {METHODDEF}
  170. procedure int_upsample (cinfo : j_decompress_ptr;
  171. compptr : jpeg_component_info_ptr;
  172. input_data : JSAMPARRAY;
  173. var output_data_ptr : JSAMPARRAY); far;
  174. var
  175. upsample : my_upsample_ptr;
  176. output_data : JSAMPARRAY;
  177. {register} inptr, outptr : JSAMPLE_PTR;
  178. {register} invalue : JSAMPLE;
  179. {register} h : int;
  180. {outend}
  181. h_expand, v_expand : int;
  182. inrow, outrow : int;
  183. var
  184. outcount : int; { Nomssi: avoid pointer arithmetic }
  185. begin
  186. upsample := my_upsample_ptr (cinfo^.upsample);
  187. output_data := output_data_ptr;
  188. h_expand := upsample^.h_expand[compptr^.component_index];
  189. v_expand := upsample^.v_expand[compptr^.component_index];
  190. inrow := 0;
  191. outrow := 0;
  192. while (outrow < cinfo^.max_v_samp_factor) do
  193. begin
  194. { Generate one output row with proper horizontal expansion }
  195. inptr := JSAMPLE_PTR(input_data^[inrow]);
  196. outptr := JSAMPLE_PTR(output_data^[outrow]);
  197. outcount := cinfo^.output_width;
  198. while (outcount > 0) do { Nomssi }
  199. begin
  200. invalue := inptr^; { don't need GETJSAMPLE() here }
  201. Inc(inptr);
  202. for h := pred(h_expand) downto 0 do
  203. begin
  204. outptr^ := invalue;
  205. inc(outptr); { <-- fix: this was left out in PasJpeg 1.0 }
  206. Dec(outcount); { thanks to Jannie Gerber for the report }
  207. end;
  208. end;
  209. { Generate any additional output rows by duplicating the first one }
  210. if (v_expand > 1) then
  211. begin
  212. jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
  213. v_expand-1, cinfo^.output_width);
  214. end;
  215. Inc(inrow);
  216. Inc(outrow, v_expand);
  217. end;
  218. end;
  219. { Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
  220. It's still a box filter. }
  221. {METHODDEF}
  222. procedure h2v1_upsample (cinfo : j_decompress_ptr;
  223. compptr : jpeg_component_info_ptr;
  224. input_data : JSAMPARRAY;
  225. var output_data_ptr : JSAMPARRAY); far;
  226. var
  227. output_data : JSAMPARRAY;
  228. {register} inptr, outptr : JSAMPLE_PTR;
  229. {register} invalue : JSAMPLE;
  230. {outend : JSAMPROW;}
  231. outcount : int;
  232. inrow : int;
  233. begin
  234. output_data := output_data_ptr;
  235. for inrow := 0 to pred(cinfo^.max_v_samp_factor) do
  236. begin
  237. inptr := JSAMPLE_PTR(input_data^[inrow]);
  238. outptr := JSAMPLE_PTR(output_data^[inrow]);
  239. {outend := outptr + cinfo^.output_width;}
  240. outcount := cinfo^.output_width;
  241. while (outcount > 0) do
  242. begin
  243. invalue := inptr^; { don't need GETJSAMPLE() here }
  244. Inc(inptr);
  245. outptr^ := invalue;
  246. Inc(outptr);
  247. outptr^ := invalue;
  248. Inc(outptr);
  249. Dec(outcount, 2); { Nomssi: to avoid pointer arithmetic }
  250. end;
  251. end;
  252. end;
  253. { Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
  254. It's still a box filter. }
  255. {METHODDEF}
  256. procedure h2v2_upsample (cinfo : j_decompress_ptr;
  257. compptr : jpeg_component_info_ptr;
  258. input_data : JSAMPARRAY;
  259. var output_data_ptr : JSAMPARRAY); far;
  260. var
  261. output_data : JSAMPARRAY;
  262. {register} inptr, outptr : JSAMPLE_PTR;
  263. {register} invalue : JSAMPLE;
  264. {outend : JSAMPROW;}
  265. outcount : int;
  266. inrow, outrow : int;
  267. begin
  268. output_data := output_data_ptr;
  269. inrow := 0;
  270. outrow := 0;
  271. while (outrow < cinfo^.max_v_samp_factor) do
  272. begin
  273. inptr := JSAMPLE_PTR(input_data^[inrow]);
  274. outptr := JSAMPLE_PTR(output_data^[outrow]);
  275. {outend := outptr + cinfo^.output_width;}
  276. outcount := cinfo^.output_width;
  277. while (outcount > 0) do
  278. begin
  279. invalue := inptr^; { don't need GETJSAMPLE() here }
  280. Inc(inptr);
  281. outptr^ := invalue;
  282. Inc(outptr);
  283. outptr^ := invalue;
  284. Inc(outptr);
  285. Dec(outcount, 2);
  286. end;
  287. jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
  288. 1, cinfo^.output_width);
  289. Inc(inrow);
  290. Inc(outrow, 2);
  291. end;
  292. end;
  293. { Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
  294. The upsampling algorithm is linear interpolation between pixel centers,
  295. also known as a "triangle filter". This is a good compromise between
  296. speed and visual quality. The centers of the output pixels are 1/4 and 3/4
  297. of the way between input pixel centers.
  298. A note about the "bias" calculations: when rounding fractional values to
  299. integer, we do not want to always round 0.5 up to the next integer.
  300. If we did that, we'd introduce a noticeable bias towards larger values.
  301. Instead, this code is arranged so that 0.5 will be rounded up or down at
  302. alternate pixel locations (a simple ordered dither pattern). }
  303. {METHODDEF}
  304. procedure h2v1_fancy_upsample (cinfo : j_decompress_ptr;
  305. compptr : jpeg_component_info_ptr;
  306. input_data : JSAMPARRAY;
  307. var output_data_ptr : JSAMPARRAY); far;
  308. var
  309. output_data : JSAMPARRAY;
  310. {register} pre_inptr, inptr, outptr : JSAMPLE_PTR;
  311. {register} invalue : int;
  312. {register} colctr : JDIMENSION;
  313. inrow : int;
  314. begin
  315. output_data := output_data_ptr;
  316. for inrow := 0 to pred(cinfo^.max_v_samp_factor) do
  317. begin
  318. inptr := JSAMPLE_PTR(input_data^[inrow]);
  319. outptr := JSAMPLE_PTR(output_data^[inrow]);
  320. { Special case for first column }
  321. pre_inptr := inptr;
  322. invalue := GETJSAMPLE(inptr^);
  323. Inc(inptr);
  324. outptr^ := JSAMPLE (invalue);
  325. Inc(outptr);
  326. outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(inptr^) + 2) shr 2);
  327. Inc(outptr);
  328. for colctr := pred(compptr^.downsampled_width - 2) downto 0 do
  329. begin
  330. { General case: 3/4 * nearer pixel + 1/4 * further pixel }
  331. invalue := GETJSAMPLE(inptr^) * 3;
  332. Inc(inptr);
  333. outptr^ := JSAMPLE ((invalue + GETJSAMPLE(pre_inptr^) + 1) shr 2);
  334. Inc(pre_inptr);
  335. Inc(outptr);
  336. outptr^ := JSAMPLE ((invalue + GETJSAMPLE(inptr^) + 2) shr 2);
  337. Inc(outptr);
  338. end;
  339. { Special case for last column }
  340. invalue := GETJSAMPLE(inptr^);
  341. outptr^ := JSAMPLE ((invalue * 3 + GETJSAMPLE(pre_inptr^) + 1) shr 2);
  342. Inc(outptr);
  343. outptr^ := JSAMPLE (invalue);
  344. {Inc(outptr); - value never used }
  345. end;
  346. end;
  347. { Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
  348. Again a triangle filter; see comments for h2v1 case, above.
  349. It is OK for us to reference the adjacent input rows because we demanded
  350. context from the main buffer controller (see initialization code). }
  351. {METHODDEF}
  352. procedure h2v2_fancy_upsample (cinfo : j_decompress_ptr;
  353. compptr : jpeg_component_info_ptr;
  354. input_data : JSAMPARRAY;
  355. var output_data_ptr : JSAMPARRAY); far;
  356. var
  357. output_data : JSAMPARRAY;
  358. {register} inptr0, inptr1, outptr : JSAMPLE_PTR;
  359. {$ifdef BITS_IN_JSAMPLE_IS_8}
  360. {register} thiscolsum, lastcolsum, nextcolsum : int;
  361. {$else}
  362. {register} thiscolsum, lastcolsum, nextcolsum : INT32;
  363. {$endif}
  364. {register} colctr : JDIMENSION;
  365. inrow, outrow, v : int;
  366. var
  367. prev_input_data : JSAMPARRAY; { Nomssi work around }
  368. begin
  369. output_data := output_data_ptr;
  370. outrow := 0;
  371. inrow := 0;
  372. while (outrow < cinfo^.max_v_samp_factor) do
  373. begin
  374. for v := 0 to pred(2) do
  375. begin
  376. { inptr0 points to nearest input row, inptr1 points to next nearest }
  377. inptr0 := JSAMPLE_PTR(input_data^[inrow]);
  378. if (v = 0) then { next nearest is row above }
  379. begin
  380. {inptr1 := JSAMPLE_PTR(input_data^[inrow-1]);}
  381. prev_input_data := input_data; { work around }
  382. Dec(JSAMPROW_PTR(prev_input_data)); { negative offsets }
  383. inptr1 := JSAMPLE_PTR(prev_input_data^[inrow]);
  384. end
  385. else { next nearest is row below }
  386. inptr1 := JSAMPLE_PTR(input_data^[inrow+1]);
  387. outptr := JSAMPLE_PTR(output_data^[outrow]);
  388. Inc(outrow);
  389. { Special case for first column }
  390. thiscolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^);
  391. Inc(inptr0);
  392. Inc(inptr1);
  393. nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^);
  394. Inc(inptr0);
  395. Inc(inptr1);
  396. outptr^ := JSAMPLE ((thiscolsum * 4 + 8) shr 4);
  397. Inc(outptr);
  398. outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4);
  399. Inc(outptr);
  400. lastcolsum := thiscolsum; thiscolsum := nextcolsum;
  401. for colctr := pred(compptr^.downsampled_width - 2) downto 0 do
  402. begin
  403. { General case: 3/4 * nearer pixel + 1/4 * further pixel in each }
  404. { dimension, thus 9/16, 3/16, 3/16, 1/16 overall }
  405. nextcolsum := GETJSAMPLE(inptr0^) * 3 + GETJSAMPLE(inptr1^);
  406. Inc(inptr0);
  407. Inc(inptr1);
  408. outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4);
  409. Inc(outptr);
  410. outptr^ := JSAMPLE ((thiscolsum * 3 + nextcolsum + 7) shr 4);
  411. Inc(outptr);
  412. lastcolsum := thiscolsum;
  413. thiscolsum := nextcolsum;
  414. end;
  415. { Special case for last column }
  416. outptr^ := JSAMPLE ((thiscolsum * 3 + lastcolsum + 8) shr 4);
  417. Inc(outptr);
  418. outptr^ := JSAMPLE ((thiscolsum * 4 + 7) shr 4);
  419. {Inc(outptr); - value never used }
  420. end;
  421. Inc(inrow);
  422. end;
  423. end;
  424. { Module initialization routine for upsampling. }
  425. {GLOBAL}
  426. procedure jinit_upsampler (cinfo : j_decompress_ptr);
  427. var
  428. upsample : my_upsample_ptr;
  429. ci : int;
  430. compptr : jpeg_component_info_ptr;
  431. need_buffer, do_fancy : boolean;
  432. h_in_group, v_in_group, h_out_group, v_out_group : int;
  433. begin
  434. upsample := my_upsample_ptr (
  435. cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
  436. SIZEOF(my_upsampler)) );
  437. cinfo^.upsample := jpeg_upsampler_ptr (upsample);
  438. upsample^.pub.start_pass := start_pass_upsample;
  439. upsample^.pub.upsample := sep_upsample;
  440. upsample^.pub.need_context_rows := FALSE; { until we find out differently }
  441. if (cinfo^.CCIR601_sampling) then { this isn't supported }
  442. ERREXIT(j_common_ptr(cinfo), JERR_CCIR601_NOTIMPL);
  443. { jdmainct.c doesn't support context rows when min_DCT_scaled_size := 1,
  444. so don't ask for it. }
  445. do_fancy := cinfo^.do_fancy_upsampling and (cinfo^.min_DCT_scaled_size > 1);
  446. { Verify we can handle the sampling factors, select per-component methods,
  447. and create storage as needed. }
  448. compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  449. for ci := 0 to pred(cinfo^.num_components) do
  450. begin
  451. { Compute size of an "input group" after IDCT scaling. This many samples
  452. are to be converted to max_h_samp_factor * max_v_samp_factor pixels. }
  453. h_in_group := (compptr^.h_samp_factor * compptr^.DCT_scaled_size) div
  454. cinfo^.min_DCT_scaled_size;
  455. v_in_group := (compptr^.v_samp_factor * compptr^.DCT_scaled_size) div
  456. cinfo^.min_DCT_scaled_size;
  457. h_out_group := cinfo^.max_h_samp_factor;
  458. v_out_group := cinfo^.max_v_samp_factor;
  459. upsample^.rowgroup_height[ci] := v_in_group; { save for use later }
  460. need_buffer := TRUE;
  461. if (not compptr^.component_needed) then
  462. begin
  463. { Don't bother to upsample an uninteresting component. }
  464. upsample^.methods[ci] := noop_upsample;
  465. need_buffer := FALSE;
  466. end
  467. else
  468. if (h_in_group = h_out_group) and (v_in_group = v_out_group) then
  469. begin
  470. { Fullsize components can be processed without any work. }
  471. upsample^.methods[ci] := fullsize_upsample;
  472. need_buffer := FALSE;
  473. end
  474. else
  475. if (h_in_group * 2 = h_out_group) and
  476. (v_in_group = v_out_group) then
  477. begin
  478. { Special cases for 2h1v upsampling }
  479. if (do_fancy) and (compptr^.downsampled_width > 2) then
  480. upsample^.methods[ci] := h2v1_fancy_upsample
  481. else
  482. upsample^.methods[ci] := h2v1_upsample;
  483. end
  484. else
  485. if (h_in_group * 2 = h_out_group) and
  486. (v_in_group * 2 = v_out_group) then
  487. begin
  488. { Special cases for 2h2v upsampling }
  489. if (do_fancy) and (compptr^.downsampled_width > 2) then
  490. begin
  491. upsample^.methods[ci] := h2v2_fancy_upsample;
  492. upsample^.pub.need_context_rows := TRUE;
  493. end
  494. else
  495. upsample^.methods[ci] := h2v2_upsample;
  496. end
  497. else
  498. if ((h_out_group mod h_in_group) = 0) and
  499. ((v_out_group mod v_in_group) = 0) then
  500. begin
  501. { Generic integral-factors upsampling method }
  502. upsample^.methods[ci] := int_upsample;
  503. upsample^.h_expand[ci] := UINT8 (h_out_group div h_in_group);
  504. upsample^.v_expand[ci] := UINT8 (v_out_group div v_in_group);
  505. end
  506. else
  507. ERREXIT(j_common_ptr(cinfo), JERR_FRACT_SAMPLE_NOTIMPL);
  508. if (need_buffer) then
  509. begin
  510. upsample^.color_buf[ci] := cinfo^.mem^.alloc_sarray
  511. (j_common_ptr(cinfo), JPOOL_IMAGE,
  512. JDIMENSION (jround_up( long (cinfo^.output_width),
  513. long (cinfo^.max_h_samp_factor))),
  514. JDIMENSION (cinfo^.max_v_samp_factor));
  515. end;
  516. Inc(compptr);
  517. end;
  518. end;
  519. end.