]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/jpeg6/jdsample.cpp
some updates to the Linux build system - obtained a core binary and all required...
[xonotic/netradiant.git] / libs / jpeg6 / jdsample.cpp
1 /*\r
2 \r
3  * jdsample.c\r
4 \r
5  *\r
6 \r
7  * Copyright (C) 1991-1994, 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 upsampling routines.\r
16 \r
17  *\r
18 \r
19  * Upsampling input data is counted in "row groups".  A row group\r
20 \r
21  * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)\r
22 \r
23  * sample rows of each component.  Upsampling will normally produce\r
24 \r
25  * max_v_samp_factor pixel rows from each row group (but this could vary\r
26 \r
27  * if the upsampler is applying a scale factor of its own).\r
28 \r
29  *\r
30 \r
31  * An excellent reference for image resampling is\r
32 \r
33  *   Digital Image Warping, George Wolberg, 1990.\r
34 \r
35  *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.\r
36 \r
37  */\r
38 \r
39 \r
40 \r
41 #define JPEG_INTERNALS\r
42 \r
43 #include "jinclude.h"\r
44 \r
45 #include "radiant_jpeglib.h"\r
46 \r
47 \r
48 \r
49 \r
50 \r
51 /* Pointer to routine to upsample a single component */\r
52 \r
53 typedef JMETHOD(void, upsample1_ptr,\r
54 \r
55                 (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
56 \r
57                  JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));\r
58 \r
59 \r
60 \r
61 /* Private subobject */\r
62 \r
63 \r
64 \r
65 typedef struct {\r
66 \r
67   struct jpeg_upsampler pub;    /* public fields */\r
68 \r
69 \r
70 \r
71   /* Color conversion buffer.  When using separate upsampling and color\r
72 \r
73    * conversion steps, this buffer holds one upsampled row group until it\r
74 \r
75    * has been color converted and output.\r
76 \r
77    * Note: we do not allocate any storage for component(s) which are full-size,\r
78 \r
79    * ie do not need rescaling.  The corresponding entry of color_buf[] is\r
80 \r
81    * simply set to point to the input data array, thereby avoiding copying.\r
82 \r
83    */\r
84 \r
85   JSAMPARRAY color_buf[MAX_COMPONENTS];\r
86 \r
87 \r
88 \r
89   /* Per-component upsampling method pointers */\r
90 \r
91   upsample1_ptr methods[MAX_COMPONENTS];\r
92 \r
93 \r
94 \r
95   int next_row_out;             /* counts rows emitted from color_buf */\r
96 \r
97   JDIMENSION rows_to_go;        /* counts rows remaining in image */\r
98 \r
99 \r
100 \r
101   /* Height of an input row group for each component. */\r
102 \r
103   int rowgroup_height[MAX_COMPONENTS];\r
104 \r
105 \r
106 \r
107   /* These arrays save pixel expansion factors so that int_expand need not\r
108 \r
109    * recompute them each time.  They are unused for other upsampling methods.\r
110 \r
111    */\r
112 \r
113   UINT8 h_expand[MAX_COMPONENTS];\r
114 \r
115   UINT8 v_expand[MAX_COMPONENTS];\r
116 \r
117 } my_upsampler;\r
118 \r
119 \r
120 \r
121 typedef my_upsampler * my_upsample_ptr;\r
122 \r
123 \r
124 \r
125 \r
126 \r
127 /*\r
128 \r
129  * Initialize for an upsampling pass.\r
130 \r
131  */\r
132 \r
133 \r
134 \r
135 METHODDEF void\r
136 \r
137 start_pass_upsample (j_decompress_ptr cinfo)\r
138 \r
139 {\r
140 \r
141   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;\r
142 \r
143 \r
144 \r
145   /* Mark the conversion buffer empty */\r
146 \r
147   upsample->next_row_out = cinfo->max_v_samp_factor;\r
148 \r
149   /* Initialize total-height counter for detecting bottom of image */\r
150 \r
151   upsample->rows_to_go = cinfo->output_height;\r
152 \r
153 }\r
154 \r
155 \r
156 \r
157 \r
158 \r
159 /*\r
160 \r
161  * Control routine to do upsampling (and color conversion).\r
162 \r
163  *\r
164 \r
165  * In this version we upsample each component independently.\r
166 \r
167  * We upsample one row group into the conversion buffer, then apply\r
168 \r
169  * color conversion a row at a time.\r
170 \r
171  */\r
172 \r
173 \r
174 \r
175 METHODDEF void\r
176 \r
177 sep_upsample (j_decompress_ptr cinfo,\r
178 \r
179               JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,\r
180 \r
181               JDIMENSION in_row_groups_avail,\r
182 \r
183               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,\r
184 \r
185               JDIMENSION out_rows_avail)\r
186 \r
187 {\r
188 \r
189   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;\r
190 \r
191   int ci;\r
192 \r
193   jpeg_component_info * compptr;\r
194 \r
195   JDIMENSION num_rows;\r
196 \r
197 \r
198 \r
199   /* Fill the conversion buffer, if it's empty */\r
200 \r
201   if (upsample->next_row_out >= cinfo->max_v_samp_factor) {\r
202 \r
203     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
204 \r
205          ci++, compptr++) {\r
206 \r
207       /* Invoke per-component upsample method.  Notice we pass a POINTER\r
208 \r
209        * to color_buf[ci], so that fullsize_upsample can change it.\r
210 \r
211        */\r
212 \r
213       (*upsample->methods[ci]) (cinfo, compptr,\r
214 \r
215         input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),\r
216 \r
217         upsample->color_buf + ci);\r
218 \r
219     }\r
220 \r
221     upsample->next_row_out = 0;\r
222 \r
223   }\r
224 \r
225 \r
226 \r
227   /* Color-convert and emit rows */\r
228 \r
229 \r
230 \r
231   /* How many we have in the buffer: */\r
232 \r
233   num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);\r
234 \r
235   /* Not more than the distance to the end of the image.  Need this test\r
236 \r
237    * in case the image height is not a multiple of max_v_samp_factor:\r
238 \r
239    */\r
240 \r
241   if (num_rows > upsample->rows_to_go) \r
242 \r
243     num_rows = upsample->rows_to_go;\r
244 \r
245   /* And not more than what the client can accept: */\r
246 \r
247   out_rows_avail -= *out_row_ctr;\r
248 \r
249   if (num_rows > out_rows_avail)\r
250 \r
251     num_rows = out_rows_avail;\r
252 \r
253 \r
254 \r
255   (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,\r
256 \r
257                                      (JDIMENSION) upsample->next_row_out,\r
258 \r
259                                      output_buf + *out_row_ctr,\r
260 \r
261                                      (int) num_rows);\r
262 \r
263 \r
264 \r
265   /* Adjust counts */\r
266 \r
267   *out_row_ctr += num_rows;\r
268 \r
269   upsample->rows_to_go -= num_rows;\r
270 \r
271   upsample->next_row_out += num_rows;\r
272 \r
273   /* When the buffer is emptied, declare this input row group consumed */\r
274 \r
275   if (upsample->next_row_out >= cinfo->max_v_samp_factor)\r
276 \r
277     (*in_row_group_ctr)++;\r
278 \r
279 }\r
280 \r
281 \r
282 \r
283 \r
284 \r
285 /*\r
286 \r
287  * These are the routines invoked by sep_upsample to upsample pixel values\r
288 \r
289  * of a single component.  One row group is processed per call.\r
290 \r
291  */\r
292 \r
293 \r
294 \r
295 \r
296 \r
297 /*\r
298 \r
299  * For full-size components, we just make color_buf[ci] point at the\r
300 \r
301  * input buffer, and thus avoid copying any data.  Note that this is\r
302 \r
303  * safe only because sep_upsample doesn't declare the input row group\r
304 \r
305  * "consumed" until we are done color converting and emitting it.\r
306 \r
307  */\r
308 \r
309 \r
310 \r
311 METHODDEF void\r
312 \r
313 fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
314 \r
315                    JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
316 \r
317 {\r
318 \r
319   *output_data_ptr = input_data;\r
320 \r
321 }\r
322 \r
323 \r
324 \r
325 \r
326 \r
327 /*\r
328 \r
329  * This is a no-op version used for "uninteresting" components.\r
330 \r
331  * These components will not be referenced by color conversion.\r
332 \r
333  */\r
334 \r
335 \r
336 \r
337 METHODDEF void\r
338 \r
339 noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
340 \r
341                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
342 \r
343 {\r
344 \r
345   *output_data_ptr = NULL;      /* safety check */\r
346 \r
347 }\r
348 \r
349 \r
350 \r
351 \r
352 \r
353 /*\r
354 \r
355  * This version handles any integral sampling ratios.\r
356 \r
357  * This is not used for typical JPEG files, so it need not be fast.\r
358 \r
359  * Nor, for that matter, is it particularly accurate: the algorithm is\r
360 \r
361  * simple replication of the input pixel onto the corresponding output\r
362 \r
363  * pixels.  The hi-falutin sampling literature refers to this as a\r
364 \r
365  * "box filter".  A box filter tends to introduce visible artifacts,\r
366 \r
367  * so if you are actually going to use 3:1 or 4:1 sampling ratios\r
368 \r
369  * you would be well advised to improve this code.\r
370 \r
371  */\r
372 \r
373 \r
374 \r
375 METHODDEF void\r
376 \r
377 int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
378 \r
379               JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
380 \r
381 {\r
382 \r
383   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;\r
384 \r
385   JSAMPARRAY output_data = *output_data_ptr;\r
386 \r
387   register JSAMPROW inptr, outptr;\r
388 \r
389   register JSAMPLE invalue;\r
390 \r
391   register int h;\r
392 \r
393   JSAMPROW outend;\r
394 \r
395   int h_expand, v_expand;\r
396 \r
397   int inrow, outrow;\r
398 \r
399 \r
400 \r
401   h_expand = upsample->h_expand[compptr->component_index];\r
402 \r
403   v_expand = upsample->v_expand[compptr->component_index];\r
404 \r
405 \r
406 \r
407   inrow = outrow = 0;\r
408 \r
409   while (outrow < cinfo->max_v_samp_factor) {\r
410 \r
411     /* Generate one output row with proper horizontal expansion */\r
412 \r
413     inptr = input_data[inrow];\r
414 \r
415     outptr = output_data[outrow];\r
416 \r
417     outend = outptr + cinfo->output_width;\r
418 \r
419     while (outptr < outend) {\r
420 \r
421       invalue = *inptr++;       /* don't need GETJSAMPLE() here */\r
422 \r
423       for (h = h_expand; h > 0; h--) {\r
424 \r
425         *outptr++ = invalue;\r
426 \r
427       }\r
428 \r
429     }\r
430 \r
431     /* Generate any additional output rows by duplicating the first one */\r
432 \r
433     if (v_expand > 1) {\r
434 \r
435       jcopy_sample_rows(output_data, outrow, output_data, outrow+1,\r
436 \r
437                         v_expand-1, cinfo->output_width);\r
438 \r
439     }\r
440 \r
441     inrow++;\r
442 \r
443     outrow += v_expand;\r
444 \r
445   }\r
446 \r
447 }\r
448 \r
449 \r
450 \r
451 \r
452 \r
453 /*\r
454 \r
455  * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.\r
456 \r
457  * It's still a box filter.\r
458 \r
459  */\r
460 \r
461 \r
462 \r
463 METHODDEF void\r
464 \r
465 h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
466 \r
467                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
468 \r
469 {\r
470 \r
471   JSAMPARRAY output_data = *output_data_ptr;\r
472 \r
473   register JSAMPROW inptr, outptr;\r
474 \r
475   register JSAMPLE invalue;\r
476 \r
477   JSAMPROW outend;\r
478 \r
479   int inrow;\r
480 \r
481 \r
482 \r
483   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {\r
484 \r
485     inptr = input_data[inrow];\r
486 \r
487     outptr = output_data[inrow];\r
488 \r
489     outend = outptr + cinfo->output_width;\r
490 \r
491     while (outptr < outend) {\r
492 \r
493       invalue = *inptr++;       /* don't need GETJSAMPLE() here */\r
494 \r
495       *outptr++ = invalue;\r
496 \r
497       *outptr++ = invalue;\r
498 \r
499     }\r
500 \r
501   }\r
502 \r
503 }\r
504 \r
505 \r
506 \r
507 \r
508 \r
509 /*\r
510 \r
511  * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.\r
512 \r
513  * It's still a box filter.\r
514 \r
515  */\r
516 \r
517 \r
518 \r
519 METHODDEF void\r
520 \r
521 h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
522 \r
523                JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
524 \r
525 {\r
526 \r
527   JSAMPARRAY output_data = *output_data_ptr;\r
528 \r
529   register JSAMPROW inptr, outptr;\r
530 \r
531   register JSAMPLE invalue;\r
532 \r
533   JSAMPROW outend;\r
534 \r
535   int inrow, outrow;\r
536 \r
537 \r
538 \r
539   inrow = outrow = 0;\r
540 \r
541   while (outrow < cinfo->max_v_samp_factor) {\r
542 \r
543     inptr = input_data[inrow];\r
544 \r
545     outptr = output_data[outrow];\r
546 \r
547     outend = outptr + cinfo->output_width;\r
548 \r
549     while (outptr < outend) {\r
550 \r
551       invalue = *inptr++;       /* don't need GETJSAMPLE() here */\r
552 \r
553       *outptr++ = invalue;\r
554 \r
555       *outptr++ = invalue;\r
556 \r
557     }\r
558 \r
559     jcopy_sample_rows(output_data, outrow, output_data, outrow+1,\r
560 \r
561                       1, cinfo->output_width);\r
562 \r
563     inrow++;\r
564 \r
565     outrow += 2;\r
566 \r
567   }\r
568 \r
569 }\r
570 \r
571 \r
572 \r
573 \r
574 \r
575 /*\r
576 \r
577  * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.\r
578 \r
579  *\r
580 \r
581  * The upsampling algorithm is linear interpolation between pixel centers,\r
582 \r
583  * also known as a "triangle filter".  This is a good compromise between\r
584 \r
585  * speed and visual quality.  The centers of the output pixels are 1/4 and 3/4\r
586 \r
587  * of the way between input pixel centers.\r
588 \r
589  *\r
590 \r
591  * A note about the "bias" calculations: when rounding fractional values to\r
592 \r
593  * integer, we do not want to always round 0.5 up to the next integer.\r
594 \r
595  * If we did that, we'd introduce a noticeable bias towards larger values.\r
596 \r
597  * Instead, this code is arranged so that 0.5 will be rounded up or down at\r
598 \r
599  * alternate pixel locations (a simple ordered dither pattern).\r
600 \r
601  */\r
602 \r
603 \r
604 \r
605 METHODDEF void\r
606 \r
607 h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
608 \r
609                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
610 \r
611 {\r
612 \r
613   JSAMPARRAY output_data = *output_data_ptr;\r
614 \r
615   register JSAMPROW inptr, outptr;\r
616 \r
617   register int invalue;\r
618 \r
619   register JDIMENSION colctr;\r
620 \r
621   int inrow;\r
622 \r
623 \r
624 \r
625   for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {\r
626 \r
627     inptr = input_data[inrow];\r
628 \r
629     outptr = output_data[inrow];\r
630 \r
631     /* Special case for first column */\r
632 \r
633     invalue = GETJSAMPLE(*inptr++);\r
634 \r
635     *outptr++ = (JSAMPLE) invalue;\r
636 \r
637     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);\r
638 \r
639 \r
640 \r
641     for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {\r
642 \r
643       /* General case: 3/4 * nearer pixel + 1/4 * further pixel */\r
644 \r
645       invalue = GETJSAMPLE(*inptr++) * 3;\r
646 \r
647       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);\r
648 \r
649       *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);\r
650 \r
651     }\r
652 \r
653 \r
654 \r
655     /* Special case for last column */\r
656 \r
657     invalue = GETJSAMPLE(*inptr);\r
658 \r
659     *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);\r
660 \r
661     *outptr++ = (JSAMPLE) invalue;\r
662 \r
663   }\r
664 \r
665 }\r
666 \r
667 \r
668 \r
669 \r
670 \r
671 /*\r
672 \r
673  * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.\r
674 \r
675  * Again a triangle filter; see comments for h2v1 case, above.\r
676 \r
677  *\r
678 \r
679  * It is OK for us to reference the adjacent input rows because we demanded\r
680 \r
681  * context from the main buffer controller (see initialization code).\r
682 \r
683  */\r
684 \r
685 \r
686 \r
687 METHODDEF void\r
688 \r
689 h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,\r
690 \r
691                      JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)\r
692 \r
693 {\r
694 \r
695   JSAMPARRAY output_data = *output_data_ptr;\r
696 \r
697   register JSAMPROW inptr0, inptr1, outptr;\r
698 \r
699 #if BITS_IN_JSAMPLE == 8\r
700 \r
701   register int thiscolsum, lastcolsum, nextcolsum;\r
702 \r
703 #else\r
704 \r
705   register INT32 thiscolsum, lastcolsum, nextcolsum;\r
706 \r
707 #endif\r
708 \r
709   register JDIMENSION colctr;\r
710 \r
711   int inrow, outrow, v;\r
712 \r
713 \r
714 \r
715   inrow = outrow = 0;\r
716 \r
717   while (outrow < cinfo->max_v_samp_factor) {\r
718 \r
719     for (v = 0; v < 2; v++) {\r
720 \r
721       /* inptr0 points to nearest input row, inptr1 points to next nearest */\r
722 \r
723       inptr0 = input_data[inrow];\r
724 \r
725       if (v == 0)               /* next nearest is row above */\r
726 \r
727         inptr1 = input_data[inrow-1];\r
728 \r
729       else                      /* next nearest is row below */\r
730 \r
731         inptr1 = input_data[inrow+1];\r
732 \r
733       outptr = output_data[outrow++];\r
734 \r
735 \r
736 \r
737       /* Special case for first column */\r
738 \r
739       thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);\r
740 \r
741       nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);\r
742 \r
743       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);\r
744 \r
745       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);\r
746 \r
747       lastcolsum = thiscolsum; thiscolsum = nextcolsum;\r
748 \r
749 \r
750 \r
751       for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {\r
752 \r
753         /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */\r
754 \r
755         /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */\r
756 \r
757         nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);\r
758 \r
759         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);\r
760 \r
761         *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);\r
762 \r
763         lastcolsum = thiscolsum; thiscolsum = nextcolsum;\r
764 \r
765       }\r
766 \r
767 \r
768 \r
769       /* Special case for last column */\r
770 \r
771       *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);\r
772 \r
773       *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);\r
774 \r
775     }\r
776 \r
777     inrow++;\r
778 \r
779   }\r
780 \r
781 }\r
782 \r
783 \r
784 \r
785 \r
786 \r
787 /*\r
788 \r
789  * Module initialization routine for upsampling.\r
790 \r
791  */\r
792 \r
793 \r
794 \r
795 GLOBAL void\r
796 \r
797 jinit_upsampler (j_decompress_ptr cinfo)\r
798 \r
799 {\r
800 \r
801   my_upsample_ptr upsample;\r
802 \r
803   int ci;\r
804 \r
805   jpeg_component_info * compptr;\r
806 \r
807   boolean need_buffer, do_fancy;\r
808 \r
809   int h_in_group, v_in_group, h_out_group, v_out_group;\r
810 \r
811 \r
812 \r
813   upsample = (my_upsample_ptr)\r
814 \r
815     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
816 \r
817                                 SIZEOF(my_upsampler));\r
818 \r
819   cinfo->upsample = (struct jpeg_upsampler *) upsample;\r
820 \r
821   upsample->pub.start_pass = start_pass_upsample;\r
822 \r
823   upsample->pub.upsample = sep_upsample;\r
824 \r
825   upsample->pub.need_context_rows = FALSE; /* until we find out differently */\r
826 \r
827 \r
828 \r
829   if (cinfo->CCIR601_sampling)  /* this isn't supported */\r
830 \r
831     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);\r
832 \r
833 \r
834 \r
835   /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,\r
836 \r
837    * so don't ask for it.\r
838 \r
839    */\r
840 \r
841   do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;\r
842 \r
843 \r
844 \r
845   /* Verify we can handle the sampling factors, select per-component methods,\r
846 \r
847    * and create storage as needed.\r
848 \r
849    */\r
850 \r
851   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;\r
852 \r
853        ci++, compptr++) {\r
854 \r
855     /* Compute size of an "input group" after IDCT scaling.  This many samples\r
856 \r
857      * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.\r
858 \r
859      */\r
860 \r
861     h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /\r
862 \r
863                  cinfo->min_DCT_scaled_size;\r
864 \r
865     v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /\r
866 \r
867                  cinfo->min_DCT_scaled_size;\r
868 \r
869     h_out_group = cinfo->max_h_samp_factor;\r
870 \r
871     v_out_group = cinfo->max_v_samp_factor;\r
872 \r
873     upsample->rowgroup_height[ci] = v_in_group; /* save for use later */\r
874 \r
875     need_buffer = TRUE;\r
876 \r
877     if (! compptr->component_needed) {\r
878 \r
879       /* Don't bother to upsample an uninteresting component. */\r
880 \r
881       upsample->methods[ci] = noop_upsample;\r
882 \r
883       need_buffer = FALSE;\r
884 \r
885     } else if (h_in_group == h_out_group && v_in_group == v_out_group) {\r
886 \r
887       /* Fullsize components can be processed without any work. */\r
888 \r
889       upsample->methods[ci] = fullsize_upsample;\r
890 \r
891       need_buffer = FALSE;\r
892 \r
893     } else if (h_in_group * 2 == h_out_group &&\r
894 \r
895                v_in_group == v_out_group) {\r
896 \r
897       /* Special cases for 2h1v upsampling */\r
898 \r
899       if (do_fancy && compptr->downsampled_width > 2)\r
900 \r
901         upsample->methods[ci] = h2v1_fancy_upsample;\r
902 \r
903       else\r
904 \r
905         upsample->methods[ci] = h2v1_upsample;\r
906 \r
907     } else if (h_in_group * 2 == h_out_group &&\r
908 \r
909                v_in_group * 2 == v_out_group) {\r
910 \r
911       /* Special cases for 2h2v upsampling */\r
912 \r
913       if (do_fancy && compptr->downsampled_width > 2) {\r
914 \r
915         upsample->methods[ci] = h2v2_fancy_upsample;\r
916 \r
917         upsample->pub.need_context_rows = TRUE;\r
918 \r
919       } else\r
920 \r
921         upsample->methods[ci] = h2v2_upsample;\r
922 \r
923     } else if ((h_out_group % h_in_group) == 0 &&\r
924 \r
925                (v_out_group % v_in_group) == 0) {\r
926 \r
927       /* Generic integral-factors upsampling method */\r
928 \r
929       upsample->methods[ci] = int_upsample;\r
930 \r
931       upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);\r
932 \r
933       upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);\r
934 \r
935     } else\r
936 \r
937       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);\r
938 \r
939     if (need_buffer) {\r
940 \r
941       upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)\r
942 \r
943         ((j_common_ptr) cinfo, JPOOL_IMAGE,\r
944 \r
945          (JDIMENSION) jround_up((long) cinfo->output_width,\r
946 \r
947                                 (long) cinfo->max_h_samp_factor),\r
948 \r
949          (JDIMENSION) cinfo->max_v_samp_factor);\r
950 \r
951     }\r
952 \r
953   }\r
954 \r
955 }\r
956 \r