]> git.xonotic.org Git - xonotic/netradiant.git/blob - libs/jpeg6/jdmainct.cpp
some updates to the Linux build system - obtained a core binary and all required...
[xonotic/netradiant.git] / libs / jpeg6 / jdmainct.cpp
1 /*\r
2 \r
3  * jdmainct.c\r
4 \r
5  *\r
6 \r
7  * Copyright (C) 1994-1995, Thomas G. Lane.\r
8 \r
9  * This file is part of the Independent JPEG Group's software.\r
10 \r
11  * For conditions of distribution and use, see the accompanying README file.\r
12 \r
13  *\r
14 \r
15  * This file contains the main buffer controller for decompression.\r
16 \r
17  * The main buffer lies between the JPEG decompressor proper and the\r
18 \r
19  * post-processor; it holds downsampled data in the JPEG colorspace.\r
20 \r
21  *\r
22 \r
23  * Note that this code is bypassed in raw-data mode, since the application\r
24 \r
25  * supplies the equivalent of the main buffer in that case.\r
26 \r
27  */\r
28 \r
29 \r
30 \r
31 #define JPEG_INTERNALS\r
32 \r
33 #include "jinclude.h"\r
34 \r
35 #include "radiant_jpeglib.h"\r
36 \r
37 \r
38 \r
39 \r
40 \r
41 /*\r
42 \r
43  * In the current system design, the main buffer need never be a full-image\r
44 \r
45  * buffer; any full-height buffers will be found inside the coefficient or\r
46 \r
47  * postprocessing controllers.  Nonetheless, the main controller is not\r
48 \r
49  * trivial.  Its responsibility is to provide context rows for upsampling/\r
50 \r
51  * rescaling, and doing this in an efficient fashion is a bit tricky.\r
52 \r
53  *\r
54 \r
55  * Postprocessor input data is counted in "row groups".  A row group\r
56 \r
57  * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)\r
58 \r
59  * sample rows of each component.  (We require DCT_scaled_size values to be\r
60 \r
61  * chosen such that these numbers are integers.  In practice DCT_scaled_size\r
62 \r
63  * values will likely be powers of two, so we actually have the stronger\r
64 \r
65  * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)\r
66 \r
67  * Upsampling will typically produce max_v_samp_factor pixel rows from each\r
68 \r
69  * row group (times any additional scale factor that the upsampler is\r
70 \r
71  * applying).\r
72 \r
73  *\r
74 \r
75  * The coefficient controller will deliver data to us one iMCU row at a time;\r
76 \r
77  * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or\r
78 \r
79  * exactly min_DCT_scaled_size row groups.  (This amount of data corresponds\r
80 \r
81  * to one row of MCUs when the image is fully interleaved.)  Note that the\r
82 \r
83  * number of sample rows varies across components, but the number of row\r
84 \r
85  * groups does not.  Some garbage sample rows may be included in the last iMCU\r
86 \r
87  * row at the bottom of the image.\r
88 \r
89  *\r
90 \r
91  * Depending on the vertical scaling algorithm used, the upsampler may need\r
92 \r
93  * access to the sample row(s) above and below its current input row group.\r
94 \r
95  * The upsampler is required to set need_context_rows TRUE at global selection\r
96 \r
97  * time if so.  When need_context_rows is FALSE, this controller can simply\r
98 \r
99  * obtain one iMCU row at a time from the coefficient controller and dole it\r
100 \r
101  * out as row groups to the postprocessor.\r
102 \r
103  *\r
104 \r
105  * When need_context_rows is TRUE, this controller guarantees that the buffer\r
106 \r
107  * passed to postprocessing contains at least one row group's worth of samples\r
108 \r
109  * above and below the row group(s) being processed.  Note that the context\r
110 \r
111  * rows "above" the first passed row group appear at negative row offsets in\r
112 \r
113  * the passed buffer.  At the top and bottom of the image, the required\r
114 \r
115  * context rows are manufactured by duplicating the first or last real sample\r
116 \r
117  * row; this avoids having special cases in the upsampling inner loops.\r
118 \r
119  *\r
120 \r
121  * The amount of context is fixed at one row group just because that's a\r
122 \r
123  * convenient number for this controller to work with.  The existing\r
124 \r
125  * upsamplers really only need one sample row of context.  An upsampler\r
126 \r
127  * supporting arbitrary output rescaling might wish for more than one row\r
128 \r
129  * group of context when shrinking the image; tough, we don't handle that.\r
130 \r
131  * (This is justified by the assumption that downsizing will be handled mostly\r
132 \r
133  * by adjusting the DCT_scaled_size values, so that the actual scale factor at\r
134 \r
135  * the upsample step needn't be much less than one.)\r
136 \r
137  *\r
138 \r
139  * To provide the desired context, we have to retain the last two row groups\r
140 \r
141  * of one iMCU row while reading in the next iMCU row.  (The last row group\r
142 \r
143  * can't be processed until we have another row group for its below-context,\r
144 \r
145  * and so we have to save the next-to-last group too for its above-context.)\r
146 \r
147  * We could do this most simply by copying data around in our buffer, but\r
148 \r
149  * that'd be very slow.  We can avoid copying any data by creating a rather\r
150 \r
151  * strange pointer structure.  Here's how it works.  We allocate a workspace\r
152 \r
153  * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number\r
154 \r
155  * of row groups per iMCU row).  We create two sets of redundant pointers to\r
156 \r
157  * the workspace.  Labeling the physical row groups 0 to M+1, the synthesized\r
158 \r
159  * pointer lists look like this:\r
160 \r
161  *                   M+1                          M-1\r
162 \r
163  * master pointer --> 0         master pointer --> 0\r
164 \r
165  *                    1                            1\r
166 \r
167  *                   ...                          ...\r
168 \r
169  *                   M-3                          M-3\r
170 \r
171  *                   M-2                           M\r
172 \r
173  *                   M-1                          M+1\r
174 \r
175  *                    M                           M-2\r
176 \r
177  *                   M+1                          M-1\r
178 \r
179  *                    0                            0\r
180 \r
181  * We read alternate iMCU rows using each master pointer; thus the last two\r
182 \r
183  * row groups of the previous iMCU row remain un-overwritten in the workspace.\r
184 \r
185  * The pointer lists are set up so that the required context rows appear to\r
186 \r
187  * be adjacent to the proper places when we pass the pointer lists to the\r
188 \r
189  * upsampler.\r
190 \r
191  *\r
192 \r
193  * The above pictures describe the normal state of the pointer lists.\r
194 \r
195  * At top and bottom of the image, we diddle the pointer lists to duplicate\r
196 \r
197  * the first or last sample row as necessary (this is cheaper than copying\r
198 \r
199  * sample rows around).\r
200 \r
201  *\r
202 \r
203  * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1.  In that\r
204 \r
205  * situation each iMCU row provides only one row group so the buffering logic\r
206 \r
207  * must be different (eg, we must read two iMCU rows before we can emit the\r
208 \r
209  * first row group).  For now, we simply do not support providing context\r
210 \r
211  * rows when min_DCT_scaled_size is 1.  That combination seems unlikely to\r
212 \r
213  * be worth providing --- if someone wants a 1/8th-size preview, they probably\r
214 \r
215  * want it quick and dirty, so a context-free upsampler is sufficient.\r
216 \r
217  */\r
218 \r
219 \r
220 \r
221 \r
222 \r
223 /* Private buffer controller object */\r
224 \r
225 \r
226 \r
227 typedef struct {\r
228 \r
229   struct jpeg_d_main_controller pub; /* public fields */\r
230 \r
231 \r
232 \r
233   /* Pointer to allocated workspace (M or M+2 row groups). */\r
234 \r
235   JSAMPARRAY buffer[MAX_COMPONENTS];\r
236 \r
237 \r
238 \r
239   boolean buffer_full;          /* Have we gotten an iMCU row from decoder? */\r
240 \r
241   JDIMENSION rowgroup_ctr;      /* counts row groups output to postprocessor */\r
242 \r
243 \r
244 \r
245   /* Remaining fields are only used in the context case. */\r
246 \r
247 \r
248 \r
249   /* These are the master pointers to the funny-order pointer lists. */\r
250 \r
251   JSAMPIMAGE xbuffer[2];        /* pointers to weird pointer lists */\r
252 \r
253 \r
254 \r
255   int whichptr;                 /* indicates which pointer set is now in use */\r
256 \r
257   int context_state;            /* process_data state machine status */\r
258 \r
259   JDIMENSION rowgroups_avail;   /* row groups available to postprocessor */\r
260 \r
261   JDIMENSION iMCU_row_ctr;      /* counts iMCU rows to detect image top/bot */\r
262 \r
263 } my_main_controller;\r
264 \r
265 \r
266 \r
267 typedef my_main_controller * my_main_ptr;\r
268 \r
269 \r
270 \r
271 /* context_state values: */\r
272 \r
273 #define CTX_PREPARE_FOR_IMCU    0       /* need to prepare for MCU row */\r
274 \r
275 #define CTX_PROCESS_IMCU        1       /* feeding iMCU to postprocessor */\r
276 \r
277 #define CTX_POSTPONED_ROW       2       /* feeding postponed row group */\r
278 \r
279 \r
280 \r
281 \r
282 \r
283 /* Forward declarations */\r
284 \r
285 METHODDEF void process_data_simple_main\r
286 \r
287         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,\r
288 \r
289              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));\r
290 \r
291 METHODDEF void process_data_context_main\r
292 \r
293         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,\r
294 \r
295              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));\r
296 \r
297 #ifdef QUANT_2PASS_SUPPORTED\r
298 \r
299 METHODDEF void process_data_crank_post\r
300 \r
301         JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,\r
302 \r
303              JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));\r
304 \r
305 #endif\r
306 \r
307 \r
308 \r
309 \r
310 \r
311 LOCAL void\r
312 \r
313 alloc_funny_pointers (j_decompress_ptr cinfo)\r
314 \r
315 /* Allocate space for the funny pointer lists.\r
316 \r
317  * This is done only once, not once per pass.\r
318 \r
319  */\r
320 \r
321 {\r
322 \r
323   my_main_ptr main = (my_main_ptr) cinfo->main;\r
324 \r
325   int ci, rgroup;\r
326 \r
327   int M = cinfo->min_DCT_scaled_size;\r
328 \r
329   jpeg_component_info *compptr;\r
330 \r
331   JSAMPARRAY xbuf;\r
332 \r
333 \r
334 \r
335   /* Get top-level space for component array pointers.\r
336 \r
337    * We alloc both arrays with one call to save a few cycles.\r
338 \r
339    */\r
340 \r
341   main->xbuffer[0] = (JSAMPIMAGE)\r
342 \r
343     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
344 \r
345                                 cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));\r
346 \r
347   main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components;\r
348 \r
349 \r
350 \r
351   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
352 \r
353        ci++, compptr++) {\r
354 \r
355     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /\r
356 \r
357       cinfo->min_DCT_scaled_size; /* height of a row group of component */\r
358 \r
359     /* Get space for pointer lists --- M+4 row groups in each list.\r
360 \r
361      * We alloc both pointer lists with one call to save a few cycles.\r
362 \r
363      */\r
364 \r
365     xbuf = (JSAMPARRAY)\r
366 \r
367       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
368 \r
369                                   2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));\r
370 \r
371     xbuf += rgroup;             /* want one row group at negative offsets */\r
372 \r
373     main->xbuffer[0][ci] = xbuf;\r
374 \r
375     xbuf += rgroup * (M + 4);\r
376 \r
377     main->xbuffer[1][ci] = xbuf;\r
378 \r
379   }\r
380 \r
381 }\r
382 \r
383 \r
384 \r
385 \r
386 \r
387 LOCAL void\r
388 \r
389 make_funny_pointers (j_decompress_ptr cinfo)\r
390 \r
391 /* Create the funny pointer lists discussed in the comments above.\r
392 \r
393  * The actual workspace is already allocated (in main->buffer),\r
394 \r
395  * and the space for the pointer lists is allocated too.\r
396 \r
397  * This routine just fills in the curiously ordered lists.\r
398 \r
399  * This will be repeated at the beginning of each pass.\r
400 \r
401  */\r
402 \r
403 {\r
404 \r
405   my_main_ptr main = (my_main_ptr) cinfo->main;\r
406 \r
407   int ci, i, rgroup;\r
408 \r
409   int M = cinfo->min_DCT_scaled_size;\r
410 \r
411   jpeg_component_info *compptr;\r
412 \r
413   JSAMPARRAY buf, xbuf0, xbuf1;\r
414 \r
415 \r
416 \r
417   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
418 \r
419        ci++, compptr++) {\r
420 \r
421     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /\r
422 \r
423       cinfo->min_DCT_scaled_size; /* height of a row group of component */\r
424 \r
425     xbuf0 = main->xbuffer[0][ci];\r
426 \r
427     xbuf1 = main->xbuffer[1][ci];\r
428 \r
429     /* First copy the workspace pointers as-is */\r
430 \r
431     buf = main->buffer[ci];\r
432 \r
433     for (i = 0; i < rgroup * (M + 2); i++) {\r
434 \r
435       xbuf0[i] = xbuf1[i] = buf[i];\r
436 \r
437     }\r
438 \r
439     /* In the second list, put the last four row groups in swapped order */\r
440 \r
441     for (i = 0; i < rgroup * 2; i++) {\r
442 \r
443       xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];\r
444 \r
445       xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];\r
446 \r
447     }\r
448 \r
449     /* The wraparound pointers at top and bottom will be filled later\r
450 \r
451      * (see set_wraparound_pointers, below).  Initially we want the "above"\r
452 \r
453      * pointers to duplicate the first actual data line.  This only needs\r
454 \r
455      * to happen in xbuffer[0].\r
456 \r
457      */\r
458 \r
459     for (i = 0; i < rgroup; i++) {\r
460 \r
461       xbuf0[i - rgroup] = xbuf0[0];\r
462 \r
463     }\r
464 \r
465   }\r
466 \r
467 }\r
468 \r
469 \r
470 \r
471 \r
472 \r
473 LOCAL void\r
474 \r
475 set_wraparound_pointers (j_decompress_ptr cinfo)\r
476 \r
477 /* Set up the "wraparound" pointers at top and bottom of the pointer lists.\r
478 \r
479  * This changes the pointer list state from top-of-image to the normal state.\r
480 \r
481  */\r
482 \r
483 {\r
484 \r
485   my_main_ptr main = (my_main_ptr) cinfo->main;\r
486 \r
487   int ci, i, rgroup;\r
488 \r
489   int M = cinfo->min_DCT_scaled_size;\r
490 \r
491   jpeg_component_info *compptr;\r
492 \r
493   JSAMPARRAY xbuf0, xbuf1;\r
494 \r
495 \r
496 \r
497   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
498 \r
499        ci++, compptr++) {\r
500 \r
501     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /\r
502 \r
503       cinfo->min_DCT_scaled_size; /* height of a row group of component */\r
504 \r
505     xbuf0 = main->xbuffer[0][ci];\r
506 \r
507     xbuf1 = main->xbuffer[1][ci];\r
508 \r
509     for (i = 0; i < rgroup; i++) {\r
510 \r
511       xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];\r
512 \r
513       xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];\r
514 \r
515       xbuf0[rgroup*(M+2) + i] = xbuf0[i];\r
516 \r
517       xbuf1[rgroup*(M+2) + i] = xbuf1[i];\r
518 \r
519     }\r
520 \r
521   }\r
522 \r
523 }\r
524 \r
525 \r
526 \r
527 \r
528 \r
529 LOCAL void\r
530 \r
531 set_bottom_pointers (j_decompress_ptr cinfo)\r
532 \r
533 /* Change the pointer lists to duplicate the last sample row at the bottom\r
534 \r
535  * of the image.  whichptr indicates which xbuffer holds the final iMCU row.\r
536 \r
537  * Also sets rowgroups_avail to indicate number of nondummy row groups in row.\r
538 \r
539  */\r
540 \r
541 {\r
542 \r
543   my_main_ptr main = (my_main_ptr) cinfo->main;\r
544 \r
545   int ci, i, rgroup, iMCUheight, rows_left;\r
546 \r
547   jpeg_component_info *compptr;\r
548 \r
549   JSAMPARRAY xbuf;\r
550 \r
551 \r
552 \r
553   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
554 \r
555        ci++, compptr++) {\r
556 \r
557     /* Count sample rows in one iMCU row and in one row group */\r
558 \r
559     iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;\r
560 \r
561     rgroup = iMCUheight / cinfo->min_DCT_scaled_size;\r
562 \r
563     /* Count nondummy sample rows remaining for this component */\r
564 \r
565     rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);\r
566 \r
567     if (rows_left == 0) rows_left = iMCUheight;\r
568 \r
569     /* Count nondummy row groups.  Should get same answer for each component,\r
570 \r
571      * so we need only do it once.\r
572 \r
573      */\r
574 \r
575     if (ci == 0) {\r
576 \r
577       main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);\r
578 \r
579     }\r
580 \r
581     /* Duplicate the last real sample row rgroup*2 times; this pads out the\r
582 \r
583      * last partial rowgroup and ensures at least one full rowgroup of context.\r
584 \r
585      */\r
586 \r
587     xbuf = main->xbuffer[main->whichptr][ci];\r
588 \r
589     for (i = 0; i < rgroup * 2; i++) {\r
590 \r
591       xbuf[rows_left + i] = xbuf[rows_left-1];\r
592 \r
593     }\r
594 \r
595   }\r
596 \r
597 }\r
598 \r
599 \r
600 \r
601 \r
602 \r
603 /*\r
604 \r
605  * Initialize for a processing pass.\r
606 \r
607  */\r
608 \r
609 \r
610 \r
611 METHODDEF void\r
612 \r
613 start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)\r
614 \r
615 {\r
616 \r
617   my_main_ptr main = (my_main_ptr) cinfo->main;\r
618 \r
619 \r
620 \r
621   switch (pass_mode) {\r
622 \r
623   case JBUF_PASS_THRU:\r
624 \r
625     if (cinfo->upsample->need_context_rows) {\r
626 \r
627       main->pub.process_data = process_data_context_main;\r
628 \r
629       make_funny_pointers(cinfo); /* Create the xbuffer[] lists */\r
630 \r
631       main->whichptr = 0;       /* Read first iMCU row into xbuffer[0] */\r
632 \r
633       main->context_state = CTX_PREPARE_FOR_IMCU;\r
634 \r
635       main->iMCU_row_ctr = 0;\r
636 \r
637     } else {\r
638 \r
639       /* Simple case with no context needed */\r
640 \r
641       main->pub.process_data = process_data_simple_main;\r
642 \r
643     }\r
644 \r
645     main->buffer_full = FALSE;  /* Mark buffer empty */\r
646 \r
647     main->rowgroup_ctr = 0;\r
648 \r
649     break;\r
650 \r
651 #ifdef QUANT_2PASS_SUPPORTED\r
652 \r
653   case JBUF_CRANK_DEST:\r
654 \r
655     /* For last pass of 2-pass quantization, just crank the postprocessor */\r
656 \r
657     main->pub.process_data = process_data_crank_post;\r
658 \r
659     break;\r
660 \r
661 #endif\r
662 \r
663   default:\r
664 \r
665     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);\r
666 \r
667     break;\r
668 \r
669   }\r
670 \r
671 }\r
672 \r
673 \r
674 \r
675 \r
676 \r
677 /*\r
678 \r
679  * Process some data.\r
680 \r
681  * This handles the simple case where no context is required.\r
682 \r
683  */\r
684 \r
685 \r
686 \r
687 METHODDEF void\r
688 \r
689 process_data_simple_main (j_decompress_ptr cinfo,\r
690 \r
691                           JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,\r
692 \r
693                           JDIMENSION out_rows_avail)\r
694 \r
695 {\r
696 \r
697   my_main_ptr main = (my_main_ptr) cinfo->main;\r
698 \r
699   JDIMENSION rowgroups_avail;\r
700 \r
701 \r
702 \r
703   /* Read input data if we haven't filled the main buffer yet */\r
704 \r
705   if (! main->buffer_full) {\r
706 \r
707     if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer))\r
708 \r
709       return;                   /* suspension forced, can do nothing more */\r
710 \r
711     main->buffer_full = TRUE;   /* OK, we have an iMCU row to work with */\r
712 \r
713   }\r
714 \r
715 \r
716 \r
717   /* There are always min_DCT_scaled_size row groups in an iMCU row. */\r
718 \r
719   rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;\r
720 \r
721   /* Note: at the bottom of the image, we may pass extra garbage row groups\r
722 \r
723    * to the postprocessor.  The postprocessor has to check for bottom\r
724 \r
725    * of image anyway (at row resolution), so no point in us doing it too.\r
726 \r
727    */\r
728 \r
729 \r
730 \r
731   /* Feed the postprocessor */\r
732 \r
733   (*cinfo->post->post_process_data) (cinfo, main->buffer,\r
734 \r
735                                      &main->rowgroup_ctr, rowgroups_avail,\r
736 \r
737                                      output_buf, out_row_ctr, out_rows_avail);\r
738 \r
739 \r
740 \r
741   /* Has postprocessor consumed all the data yet? If so, mark buffer empty */\r
742 \r
743   if (main->rowgroup_ctr >= rowgroups_avail) {\r
744 \r
745     main->buffer_full = FALSE;\r
746 \r
747     main->rowgroup_ctr = 0;\r
748 \r
749   }\r
750 \r
751 }\r
752 \r
753 \r
754 \r
755 \r
756 \r
757 /*\r
758 \r
759  * Process some data.\r
760 \r
761  * This handles the case where context rows must be provided.\r
762 \r
763  */\r
764 \r
765 \r
766 \r
767 METHODDEF void\r
768 \r
769 process_data_context_main (j_decompress_ptr cinfo,\r
770 \r
771                            JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,\r
772 \r
773                            JDIMENSION out_rows_avail)\r
774 \r
775 {\r
776 \r
777   my_main_ptr main = (my_main_ptr) cinfo->main;\r
778 \r
779 \r
780 \r
781   /* Read input data if we haven't filled the main buffer yet */\r
782 \r
783   if (! main->buffer_full) {\r
784 \r
785     if (! (*cinfo->coef->decompress_data) (cinfo,\r
786 \r
787                                            main->xbuffer[main->whichptr]))\r
788 \r
789       return;                   /* suspension forced, can do nothing more */\r
790 \r
791     main->buffer_full = TRUE;   /* OK, we have an iMCU row to work with */\r
792 \r
793     main->iMCU_row_ctr++;       /* count rows received */\r
794 \r
795   }\r
796 \r
797 \r
798 \r
799   /* Postprocessor typically will not swallow all the input data it is handed\r
800 \r
801    * in one call (due to filling the output buffer first).  Must be prepared\r
802 \r
803    * to exit and restart.  This switch lets us keep track of how far we got.\r
804 \r
805    * Note that each case falls through to the next on successful completion.\r
806 \r
807    */\r
808 \r
809   switch (main->context_state) {\r
810 \r
811   case CTX_POSTPONED_ROW:\r
812 \r
813     /* Call postprocessor using previously set pointers for postponed row */\r
814 \r
815     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],\r
816 \r
817                         &main->rowgroup_ctr, main->rowgroups_avail,\r
818 \r
819                         output_buf, out_row_ctr, out_rows_avail);\r
820 \r
821     if (main->rowgroup_ctr < main->rowgroups_avail)\r
822 \r
823       return;                   /* Need to suspend */\r
824 \r
825     main->context_state = CTX_PREPARE_FOR_IMCU;\r
826 \r
827     if (*out_row_ctr >= out_rows_avail)\r
828 \r
829       return;                   /* Postprocessor exactly filled output buf */\r
830 \r
831     /*FALLTHROUGH*/\r
832 \r
833   case CTX_PREPARE_FOR_IMCU:\r
834 \r
835     /* Prepare to process first M-1 row groups of this iMCU row */\r
836 \r
837     main->rowgroup_ctr = 0;\r
838 \r
839     main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);\r
840 \r
841     /* Check for bottom of image: if so, tweak pointers to "duplicate"\r
842 \r
843      * the last sample row, and adjust rowgroups_avail to ignore padding rows.\r
844 \r
845      */\r
846 \r
847     if (main->iMCU_row_ctr == cinfo->total_iMCU_rows)\r
848 \r
849       set_bottom_pointers(cinfo);\r
850 \r
851     main->context_state = CTX_PROCESS_IMCU;\r
852 \r
853     /*FALLTHROUGH*/\r
854 \r
855   case CTX_PROCESS_IMCU:\r
856 \r
857     /* Call postprocessor using previously set pointers */\r
858 \r
859     (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],\r
860 \r
861                         &main->rowgroup_ctr, main->rowgroups_avail,\r
862 \r
863                         output_buf, out_row_ctr, out_rows_avail);\r
864 \r
865     if (main->rowgroup_ctr < main->rowgroups_avail)\r
866 \r
867       return;                   /* Need to suspend */\r
868 \r
869     /* After the first iMCU, change wraparound pointers to normal state */\r
870 \r
871     if (main->iMCU_row_ctr == 1)\r
872 \r
873       set_wraparound_pointers(cinfo);\r
874 \r
875     /* Prepare to load new iMCU row using other xbuffer list */\r
876 \r
877     main->whichptr ^= 1;        /* 0=>1 or 1=>0 */\r
878 \r
879     main->buffer_full = FALSE;\r
880 \r
881     /* Still need to process last row group of this iMCU row, */\r
882 \r
883     /* which is saved at index M+1 of the other xbuffer */\r
884 \r
885     main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);\r
886 \r
887     main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);\r
888 \r
889     main->context_state = CTX_POSTPONED_ROW;\r
890 \r
891   }\r
892 \r
893 }\r
894 \r
895 \r
896 \r
897 \r
898 \r
899 /*\r
900 \r
901  * Process some data.\r
902 \r
903  * Final pass of two-pass quantization: just call the postprocessor.\r
904 \r
905  * Source data will be the postprocessor controller's internal buffer.\r
906 \r
907  */\r
908 \r
909 \r
910 \r
911 #ifdef QUANT_2PASS_SUPPORTED\r
912 \r
913 \r
914 \r
915 METHODDEF void\r
916 \r
917 process_data_crank_post (j_decompress_ptr cinfo,\r
918 \r
919                          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,\r
920 \r
921                          JDIMENSION out_rows_avail)\r
922 \r
923 {\r
924 \r
925   (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,\r
926 \r
927                                      (JDIMENSION *) NULL, (JDIMENSION) 0,\r
928 \r
929                                      output_buf, out_row_ctr, out_rows_avail);\r
930 \r
931 }\r
932 \r
933 \r
934 \r
935 #endif /* QUANT_2PASS_SUPPORTED */\r
936 \r
937 \r
938 \r
939 \r
940 \r
941 /*\r
942 \r
943  * Initialize main buffer controller.\r
944 \r
945  */\r
946 \r
947 \r
948 \r
949 GLOBAL void\r
950 \r
951 jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)\r
952 \r
953 {\r
954 \r
955   my_main_ptr main;\r
956 \r
957   int ci, rgroup, ngroups;\r
958 \r
959   jpeg_component_info *compptr;\r
960 \r
961 \r
962 \r
963   main = (my_main_ptr)\r
964 \r
965     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
966 \r
967                                 SIZEOF(my_main_controller));\r
968 \r
969   cinfo->main = (struct jpeg_d_main_controller *) main;\r
970 \r
971   main->pub.start_pass = start_pass_main;\r
972 \r
973 \r
974 \r
975   if (need_full_buffer)         /* shouldn't happen */\r
976 \r
977     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);\r
978 \r
979 \r
980 \r
981   /* Allocate the workspace.\r
982 \r
983    * ngroups is the number of row groups we need.\r
984 \r
985    */\r
986 \r
987   if (cinfo->upsample->need_context_rows) {\r
988 \r
989     if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */\r
990 \r
991       ERREXIT(cinfo, JERR_NOTIMPL);\r
992 \r
993     alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */\r
994 \r
995     ngroups = cinfo->min_DCT_scaled_size + 2;\r
996 \r
997   } else {\r
998 \r
999     ngroups = cinfo->min_DCT_scaled_size;\r
1000 \r
1001   }\r
1002 \r
1003 \r
1004 \r
1005   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
1006 \r
1007        ci++, compptr++) {\r
1008 \r
1009     rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /\r
1010 \r
1011       cinfo->min_DCT_scaled_size; /* height of a row group of component */\r
1012 \r
1013     main->buffer[ci] = (*cinfo->mem->alloc_sarray)\r
1014 \r
1015                         ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
1016 \r
1017                          compptr->width_in_blocks * compptr->DCT_scaled_size,\r
1018 \r
1019                          (JDIMENSION) (rgroup * ngroups));\r
1020 \r
1021   }\r
1022 \r
1023 }\r
1024 \r