Repo for the search and displace ingest module that takes odf, docx and pdf and transforms it into .md to be used with search and displace operations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

592 lines
19 KiB

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