Coverage Report

Created: 2024-05-04 12:45

/proc/self/cwd/external/libjpeg_turbo/jcmainct.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * jcmainct.c
3
 *
4
 * This file was part of the Independent JPEG Group's software:
5
 * Copyright (C) 1994-1996, Thomas G. Lane.
6
 * It was modified by The libjpeg-turbo Project to include only code relevant
7
 * to libjpeg-turbo.
8
 * For conditions of distribution and use, see the accompanying README.ijg
9
 * file.
10
 *
11
 * This file contains the main buffer controller for compression.
12
 * The main buffer lies between the pre-processor and the JPEG
13
 * compressor proper; it holds downsampled data in the JPEG colorspace.
14
 */
15
16
#define JPEG_INTERNALS
17
#include "jinclude.h"
18
#include "jpeglib.h"
19
20
21
/* Private buffer controller object */
22
23
typedef struct {
24
  struct jpeg_c_main_controller pub; /* public fields */
25
26
  JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
27
  JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
28
  boolean suspended;            /* remember if we suspended output */
29
  J_BUF_MODE pass_mode;         /* current operating mode */
30
31
  /* If using just a strip buffer, this points to the entire set of buffers
32
   * (we allocate one for each component).  In the full-image case, this
33
   * points to the currently accessible strips of the virtual arrays.
34
   */
35
  JSAMPARRAY buffer[MAX_COMPONENTS];
36
} my_main_controller;
37
38
typedef my_main_controller *my_main_ptr;
39
40
41
/* Forward declarations */
42
METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo,
43
                                         JSAMPARRAY input_buf,
44
                                         JDIMENSION *in_row_ctr,
45
                                         JDIMENSION in_rows_avail);
46
47
48
/*
49
 * Initialize for a processing pass.
50
 */
51
52
METHODDEF(void)
53
start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
54
933
{
55
933
  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
56
57
  /* Do nothing in raw-data mode. */
58
933
  if (cinfo->raw_data_in)
59
0
    return;
60
61
933
  if (pass_mode != JBUF_PASS_THRU)
62
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
63
64
933
  main_ptr->cur_iMCU_row = 0;   /* initialize counters */
65
933
  main_ptr->rowgroup_ctr = 0;
66
933
  main_ptr->suspended = FALSE;
67
933
  main_ptr->pass_mode = pass_mode;      /* save mode for use by process_data */
68
933
  main_ptr->pub.process_data = process_data_simple_main;
69
933
}
70
71
72
/*
73
 * Process some data.
74
 * This routine handles the simple pass-through mode,
75
 * where we have only a strip buffer.
76
 */
77
78
METHODDEF(void)
79
process_data_simple_main(j_compress_ptr cinfo, JSAMPARRAY input_buf,
80
                         JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)
81
1.72M
{
82
1.72M
  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
83
84
1.93M
  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
85
    /* Read input data if we haven't filled the main buffer yet */
86
1.93M
    if (main_ptr->rowgroup_ctr < DCTSIZE)
87
1.93M
      (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr,
88
1.93M
                                        in_rows_avail, main_ptr->buffer,
89
1.93M
                                        &main_ptr->rowgroup_ctr,
90
1.93M
                                        (JDIMENSION)DCTSIZE);
91
92
    /* If we don't have a full iMCU row buffered, return to application for
93
     * more data.  Note that preprocessor will always pad to fill the iMCU row
94
     * at the bottom of the image.
95
     */
96
1.93M
    if (main_ptr->rowgroup_ctr != DCTSIZE)
97
1.72M
      return;
98
99
    /* Send the completed row to the compressor */
100
208k
    if (!(*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
101
      /* If compressor did not consume the whole row, then we must need to
102
       * suspend processing and return to the application.  In this situation
103
       * we pretend we didn't yet consume the last input row; otherwise, if
104
       * it happened to be the last row of the image, the application would
105
       * think we were done.
106
       */
107
0
      if (!main_ptr->suspended) {
108
0
        (*in_row_ctr)--;
109
0
        main_ptr->suspended = TRUE;
110
0
      }
111
0
      return;
112
0
    }
113
    /* We did finish the row.  Undo our little suspension hack if a previous
114
     * call suspended; then mark the main buffer empty.
115
     */
116
208k
    if (main_ptr->suspended) {
117
0
      (*in_row_ctr)++;
118
0
      main_ptr->suspended = FALSE;
119
0
    }
120
208k
    main_ptr->rowgroup_ctr = 0;
121
208k
    main_ptr->cur_iMCU_row++;
122
208k
  }
123
1.72M
}
124
125
126
/*
127
 * Initialize main buffer controller.
128
 */
129
130
GLOBAL(void)
131
jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
132
933
{
133
933
  my_main_ptr main_ptr;
134
933
  int ci;
135
933
  jpeg_component_info *compptr;
136
137
933
  main_ptr = (my_main_ptr)
138
933
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
139
933
                                sizeof(my_main_controller));
140
933
  cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
141
933
  main_ptr->pub.start_pass = start_pass_main;
142
143
  /* We don't need to create a buffer in raw-data mode. */
144
933
  if (cinfo->raw_data_in)
145
0
    return;
146
147
  /* Create the buffer.  It holds downsampled data, so each component
148
   * may be of a different size.
149
   */
150
933
  if (need_full_buffer) {
151
0
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
152
933
  } else {
153
    /* Allocate a strip buffer for each component */
154
2.18k
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
155
1.25k
         ci++, compptr++) {
156
1.25k
      main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
157
1.25k
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
158
1.25k
         compptr->width_in_blocks * DCTSIZE,
159
1.25k
         (JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
160
1.25k
    }
161
933
  }
162
933
}