Coverage Report

Created: 2026-02-26 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjpeg-turbo.dev/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
22.5k
{
38
22.5k
  int pool;
39
40
  /* Do nothing if called on a not-initialized or destroyed JPEG object. */
41
22.5k
  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
45.0k
  for (pool = JPOOL_NUMPOOLS - 1; pool > JPOOL_PERMANENT; pool--) {
48
22.5k
    (*cinfo->mem->free_pool) (cinfo, pool);
49
22.5k
  }
50
51
  /* Reset overall state for possible reuse of object */
52
22.5k
  if (cinfo->is_decompressor) {
53
22.5k
    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
22.5k
    ((j_decompress_ptr)cinfo)->marker_list = NULL;
58
22.5k
    ((j_decompress_ptr)cinfo)->master->marker_list_end = NULL;
59
22.5k
  } else {
60
0
    cinfo->global_state = CSTATE_START;
61
0
  }
62
63
#ifdef WITH_PROFILE
64
  if (cinfo->is_decompressor)
65
    ((j_decompress_ptr)cinfo)->master->total_elapsed +=
66
      getTime() - ((j_decompress_ptr)cinfo)->master->total_start;
67
  else
68
    ((j_compress_ptr)cinfo)->master->total_elapsed +=
69
      getTime() - ((j_compress_ptr)cinfo)->master->total_start;
70
#endif
71
22.5k
}
72
73
74
/*
75
 * Destruction of a JPEG object.
76
 *
77
 * Everything gets deallocated except the master jpeg_compress_struct itself
78
 * and the error manager struct.  Both of these are supplied by the application
79
 * and must be freed, if necessary, by the application.  (Often they are on
80
 * the stack and so don't need to be freed anyway.)
81
 * Closing a data source or destination, if necessary, is the application's
82
 * responsibility.
83
 */
