]> Creatis software - gdcm.git/blob - src/gdcmmpeg2/src/mpeg2dec/store.c
COMP: Remove compiler warnings using gcc
[gdcm.git] / src / gdcmmpeg2 / src / mpeg2dec / store.c
1 /* store.c, picture output 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 <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <unistd.h> // for write
34 #include <string.h> // for strcat
35
36 #include "config.h"
37 #include "global.h"
38
39 /* private prototypes */
40 static void store_one _ANSI_ARGS_((char *outname, unsigned char *src[],
41   int offset, int incr, int height));
42 static void store_yuv _ANSI_ARGS_((char *outname, unsigned char *src[],
43   int offset, int incr, int height));
44 static void store_sif _ANSI_ARGS_((char *outname, unsigned char *src[],
45   int offset, int incr, int height));
46 static void store_ppm_tga _ANSI_ARGS_((char *outname, unsigned char *src[],
47   int offset, int incr, int height, int tgaflag));
48 static void store_yuv1 _ANSI_ARGS_((char *name, unsigned char *src,
49   int offset, int incr, int width, int height));
50 static void putbyte _ANSI_ARGS_((int c));
51 static void putword _ANSI_ARGS_((int w));
52 static void conv422to444 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
53 static void conv420to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
54
55 #define OBFRSIZE 4096
56 static unsigned char obfr[OBFRSIZE];
57 static unsigned char *optr;
58 static int outfile;
59
60 /*
61  * store a picture as either one frame or two fields
62  */
63 void Write_Frame(src,frame)
64 unsigned char *src[];
65 int frame;
66 {
67   char outname[FILENAME_LENGTH];
68
69   if (progressive_sequence || progressive_frame || Frame_Store_Flag)
70   {
71     /* progressive */
72     sprintf(outname,Output_Picture_Filename,frame,'f');
73     store_one(outname,src,0,Coded_Picture_Width,vertical_size);
74   }
75   else
76   {
77     /* interlaced */
78     sprintf(outname,Output_Picture_Filename,frame,'a');
79     store_one(outname,src,0,Coded_Picture_Width<<1,vertical_size>>1);
80
81     sprintf(outname,Output_Picture_Filename,frame,'b');
82     store_one(outname,src,
83       Coded_Picture_Width,Coded_Picture_Width<<1,vertical_size>>1);
84   }
85 }
86
87 /*
88  * store one frame or one field
89  */
90 static void store_one(outname,src,offset,incr,height)
91 char *outname;
92 unsigned char *src[];
93 int offset, incr, height;
94 {
95   switch (Output_Type)
96   {
97   case T_YUV:
98     store_yuv(outname,src,offset,incr,height);
99     break;
100   case T_SIF:
101     store_sif(outname,src,offset,incr,height);
102     break;
103   case T_TGA:
104     store_ppm_tga(outname,src,offset,incr,height,1);
105     break;
106   case T_PPM:
107     store_ppm_tga(outname,src,offset,incr,height,0);
108     break;
109 #ifdef DISPLAY
110   case T_X11:
111     dither(src);
112     break;
113 #endif
114   default:
115     break;
116   }
117 }
118
119 /* separate headerless files for y, u and v */
120 static void store_yuv(outname,src,offset,incr,height)
121 char *outname;
122 unsigned char *src[];
123 int offset,incr,height;
124 {
125   int hsize;
126   char tmpname[FILENAME_LENGTH];
127
128   hsize = horizontal_size;
129
130   sprintf(tmpname,"%s.Y",outname);
131   store_yuv1(tmpname,src[0],offset,incr,hsize,height);
132
133   if (chroma_format!=CHROMA444)
134   {
135     offset>>=1; incr>>=1; hsize>>=1;
136   }
137
138   if (chroma_format==CHROMA420)
139   {
140     height>>=1;
141   }
142
143   sprintf(tmpname,"%s.U",outname);
144   store_yuv1(tmpname,src[1],offset,incr,hsize,height);
145
146   sprintf(tmpname,"%s.V",outname);
147   store_yuv1(tmpname,src[2],offset,incr,hsize,height);
148 }
149
150 /* auxiliary routine */
151 static void store_yuv1(name,src,offset,incr,width,height)
152 char *name;
153 unsigned char *src;
154 int offset,incr,width,height;
155 {
156   int i, j;
157   unsigned char *p;
158
159   if (!Quiet_Flag)
160     fprintf(stderr,"saving %s\n",name);
161
162   if ((outfile = open(name,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
163   {
164     sprintf(Error_Text,"Couldn't create %s\n",name);
165     Error(Error_Text);
166   }
167
168   optr=obfr;
169
170   for (i=0; i<height; i++)
171   {
172     p = src + offset + incr*i;
173     for (j=0; j<width; j++)
174       putbyte(*p++);
175   }
176
177   if (optr!=obfr)
178     write(outfile,obfr,optr-obfr);
179
180   close(outfile);
181 }
182
183 /*
184  * store as headerless file in U,Y,V,Y format
185  */
186 static void store_sif (outname,src,offset,incr,height)
187 char *outname;
188 unsigned char *src[];
189 int offset, incr, height;
190 {
191   int i,j;
192   unsigned char *py, *pu, *pv;
193   static unsigned char *u422, *v422;
194
195   if (chroma_format==CHROMA444)
196     Error("4:4:4 not supported for SIF format");
197
198   if (chroma_format==CHROMA422)
199   {
200     u422 = src[1];
201     v422 = src[2];
202   }
203   else
204   {
205     if (!u422)
206     {
207       if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
208                                            *Coded_Picture_Height)))
209         Error("malloc failed");
210       if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
211                                            *Coded_Picture_Height)))
212         Error("malloc failed");
213     }
214   
215     conv420to422(src[1],u422);
216     conv420to422(src[2],v422);
217   }
218
219   strcat(outname,".SIF");
220
221   if (!Quiet_Flag)
222     fprintf(stderr,"saving %s\n",outname);
223
224   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
225   {
226     sprintf(Error_Text,"Couldn't create %s\n",outname);
227     Error(Error_Text);
228   }
229
230   optr = obfr;
231
232   for (i=0; i<height; i++)
233   {
234     py = src[0] + offset + incr*i;
235     pu = u422 + (offset>>1) + (incr>>1)*i;
236     pv = v422 + (offset>>1) + (incr>>1)*i;
237
238     for (j=0; j<horizontal_size; j+=2)
239     {
240       putbyte(*pu++);
241       putbyte(*py++);
242       putbyte(*pv++);
243       putbyte(*py++);
244     }
245   }
246
247   if (optr!=obfr)
248     write(outfile,obfr,optr-obfr);
249
250   close(outfile);
251 }
252
253 /*
254  * store as PPM (PBMPLUS) or uncompressed Truevision TGA ('Targa') file
255  */
256 static void store_ppm_tga(outname,src,offset,incr,height,tgaflag)
257 char *outname;
258 unsigned char *src[];
259 int offset, incr, height;
260 int tgaflag;
261 {
262   int i, j;
263   int y, u, v, r, g, b;
264   int crv, cbu, cgu, cgv;
265   unsigned char *py, *pu, *pv;
266   static unsigned char tga24[14] = {0,0,2,0,0,0,0, 0,0,0,0,0,24,32};
267   char header[FILENAME_LENGTH];
268   static unsigned char *u422, *v422, *u444, *v444;
269
270   if (chroma_format==CHROMA444)
271   {
272     u444 = src[1];
273     v444 = src[2];
274   }
275   else
276   {
277     if (!u444)
278     {
279       if (chroma_format==CHROMA420)
280       {
281         if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
282                                              *Coded_Picture_Height)))
283           Error("malloc failed");
284         if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
285                                              *Coded_Picture_Height)))
286           Error("malloc failed");
287       }
288
289       if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width
290                                            *Coded_Picture_Height)))
291         Error("malloc failed");
292
293       if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width
294                                            *Coded_Picture_Height)))
295         Error("malloc failed");
296     }
297
298     if (chroma_format==CHROMA420)
299     {
300       conv420to422(src[1],u422);
301       conv420to422(src[2],v422);
302       conv422to444(u422,u444);
303       conv422to444(v422,v444);
304     }
305     else
306     {
307       conv422to444(src[1],u444);
308       conv422to444(src[2],v444);
309     }
310   }
311
312   strcat(outname,tgaflag ? ".tga" : ".ppm");
313
314   if (!Quiet_Flag)
315     fprintf(stderr,"saving %s\n",outname);
316
317   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
318   {
319     sprintf(Error_Text,"Couldn't create %s\n",outname);
320     Error(Error_Text);
321   }
322
323   optr = obfr;
324
325   if (tgaflag)
326   {
327     /* TGA header */
328     for (i=0; i<12; i++)
329       putbyte(tga24[i]);
330
331     putword(horizontal_size); putword(height);
332     putbyte(tga24[12]); putbyte(tga24[13]);
333   }
334   else
335   {
336     /* PPM header */
337     sprintf(header,"P6\n%d %d\n255\n",horizontal_size,height);
338
339     for (i=0; header[i]!=0; i++)
340       putbyte(header[i]);
341   }
342
343   /* matrix coefficients */
344   crv = Inverse_Table_6_9[matrix_coefficients][0];
345   cbu = Inverse_Table_6_9[matrix_coefficients][1];
346   cgu = Inverse_Table_6_9[matrix_coefficients][2];
347   cgv = Inverse_Table_6_9[matrix_coefficients][3];
348   
349   for (i=0; i<height; i++)
350   {
351     py = src[0] + offset + incr*i;
352     pu = u444 + offset + incr*i;
353     pv = v444 + offset + incr*i;
354
355     for (j=0; j<horizontal_size; j++)
356     {
357       u = *pu++ - 128;
358       v = *pv++ - 128;
359       y = 76309 * (*py++ - 16); /* (255/219)*65536 */
360       r = Clip[(y + crv*v + 32768)>>16];
361       g = Clip[(y - cgu*u - cgv*v + 32768)>>16];
362       b = Clip[(y + cbu*u + 32786)>>16];
363
364       if (tgaflag)
365       {
366         putbyte(b); putbyte(g); putbyte(r);
367       }
368       else
369       {
370         putbyte(r); putbyte(g); putbyte(b);
371       }
372     }
373   }
374
375   if (optr!=obfr)
376     write(outfile,obfr,optr-obfr);
377
378   close(outfile);
379 }
380
381 static void putbyte(c)
382 int c;
383 {
384   *optr++ = c;
385
386   if (optr == obfr+OBFRSIZE)
387   {
388     write(outfile,obfr,OBFRSIZE);
389     optr = obfr;
390   }
391 }
392
393 static void putword(w)
394 int w;
395 {
396   putbyte(w); putbyte(w>>8);
397 }
398
399 /* horizontal 1:2 interpolation filter */
400 static void conv422to444(src,dst)
401 unsigned char *src,*dst;
402 {
403   int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;
404
405   w = Coded_Picture_Width>>1;
406
407   if (base.MPEG2_Flag)
408   {
409     for (j=0; j<Coded_Picture_Height; j++)
410     {
411       for (i=0; i<w; i++)
412       {
413         i2 = i<<1;
414         im2 = (i<2) ? 0 : i-2;
415         im1 = (i<1) ? 0 : i-1;
416         ip1 = (i<w-1) ? i+1 : w-1;
417         ip2 = (i<w-2) ? i+2 : w-1;
418         ip3 = (i<w-3) ? i+3 : w-1;
419
420         /* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */
421         /* even samples (0 0 256 0 0) */
422         dst[i2] = src[i];
423
424         /* odd samples (21 -52 159 159 -52 21) */
425         dst[i2+1] = Clip[(int)(21*(src[im2]+src[ip3])
426                         -52*(src[im1]+src[ip2]) 
427                        +159*(src[i]+src[ip1])+128)>>8];
428       }
429       src+= w;
430       dst+= Coded_Picture_Width;
431     }
432   }
433   else
434   {
435     for (j=0; j<Coded_Picture_Height; j++)
436     {
437       for (i=0; i<w; i++)
438       {
439
440         i2 = i<<1;
441         im3 = (i<3) ? 0 : i-3;
442         im2 = (i<2) ? 0 : i-2;
443         im1 = (i<1) ? 0 : i-1;
444         ip1 = (i<w-1) ? i+1 : w-1;
445         ip2 = (i<w-2) ? i+2 : w-1;
446         ip3 = (i<w-3) ? i+3 : w-1;
447
448         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
449         dst[i2] =   Clip[(int)(  5*src[im3]
450                          -21*src[im2]
451                          +70*src[im1]
452                         +228*src[i]
453                          -37*src[ip1]
454                          +11*src[ip2]+128)>>8];
455
456        dst[i2+1] = Clip[(int)(  5*src[ip3]
457                          -21*src[ip2]
458                          +70*src[ip1]
459                         +228*src[i]
460                          -37*src[im1]
461                          +11*src[im2]+128)>>8];
462       }
463       src+= w;
464       dst+= Coded_Picture_Width;
465     }
466   }
467 }
468
469 /* vertical 1:2 interpolation filter */
470 static void conv420to422(src,dst)
471 unsigned char *src,*dst;
472 {
473   int w, h, i, j, j2;
474   int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7;
475
476   w = Coded_Picture_Width>>1;
477   h = Coded_Picture_Height>>1;
478
479   if (progressive_frame)
480   {
481     /* intra frame */
482     for (i=0; i<w; i++)
483     {
484       for (j=0; j<h; j++)
485       {
486         j2 = j<<1;
487         jm3 = (j<3) ? 0 : j-3;
488         jm2 = (j<2) ? 0 : j-2;
489         jm1 = (j<1) ? 0 : j-1;
490         jp1 = (j<h-1) ? j+1 : h-1;
491         jp2 = (j<h-2) ? j+2 : h-1;
492         jp3 = (j<h-3) ? j+3 : h-1;
493
494         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
495         /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */
496         dst[w*j2] =     Clip[(int)(  3*src[w*jm3]
497                              -16*src[w*jm2]
498                              +67*src[w*jm1]
499                             +227*src[w*j]
500                              -32*src[w*jp1]
501                              +7*src[w*jp2]+128)>>8];
502
503         dst[w*(j2+1)] = Clip[(int)(  3*src[w*jp3]
504                              -16*src[w*jp2]
505                              +67*src[w*jp1]
506                             +227*src[w*j]
507                              -32*src[w*jm1]
508                              +7*src[w*jm2]+128)>>8];
509       }
510       src++;
511       dst++;
512     }
513   }
514   else
515   {
516     /* intra field */
517     for (i=0; i<w; i++)
518     {
519       for (j=0; j<h; j+=2)
520       {
521         j2 = j<<1;
522
523         /* top field */
524         jm6 = (j<6) ? 0 : j-6;
525         jm4 = (j<4) ? 0 : j-4;
526         jm2 = (j<2) ? 0 : j-2;
527         jp2 = (j<h-2) ? j+2 : h-2;
528         jp4 = (j<h-4) ? j+4 : h-2;
529         jp6 = (j<h-6) ? j+6 : h-2;
530
531         /* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */
532         /* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */
533         dst[w*j2] = Clip[(int)(  1*src[w*jm6]
534                          -7*src[w*jm4]
535                          +30*src[w*jm2]
536                         +248*src[w*j]
537                          -21*src[w*jp2]
538                           +5*src[w*jp4]+128)>>8];
539
540         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
541         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
542         dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4]
543                              -35*src[w*jm2]
544                             +194*src[w*j]
545                             +110*src[w*jp2]
546                              -24*src[w*jp4]
547                               +4*src[w*jp6]+128)>>8];
548
549         /* bottom field */
550         jm5 = (j<5) ? 1 : j-5;
551         jm3 = (j<3) ? 1 : j-3;
552         jm1 = (j<1) ? 1 : j-1;
553         jp1 = (j<h-1) ? j+1 : h-1;
554         jp3 = (j<h-3) ? j+3 : h-1;
555         jp5 = (j<h-5) ? j+5 : h-1;
556         jp7 = (j<h-7) ? j+7 : h-1;
557
558         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
559         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
560         dst[w*(j2+1)] = Clip[(int)( 7*src[w*jp5]
561                              -35*src[w*jp3]
562                             +194*src[w*jp1]
563                             +110*src[w*jm1]
564                              -24*src[w*jm3]
565                               +4*src[w*jm5]+128)>>8];
566
567         dst[w*(j2+3)] = Clip[(int)(  1*src[w*jp7]
568                              -7*src[w*jp5]
569                              +30*src[w*jp3]
570                             +248*src[w*jp1]
571                              -21*src[w*jm1]
572                               +5*src[w*jm3]+128)>>8];
573       }
574       src++;
575       dst++;
576     }
577   }
578 }