/src/libjpeg-turbo.3.0.x/jcapistd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * jcapistd.c |
3 | | * |
4 | | * This file was part of the Independent JPEG Group's software: |
5 | | * Copyright (C) 1994-1996, Thomas G. Lane. |
6 | | * libjpeg-turbo Modifications: |
7 | | * Copyright (C) 2022, 2024, D. R. Commander. |
8 | | * For conditions of distribution and use, see the accompanying README.ijg |
9 | | * file. |
10 | | * |
11 | | * This file contains application interface code for the compression half |
12 | | * of the JPEG library. These are the "standard" API routines that are |
13 | | * used in the normal full-compression case. They are not used by a |
14 | | * transcoding-only application. Note that if an application links in |
15 | | * jpeg_start_compress, it will end up linking in the entire compressor. |
16 | | * We thus must separate this file from jcapimin.c to avoid linking the |
17 | | * whole compression library into a transcoder. |
18 | | */ |
19 | | |
20 | | #define JPEG_INTERNALS |
21 | | #include "jinclude.h" |
22 | | #include "jpeglib.h" |
23 | | #include "jsamplecomp.h" |
24 | | |
25 | | |
26 | | #if BITS_IN_JSAMPLE == 8 |
27 | | |
28 | | /* |
29 | | * Compression initialization. |
30 | | * Before calling this, all parameters and a data destination must be set up. |
31 | | * |
32 | | * We require a write_all_tables parameter as a failsafe check when writing |
33 | | * multiple datastreams from the same compression object. Since prior runs |
34 | | * will have left all the tables marked sent_table=TRUE, a subsequent run |
35 | | * would emit an abbreviated stream (no tables) by default. This may be what |
36 | | * is wanted, but for safety's sake it should not be the default behavior: |
37 | | * programmers should have to make a deliberate choice to emit abbreviated |
38 | | * images. Therefore the documentation and examples should encourage people |
39 | | * to pass write_all_tables=TRUE; then it will take active thought to do the |
40 | | * wrong thing. |
41 | | */ |
42 | | |
43 | | GLOBAL(void) |
44 | | jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables) |
45 | 13.3k | { |
46 | 13.3k | if (cinfo->global_state != CSTATE_START) |
47 | 0 | ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); |
48 | | |
49 | 13.3k | if (write_all_tables) |
50 | 13.3k | jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ |
51 | | |
52 | | /* (Re)initialize error mgr and destination modules */ |
53 | 13.3k | (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo); |
54 | 13.3k | (*cinfo->dest->init_destination) (cinfo); |
55 | | /* Perform master selection of active modules */ |
56 | 13.3k | jinit_compress_master(cinfo); |
57 | | /* Set up for the first pass */ |
58 | 13.3k | (*cinfo->master->prepare_for_pass) (cinfo); |
59 | | /* Ready for application to drive first pass through _jpeg_write_scanlines |
60 | | * or _jpeg_write_raw_data. |
61 | | */ |
62 | 13.3k | cinfo->next_scanline = 0; |
63 | 13.3k | cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING); |
64 | 13.3k | } |
65 | | |
66 | | #endif |
67 | | |
68 | | |
69 | | /* |
70 | | * Write some scanlines of data to the JPEG compressor. |
71 | | * |
72 | | * The return value will be the number of lines actually written. |
73 | | * This should be less than the supplied num_lines only in case that |
74 | | * the data destination module has requested suspension of the compressor, |
75 | | * or if more than image_height scanlines are passed in. |
76 | | * |
77 | | * Note: we warn about excess calls to _jpeg_write_scanlines() since |
78 | | * this likely signals an application programmer error. However, |
79 | | * excess scanlines passed in the last valid call are *silently* ignored, |
80 | | * so that the application need not adjust num_lines for end-of-image |
81 | | * when using a multiple-scanline buffer. |
82 | | */ |
83 | | |
84 | | GLOBAL(JDIMENSION) |
85 | | _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines, |
86 | | JDIMENSION num_lines) |
87 | 13.3k | { |
88 | 13.3k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) |
89 | 13.3k | JDIMENSION row_ctr, rows_left; |
90 | | |
91 | 13.3k | if (cinfo->data_precision != BITS_IN_JSAMPLE) |
92 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |
93 | | |
94 | 13.3k | if (cinfo->global_state != CSTATE_SCANNING) |
95 | 0 | ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); |
96 | 13.3k | if (cinfo->next_scanline >= cinfo->image_height) |
97 | 0 | WARNMS(cinfo, JWRN_TOO_MUCH_DATA); |
98 | | |
99 | | /* Call progress monitor hook if present */ |
100 | 13.3k | if (cinfo->progress != NULL) { |
101 | 0 | cinfo->progress->pass_counter = (long)cinfo->next_scanline; |
102 | 0 | cinfo->progress->pass_limit = (long)cinfo->image_height; |
103 | 0 | (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); |
104 | 0 | } |
105 | | |
106 | | /* Give master control module another chance if this is first call to |
107 | | * _jpeg_write_scanlines. This lets output of the frame/scan headers be |
108 | | * delayed so that application can write COM, etc, markers between |
109 | | * jpeg_start_compress and _jpeg_write_scanlines. |
110 | | */ |
111 | 13.3k | if (cinfo->master->call_pass_startup) |
112 | 3.90k | (*cinfo->master->pass_startup) (cinfo); |
113 | | |
114 | | /* Ignore any extra scanlines at bottom of image. */ |
115 | 13.3k | rows_left = cinfo->image_height - cinfo->next_scanline; |
116 | 13.3k | if (num_lines > rows_left) |
117 | 0 | num_lines = rows_left; |
118 | | |
119 | 13.3k | row_ctr = 0; |
120 | 13.3k | if (cinfo->main->_process_data == NULL) |
121 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |
122 | 13.3k | (*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines); |
123 | 13.3k | cinfo->next_scanline += row_ctr; |
124 | 13.3k | return row_ctr; |
125 | | #else |
126 | | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |
127 | | return 0; |
128 | | #endif |
129 | 13.3k | } Line | Count | Source | 87 | 13.3k | { | 88 | 13.3k | #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) | 89 | 13.3k | JDIMENSION row_ctr, rows_left; | 90 | | | 91 | 13.3k | if (cinfo->data_precision != BITS_IN_JSAMPLE) | 92 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 93 | | | 94 | 13.3k | if (cinfo->global_state != CSTATE_SCANNING) | 95 | 0 | ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 96 | 13.3k | if (cinfo->next_scanline >= cinfo->image_height) | 97 | 0 | WARNMS(cinfo, JWRN_TOO_MUCH_DATA); | 98 | | | 99 | | /* Call progress monitor hook if present */ | 100 | 13.3k | if (cinfo->progress != NULL) { | 101 | 0 | cinfo->progress->pass_counter = (long)cinfo->next_scanline; | 102 | 0 | cinfo->progress->pass_limit = (long)cinfo->image_height; | 103 | 0 | (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); | 104 | 0 | } | 105 | | | 106 | | /* Give master control module another chance if this is first call to | 107 | | * _jpeg_write_scanlines. This lets output of the frame/scan headers be | 108 | | * delayed so that application can write COM, etc, markers between | 109 | | * jpeg_start_compress and _jpeg_write_scanlines. | 110 | | */ | 111 | 13.3k | if (cinfo->master->call_pass_startup) | 112 | 3.90k | (*cinfo->master->pass_startup) (cinfo); | 113 | | | 114 | | /* Ignore any extra scanlines at bottom of image. */ | 115 | 13.3k | rows_left = cinfo->image_height - cinfo->next_scanline; | 116 | 13.3k | if (num_lines > rows_left) | 117 | 0 | num_lines = rows_left; | 118 | | | 119 | 13.3k | row_ctr = 0; | 120 | 13.3k | if (cinfo->main->_process_data == NULL) | 121 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 122 | 13.3k | (*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines); | 123 | 13.3k | cinfo->next_scanline += row_ctr; | 124 | 13.3k | return row_ctr; | 125 | | #else | 126 | | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 127 | | return 0; | 128 | | #endif | 129 | 13.3k | } |
Unexecuted instantiation: jpeg16_write_scanlines Unexecuted instantiation: jpeg_write_scanlines |
130 | | |
131 | | |
132 | | #if BITS_IN_JSAMPLE != 16 |
133 | | |
134 | | /* |
135 | | * Alternate entry point to write raw data. |
136 | | * Processes exactly one iMCU row per call, unless suspended. |
137 | | */ |
138 | | |
139 | | GLOBAL(JDIMENSION) |
140 | | _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data, |
141 | | JDIMENSION num_lines) |
142 | 0 | { |
143 | 0 | JDIMENSION lines_per_iMCU_row; |
144 | |
|
145 | 0 | if (cinfo->data_precision != BITS_IN_JSAMPLE) |
146 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |
147 | |
|
148 | 0 | if (cinfo->master->lossless) |
149 | 0 | ERREXIT(cinfo, JERR_NOTIMPL); |
150 | |
|
151 | 0 | if (cinfo->global_state != CSTATE_RAW_OK) |
152 | 0 | ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); |
153 | 0 | if (cinfo->next_scanline >= cinfo->image_height) { |
154 | 0 | WARNMS(cinfo, JWRN_TOO_MUCH_DATA); |
155 | 0 | return 0; |
156 | 0 | } |
157 | | |
158 | | /* Call progress monitor hook if present */ |
159 | 0 | if (cinfo->progress != NULL) { |
160 | 0 | cinfo->progress->pass_counter = (long)cinfo->next_scanline; |
161 | 0 | cinfo->progress->pass_limit = (long)cinfo->image_height; |
162 | 0 | (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); |
163 | 0 | } |
164 | | |
165 | | /* Give master control module another chance if this is first call to |
166 | | * _jpeg_write_raw_data. This lets output of the frame/scan headers be |
167 | | * delayed so that application can write COM, etc, markers between |
168 | | * jpeg_start_compress and _jpeg_write_raw_data. |
169 | | */ |
170 | 0 | if (cinfo->master->call_pass_startup) |
171 | 0 | (*cinfo->master->pass_startup) (cinfo); |
172 | | |
173 | | /* Verify that at least one iMCU row has been passed. */ |
174 | 0 | lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; |
175 | 0 | if (num_lines < lines_per_iMCU_row) |
176 | 0 | ERREXIT(cinfo, JERR_BUFFER_SIZE); |
177 | | |
178 | | /* Directly compress the row. */ |
179 | 0 | if (cinfo->coef->_compress_data == NULL) |
180 | 0 | ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |
181 | 0 | if (!(*cinfo->coef->_compress_data) (cinfo, data)) { |
182 | | /* If compressor did not consume the whole row, suspend processing. */ |
183 | 0 | return 0; |
184 | 0 | } |
185 | | |
186 | | /* OK, we processed one iMCU row. */ |
187 | 0 | cinfo->next_scanline += lines_per_iMCU_row; |
188 | 0 | return lines_per_iMCU_row; |
189 | 0 | } Unexecuted instantiation: jpeg12_write_raw_data Unexecuted instantiation: jpeg_write_raw_data |
190 | | |
191 | | #endif /* BITS_IN_JSAMPLE != 16 */ |