]> Creatis software - gdcm.git/blob - src/gdcmjpeg/jdlossy.c
ENH: Note for myself: Never work on gdcm without first a coffee. double is 8bits...
[gdcm.git] / src / gdcmjpeg / jdlossy.c
1 /*
2  * jdlossy.c
3  *
4  * Copyright (C) 1998, Thomas G. Lane.
5  * This file is part of the Independent JPEG Group's software.
6  * For conditions of distribution and use, see the accompanying README file.
7  *
8  * This file contains the control logic for the lossy JPEG decompressor.
9  */
10
11 #define JPEG_INTERNALS
12 #include "jinclude.h"
13 #include "jpeglib.h"
14 #include "jlossy.h"
15
16
17 /*
18  * Compute output image dimensions and related values.
19  */
20
21 METHODDEF(void)
22 calc_output_dimensions (j_decompress_ptr cinfo)
23 {
24 #ifdef IDCT_SCALING_SUPPORTED
25   int ci;
26   jpeg_component_info *compptr;
27
28   /* Compute actual output image dimensions and DCT scaling choices. */
29   if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
30     /* Provide 1/8 scaling */
31     cinfo->output_width = (JDIMENSION)
32       jdiv_round_up((long) cinfo->image_width, 8L);
33     cinfo->output_height = (JDIMENSION)
34       jdiv_round_up((long) cinfo->image_height, 8L);
35     cinfo->min_codec_data_unit = 1;
36   } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
37     /* Provide 1/4 scaling */
38     cinfo->output_width = (JDIMENSION)
39       jdiv_round_up((long) cinfo->image_width, 4L);
40     cinfo->output_height = (JDIMENSION)
41       jdiv_round_up((long) cinfo->image_height, 4L);
42     cinfo->min_codec_data_unit = 2;
43   } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
44     /* Provide 1/2 scaling */
45     cinfo->output_width = (JDIMENSION)
46       jdiv_round_up((long) cinfo->image_width, 2L);
47     cinfo->output_height = (JDIMENSION)
48       jdiv_round_up((long) cinfo->image_height, 2L);
49     cinfo->min_codec_data_unit = 4;
50   } else {
51     /* Provide 1/1 scaling */
52     cinfo->output_width = cinfo->image_width;
53     cinfo->output_height = cinfo->image_height;
54     cinfo->min_codec_data_unit = DCTSIZE;
55   }
56   /* In selecting the actual DCT scaling for each component, we try to
57    * scale up the chroma components via IDCT scaling rather than upsampling.
58    * This saves time if the upsampler gets to use 1:1 scaling.
59    * Note this code assumes that the supported DCT scalings are powers of 2.
60    */
61   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
62        ci++, compptr++) {
63     int ssize = cinfo->min_codec_data_unit;
64     while (ssize < DCTSIZE &&
65      (compptr->h_samp_factor * ssize * 2 <=
66       cinfo->max_h_samp_factor * cinfo->min_codec_data_unit) &&
67      (compptr->v_samp_factor * ssize * 2 <=
68       cinfo->max_v_samp_factor * cinfo->min_codec_data_unit)) {
69       ssize = ssize * 2;
70     }
71     compptr->codec_data_unit = ssize;
72   }
73
74   /* Recompute downsampled dimensions of components;
75    * application needs to know these if using raw downsampled data.
76    */
77   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
78        ci++, compptr++) {
79     /* Size in samples, after IDCT scaling */
80     compptr->downsampled_width = (JDIMENSION)
81       jdiv_round_up((long) cinfo->image_width *
82         (long) (compptr->h_samp_factor * compptr->codec_data_unit),
83         (long) (cinfo->max_h_samp_factor * DCTSIZE));
84     compptr->downsampled_height = (JDIMENSION)
85       jdiv_round_up((long) cinfo->image_height *
86         (long) (compptr->v_samp_factor * compptr->codec_data_unit),
87         (long) (cinfo->max_v_samp_factor * DCTSIZE));
88   }
89
90 #else /* !IDCT_SCALING_SUPPORTED */
91
92   /* Hardwire it to "no scaling" */
93   cinfo->output_width = cinfo->image_width;
94   cinfo->output_height = cinfo->image_height;
95   /* jdinput.c has already initialized codec_data_unit to DCTSIZE,
96    * and has computed unscaled downsampled_width and downsampled_height.
97    */
98
99 #endif /* IDCT_SCALING_SUPPORTED */
100 }
101
102
103 /*
104  * Save away a copy of the Q-table referenced by each component present
105  * in the current scan, unless already saved during a prior scan.
106  *
107  * In a multiple-scan JPEG file, the encoder could assign different components
108  * the same Q-table slot number, but change table definitions between scans
109  * so that each component uses a different Q-table.  (The IJG encoder is not
110  * currently capable of doing this, but other encoders might.)  Since we want
111  * to be able to dequantize all the components at the end of the file, this
112  * means that we have to save away the table actually used for each component.
113  * We do this by copying the table at the start of the first scan containing
114  * the component.
115  * The JPEG spec prohibits the encoder from changing the contents of a Q-table
116  * slot between scans of a component using that slot.  If the encoder does so
117  * anyway, this decoder will simply use the Q-table values that were current
118  * at the start of the first scan for the component.
119  *
120  * The decompressor output side looks only at the saved quant tables,
121  * not at the current Q-table slots.
122  */
123
124 LOCAL(void)
125 latch_quant_tables (j_decompress_ptr cinfo)
126 {
127   int ci, qtblno;
128   jpeg_component_info *compptr;
129   JQUANT_TBL * qtbl;
130
131   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
132     compptr = cinfo->cur_comp_info[ci];
133     /* No work if we already saved Q-table for this component */
134     if (compptr->quant_table != NULL)
135       continue;
136     /* Make sure specified quantization table is present */
137     qtblno = compptr->quant_tbl_no;
138     if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
139   cinfo->quant_tbl_ptrs[qtblno] == NULL)
140       ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
141     /* OK, save away the quantization table */
142     qtbl = (JQUANT_TBL *)
143       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
144           SIZEOF(JQUANT_TBL));
145     MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL));
146     compptr->quant_table = qtbl;
147   }
148 }
149
150
151 /*
152  * Initialize for an input processing pass.
153  */
154
155 METHODDEF(void)
156 start_input_pass (j_decompress_ptr cinfo)
157 {
158   j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec;
159
160   latch_quant_tables(cinfo);
161   (*lossyd->entropy_start_pass) (cinfo);
162   (*lossyd->coef_start_input_pass) (cinfo);
163 }
164
165
166 /*
167  * Initialize for an output processing pass.
168  */
169
170 METHODDEF(void)
171 start_output_pass (j_decompress_ptr cinfo)
172 {
173   j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec;
174
175   (*lossyd->idct_start_pass) (cinfo);
176   (*lossyd->coef_start_output_pass) (cinfo);
177 }
178
179 /*
180  * Initialize the lossy decompression codec.
181  * This is called only once, during master selection.
182  */
183
184 GLOBAL(void)
185 jinit_lossy_d_codec (j_decompress_ptr cinfo)
186 {
187   j_lossy_d_ptr lossyd;
188   boolean use_c_buffer;
189
190   /* Create subobject in permanent pool */
191   lossyd = (j_lossy_d_ptr)
192     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
193         SIZEOF(jpeg_lossy_d_codec));
194   cinfo->codec = (struct jpeg_d_codec *) lossyd;
195
196   /* Initialize sub-modules */
197
198   /* Inverse DCT */
199   jinit_inverse_dct(cinfo);
200   /* Entropy decoding: either Huffman or arithmetic coding. */
201   if (cinfo->arith_code) {
202     jinit_arith_decoder(cinfo);
203   } else {
204     if (cinfo->process == JPROC_PROGRESSIVE) {
205 #ifdef D_PROGRESSIVE_SUPPORTED
206       jinit_phuff_decoder(cinfo);
207 #else
208       ERREXIT(cinfo, JERR_NOT_COMPILED);
209 #endif
210     } else
211       jinit_shuff_decoder(cinfo);
212   }
213
214   use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
215   jinit_d_coef_controller(cinfo, use_c_buffer);
216
217   /* Initialize method pointers.
218    *
219    * Note: consume_data and decompress_data are assigned in jdcoefct.c.
220    */
221   lossyd->pub.calc_output_dimensions = calc_output_dimensions;
222   lossyd->pub.start_input_pass = start_input_pass;
223   lossyd->pub.start_output_pass = start_output_pass;
224 }
225
226
227
228