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
8 * For conditions of distribution and use, see the accompanying README.ijg
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.
16 #define JPEG_INTERNALS
21 /* Private buffer controller object */
24 struct jpeg_c_main_controller pub
; /* public fields */
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 */
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.
35 JSAMPARRAY buffer
[MAX_COMPONENTS
];
38 typedef my_main_controller
*my_main_ptr
;
41 /* Forward declarations */
42 METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo
,
44 JDIMENSION
*in_row_ctr
,
45 JDIMENSION in_rows_avail
);
49 * Initialize for a processing pass.
53 start_pass_main(j_compress_ptr cinfo
, J_BUF_MODE pass_mode
)
55 my_main_ptr main_ptr
= (my_main_ptr
)cinfo
->main
;
57 /* Do nothing in raw-data mode. */
58 if (cinfo
->raw_data_in
)
61 if (pass_mode
!= JBUF_PASS_THRU
)
62 ERREXIT(cinfo
, JERR_BAD_BUFFER_MODE
);
64 main_ptr
->cur_iMCU_row
= 0; /* initialize counters */
65 main_ptr
->rowgroup_ctr
= 0;
66 main_ptr
->suspended
= FALSE
;
67 main_ptr
->pass_mode
= pass_mode
; /* save mode for use by process_data */
68 main_ptr
->pub
.process_data
= process_data_simple_main
;
74 * This routine handles the simple pass-through mode,
75 * where we have only a strip buffer.
79 process_data_simple_main(j_compress_ptr cinfo
, JSAMPARRAY input_buf
,
80 JDIMENSION
*in_row_ctr
, JDIMENSION in_rows_avail
)
82 my_main_ptr main_ptr
= (my_main_ptr
)cinfo
->main
;
84 while (main_ptr
->cur_iMCU_row
< cinfo
->total_iMCU_rows
) {
85 /* Read input data if we haven't filled the main buffer yet */
86 if (main_ptr
->rowgroup_ctr
< DCTSIZE
)
87 (*cinfo
->prep
->pre_process_data
) (cinfo
, input_buf
, in_row_ctr
,
88 in_rows_avail
, main_ptr
->buffer
,
89 &main_ptr
->rowgroup_ctr
,
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.
96 if (main_ptr
->rowgroup_ctr
!= DCTSIZE
)
99 /* Send the completed row to the compressor */
100 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.
107 if (!main_ptr
->suspended
) {
109 main_ptr
->suspended
= TRUE
;
113 /* We did finish the row. Undo our little suspension hack if a previous
114 * call suspended; then mark the main buffer empty.
116 if (main_ptr
->suspended
) {
118 main_ptr
->suspended
= FALSE
;
120 main_ptr
->rowgroup_ctr
= 0;
121 main_ptr
->cur_iMCU_row
++;
127 * Initialize main buffer controller.
131 jinit_c_main_controller(j_compress_ptr cinfo
, boolean need_full_buffer
)
133 my_main_ptr main_ptr
;
135 jpeg_component_info
*compptr
;
137 main_ptr
= (my_main_ptr
)
138 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
)cinfo
, JPOOL_IMAGE
,
139 sizeof(my_main_controller
));
140 cinfo
->main
= (struct jpeg_c_main_controller
*)main_ptr
;
141 main_ptr
->pub
.start_pass
= start_pass_main
;
143 /* We don't need to create a buffer in raw-data mode. */
144 if (cinfo
->raw_data_in
)
147 /* Create the buffer. It holds downsampled data, so each component
148 * may be of a different size.
150 if (need_full_buffer
) {
151 ERREXIT(cinfo
, JERR_BAD_BUFFER_MODE
);
153 /* Allocate a strip buffer for each component */
154 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
156 main_ptr
->buffer
[ci
] = (*cinfo
->mem
->alloc_sarray
)
157 ((j_common_ptr
)cinfo
, JPOOL_IMAGE
,
158 compptr
->width_in_blocks
* DCTSIZE
,
159 (JDIMENSION
)(compptr
->v_samp_factor
* DCTSIZE
));