]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/spatscal.c
ENH: Start working again on the MPEG2 stuff. Gather the stdio mess in a single place
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / spatscal.c
1 /* spatscal.c, ????                                                         */
2
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29
30 #include <string.h> /* for strcat */
31 #include "config.h"
32 #include "global.h"
33
34 /* private prototypes */
35 static void Read_Lower_Layer_Component_Framewise _ANSI_ARGS_((int comp, int lw, int lh));
36 static void Read_Lower_Layer_Component_Fieldwise _ANSI_ARGS_((int comp, int lw, int lh));
37 static void Make_Spatial_Prediction_Frame _ANSI_ARGS_((int progressive_frame,
38   int llprogressive_frame, unsigned char *fld0, unsigned char *fld1, 
39   short *tmp, unsigned char *dst, int llx0, int lly0, int llw, int llh, 
40   int horizontal_size, int vertical_size, int vm, int vn, int hm, int hn, 
41   int aperture));
42 static void Deinterlace _ANSI_ARGS_((unsigned char *fld0, unsigned char *fld1,
43   int j0, int lx, int ly, int aperture));
44 static void Subsample_Vertical _ANSI_ARGS_((unsigned char *s, short *d,
45   int lx, int lys, int lyd, int m, int n, int j0, int dj));
46 static void Subsample_Horizontal _ANSI_ARGS_((short *s, unsigned char *d,
47   int x0, int lx, int lxs, int lxd, int ly, int m, int n));
48
49
50
51 /* get reference frame */
52 void Spatial_Prediction()
53 {
54   
55   if(Frame_Store_Flag)
56   {
57     Read_Lower_Layer_Component_Framewise(0,lower_layer_prediction_horizontal_size, 
58       lower_layer_prediction_vertical_size);      /* Y */
59     Read_Lower_Layer_Component_Framewise(1,lower_layer_prediction_horizontal_size>>1,
60       lower_layer_prediction_vertical_size>>1);   /* Cb ("U") */
61     Read_Lower_Layer_Component_Framewise(2,lower_layer_prediction_horizontal_size>>1,
62       lower_layer_prediction_vertical_size>>1);   /* Cr ("V") */
63   }
64   else
65   {
66     Read_Lower_Layer_Component_Fieldwise(0,lower_layer_prediction_horizontal_size, 
67       lower_layer_prediction_vertical_size);      /* Y */
68     Read_Lower_Layer_Component_Fieldwise(1,lower_layer_prediction_horizontal_size>>1,
69       lower_layer_prediction_vertical_size>>1);   /* Cb ("U") */
70     Read_Lower_Layer_Component_Fieldwise(2,lower_layer_prediction_horizontal_size>>1,
71       lower_layer_prediction_vertical_size>>1);   /* Cr ("V") */
72   }
73
74
75   Make_Spatial_Prediction_Frame  /* Y */
76     (progressive_frame,lower_layer_progressive_frame,llframe0[0],llframe1[0],
77      lltmp,current_frame[0],lower_layer_horizontal_offset,
78      lower_layer_vertical_offset,
79      lower_layer_prediction_horizontal_size,
80      lower_layer_prediction_vertical_size,
81      horizontal_size,vertical_size,vertical_subsampling_factor_m,
82      vertical_subsampling_factor_n,horizontal_subsampling_factor_m,
83      horizontal_subsampling_factor_n,
84      picture_structure!=FRAME_PICTURE); /* this changed from CD to DIS */
85
86   Make_Spatial_Prediction_Frame  /* Cb */
87     (progressive_frame,lower_layer_progressive_frame,llframe0[1],llframe1[1],
88      lltmp,current_frame[1],lower_layer_horizontal_offset/2,
89      lower_layer_vertical_offset/2,
90      lower_layer_prediction_horizontal_size>>1,
91      lower_layer_prediction_vertical_size>>1,
92      horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m,
93      vertical_subsampling_factor_n,horizontal_subsampling_factor_m,
94      horizontal_subsampling_factor_n,1);
95
96   Make_Spatial_Prediction_Frame  /* Cr */
97     (progressive_frame,lower_layer_progressive_frame,llframe0[2],llframe1[2],
98      lltmp,current_frame[2],lower_layer_horizontal_offset/2,
99      lower_layer_vertical_offset/2,
100      lower_layer_prediction_horizontal_size>>1,
101      lower_layer_prediction_vertical_size>>1,
102      horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m,
103      vertical_subsampling_factor_n,horizontal_subsampling_factor_m,
104      horizontal_subsampling_factor_n,1);
105
106 }
107
108 static void Read_Lower_Layer_Component_Framewise(comp,lw,lh)
109      int comp;
110      int lw, lh;
111 {
112   FILE *fd;
113   char fname[256];
114   char ext[3][3] = {".Y",".U",".V"}; 
115 /*  char *ext = {".Y",".U",".V"}; */
116   int i,j;
117
118   sprintf(fname,Lower_Layer_Picture_Filename,True_Framenum);
119   strcat(fname,ext[comp]);
120 #ifdef VERBOSE
121   if (Verbose_Flag>1)
122     printf("reading %s\n",fname);
123 #endif /* VERBOSE */
124   fd=fopen(fname,"rb");
125   if (fd==NULL) my_exit(-1);
126   for (j=0; j<lh; j++) {
127      for (i=0; i<lw; i++)
128        llframe0[comp][lw*j+i]=getc(fd);
129      if (! lower_layer_progressive_frame) {
130        j++;
131        for (i=0; i<lw; i++)
132          llframe1[comp][lw*j+i]=getc(fd);
133      }
134   }
135   fclose(fd);
136 }
137
138
139 static void Read_Lower_Layer_Component_Fieldwise(comp,lw,lh)
140      int comp;
141      int lw, lh;
142 {
143   FILE *fd;
144   char fname[256];
145   char ext[3][3] = {".Y",".U",".V"}; 
146 /*  char *ext = {".Y",".U",".V"}; */
147   int i,j;
148
149   sprintf(fname,Lower_Layer_Picture_Filename,True_Framenum,lower_layer_progressive_frame ? 'f':'a');
150   strcat(fname,ext[comp]);
151 #ifdef VERBOSE
152   if (Verbose_Flag>1)
153     printf("reading %s\n",fname);
154 #endif /* VERBOSE */
155   fd=fopen(fname,"rb");
156   if (fd==NULL) my_exit(-1);
157   for (j=0; j<lh; j+=lower_layer_progressive_frame?1:2)
158     for (i=0; i<lw; i++)
159       llframe0[comp][lw*j+i]=getc(fd);
160   fclose(fd);
161
162   if (! lower_layer_progressive_frame) {
163     sprintf(fname,Lower_Layer_Picture_Filename,True_Framenum,'b');
164     strcat(fname,ext[comp]);
165 #ifdef VERBOSE
166     if (Verbose_Flag>1)
167       printf("reading %s\n",fname);
168 #endif /* VERBOSE */
169     fd=fopen(fname,"rb");
170     if (fd==NULL) my_exit(-1);
171     for (j=1; j<lh; j+=2)
172       for (i=0; i<lw; i++)
173         llframe1[comp][lw*j+i]=getc(fd);
174     fclose(fd);
175   }
176 }
177
178
179 /* form spatial prediction */
180 static void Make_Spatial_Prediction_Frame(progressive_frame,
181   llprogressive_frame,fld0,fld1,tmp,dst,llx0,lly0,llw,llh,horizontal_size,
182   vertical_size,vm,vn,hm,hn,aperture)
183 int progressive_frame,llprogressive_frame;
184 unsigned char *fld0,*fld1;
185 short *tmp;
186 unsigned char *dst;
187 int llx0,lly0,llw,llh,horizontal_size,vertical_size,vm,vn,hm,hn,aperture;
188 {
189   int w, h, x0, llw2, llh2;
190
191   llw2 = (llw*hn)/hm;
192   llh2 = (llh*vn)/vm;
193
194   if (llprogressive_frame)
195   {
196     /* progressive -> progressive / interlaced */
197     Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1);
198   }
199   else if (progressive_frame)
200   {
201     /* interlaced -> progressive */
202     if (lower_layer_deinterlaced_field_select)
203     {
204       Deinterlace(fld1,fld0,0,llw,llh,aperture);
205       Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,0,1);
206     }
207     else
208     {
209       Deinterlace(fld0,fld1,1,llw,llh,aperture);
210       Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1);
211     }
212   }
213   else
214   {
215     /* interlaced -> interlaced */
216     Deinterlace(fld0,fld1,1,llw,llh,aperture);
217     Deinterlace(fld1,fld0,0,llw,llh,aperture);
218     Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,2);
219     Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,1,2);
220   }
221
222     /* vertical limits */
223     if (lly0<0)
224     {
225       tmp-= llw*lly0;
226       llh2+= lly0;
227       if (llh2<0)
228         llh2 = 0;
229       h = (vertical_size<llh2) ? vertical_size : llh2;
230     }
231     else
232     {
233       dst+= horizontal_size*lly0;
234       h= vertical_size - lly0;
235       if (h>llh2)
236         h = llh2;
237     }
238
239     /* horizontal limits */
240     if (llx0<0)
241     {
242       x0 = -llx0;
243       llw2+= llx0;
244       if (llw2<0)
245         llw2 = 0;
246       w = (horizontal_size<llw2) ? horizontal_size : llw2;
247     }
248     else
249     {
250       dst+= llx0;
251       x0 = 0;
252       w = horizontal_size - llx0;
253       if (w>llw2)
254         w = llw2;
255     }
256   
257   Subsample_Horizontal(tmp,dst,x0,w,llw,horizontal_size,h,hm,hn);
258 }
259
260 /* deinterlace one field (interpolate opposite parity samples)
261  *
262  * deinterlacing is done in-place: if j0=1, fld0 contains the input field in
263  * its even lines and the odd lines are interpolated by this routine
264  * if j0=0, the input field is in the odd lines and the even lines are
265  * interpolated
266  *
267  * fld0: field to be deinterlaced
268  * fld1: other field (referenced by the two field aperture filter)
269  * j0:   0: interpolate even (top) lines, 1: interpolate odd (bottom) lines
270  * lx:   width of fld0 and fld1
271  * ly:   height of the deinterlaced field (has to be even)
272  * aperture: 1: use one field aperture filter (two field otherwise)
273  */
274 static void Deinterlace(fld0,fld1,j0,lx,ly,aperture)
275 unsigned char *fld0,*fld1;
276 int j0,lx,ly; /* ly has to be even */
277 int aperture;
278 {
279   int i,j,v;
280   unsigned char *p0, *p0m1, *p0p1, *p1, *p1m2, *p1p2;
281
282   /* deinterlace one field */
283   for (j=j0; j<ly; j+=2)
284   {
285     p0 = fld0+lx*j;
286     p0m1 = (j==0)    ? p0+lx : p0-lx;
287     p0p1 = (j==ly-1) ? p0-lx : p0+lx;
288
289     if (aperture)
290       for (i=0; i<lx; i++)
291         p0[i] = (unsigned int)(p0m1[i] + p0p1[i] + 1)>>1;
292     else
293     {
294       p1 = fld1 + lx*j;
295       p1m2 = (j<2)     ? p1 : p1-2*lx;
296       p1p2 = (j>=ly-2) ? p1 : p1+2*lx;
297       for (i=0; i<lx; i++)
298       {
299         v = 8*(p0m1[i]+p0p1[i]) + 2*p1[i] - p1m2[i] - p1p2[i];
300         p0[i] = Clip[(v + ((v>=0) ? 8 : 7))>>4];
301       }
302     }
303   }
304 }
305
306 /* vertical resampling */
307 static void Subsample_Vertical(s,d,lx,lys,lyd,m,n,j0,dj)
308 unsigned char *s;
309 short *d;
310 int lx, lys, lyd, m, n, j0, dj;
311 {
312   int i, j, c1, c2, jd;
313   unsigned char *s1, *s2;
314   short *d1;
315
316   for (j=j0; j<lyd; j+=dj)
317   {
318     d1 = d + lx*j;
319     jd = (j*m)/n;
320     s1 = s + lx*jd;
321     s2 = (jd<lys-1)? s1+lx : s1;
322     c2 = (16*((j*m)%n) + (n>>1))/n;
323     c1 = 16 - c2;
324     for (i=0; i<lx; i++)
325       d1[i] = c1*s1[i] + c2*s2[i];
326   }
327 }
328
329 /* horizontal resampling */
330 static void Subsample_Horizontal(s,d,x0,lx,lxs,lxd,ly,m,n)
331 short *s;
332 unsigned char *d;
333 int x0, lx, lxs, lxd, ly, m, n;
334 {
335   int i, i1, j, id, c1, c2, v;
336   short *s1, *s2;
337   unsigned char *d1;
338
339   for (i1=0; i1<lx; i1++)
340   {
341     d1 = d + i1;
342     i = x0 + i1;
343     id = (i*m)/n;
344     s1 = s+id;
345     s2 = (id<lxs-1) ? s1+1 : s1;
346     c2 = (16*((i*m)%n) + (n>>1))/n;
347     c1 = 16 - c2;
348     for (j=0; j<ly; j++)
349     {
350       v = c1*(*s1) + c2*(*s2);
351       *d1 = (v + ((v>=0) ? 128 : 127))>>8;
352       d1+= lxd;
353       s1+= lxs;
354       s2+= lxs;
355     }
356   }
357 }
358
359