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