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