]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/subspic.c
COMP: Fix warning
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / subspic.c
1 /* subspic.c, Frame buffer substitution routines */
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 "config.h"
31 #include "global.h"
32
33 /* private prototypes*/
34 static void Read_Frame _ANSI_ARGS_((const char *filename, 
35   unsigned char *frame_buffer[], int framenum));
36 static void Copy_Frame _ANSI_ARGS_((unsigned char *src, unsigned char *dst, 
37   int width, int height, int parity, int incr));
38 static int Read_Components _ANSI_ARGS_ ((const char *filename, 
39   unsigned char *frame[3], int framenum));
40 static int Read_Component _ANSI_ARGS_ ((char *fname, unsigned char *frame, 
41   int width, int height));
42 static int Extract_Components _ANSI_ARGS_ ((const char *filename,
43   unsigned char *frame[3], int framenum));
44
45
46 /* substitute frame buffer routine */
47 void Substitute_Frame_Buffer (bitstream_framenum, sequence_framenum)
48 int bitstream_framenum;
49 int sequence_framenum;
50 {
51   /* static tracking variables */
52   static int previous_temporal_reference;
53   static int previous_bitstream_framenum;
54   static int previous_anchor_temporal_reference;
55   static int previous_anchor_bitstream_framenum;
56   static int previous_picture_coding_type;
57   static int bgate;
58   
59   /* local temporary variables */
60   int substitute_display_framenum;
61
62
63 #ifdef DEBUG
64   my_printf("SUB: seq fn(%d) bitfn(%d) tempref(%d) picstr(%d) type(%d)\n", 
65     sequence_framenum, bitstream_framenum, temporal_reference, 
66     picture_structure, picture_coding_type);
67 #endif
68
69   /* we don't substitute at the first picture of a sequence */
70   if((sequence_framenum!=0)||(Second_Field))
71   {
72     /* only at the start of the frame */
73     if ((picture_structure==FRAME_PICTURE)||(!Second_Field))
74     {
75       if(picture_coding_type==P_TYPE)
76       {
77         /* the most recently decoded reference frame needs substituting */
78         substitute_display_framenum = bitstream_framenum - 1;
79         
80         Read_Frame(Substitute_Picture_Filename, forward_reference_frame, 
81           substitute_display_framenum);
82       }
83       /* only the first B frame in a consequitve set of B pictures
84          loads a substitute backward_reference_frame since all subsequent
85          B frames predict from the same reference pictures */
86       else if((picture_coding_type==B_TYPE)&&(bgate!=1))
87       {
88         substitute_display_framenum = 
89           (previous_temporal_reference - temporal_reference) 
90             + bitstream_framenum - 1;
91
92         Read_Frame(Substitute_Picture_Filename, backward_reference_frame, 
93           substitute_display_framenum);
94       }
95     } /* P fields can predict from the two most recently decoded fields, even
96          from the first field of the same frame being decoded */
97     else if(Second_Field && (picture_coding_type==P_TYPE))
98     {
99       /* our favourite case: the IP field picture pair */
100       if((previous_picture_coding_type==I_TYPE)&&(picture_coding_type==P_TYPE))
101       {
102         substitute_display_framenum = bitstream_framenum;
103       }
104       else /* our more generic P field picture pair */
105       {
106         substitute_display_framenum = 
107           (temporal_reference - previous_anchor_temporal_reference) 
108             + bitstream_framenum - 1;
109       }
110
111       Read_Frame(Substitute_Picture_Filename, current_frame, substitute_display_framenum);
112     }
113 #ifdef DEBUG
114     else if((picture_coding_type!=B_TYPE)||(picture_coding_type!=D_TYPE))
115     {
116       my_printf("NO SUBS FOR THIS PICTURE\n");
117     }
118 #endif
119   }
120
121
122   /* set b gate so we don't redundantly load next time around */
123   if(picture_coding_type==B_TYPE)
124     bgate = 1;
125   else
126     bgate = 0;
127
128   /* update general tracking variables */
129   if((picture_structure==FRAME_PICTURE)||(!Second_Field))
130   {
131     previous_temporal_reference  = temporal_reference;
132     previous_bitstream_framenum  = bitstream_framenum;
133   }
134   
135   /* update reference frame tracking variables */
136   if((picture_coding_type!=B_TYPE) && 
137     ((picture_structure==FRAME_PICTURE)||Second_Field))
138   {
139     previous_anchor_temporal_reference  = temporal_reference;
140     previous_anchor_bitstream_framenum  = bitstream_framenum;
141   }
142
143   previous_picture_coding_type = picture_coding_type;
144
145 }
146
147
148 /* Note: fields are only read to serve as the same-frame reference for 
149    a second field */
150 static void Read_Frame(fname,frame,framenum)
151 const char *fname;
152 unsigned char *frame[];
153 int framenum;
154 {
155   int parity;
156   int rerr;
157   int field_mode;
158
159   if(framenum<0)
160     my_printf("ERROR: framenum (%d) is less than zero\n", framenum);
161
162
163   if(Big_Picture_Flag)
164     rerr = Extract_Components(fname, substitute_frame, framenum);
165   else
166     rerr = Read_Components(fname, substitute_frame, framenum);
167
168   if(rerr!=0)
169   {
170     my_printf("was unable to substitute frame\n");
171   }
172
173   /* now copy to the appropriate buffer */
174   /* first field (which we are attempting to substitute) must be
175      of opposite field parity to the current one */
176   if((Second_Field)&&(picture_coding_type==P_TYPE))
177   {
178     parity      = (picture_structure==TOP_FIELD ? 1:0);      
179     field_mode  = (picture_structure==FRAME_PICTURE ? 0:1);
180   }
181   else
182   {
183     /* Like frame structued pictures, B pictures only substitute an entire frame 
184        since both fields always predict from the same frame (with respect 
185        to forward/backwards directions) */
186     parity = 0;
187     field_mode = 0;
188   }
189
190
191   Copy_Frame(substitute_frame[0], frame[0], Coded_Picture_Width, 
192     Coded_Picture_Height, parity, field_mode);
193   
194   Copy_Frame(substitute_frame[1], frame[1], Chroma_Width, Chroma_Height, 
195     parity, field_mode);
196   
197   Copy_Frame(substitute_frame[2], frame[2], Chroma_Width, Chroma_Height,
198     parity, field_mode);
199
200 #ifdef VERBOSE
201   if(Verbose_Flag > NO_LAYER)
202     my_printf("substituted %s %d\n",
203       (field_mode ? (parity?"bottom field":"bottom field"):"frame"), framenum);
204 #endif
205 }
206
207
208
209
210 static int Read_Components(filename, frame, framenum) 
211 const char *filename;
212 unsigned char *frame[3];
213 int framenum;
214 {
215   int err = 0;
216   char outname[FILENAME_LENGTH];
217   char name[FILENAME_LENGTH];
218
219   my_sprintf(outname,filename,framenum);
220
221
222   my_sprintf(name,"%s.Y",outname);
223   err += Read_Component(name, frame[0], Coded_Picture_Width, 
224     Coded_Picture_Height);
225
226   my_sprintf(name,"%s.U",outname);
227   err += Read_Component(name, frame[1], Chroma_Width, Chroma_Height);
228
229   my_sprintf(name,"%s.V",outname);
230   err += Read_Component(name, frame[2], Chroma_Width, Chroma_Height);
231
232   return(err);
233 }
234
235
236 static int Read_Component(Filename, Frame, Width, Height)
237 char *Filename;
238 unsigned char *Frame;
239 int Width;
240 int Height;
241 {
242   int Size;
243   int Bytes_Read;
244   istream Infile;
245
246   Size = Width*Height;
247
248 #ifdef DEBUG
249   my_printf("SUBS: reading %s\n", filename);
250 #endif
251
252   if(!my_fopenr(Filename, "rb", &Infile))
253   {
254     my_printf("ERROR: unable to open reference filename (%s)\n", Filename);
255     return(-1);
256   }
257
258   /*abort();*/
259   Bytes_Read = my_fread(Frame, Size, 1, &Infile);
260   
261   if(Bytes_Read!=Size)
262   {
263     my_printf("was able to read only %d bytes of %d of file %s\n",
264       Bytes_Read, Size, Filename);
265   }
266  
267   my_fcloser(&Infile); 
268   return(0);
269 }
270
271
272 /* optimization: do not open the big file each time. Open once at start
273    of decoder, and close at the very last frame */
274
275 /* Note: "big" files were used in E-mail exchanges almost exclusively by the 
276    MPEG Committee's syntax validation and conformance ad-hoc groups from 
277    the year 1993 until 1995 */
278 static int Extract_Components(filename, frame, framenum) 
279 const char *filename;
280 unsigned char *frame[3];
281 int framenum;
282 {
283 /*  int err = 0; */
284   istream fd;
285   int line;
286   int size, offset;
287   /*abort();*/
288
289
290   if (!my_fopenr(filename,"rb", &fd))
291   {
292     my_sprintf(Error_Text,"Couldn't open %s\n",filename);
293     return(-1);
294   }
295
296   /* compute size of each frame (in bytes) */
297   size = (Coded_Picture_Width*Coded_Picture_Height);
298
299   if(chroma_format==CHROMA444)
300     size = (size * 3);
301   else if(chroma_format==CHROMA422)
302     size = (size * 2);
303   else if(chroma_format==CHROMA420)
304     size = ((size*3)>>1);
305   else
306     my_printf("ERROR: chroma_format (%d) not recognized\n", chroma_format);
307
308
309   /* compute distance into "big" file */
310   offset = size*framenum;
311
312 #ifdef DEBUG
313   my_printf("EXTRACTING: frame(%d) offset(%d), size (%d) from %s\n", 
314     framenum, offset, size, filename);
315 #endif
316
317   /* seek to location in big file where desired frame begins */
318   /* note: this offset cannot exceed a few billion bytes due to the */
319   /*       obvious limitations of 32-bit integers */
320   my_fseekr(&fd, offset, SEEK_SET);
321
322   /* Y  */
323   for (line=0; line<Coded_Picture_Height; line++)
324   {
325     my_fread(frame[0]+(line*Coded_Picture_Width),1,Coded_Picture_Width,&fd);
326   }
327
328   /* Cb */
329   for (line=0; line<Chroma_Height; line++)
330   {
331     my_fread(frame[1]+(line*Chroma_Width),1,Chroma_Width,&fd);
332   }
333
334   /* Cr */
335   for (line=0; line<Chroma_Height; line++)
336   {
337     my_fread(frame[2]+(line*Chroma_Width),1,Chroma_Width,&fd);
338   }
339
340
341   my_fcloser(&fd);
342   return(0);
343 }
344
345
346 static void Copy_Frame(src, dst, width, height, parity, field_mode)
347 unsigned char *src;
348 unsigned char *dst;
349 int width;
350 int height;
351 int parity;        /* field parity (top or bottom) to overwrite */
352 int field_mode;    /* 0 = frame, 1 = field                      */
353 {
354   int row, col;
355   int s, d;
356   int incr;
357
358   s = d = 0;
359
360 #ifdef DEBUG
361   my_printf("COPYING (w=%d, h=%d, parity=%d, field_mode=%d)\n",
362     width,height,parity,field_mode);
363 #endif /* DEBUG */
364
365   if(field_mode)
366   {
367     incr = 2;
368
369     if(parity==0)
370       s += width;
371   }
372   else
373   {
374     incr = 1;
375   }
376
377   for(row=0; row<height; row+=incr) 
378   {
379     for(col=0; col<width; col++)
380     {
381       dst[d+col] = src[s+col];
382     }
383     
384     d += (width*incr);
385     s += (width*incr);
386   }
387
388 }
389