jcmarker.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. {$IFNDEF FPC_DOTTEDUNITS}
  2. Unit jcmarker;
  3. {$ENDIF FPC_DOTTEDUNITS}
  4. { This file contains routines to write JPEG datastream markers. }
  5. { Original: jcmarker.c; Copyright (C) 1991-1998, Thomas G. Lane. }
  6. interface
  7. {$I jconfig.inc}
  8. {$IFDEF FPC_DOTTEDUNITS}
  9. uses
  10. System.Jpeg.Jinclude, System.Jpeg.Jmorecfg, System.Jpeg.Jerror,
  11. System.Jpeg.Jdeferr, System.Jpeg.Jpeglib, System.Jpeg.Jutils;
  12. {$ELSE FPC_DOTTEDUNITS}
  13. uses
  14. jinclude, jmorecfg, jerror,
  15. jdeferr, jpeglib, jutils;
  16. {$ENDIF FPC_DOTTEDUNITS}
  17. const
  18. { JPEG marker codes }
  19. M_SOF0 = $c0;
  20. M_SOF1 = $c1;
  21. M_SOF2 = $c2;
  22. M_SOF3 = $c3;
  23. M_SOF5 = $c5;
  24. M_SOF6 = $c6;
  25. M_SOF7 = $c7;
  26. M_JPG = $c8;
  27. M_SOF9 = $c9;
  28. M_SOF10 = $ca;
  29. M_SOF11 = $cb;
  30. M_SOF13 = $cd;
  31. M_SOF14 = $ce;
  32. M_SOF15 = $cf;
  33. M_DHT = $c4;
  34. M_DAC = $cc;
  35. M_RST0 = $d0;
  36. M_RST1 = $d1;
  37. M_RST2 = $d2;
  38. M_RST3 = $d3;
  39. M_RST4 = $d4;
  40. M_RST5 = $d5;
  41. M_RST6 = $d6;
  42. M_RST7 = $d7;
  43. M_SOI = $d8;
  44. M_EOI = $d9;
  45. M_SOS = $da;
  46. M_DQT = $db;
  47. M_DNL = $dc;
  48. M_DRI = $dd;
  49. M_DHP = $de;
  50. M_EXP = $df;
  51. M_APP0 = $e0;
  52. M_APP1 = $e1;
  53. M_APP2 = $e2;
  54. M_APP3 = $e3;
  55. M_APP4 = $e4;
  56. M_APP5 = $e5;
  57. M_APP6 = $e6;
  58. M_APP7 = $e7;
  59. M_APP8 = $e8;
  60. M_APP9 = $e9;
  61. M_APP10 = $ea;
  62. M_APP11 = $eb;
  63. M_APP12 = $ec;
  64. M_APP13 = $ed;
  65. M_APP14 = $ee;
  66. M_APP15 = $ef;
  67. M_JPG0 = $f0;
  68. M_JPG13 = $fd;
  69. M_COM = $fe;
  70. M_TEM = $01;
  71. M_ERROR = $100;
  72. type
  73. JPEG_MARKER = Word;
  74. { Private state }
  75. type
  76. my_marker_ptr = ^my_marker_writer;
  77. my_marker_writer = record
  78. pub : jpeg_marker_writer; { public fields }
  79. last_restart_interval : uint; { last DRI value emitted; 0 after SOI }
  80. end;
  81. {GLOBAL}
  82. procedure jinit_marker_writer (cinfo : j_compress_ptr);
  83. implementation
  84. { Basic output routines.
  85. Note that we do not support suspension while writing a marker.
  86. Therefore, an application using suspension must ensure that there is
  87. enough buffer space for the initial markers (typ. 600-700 bytes) before
  88. calling jpeg_start_compress, and enough space to write the trailing EOI
  89. (a few bytes) before calling jpeg_finish_compress. Multipass compression
  90. modes are not supported at all with suspension, so those two are the only
  91. points where markers will be written. }
  92. {LOCAL}
  93. procedure emit_byte (cinfo : j_compress_ptr; val : int);
  94. { Emit a byte }
  95. var
  96. dest : jpeg_destination_mgr_ptr;
  97. begin
  98. dest := cinfo^.dest;
  99. dest^.next_output_byte^ := JOCTET(val);
  100. Inc(dest^.next_output_byte);
  101. Dec(dest^.free_in_buffer);
  102. if (dest^.free_in_buffer = 0) then
  103. begin
  104. if not dest^.empty_output_buffer(cinfo) then
  105. ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND);
  106. end;
  107. end;
  108. {LOCAL}
  109. procedure emit_marker(cinfo : j_compress_ptr; mark : JPEG_MARKER);
  110. { Emit a marker code }
  111. begin
  112. emit_byte(cinfo, $FF);
  113. emit_byte(cinfo, int(mark));
  114. end;
  115. {LOCAL}
  116. procedure emit_2bytes (cinfo : j_compress_ptr; value : int);
  117. { Emit a 2-byte integer; these are always MSB first in JPEG files }
  118. begin
  119. emit_byte(cinfo, (value shr 8) and $FF);
  120. emit_byte(cinfo, value and $FF);
  121. end;
  122. { Routines to write specific marker types. }
  123. {LOCAL}
  124. function emit_dqt (cinfo : j_compress_ptr; index : int) : int;
  125. { Emit a DQT marker }
  126. { Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking }
  127. var
  128. qtbl : JQUANT_TBL_PTR;
  129. prec : int;
  130. i : int;
  131. var
  132. qval : uint;
  133. begin
  134. qtbl := cinfo^.quant_tbl_ptrs[index];
  135. if (qtbl = NIL) then
  136. ERREXIT1(j_common_ptr(cinfo), JERR_NO_QUANT_TABLE, index);
  137. prec := 0;
  138. for i := 0 to Pred(DCTSIZE2) do
  139. begin
  140. if (qtbl^.quantval[i] > 255) then
  141. prec := 1;
  142. end;
  143. if not qtbl^.sent_table then
  144. begin
  145. emit_marker(cinfo, M_DQT);
  146. if (prec <> 0) then
  147. emit_2bytes(cinfo, DCTSIZE2*2 + 1 + 2)
  148. else
  149. emit_2bytes(cinfo, DCTSIZE2 + 1 + 2);
  150. emit_byte(cinfo, index + (prec shl 4));
  151. for i := 0 to Pred(DCTSIZE2) do
  152. begin
  153. { The table entries must be emitted in zigzag order. }
  154. qval := qtbl^.quantval[jpeg_natural_order[i]];
  155. if (prec <> 0) then
  156. emit_byte(cinfo, int(qval shr 8));
  157. emit_byte(cinfo, int(qval and $FF));
  158. end;
  159. qtbl^.sent_table := TRUE;
  160. end;
  161. emit_dqt := prec;
  162. end;
  163. {LOCAL}
  164. procedure emit_dht (cinfo : j_compress_ptr; index : int; is_ac : boolean);
  165. { Emit a DHT marker }
  166. var
  167. htbl : JHUFF_TBL_PTR;
  168. length, i : int;
  169. begin
  170. if (is_ac) then
  171. begin
  172. htbl := cinfo^.ac_huff_tbl_ptrs[index];
  173. index := index + $10; { output index has AC bit set }
  174. end
  175. else
  176. begin
  177. htbl := cinfo^.dc_huff_tbl_ptrs[index];
  178. end;
  179. if (htbl = NIL) then
  180. ERREXIT1(j_common_ptr(cinfo), JERR_NO_HUFF_TABLE, index);
  181. if not htbl^.sent_table then
  182. begin
  183. emit_marker(cinfo, M_DHT);
  184. length := 0;
  185. for i := 1 to 16 do
  186. length := length + htbl^.bits[i];
  187. emit_2bytes(cinfo, length + 2 + 1 + 16);
  188. emit_byte(cinfo, index);
  189. for i := 1 to 16 do
  190. emit_byte(cinfo, htbl^.bits[i]);
  191. for i := 0 to Pred(length) do
  192. emit_byte(cinfo, htbl^.huffval[i]);
  193. htbl^.sent_table := TRUE;
  194. end;
  195. end;
  196. {LOCAL}
  197. procedure emit_dac (cinfo : j_compress_ptr);
  198. { Emit a DAC marker }
  199. { Since the useful info is so small, we want to emit all the tables in }
  200. { one DAC marker. Therefore this routine does its own scan of the table. }
  201. {$ifdef C_ARITH_CODING_SUPPORTED}
  202. var
  203. dc_in_use : array[0..NUM_ARITH_TBLS] of byte;
  204. ac_in_use : array[0..NUM_ARITH_TBLS] of byte;
  205. length, i : int;
  206. compptr : jpeg_component_info_ptr;
  207. begin
  208. for i := 0 to pred(NUM_ARITH_TBLS) do
  209. begin
  210. dc_in_use[i] := 0;
  211. ac_in_use[i] := 0;
  212. end;
  213. for i := 0 to pred(cinfo^.comps_in_scan) do
  214. begin
  215. compptr := cinfo^.cur_comp_info[i];
  216. dc_in_use[compptr^.dc_tbl_no] := 1;
  217. ac_in_use[compptr^.ac_tbl_no] := 1;
  218. end;
  219. length := 0;
  220. for i := 0 to pred(NUM_ARITH_TBLS) do
  221. Inc(length, dc_in_use[i] + ac_in_use[i]);
  222. emit_marker(cinfo, M_DAC);
  223. emit_2bytes(cinfo, length*2 + 2);
  224. for i := 0 to pred(NUM_ARITH_TBLS) do
  225. begin
  226. if (dc_in_use[i] <> 0) then
  227. begin
  228. emit_byte(cinfo, i);
  229. emit_byte(cinfo, cinfo^.arith_dc_L[i] + (cinfo^.arith_dc_U[i] shl 4));
  230. end;
  231. if (ac_in_use[i] <> 0) then
  232. begin
  233. emit_byte(cinfo, i + $10);
  234. emit_byte(cinfo, cinfo^.arith_ac_K[i]);
  235. end;
  236. end;
  237. end;
  238. {$else}
  239. begin
  240. end;
  241. {$endif} {C_ARITH_CODING_SUPPORTED}
  242. {LOCAL}
  243. procedure emit_dri (cinfo : j_compress_ptr);
  244. { Emit a DRI marker }
  245. begin
  246. emit_marker(cinfo, M_DRI);
  247. emit_2bytes(cinfo, 4); { fixed length }
  248. emit_2bytes(cinfo, int(cinfo^.restart_interval));
  249. end;
  250. {LOCAL}
  251. procedure emit_sof (cinfo : j_compress_ptr; code : JPEG_MARKER);
  252. { Emit a SOF marker }
  253. var
  254. ci : int;
  255. compptr : jpeg_component_info_ptr;
  256. begin
  257. emit_marker(cinfo, code);
  258. emit_2bytes(cinfo, 3 * cinfo^.num_components + 2 + 5 + 1); { length }
  259. { Make sure image isn't bigger than SOF field can handle }
  260. if (long(cinfo^.image_height) > long(65535)) or
  261. (long(cinfo^.image_width) > long(65535)) then
  262. ERREXIT1(j_common_ptr(cinfo), JERR_IMAGE_TOO_BIG, uInt(65535));
  263. emit_byte(cinfo, cinfo^.data_precision);
  264. emit_2bytes(cinfo, int(cinfo^.image_height));
  265. emit_2bytes(cinfo, int(cinfo^.image_width));
  266. emit_byte(cinfo, cinfo^.num_components);
  267. compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  268. for ci := 0 to Pred(cinfo^.num_components) do
  269. begin
  270. emit_byte(cinfo, compptr^.component_id);
  271. emit_byte(cinfo, (compptr^.h_samp_factor shl 4) + compptr^.v_samp_factor);
  272. emit_byte(cinfo, compptr^.quant_tbl_no);
  273. Inc(compptr);
  274. end;
  275. end;
  276. {LOCAL}
  277. procedure emit_sos (cinfo : j_compress_ptr);
  278. { Emit a SOS marker }
  279. var
  280. i, td, ta : int;
  281. compptr : jpeg_component_info_ptr;
  282. begin
  283. emit_marker(cinfo, M_SOS);
  284. emit_2bytes(cinfo, 2 * cinfo^.comps_in_scan + 2 + 1 + 3); { length }
  285. emit_byte(cinfo, cinfo^.comps_in_scan);
  286. for i := 0 to Pred(cinfo^.comps_in_scan) do
  287. begin
  288. compptr := cinfo^.cur_comp_info[i];
  289. emit_byte(cinfo, compptr^.component_id);
  290. td := compptr^.dc_tbl_no;
  291. ta := compptr^.ac_tbl_no;
  292. if (cinfo^.progressive_mode) then
  293. begin
  294. { Progressive mode: only DC or only AC tables are used in one scan;
  295. furthermore, Huffman coding of DC refinement uses no table at all.
  296. We emit 0 for unused field(s); this is recommended by the P&M text
  297. but does not seem to be specified in the standard. }
  298. if (cinfo^.Ss = 0) then
  299. begin
  300. ta := 0; { DC scan }
  301. if (cinfo^.Ah <> 0) and not cinfo^.arith_code then
  302. td := 0; { no DC table either }
  303. end
  304. else
  305. begin
  306. td := 0; { AC scan }
  307. end;
  308. end;
  309. emit_byte(cinfo, (td shl 4) + ta);
  310. end;
  311. emit_byte(cinfo, cinfo^.Ss);
  312. emit_byte(cinfo, cinfo^.Se);
  313. emit_byte(cinfo, (cinfo^.Ah shl 4) + cinfo^.Al);
  314. end;
  315. {LOCAL}
  316. procedure emit_jfif_app0 (cinfo : j_compress_ptr);
  317. { Emit a JFIF-compliant APP0 marker }
  318. {
  319. Length of APP0 block (2 bytes)
  320. Block ID (4 bytes - ASCII "JFIF")
  321. Zero byte (1 byte to terminate the ID string)
  322. Version Major, Minor (2 bytes - major first)
  323. Units (1 byte - $00 = none, $01 = inch, $02 = cm)
  324. Xdpu (2 bytes - dots per unit horizontal)
  325. Ydpu (2 bytes - dots per unit vertical)
  326. Thumbnail X size (1 byte)
  327. Thumbnail Y size (1 byte)
  328. }
  329. begin
  330. emit_marker(cinfo, M_APP0);
  331. emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); { length }
  332. emit_byte(cinfo, $4A); { Identifier: ASCII "JFIF" }
  333. emit_byte(cinfo, $46);
  334. emit_byte(cinfo, $49);
  335. emit_byte(cinfo, $46);
  336. emit_byte(cinfo, 0);
  337. emit_byte(cinfo, cinfo^.JFIF_major_version); { Version fields }
  338. emit_byte(cinfo, cinfo^.JFIF_minor_version);
  339. emit_byte(cinfo, cinfo^.density_unit); { Pixel size information }
  340. emit_2bytes(cinfo, int(cinfo^.X_density));
  341. emit_2bytes(cinfo, int(cinfo^.Y_density));
  342. emit_byte(cinfo, 0); { No thumbnail image }
  343. emit_byte(cinfo, 0);
  344. end;
  345. {LOCAL}
  346. procedure emit_adobe_app14 (cinfo : j_compress_ptr);
  347. { Emit an Adobe APP14 marker }
  348. {
  349. Length of APP14 block (2 bytes)
  350. Block ID (5 bytes - ASCII "Adobe")
  351. Version Number (2 bytes - currently 100)
  352. Flags0 (2 bytes - currently 0)
  353. Flags1 (2 bytes - currently 0)
  354. Color transform (1 byte)
  355. Although Adobe TN 5116 mentions Version = 101, all the Adobe files
  356. now in circulation seem to use Version = 100, so that's what we write.
  357. We write the color transform byte as 1 if the JPEG color space is
  358. YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with
  359. whether the encoder performed a transformation, which is pretty useless.
  360. }
  361. begin
  362. emit_marker(cinfo, M_APP14);
  363. emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); { length }
  364. emit_byte(cinfo, $41); { Identifier: ASCII "Adobe" }
  365. emit_byte(cinfo, $64);
  366. emit_byte(cinfo, $6F);
  367. emit_byte(cinfo, $62);
  368. emit_byte(cinfo, $65);
  369. emit_2bytes(cinfo, 100); { Version }
  370. emit_2bytes(cinfo, 0); { Flags0 }
  371. emit_2bytes(cinfo, 0); { Flags1 }
  372. case (cinfo^.jpeg_color_space) of
  373. JCS_YCbCr:
  374. emit_byte(cinfo, 1); { Color transform = 1 }
  375. JCS_YCCK:
  376. emit_byte(cinfo, 2); { Color transform = 2 }
  377. else
  378. emit_byte(cinfo, 0); { Color transform = 0 }
  379. end;
  380. end;
  381. { These routines allow writing an arbitrary marker with parameters.
  382. The only intended use is to emit COM or APPn markers after calling
  383. write_file_header and before calling write_frame_header.
  384. Other uses are not guaranteed to produce desirable results.
  385. Counting the parameter bytes properly is the caller's responsibility. }
  386. {METHODDEF}
  387. procedure write_marker_header (cinfo : j_compress_ptr;
  388. marker : int;
  389. datalen : uint); far;
  390. { Emit an arbitrary marker header }
  391. begin
  392. if (datalen > uint(65533)) then { safety check }
  393. ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
  394. emit_marker(cinfo, JPEG_MARKER(marker));
  395. emit_2bytes(cinfo, int(datalen + 2)); { total length }
  396. end;
  397. {METHODDEF}
  398. procedure write_marker_byte (cinfo : j_compress_ptr; val : int); far;
  399. { Emit one byte of marker parameters following write_marker_header }
  400. begin
  401. emit_byte(cinfo, val);
  402. end;
  403. { Write datastream header.
  404. This consists of an SOI and optional APPn markers.
  405. We recommend use of the JFIF marker, but not the Adobe marker,
  406. when using YCbCr or grayscale data. The JFIF marker should NOT
  407. be used for any other JPEG colorspace. The Adobe marker is helpful
  408. to distinguish RGB, CMYK, and YCCK colorspaces.
  409. Note that an application can write additional header markers after
  410. jpeg_start_compress returns. }
  411. {METHODDEF}
  412. procedure write_file_header (cinfo : j_compress_ptr); far;
  413. var
  414. marker : my_marker_ptr;
  415. begin
  416. marker := my_marker_ptr(cinfo^.marker);
  417. emit_marker(cinfo, M_SOI); { first the SOI }
  418. { SOI is defined to reset restart interval to 0 }
  419. marker^.last_restart_interval := 0;
  420. if (cinfo^.write_JFIF_header) then { next an optional JFIF APP0 }
  421. emit_jfif_app0(cinfo);
  422. if (cinfo^.write_Adobe_marker) then { next an optional Adobe APP14 }
  423. emit_adobe_app14(cinfo);
  424. end;
  425. { Write frame header.
  426. This consists of DQT and SOFn markers.
  427. Note that we do not emit the SOF until we have emitted the DQT(s).
  428. This avoids compatibility problems with incorrect implementations that
  429. try to error-check the quant table numbers as soon as they see the SOF. }
  430. {METHODDEF}
  431. procedure write_frame_header (cinfo : j_compress_ptr); far;
  432. var
  433. ci, prec : int;
  434. is_baseline : boolean;
  435. compptr : jpeg_component_info_ptr;
  436. begin
  437. { Emit DQT for each quantization table.
  438. Note that emit_dqt() suppresses any duplicate tables. }
  439. prec := 0;
  440. compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  441. for ci := 0 to Pred(cinfo^.num_components) do
  442. begin
  443. prec := prec + emit_dqt(cinfo, compptr^.quant_tbl_no);
  444. Inc(compptr);
  445. end;
  446. { now prec is nonzero iff there are any 16-bit quant tables. }
  447. { Check for a non-baseline specification.
  448. Note we assume that Huffman table numbers won't be changed later. }
  449. if (cinfo^.arith_code) or (cinfo^.progressive_mode)
  450. or (cinfo^.data_precision <> 8) then
  451. begin
  452. is_baseline := FALSE;
  453. end
  454. else
  455. begin
  456. is_baseline := TRUE;
  457. compptr := jpeg_component_info_ptr(cinfo^.comp_info);
  458. for ci := 0 to Pred(cinfo^.num_components) do
  459. begin
  460. if (compptr^.dc_tbl_no > 1) or (compptr^.ac_tbl_no > 1) then
  461. is_baseline := FALSE;
  462. Inc(compptr);
  463. end;
  464. if (prec <> 0) and (is_baseline) then
  465. begin
  466. is_baseline := FALSE;
  467. { If it's baseline except for quantizer size, warn the user }
  468. {$IFDEF DEBUG}
  469. TRACEMS(j_common_ptr(cinfo), 0, JTRC_16BIT_TABLES);
  470. {$ENDIF}
  471. end;
  472. end;
  473. { Emit the proper SOF marker }
  474. if (cinfo^.arith_code) then
  475. begin
  476. emit_sof(cinfo, M_SOF9); { SOF code for arithmetic coding }
  477. end
  478. else
  479. begin
  480. if (cinfo^.progressive_mode) then
  481. emit_sof(cinfo, M_SOF2) { SOF code for progressive Huffman }
  482. else if (is_baseline) then
  483. emit_sof(cinfo, M_SOF0) { SOF code for baseline implementation }
  484. else
  485. emit_sof(cinfo, M_SOF1); { SOF code for non-baseline Huffman file }
  486. end;
  487. end;
  488. { Write scan header.
  489. This consists of DHT or DAC markers, optional DRI, and SOS.
  490. Compressed data will be written following the SOS. }
  491. {METHODDEF}
  492. procedure write_scan_header (cinfo : j_compress_ptr); far;
  493. var
  494. marker : my_marker_ptr;
  495. i : int;
  496. compptr : jpeg_component_info_ptr;
  497. begin
  498. marker := my_marker_ptr(cinfo^.marker);
  499. if (cinfo^.arith_code) then
  500. begin
  501. { Emit arith conditioning info. We may have some duplication
  502. if the file has multiple scans, but it's so small it's hardly
  503. worth worrying about. }
  504. emit_dac(cinfo);
  505. end
  506. else
  507. begin
  508. { Emit Huffman tables.
  509. Note that emit_dht() suppresses any duplicate tables. }
  510. for i := 0 to Pred(cinfo^.comps_in_scan) do
  511. begin
  512. compptr := cinfo^.cur_comp_info[i];
  513. if (cinfo^.progressive_mode) then
  514. begin
  515. { Progressive mode: only DC or only AC tables are used in one scan }
  516. if (cinfo^.Ss = 0) then
  517. begin
  518. if (cinfo^.Ah = 0) then { DC needs no table for refinement scan }
  519. emit_dht(cinfo, compptr^.dc_tbl_no, FALSE);
  520. end
  521. else
  522. begin
  523. emit_dht(cinfo, compptr^.ac_tbl_no, TRUE);
  524. end;
  525. end
  526. else
  527. begin
  528. { Sequential mode: need both DC and AC tables }
  529. emit_dht(cinfo, compptr^.dc_tbl_no, FALSE);
  530. emit_dht(cinfo, compptr^.ac_tbl_no, TRUE);
  531. end;
  532. end;
  533. end;
  534. { Emit DRI if required --- note that DRI value could change for each scan.
  535. We avoid wasting space with unnecessary DRIs, however. }
  536. if (cinfo^.restart_interval <> marker^.last_restart_interval) then
  537. begin
  538. emit_dri(cinfo);
  539. marker^.last_restart_interval := cinfo^.restart_interval;
  540. end;
  541. emit_sos(cinfo);
  542. end;
  543. { Write datastream trailer. }
  544. {METHODDEF}
  545. procedure write_file_trailer (cinfo : j_compress_ptr); far;
  546. begin
  547. emit_marker(cinfo, M_EOI);
  548. end;
  549. { Write an abbreviated table-specification datastream.
  550. This consists of SOI, DQT and DHT tables, and EOI.
  551. Any table that is defined and not marked sent_table = TRUE will be
  552. emitted. Note that all tables will be marked sent_table = TRUE at exit. }
  553. {METHODDEF}
  554. procedure write_tables_only (cinfo : j_compress_ptr); far;
  555. var
  556. i : int;
  557. begin
  558. emit_marker(cinfo, M_SOI);
  559. for i := 0 to Pred(NUM_QUANT_TBLS) do
  560. begin
  561. if (cinfo^.quant_tbl_ptrs[i] <> NIL) then
  562. emit_dqt(cinfo, i); { dummy := ... }
  563. end;
  564. if (not cinfo^.arith_code) then
  565. begin
  566. for i := 0 to Pred(NUM_HUFF_TBLS) do
  567. begin
  568. if (cinfo^.dc_huff_tbl_ptrs[i] <> NIL) then
  569. emit_dht(cinfo, i, FALSE);
  570. if (cinfo^.ac_huff_tbl_ptrs[i] <> NIL) then
  571. emit_dht(cinfo, i, TRUE);
  572. end;
  573. end;
  574. emit_marker(cinfo, M_EOI);
  575. end;
  576. { Initialize the marker writer module. }
  577. {GLOBAL}
  578. procedure jinit_marker_writer (cinfo : j_compress_ptr);
  579. var
  580. marker : my_marker_ptr;
  581. begin
  582. { Create the subobject }
  583. marker := my_marker_ptr(
  584. cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
  585. SIZEOF(my_marker_writer)) );
  586. cinfo^.marker := jpeg_marker_writer_ptr(marker);
  587. { Initialize method pointers }
  588. marker^.pub.write_file_header := write_file_header;
  589. marker^.pub.write_frame_header := write_frame_header;
  590. marker^.pub.write_scan_header := write_scan_header;
  591. marker^.pub.write_file_trailer := write_file_trailer;
  592. marker^.pub.write_tables_only := write_tables_only;
  593. marker^.pub.write_marker_header := write_marker_header;
  594. marker^.pub.write_marker_byte := write_marker_byte;
  595. { Initialize private state }
  596. marker^.last_restart_interval := 0;
  597. end;
  598. end.