]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/jpeg6/jdpostct.cpp
more eol-style
[xonotic/netradiant.git] / libs / jpeg6 / jdpostct.cpp
1 /*
2
3  * jdpostct.c
4
5  *
6
7  * Copyright (C) 1994-1995, Thomas G. Lane.
8
9  * This file is part of the Independent JPEG Group's software.
10
11  * For conditions of distribution and use, see the accompanying README file.
12
13  *
14
15  * This file contains the decompression postprocessing controller.
16
17  * This controller manages the upsampling, color conversion, and color
18
19  * quantization/reduction steps; specifically, it controls the buffering
20
21  * between upsample/color conversion and color quantization/reduction.
22
23  *
24
25  * If no color quantization/reduction is required, then this module has no
26
27  * work to do, and it just hands off to the upsample/color conversion code.
28
29  * An integrated upsample/convert/quantize process would replace this module
30
31  * entirely.
32
33  */
34
35
36
37 #define JPEG_INTERNALS
38
39 #include "jinclude.h"
40
41 #include "radiant_jpeglib.h"
42
43
44
45
46
47 /* Private buffer controller object */
48
49
50
51 typedef struct {
52
53   struct jpeg_d_post_controller pub; /* public fields */
54
55
56
57   /* Color quantization source buffer: this holds output data from
58
59    * the upsample/color conversion step to be passed to the quantizer.
60
61    * For two-pass color quantization, we need a full-image buffer;
62
63    * for one-pass operation, a strip buffer is sufficient.
64
65    */
66
67   jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
68
69   JSAMPARRAY buffer;            /* strip buffer, or current strip of virtual */
70
71   JDIMENSION strip_height;      /* buffer size in rows */
72
73   /* for two-pass mode only: */
74
75   JDIMENSION starting_row;      /* row # of first row in current strip */
76
77   JDIMENSION next_row;          /* index of next row to fill/empty in strip */
78
79 } my_post_controller;
80
81
82
83 typedef my_post_controller * my_post_ptr;
84
85
86
87
88
89 /* Forward declarations */
90
91 METHODDEF void post_process_1pass
92
93         JPP((j_decompress_ptr cinfo,
94
95              JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
96
97              JDIMENSION in_row_groups_avail,
98
99              JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
100
101              JDIMENSION out_rows_avail));
102
103 #ifdef QUANT_2PASS_SUPPORTED
104
105 METHODDEF void post_process_prepass
106
107         JPP((j_decompress_ptr cinfo,
108
109              JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
110
111              JDIMENSION in_row_groups_avail,
112
113              JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
114
115              JDIMENSION out_rows_avail));
116
117 METHODDEF void post_process_2pass
118
119         JPP((j_decompress_ptr cinfo,
120
121              JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
122
123              JDIMENSION in_row_groups_avail,
124
125              JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
126
127              JDIMENSION out_rows_avail));
128
129 #endif
130
131
132
133
134
135 /*
136
137  * Initialize for a processing pass.
138
139  */
140
141
142
143 METHODDEF void
144
145 start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
146
147 {
148
149   my_post_ptr post = (my_post_ptr) cinfo->post;
150
151
152
153   switch (pass_mode) {
154
155   case JBUF_PASS_THRU:
156
157     if (cinfo->quantize_colors) {
158
159       /* Single-pass processing with color quantization. */
160
161       post->pub.post_process_data = post_process_1pass;
162
163       /* We could be doing buffered-image output before starting a 2-pass
164
165        * color quantization; in that case, jinit_d_post_controller did not
166
167        * allocate a strip buffer.  Use the virtual-array buffer as workspace.
168
169        */
170
171       if (post->buffer == NULL) {
172
173         post->buffer = (*cinfo->mem->access_virt_sarray)
174
175           ((j_common_ptr) cinfo, post->whole_image,
176
177            (JDIMENSION) 0, post->strip_height, TRUE);
178
179       }
180
181     } else {
182
183       /* For single-pass processing without color quantization,
184
185        * I have no work to do; just call the upsampler directly.
186
187        */
188
189       post->pub.post_process_data = cinfo->upsample->upsample;
190
191     }
192
193     break;
194
195 #ifdef QUANT_2PASS_SUPPORTED
196
197   case JBUF_SAVE_AND_PASS:
198
199     /* First pass of 2-pass quantization */
200
201     if (post->whole_image == NULL)
202
203       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
204
205     post->pub.post_process_data = post_process_prepass;
206
207     break;
208
209   case JBUF_CRANK_DEST:
210
211     /* Second pass of 2-pass quantization */
212
213     if (post->whole_image == NULL)
214
215       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
216
217     post->pub.post_process_data = post_process_2pass;
218
219     break;
220
221 #endif /* QUANT_2PASS_SUPPORTED */
222
223   default:
224
225     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
226
227     break;
228
229   }
230
231   post->starting_row = post->next_row = 0;
232
233 }
234
235
236
237
238
239 /*
240
241  * Process some data in the one-pass (strip buffer) case.
242
243  * This is used for color precision reduction as well as one-pass quantization.
244
245  */
246
247
248
249 METHODDEF void
250
251 post_process_1pass (j_decompress_ptr cinfo,
252
253                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
254
255                     JDIMENSION in_row_groups_avail,
256
257                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
258
259                     JDIMENSION out_rows_avail)
260
261 {
262
263   my_post_ptr post = (my_post_ptr) cinfo->post;
264
265   JDIMENSION num_rows, max_rows;
266
267
268
269   /* Fill the buffer, but not more than what we can dump out in one go. */
270
271   /* Note we rely on the upsampler to detect bottom of image. */
272
273   max_rows = out_rows_avail - *out_row_ctr;
274
275   if (max_rows > post->strip_height)
276
277     max_rows = post->strip_height;
278
279   num_rows = 0;
280
281   (*cinfo->upsample->upsample) (cinfo,
282
283                 input_buf, in_row_group_ctr, in_row_groups_avail,
284
285                 post->buffer, &num_rows, max_rows);
286
287   /* Quantize and emit data. */
288
289   (*cinfo->cquantize->color_quantize) (cinfo,
290
291                 post->buffer, output_buf + *out_row_ctr, (int) num_rows);
292
293   *out_row_ctr += num_rows;
294
295 }
296
297
298
299
300
301 #ifdef QUANT_2PASS_SUPPORTED
302
303
304
305 /*
306
307  * Process some data in the first pass of 2-pass quantization.
308
309  */
310
311
312
313 METHODDEF void
314
315 post_process_prepass (j_decompress_ptr cinfo,
316
317                       JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
318
319                       JDIMENSION in_row_groups_avail,
320
321                       JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
322
323                       JDIMENSION out_rows_avail)
324
325 {
326
327   my_post_ptr post = (my_post_ptr) cinfo->post;
328
329   JDIMENSION old_next_row, num_rows;
330
331
332
333   /* Reposition virtual buffer if at start of strip. */
334
335   if (post->next_row == 0) {
336
337     post->buffer = (*cinfo->mem->access_virt_sarray)
338
339         ((j_common_ptr) cinfo, post->whole_image,
340
341          post->starting_row, post->strip_height, TRUE);
342
343   }
344
345
346
347   /* Upsample some data (up to a strip height's worth). */
348
349   old_next_row = post->next_row;
350
351   (*cinfo->upsample->upsample) (cinfo,
352
353                 input_buf, in_row_group_ctr, in_row_groups_avail,
354
355                 post->buffer, &post->next_row, post->strip_height);
356
357
358
359   /* Allow quantizer to scan new data.  No data is emitted, */
360
361   /* but we advance out_row_ctr so outer loop can tell when we're done. */
362
363   if (post->next_row > old_next_row) {
364
365     num_rows = post->next_row - old_next_row;
366
367     (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
368
369                                          (JSAMPARRAY) NULL, (int) num_rows);
370
371     *out_row_ctr += num_rows;
372
373   }
374
375
376
377   /* Advance if we filled the strip. */
378
379   if (post->next_row >= post->strip_height) {
380
381     post->starting_row += post->strip_height;
382
383     post->next_row = 0;
384
385   }
386
387 }
388
389
390
391
392
393 /*
394
395  * Process some data in the second pass of 2-pass quantization.
396
397  */
398
399
400
401 METHODDEF void
402
403 post_process_2pass (j_decompress_ptr cinfo,
404
405                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
406
407                     JDIMENSION in_row_groups_avail,
408
409                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
410
411                     JDIMENSION out_rows_avail)
412
413 {
414
415   my_post_ptr post = (my_post_ptr) cinfo->post;
416
417   JDIMENSION num_rows, max_rows;
418
419
420
421   /* Reposition virtual buffer if at start of strip. */
422
423   if (post->next_row == 0) {
424
425     post->buffer = (*cinfo->mem->access_virt_sarray)
426
427         ((j_common_ptr) cinfo, post->whole_image,
428
429          post->starting_row, post->strip_height, FALSE);
430
431   }
432
433
434
435   /* Determine number of rows to emit. */
436
437   num_rows = post->strip_height - post->next_row; /* available in strip */
438
439   max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
440
441   if (num_rows > max_rows)
442
443     num_rows = max_rows;
444
445   /* We have to check bottom of image here, can't depend on upsampler. */
446
447   max_rows = cinfo->output_height - post->starting_row;
448
449   if (num_rows > max_rows)
450
451     num_rows = max_rows;
452
453
454
455   /* Quantize and emit data. */
456
457   (*cinfo->cquantize->color_quantize) (cinfo,
458
459                 post->buffer + post->next_row, output_buf + *out_row_ctr,
460
461                 (int) num_rows);
462
463   *out_row_ctr += num_rows;
464
465
466
467   /* Advance if we filled the strip. */
468
469   post->next_row += num_rows;
470
471   if (post->next_row >= post->strip_height) {
472
473     post->starting_row += post->strip_height;
474
475     post->next_row = 0;
476
477   }
478
479 }
480
481
482
483 #endif /* QUANT_2PASS_SUPPORTED */
484
485
486
487
488
489 /*
490
491  * Initialize postprocessing controller.
492
493  */
494
495
496
497 GLOBAL void
498
499 jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
500
501 {
502
503   my_post_ptr post;
504
505
506
507   post = (my_post_ptr)
508
509     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
510
511                                 SIZEOF(my_post_controller));
512
513   cinfo->post = (struct jpeg_d_post_controller *) post;
514
515   post->pub.start_pass = start_pass_dpost;
516
517   post->whole_image = NULL;     /* flag for no virtual arrays */
518
519   post->buffer = NULL;          /* flag for no strip buffer */
520
521
522
523   /* Create the quantization buffer, if needed */
524
525   if (cinfo->quantize_colors) {
526
527     /* The buffer strip height is max_v_samp_factor, which is typically
528
529      * an efficient number of rows for upsampling to return.
530
531      * (In the presence of output rescaling, we might want to be smarter?)
532
533      */
534
535     post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
536
537     if (need_full_buffer) {
538
539       /* Two-pass color quantization: need full-image storage. */
540
541       /* We round up the number of rows to a multiple of the strip height. */
542
543 #ifdef QUANT_2PASS_SUPPORTED
544
545       post->whole_image = (*cinfo->mem->request_virt_sarray)
546
547         ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
548
549          cinfo->output_width * cinfo->out_color_components,
550
551          (JDIMENSION) jround_up((long) cinfo->output_height,
552
553                                 (long) post->strip_height),
554
555          post->strip_height);
556
557 #else
558
559       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
560
561 #endif /* QUANT_2PASS_SUPPORTED */
562
563     } else {
564
565       /* One-pass color quantization: just make a strip buffer. */
566
567       post->buffer = (*cinfo->mem->alloc_sarray)
568
569         ((j_common_ptr) cinfo, JPOOL_IMAGE,
570
571          cinfo->output_width * cinfo->out_color_components,
572
573          post->strip_height);
574
575     }
576
577   }
578
579 }
580