root / Imaging / JpegLib / imjcapistd.pas @ 0:95bd93c28625
History | View | Annotate | Download (8.3 kB)
| 1 | unit imjcapistd;
|
|---|---|
| 2 | |
| 3 | { Original : jcapistd.c ; Copyright (C) 1994-1996, Thomas G. Lane. }
|
| 4 | |
| 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 application interface code for the compression half |
| 9 | of the JPEG library. These are the "standard" API routines that are |
| 10 | used in the normal full-compression case. They are not used by a |
| 11 | transcoding-only application. Note that if an application links in |
| 12 | jpeg_start_compress, it will end up linking in the entire compressor. |
| 13 | We thus must separate this file from jcapimin.c to avoid linking the |
| 14 | whole compression library into a transcoder. } |
| 15 | |
| 16 | interface
|
| 17 | |
| 18 | {$I imjconfig.inc}
|
| 19 | |
| 20 | uses
|
| 21 | imjmorecfg, |
| 22 | imjinclude, |
| 23 | imjdeferr, |
| 24 | imjerror, |
| 25 | imjpeglib, |
| 26 | imjcapimin, imjcinit; |
| 27 | |
| 28 | |
| 29 | |
| 30 | { Compression initialization.
|
| 31 | Before calling this, all parameters and a data destination must be set up. |
| 32 | |
| 33 | We require a write_all_tables parameter as a failsafe check when writing |
| 34 | multiple datastreams from the same compression object. Since prior runs |
| 35 | will have left all the tables marked sent_table=TRUE, a subsequent run |
| 36 | would emit an abbreviated stream (no tables) by default. This may be what |
| 37 | is wanted, but for safety's sake it should not be the default behavior: |
| 38 | programmers should have to make a deliberate choice to emit abbreviated |
| 39 | images. Therefore the documentation and examples should encourage people |
| 40 | to pass write_all_tables=TRUE; then it will take active thought to do the |
| 41 | wrong thing. } |
| 42 | |
| 43 | {GLOBAL}
|
| 44 | procedure jpeg_start_compress (cinfo : j_compress_ptr;
|
| 45 | write_all_tables : boolean); |
| 46 | |
| 47 | |
| 48 | { Write some scanlines of data to the JPEG compressor.
|
| 49 | |
| 50 | The return value will be the number of lines actually written. |
| 51 | This should be less than the supplied num_lines only in case that |
| 52 | the data destination module has requested suspension of the compressor, |
| 53 | or if more than image_height scanlines are passed in. |
| 54 | |
| 55 | Note: we warn about excess calls to jpeg_write_scanlines() since |
| 56 | this likely signals an application programmer error. However, |
| 57 | excess scanlines passed in the last valid call are *silently* ignored, |
| 58 | so that the application need not adjust num_lines for end-of-image |
| 59 | when using a multiple-scanline buffer. } |
| 60 | |
| 61 | {GLOBAL}
|
| 62 | function jpeg_write_scanlines (cinfo : j_compress_ptr;
|
| 63 | scanlines : JSAMPARRAY; |
| 64 | num_lines : JDIMENSION) : JDIMENSION; |
| 65 | |
| 66 | { Alternate entry point to write raw data.
|
| 67 | Processes exactly one iMCU row per call, unless suspended. } |
| 68 | |
| 69 | {GLOBAL}
|
| 70 | function jpeg_write_raw_data (cinfo : j_compress_ptr;
|
| 71 | data : JSAMPIMAGE; |
| 72 | num_lines : JDIMENSION) : JDIMENSION; |
| 73 | |
| 74 | implementation
|
| 75 | |
| 76 | { Compression initialization.
|
| 77 | Before calling this, all parameters and a data destination must be set up. |
| 78 | |
| 79 | We require a write_all_tables parameter as a failsafe check when writing |
| 80 | multiple datastreams from the same compression object. Since prior runs |
| 81 | will have left all the tables marked sent_table=TRUE, a subsequent run |
| 82 | would emit an abbreviated stream (no tables) by default. This may be what |
| 83 | is wanted, but for safety's sake it should not be the default behavior: |
| 84 | programmers should have to make a deliberate choice to emit abbreviated |
| 85 | images. Therefore the documentation and examples should encourage people |
| 86 | to pass write_all_tables=TRUE; then it will take active thought to do the |
| 87 | wrong thing. } |
| 88 | |
| 89 | {GLOBAL}
|
| 90 | procedure jpeg_start_compress (cinfo : j_compress_ptr;
|
| 91 | write_all_tables : boolean); |
| 92 | begin
|
| 93 | if (cinfo^.global_state <> CSTATE_START) then |
| 94 | ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); |
| 95 | |
| 96 | if (write_all_tables) then |
| 97 | jpeg_suppress_tables(cinfo, FALSE); { mark all tables to be written }
|
| 98 | |
| 99 | { (Re)initialize error mgr and destination modules }
|
| 100 | cinfo^.err^.reset_error_mgr (j_common_ptr(cinfo)); |
| 101 | cinfo^.dest^.init_destination (cinfo); |
| 102 | { Perform master selection of active modules }
|
| 103 | jinit_compress_master(cinfo); |
| 104 | { Set up for the first pass }
|
| 105 | cinfo^.master^.prepare_for_pass (cinfo); |
| 106 | { Ready for application to drive first pass through jpeg_write_scanlines
|
| 107 | or jpeg_write_raw_data. } |
| 108 | |
| 109 | cinfo^.next_scanline := 0;
|
| 110 | if cinfo^.raw_data_in then |
| 111 | cinfo^.global_state := CSTATE_RAW_OK |
| 112 | else
|
| 113 | cinfo^.global_state := CSTATE_SCANNING; |
| 114 | end;
|
| 115 | |
| 116 | |
| 117 | { Write some scanlines of data to the JPEG compressor.
|
| 118 | |
| 119 | The return value will be the number of lines actually written. |
| 120 | This should be less than the supplied num_lines only in case that |
| 121 | the data destination module has requested suspension of the compressor, |
| 122 | or if more than image_height scanlines are passed in. |
| 123 | |
| 124 | Note: we warn about excess calls to jpeg_write_scanlines() since |
| 125 | this likely signals an application programmer error. However, |
| 126 | excess scanlines passed in the last valid call are *silently* ignored, |
| 127 | so that the application need not adjust num_lines for end-of-image |
| 128 | when using a multiple-scanline buffer. } |
| 129 | |
| 130 | {GLOBAL}
|
| 131 | function jpeg_write_scanlines (cinfo : j_compress_ptr;
|
| 132 | scanlines : JSAMPARRAY; |
| 133 | num_lines : JDIMENSION) : JDIMENSION; |
| 134 | var
|
| 135 | row_ctr, rows_left : JDIMENSION; |
| 136 | begin
|
| 137 | if (cinfo^.global_state <> CSTATE_SCANNING) then |
| 138 | ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); |
| 139 | if (cinfo^.next_scanline >= cinfo^.image_height) then |
| 140 | WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); |
| 141 | |
| 142 | { Call progress monitor hook if present }
|
| 143 | if (cinfo^.progress <> NIL) then |
| 144 | begin
|
| 145 | cinfo^.progress^.pass_counter := long (cinfo^.next_scanline); |
| 146 | cinfo^.progress^.pass_limit := long (cinfo^.image_height); |
| 147 | cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); |
| 148 | end;
|
| 149 | |
| 150 | { Give master control module another chance if this is first call to
|
| 151 | jpeg_write_scanlines. This lets output of the frame/scan headers be |
| 152 | delayed so that application can write COM, etc, markers between |
| 153 | jpeg_start_compress and jpeg_write_scanlines. } |
| 154 | if (cinfo^.master^.call_pass_startup) then |
| 155 | cinfo^.master^.pass_startup (cinfo); |
| 156 | |
| 157 | { Ignore any extra scanlines at bottom of image. }
|
| 158 | rows_left := cinfo^.image_height - cinfo^.next_scanline; |
| 159 | if (num_lines > rows_left) then |
| 160 | num_lines := rows_left; |
| 161 | |
| 162 | row_ctr := 0;
|
| 163 | cinfo^.main^.process_data (cinfo, scanlines, {var}row_ctr, num_lines);
|
| 164 | Inc(cinfo^.next_scanline, row_ctr); |
| 165 | jpeg_write_scanlines := row_ctr; |
| 166 | end;
|
| 167 | |
| 168 | |
| 169 | { Alternate entry point to write raw data.
|
| 170 | Processes exactly one iMCU row per call, unless suspended. } |
| 171 | |
| 172 | {GLOBAL}
|
| 173 | function jpeg_write_raw_data (cinfo : j_compress_ptr;
|
| 174 | data : JSAMPIMAGE; |
| 175 | num_lines : JDIMENSION) : JDIMENSION; |
| 176 | var
|
| 177 | lines_per_iMCU_row : JDIMENSION; |
| 178 | begin
|
| 179 | if (cinfo^.global_state <> CSTATE_RAW_OK) then |
| 180 | ERREXIT1(j_common_ptr(cinfo), JERR_BAD_STATE, cinfo^.global_state); |
| 181 | if (cinfo^.next_scanline >= cinfo^.image_height) then |
| 182 | begin
|
| 183 | WARNMS(j_common_ptr(cinfo), JWRN_TOO_MUCH_DATA); |
| 184 | jpeg_write_raw_data := 0;
|
| 185 | exit; |
| 186 | end;
|
| 187 | |
| 188 | { Call progress monitor hook if present }
|
| 189 | if (cinfo^.progress <> NIL) then |
| 190 | begin
|
| 191 | cinfo^.progress^.pass_counter := long(cinfo^.next_scanline); |
| 192 | cinfo^.progress^.pass_limit := long(cinfo^.image_height); |
| 193 | cinfo^.progress^.progress_monitor (j_common_ptr(cinfo)); |
| 194 | end;
|
| 195 | |
| 196 | { Give master control module another chance if this is first call to
|
| 197 | jpeg_write_raw_data. This lets output of the frame/scan headers be |
| 198 | delayed so that application can write COM, etc, markers between |
| 199 | jpeg_start_compress and jpeg_write_raw_data. } |
| 200 | |
| 201 | if (cinfo^.master^.call_pass_startup) then |
| 202 | cinfo^.master^.pass_startup (cinfo); |
| 203 | |
| 204 | { Verify that at least one iMCU row has been passed. }
|
| 205 | lines_per_iMCU_row := cinfo^.max_v_samp_factor * DCTSIZE; |
| 206 | if (num_lines < lines_per_iMCU_row) then |
| 207 | ERREXIT(j_common_ptr(cinfo), JERR_BUFFER_SIZE); |
| 208 | |
| 209 | { Directly compress the row. }
|
| 210 | if (not cinfo^.coef^.compress_data (cinfo, data)) then |
| 211 | begin
|
| 212 | { If compressor did not consume the whole row, suspend processing. }
|
| 213 | jpeg_write_raw_data := 0;
|
| 214 | exit; |
| 215 | end;
|
| 216 | |
| 217 | { OK, we processed one iMCU row. }
|
| 218 | Inc(cinfo^.next_scanline, lines_per_iMCU_row); |
| 219 | jpeg_write_raw_data := lines_per_iMCU_row; |
| 220 | end;
|
| 221 | |
| 222 | end.
|