Coverage Report

Created: 2026-04-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjpeg-turbo/src/jcomapi.c
Line
Count
Source
1
/*
2
 * jcomapi.c
3
 *
4
 * This file was part of the Independent JPEG Group's software:
5
 * Copyright (C) 1994-1997, Thomas G. Lane.
6
 * libjpeg-turbo Modifications:
7
 * Copyright (C) 2024-2026, D. R. Commander.
8
 * For conditions of distribution and use, see the accompanying README.ijg
9
 * file.
10
 *
11
 * This file contains application interface routines that are used for both
12
 * compression and decompression.
13
 */
14
15
#define JPEG_INTERNALS
16
#include "jinclude.h"
17
#include "jpeglib.h"
18
#ifdef WITH_PROFILE
19
#include <stdio.h>
20
#include "tjutil.h"
21
#endif
22
23
24
/*
25
 * Abort processing of a JPEG compression or decompression operation,
26
 * but don't destroy the object itself.
27
 *
28
 * For this, we merely clean up all the nonpermanent memory pools.
29
 * Note that temp files (virtual arrays) are not allowed to belong to
30
 * the permanent pool, so we will be able to close all temp files here.
31
 * Closing a data source or destination, if necessary, is the application's
32
 * responsibility.
33
 */
34
35
GLOBAL(void)
36
jpeg_abort(j_common_ptr cinfo)
37
2.30k
{
38
2.30k
  int pool;
39
40
  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
41
2.30k
  if (cinfo->mem == NULL)
42
0
    return;
43
44
  /* Releasing pools in reverse order might help avoid fragmentation
45
   * with some (brain-damaged) malloc libraries.
46
   */
47
4.60k
  for (pool = JPOOL_NUMPOOLS - 1; pool > JPOOL_PERMANENT; pool--) {
48
2.30k
    (*cinfo->mem->free_pool) (cinfo, pool);
49
2.30k
  }
50
51
  /* Reset overall state for possible reuse of object */
52
2.30k
  if (cinfo->is_decompressor) {
53
2.30k
    cinfo->global_state = DSTATE_START;
54
    /* Try to keep application from accessing now-deleted marker list.
55
     * A bit kludgy to do it here, but this is the most central place.
56
     */
57
2.30k
    ((j_decompress_ptr)cinfo)->marker_list = NULL;
58
2.30k
    ((j_decompress_ptr)cinfo)->master->marker_list_end = NULL;
59
2.30k
  } else {
60
0
    cinfo->global_state = CSTATE_START;
61
0
  }
62
63
#ifdef WITH_PROFILE
64
  if (cinfo->is_decompressor) {
65
    if (((j_decompress_ptr)cinfo)->master->total_start > 0.0)
66
      ((j_decompress_ptr)cinfo)->master->total_elapsed +=
67
        getTime() - ((j_decompress_ptr)cinfo)->master->total_start;
68
  } else {
69
    if (((j_compress_ptr)cinfo)->master->total_start > 0.0)
70
      ((j_compress_ptr)cinfo)->master->total_elapsed +=
71
        getTime() - ((j_compress_ptr)cinfo)->master->total_start;
72
  }
73
#endif
74
2.30k
}
75
76
77
/*
78
 * Destruction of a JPEG object.
79
 *
80
 * Everything gets deallocated except the master jpeg_compress_struct itself
81
 * and the error manager struct.  Both of these are supplied by the application
82
 * and must be freed, if necessary, by the application.  (Often they are on
83
 * the stack and so don't need to be freed anyway.)
84
 * Closing a data source or destination, if necessary, is the application's
85
 * responsibility.
86
 */