84
85
GLOBAL(void)
86
jpeg_destroy(j_common_ptr cinfo)
87
6.05k
{
88
#ifdef WITH_PROFILE
89
  if (cinfo->is_decompressor) {
90
    j_decompress_ptr dinfo = (j_decompress_ptr)cinfo;
91
92
    if (dinfo->master->entropy_mcoeffs > 0.0) {
93
      fprintf(stderr, "Entropy decoding:    %14.6f Mcoefficients/sec",
94
              dinfo->master->entropy_mcoeffs / dinfo->master->entropy_elapsed);
95
      if (dinfo->master->total_elapsed > 0.0)
96
        fprintf(stderr, "  (%5.2f%% of total time)",
97
                dinfo->master->entropy_elapsed * 100.0 /
98
                  dinfo->master->total_elapsed);
99
      fprintf(stderr, "\n");
100
    }
101
    if (dinfo->master->idct_mcoeffs > 0.0) {
102
      fprintf(stderr, "Inverse DCT:         %14.6f Mcoefficients/sec",
103
              dinfo->master->idct_mcoeffs / dinfo->master->idct_elapsed);
104
      if (dinfo->master->total_elapsed > 0.0)
105
        fprintf(stderr, "  (%5.2f%% of total time)",
106
                dinfo->master->idct_elapsed * 100.0 /
107
                  dinfo->master->total_elapsed);
108
      fprintf(stderr, "\n");
109
    }
110
    if (dinfo->master->merged_upsample_mpixels > 0.0) {
111
      fprintf(stderr, "Merged upsampling:   %14.6f Mpixels/sec",
112
              dinfo->master->merged_upsample_mpixels /
113
                dinfo->master->merged_upsample_elapsed);
114
      if (dinfo->master->total_elapsed > 0.0)
115
        fprintf(stderr, "        (%5.2f%% of total time)",
116
                dinfo->master->merged_upsample_elapsed * 100.0 /
117
                  dinfo->master->total_elapsed);
118
      fprintf(stderr, "\n");
119
    }
120
    if (dinfo->master->upsample_msamples > 0.0) {
121
      fprintf(stderr, "Upsampling:          %14.6f Msamples/sec",
122
              dinfo->master->upsample_msamples /
123
                dinfo->master->upsample_elapsed);
124
      if (dinfo->master->total_elapsed > 0.0)
125
        fprintf(stderr, "       (%5.2f%% of total time)",
126
                dinfo->master->upsample_elapsed * 100.0 /
127
                  dinfo->master->total_elapsed);
128
      fprintf(stderr, "\n");
129
    }
130
    if (dinfo->master->cconvert_mpixels > 0.0) {
131
      fprintf(stderr, "Color deconversion:  %14.6f Mpixels/sec",
132
              dinfo->master->cconvert_mpixels /
133
                dinfo->master->cconvert_elapsed);
134
      if (dinfo->master->total_elapsed > 0.0)
135
        fprintf(stderr, "        (%5.2f%% of total time)",
136
                dinfo->master->cconvert_elapsed * 100.0 /
137
                  dinfo->master->total_elapsed);
138
      fprintf(stderr, "\n");
139
    }
140
  } else {
141
    j_compress_ptr _cinfo = (j_compress_ptr)cinfo;
142
143
    if (_cinfo->master->cconvert_mpixels > 0.0) {
144
      fprintf(stderr, "Color conversion:    %14.6f Mpixels/sec",
145
              _cinfo->master->cconvert_mpixels /
146
                _cinfo->master->cconvert_elapsed);
147
      if (_cinfo->master->total_elapsed > 0.0)
148
        fprintf(stderr, "        (%5.2f%% of total time)",
149
                _cinfo->master->cconvert_elapsed * 100.0 /
150
                  _cinfo->master->total_elapsed);
151
      fprintf(stderr, "\n");
152
    }
153
    if (_cinfo->master->downsample_msamples > 0.0) {
154
      fprintf(stderr, "Downsampling:        %14.6f Msamples/sec",
155
              _cinfo->master->downsample_msamples /
156
                _cinfo->master->downsample_elapsed);
157
      if (_cinfo->master->total_elapsed > 0.0)
158
        fprintf(stderr, "       (%5.2f%% of total time)",
159
                _cinfo->master->downsample_elapsed * 100.0 /
160
                  _cinfo->master->total_elapsed);
161
      fprintf(stderr, "\n");
162
    }
163
    if (_cinfo->master->convsamp_msamples > 0.0) {
164
      fprintf(stderr, "Sample conversion:   %14.6f Msamples/sec",
165
              _cinfo->master->convsamp_msamples /
166
                _cinfo->master->convsamp_elapsed);
167
      if (_cinfo->master->total_elapsed > 0.0)
168
        fprintf(stderr, "       (%5.2f%% of total time)",
169
                _cinfo->master->convsamp_elapsed * 100.0 /
170
                  _cinfo->master->total_elapsed);
171
      fprintf(stderr, "\n");
172
    }
173
    if (_cinfo->master->fdct_mcoeffs > 0.0) {
174
      fprintf(stderr, "Forward DCT:         %14.6f Mcoefficients/sec",
175
              _cinfo->master->fdct_mcoeffs / _cinfo->master->fdct_elapsed);
176
      if (_cinfo->master->total_elapsed > 0.0)
177
        fprintf(stderr, "  (%5.2f%% of total time)",
178
                _cinfo->master->fdct_elapsed * 100.0 /
179
                  _cinfo->master->total_elapsed);
180
      fprintf(stderr, "\n");
181
    }
182
    if (_cinfo->master->quantize_mcoeffs > 0.0) {
183
      fprintf(stderr, "Quantization:        %14.6f Mcoefficients/sec",
184
              _cinfo->master->quantize_mcoeffs /
185
                _cinfo->master->quantize_elapsed);
186
      if (_cinfo->master->total_elapsed > 0.0)
187
        fprintf(stderr, "  (%5.2f%% of total time)",
188
                _cinfo->master->quantize_elapsed * 100.0 /
189
                  _cinfo->master->total_elapsed);
190
      fprintf(stderr, "\n");
191
    }
192
    if (_cinfo->master->entropy_mcoeffs > 0.0) {
193
      fprintf(stderr, "Entropy encoding:    %14.6f Mcoefficients/sec",
194
              _cinfo->master->entropy_mcoeffs /
195
                _cinfo->master->entropy_elapsed);
196
      if (_cinfo->master->total_elapsed > 0.0)
197
        fprintf(stderr, "  (%5.2f%% of total time)",
198
                _cinfo->master->entropy_elapsed * 100.0 /
199
                  _cinfo->master->total_elapsed);
200
      fprintf(stderr, "\n");
201
    }
202
  }
203
#endif
204
205
  /* We need only tell the memory manager to release everything. */
206
  /* NB: mem pointer is NULL if memory mgr failed to initialize. */
207
6.05k
  if (cinfo->mem != NULL)
208
6.05k
    (*cinfo->mem->self_destruct) (cinfo);
209
6.05k
  cinfo->mem = NULL;            /* be safe if jpeg_destroy is called twice */
210
6.05k
  cinfo->global_state = 0;      /* mark it destroyed */
211
6.05k
}
212
213
214
/*
215
 * Convenience routines for allocating quantization and Huffman tables.
216
 * (Would jutils.c be a more reasonable place to put these?)
217
 */
218
219
GLOBAL(JQUANT_TBL *)
220
jpeg_alloc_quant_table(j_common_ptr cinfo)
221
3.51k
{
222
3.51k
  JQUANT_TBL *tbl;
223
224
3.51k
  tbl = (JQUANT_TBL *)
225
3.51k
    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, sizeof(JQUANT_TBL));
226
3.51k
  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
227
3.51k
  return tbl;
228
3.51k
}
229
230
231
GLOBAL(JHUFF_TBL *)
232
jpeg_alloc_huff_table(j_common_ptr cinfo)
233
6.86k
{
234
6.86k
  JHUFF_TBL *tbl;
235
236
6.86k
  tbl = (JHUFF_TBL *)
237
6.86k
    (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, sizeof(JHUFF_TBL));
238
6.86k
  tbl->sent_table = FALSE;      /* make sure this is false in any new table */
239
6.86k
  return tbl;
240
6.86k
}