87
88
GLOBAL(void)
89
jpeg_destroy(j_common_ptr cinfo)
90
6.71k
{
91
#ifdef WITH_PROFILE
92
  if (cinfo->is_decompressor) {
93
    j_decompress_ptr dinfo = (j_decompress_ptr)cinfo;
94
95
    if (dinfo->master->entropy_mcoeffs > 0.0) {
96
      fprintf(stderr, "Entropy decoding:    %14.6f Mcoefficients/sec",
97
              dinfo->master->entropy_mcoeffs / dinfo->master->entropy_elapsed);
98
      if (dinfo->master->total_elapsed > 0.0)
99
        fprintf(stderr, "  (%5.2f%% of total time)",
100
                dinfo->master->entropy_elapsed * 100.0 /
101
                  dinfo->master->total_elapsed);
102
      fprintf(stderr, "\n");
103
    }
104
    if (dinfo->master->idct_mcoeffs > 0.0) {
105
      fprintf(stderr, "Inverse DCT:         %14.6f Mcoefficients/sec",
106
              dinfo->master->idct_mcoeffs / dinfo->master->idct_elapsed);
107
      if (dinfo->master->total_elapsed > 0.0)
108
        fprintf(stderr, "  (%5.2f%% of total time)",
109
                dinfo->master->idct_elapsed * 100.0 /
110
                  dinfo->master->total_elapsed);
111
      fprintf(stderr, "\n");
112
    }
113
    if (dinfo->master->merged_upsample_mpixels > 0.0) {
114
      fprintf(stderr, "Merged upsampling:   %14.6f Mpixels/sec",
115
              dinfo->master->merged_upsample_mpixels /
116
                dinfo->master->merged_upsample_elapsed);
117
      if (dinfo->master->total_elapsed > 0.0)
118
        fprintf(stderr, "        (%5.2f%% of total time)",
119
                dinfo->master->merged_upsample_elapsed * 100.0 /
120
                  dinfo->master->total_elapsed);
121
      fprintf(stderr, "\n");
122
    }
123
    if (dinfo->master->upsample_msamples > 0.0) {
124
      fprintf(stderr, "Upsampling:          %14.6f Msamples/sec",
125
              dinfo->master->upsample_msamples /
126
                dinfo->master->upsample_elapsed);
127
      if (dinfo->master->total_elapsed > 0.0)
128
        fprintf(stderr, "       (%5.2f%% of total time)",
129
                dinfo->master->upsample_elapsed * 100.0 /
130
                  dinfo->master->total_elapsed);
131
      fprintf(stderr, "\n");
132
    }
133
    if (dinfo->master->cconvert_mpixels > 0.0) {
134
      fprintf(stderr, "Color deconversion:  %14.6f Mpixels/sec",
135
              dinfo->master->cconvert_mpixels /
136
                dinfo->master->cconvert_elapsed);
137
      if (dinfo->master->total_elapsed > 0.0)
138
        fprintf(stderr, "        (%5.2f%% of total time)",
139
                dinfo->master->cconvert_elapsed * 100.0 /
140
                  dinfo->master->total_elapsed);
141
      fprintf(stderr, "\n");
142
    }
143
  } else {
144
    j_compress_ptr _cinfo = (j_compress_ptr)cinfo;
145
146
    if (_cinfo->master->cconvert_mpixels > 0.0) {
147
      fprintf(stderr, "Color conversion:    %14.6f Mpixels/sec",
148
              _cinfo->master->cconvert_mpixels /
149
                _cinfo->master->cconvert_elapsed);
150
      if (_cinfo->master->total_elapsed > 0.0)
151
        fprintf(stderr, "        (%5.2f%% of total time)",
152
                _cinfo->master->cconvert_elapsed * 100.0 /
153
                  _cinfo->master->total_elapsed);
154
      fprintf(stderr, "\n");
155
    }
156
    if (_cinfo->master->downsample_msamples > 0.0) {
157
      fprintf(stderr, "Downsampling:        %14.6f Msamples/sec",
158
              _cinfo->master->downsample_msamples /
159
                _cinfo->master->downsample_elapsed);
160
      if (_cinfo->master->total_elapsed > 0.0)
161
        fprintf(stderr, "       (%5.2f%% of total time)",
162
                _cinfo->master->downsample_elapsed * 100.0 /
163
                  _cinfo->master->total_elapsed);
164
      fprintf(stderr, "\n");
165
    }
166
    if (_cinfo->master->convsamp_msamples > 0.0) {
167
      fprintf(stderr, "Sample conversion:   %14.6f Msamples/sec",
168
              _cinfo->master->convsamp_msamples /
169
                _cinfo->master->convsamp_elapsed);
170
      if (_cinfo->master->total_elapsed > 0.0)
171
        fprintf(stderr, "       (%5.2f%% of total time)",
172
                _cinfo->master->convsamp_elapsed * 100.0 /
173
                  _cinfo->master->total_elapsed);
174
      fprintf(stderr, "\n");
175
    }
176
    if (_cinfo->master->fdct_mcoeffs > 0.0) {
177
      fprintf(stderr, "Forward DCT:         %14.6f Mcoefficients/sec",
178
              _cinfo->master->fdct_mcoeffs / _cinfo->master->fdct_elapsed);
179
      if (_cinfo->master->total_elapsed > 0.0)
180
        fprintf(stderr, "  (%5.2f%% of total time)",
181
                _cinfo->master->fdct_elapsed * 100.0 /
182
                  _cinfo->master->total_elapsed);
183
      fprintf(stderr, "\n");
184
    }
185
    if (_cinfo->master->quantize_mcoeffs > 0.0) {
186
      fprintf(stderr, "Quantization:        %14.6f Mcoefficients/sec",
187
              _cinfo->master->quantize_mcoeffs /
188
                _cinfo->master->quantize_elapsed);
189
      if (_cinfo->master->total_elapsed > 0.0)
190
        fprintf(stderr, "  (%5.2f%% of total time)",
191
                _cinfo->master->quantize_elapsed * 100.0 /
192
                  _cinfo->master->total_elapsed);
193
      fprintf(stderr, "\n");
194
    }
195
    if (_cinfo->master->entropy_mcoeffs > 0.0) {
196
      fprintf(stderr, "Entropy encoding:    %14.6f Mcoefficients/sec",
197
              _cinfo->master->entropy_mcoeffs /
198
                _cinfo->master->entropy_elapsed);
199
      if (_cinfo->master->total_elapsed > 0.0)
200
        fprintf(stderr, "  (%5.2f%% of total time)",
201
                _cinfo->master->entropy_elapsed * 100.0 /
202
                  _cinfo->master->total_elapsed);
203
      fprintf(stderr, "\n");
204
    }
205
  }
206
#endif
207
208
  /* We need only tell the memory manager to release everything. */
209
  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
210
6.71k
  if (cinfo->mem != NULL)
211
6.71k
    (*cinfo->mem->self_destruct) (cinfo);
212
6.71k
  cinfo->mem = NULL;            /* be safe if jpeg_destroy is called twice */
213
6.71k
  cinfo->global_state = 0;      /* mark it destroyed */
214
6.71k
}
215
216
217
/*
218
 * Convenience routines for allocating quantization and Huffman tables.
219
 * (Would jutils.c be a more reasonable place to put these?)
220
 */
221
222
GLOBAL(JQUANT_TBL *)
223
jpeg_alloc_quant_table(j_common_ptr cinfo)
224
9.75k
{
225
9.75k
  JQUANT_TBL *tbl;
226
227
9.75k
  tbl = (JQUANT_TBL *)
228
9.75k
    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, sizeof(JQUANT_TBL));
229
9.75k
  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
230
9.75k
  return tbl;
231
9.75k
}
232
233
234
GLOBAL(JHUFF_TBL *)
235
jpeg_alloc_huff_table(j_common_ptr cinfo)
236
13.8k
{
237
13.8k
  JHUFF_TBL *tbl;
238
239
13.8k
  tbl = (JHUFF_TBL *)
240
13.8k
    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, sizeof(JHUFF_TBL));
241
13.8k
  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
242
13.8k
  return tbl;
243
13.8k
}