store.c
上传用户:ma_junhua
上传日期:2008-04-11
资源大小:2752k
文件大小:15k
开发平台:

C/C++

  1.   /* store.c, picture output routines                                         */
  2. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  3. /*
  4.  * Disclaimer of Warranty
  5.  *
  6.  * These software programs are available to the user without any license fee or
  7.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  8.  * any and all warranties, whether express, implied, or statuary, including any
  9.  * implied warranties or merchantability or of fitness for a particular
  10.  * purpose.  In no event shall the copyright-holder be liable for any
  11.  * incidental, punitive, or consequential damages of any kind whatsoever
  12.  * arising from the use of these programs.
  13.  *
  14.  * This disclaimer of warranty extends to the user of these programs and user's
  15.  * customers, employees, agents, transferees, successors, and assigns.
  16.  *
  17.  * The MPEG Software Simulation Group does not represent or warrant that the
  18.  * programs furnished hereunder are free of infringement of any third-party
  19.  * patents.
  20.  *
  21.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  22.  * are subject to royalty fees to patent holders.  Many of these patents are
  23.  * general enough such that they are unavoidable regardless of implementation
  24.  * design.
  25.  *
  26.  */
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <fcntl.h>
  30. #include "config.h"
  31. #include "global.h"
  32. /* private prototypes */
  33. static void store_one _ANSI_ARGS_((char *outname, unsigned char *src[],
  34.   int offset, int incr, int height));
  35. static void store_yuv _ANSI_ARGS_((char *outname, unsigned char *src[],
  36.   int offset, int incr, int height));
  37. static void store_sif _ANSI_ARGS_((char *outname, unsigned char *src[],
  38.   int offset, int incr, int height));
  39. static void store_ppm_tga _ANSI_ARGS_((char *outname, unsigned char *src[],
  40.   int offset, int incr, int height, int tgaflag));
  41. static void store_yuv1 _ANSI_ARGS_((char *name, unsigned char *src,
  42.   int offset, int incr, int width, int height));
  43. static void putbyte _ANSI_ARGS_((int c));
  44. static void putword _ANSI_ARGS_((int w));
  45. static void conv422to444 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  46. static void conv420to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  47. #define OBFRSIZE 4096
  48. static unsigned char obfr[OBFRSIZE];
  49. static unsigned char *optr;
  50. static int outfile;
  51. /*
  52.  * store a picture as either one frame or two fields
  53.  */
  54. void Write_Frame(src,frame)
  55. unsigned char *src[];
  56. int frame;
  57. {
  58.   char outname[FILENAME_LENGTH];
  59.   if (progressive_sequence || progressive_frame || Frame_Store_Flag)
  60.   {
  61.     /* progressive */
  62.     sprintf(outname,Output_Picture_Filename,frame,'f');
  63.     store_one(outname,src,0,Coded_Picture_Width,vertical_size);
  64.   }
  65.   else
  66.   {
  67.     /* interlaced */
  68.     sprintf(outname,Output_Picture_Filename,frame,'a');
  69.     store_one(outname,src,0,Coded_Picture_Width<<1,vertical_size>>1);
  70.     sprintf(outname,Output_Picture_Filename,frame,'b');
  71.     store_one(outname,src,
  72.       Coded_Picture_Width,Coded_Picture_Width<<1,vertical_size>>1);
  73.   }
  74. }
  75. /*
  76.  * store one frame or one field
  77.  */
  78. static void store_one(outname,src,offset,incr,height)
  79. char *outname;
  80. unsigned char *src[];
  81. int offset, incr, height;
  82. {
  83.   switch (Output_Type)
  84.   {
  85.   case T_YUV:
  86.     store_yuv(outname,src,offset,incr,height);
  87.     break;
  88.   case T_SIF:
  89.     store_sif(outname,src,offset,incr,height);
  90.     break;
  91.   case T_TGA:
  92.     store_ppm_tga(outname,src,offset,incr,height,1);
  93.     break;
  94.   case T_PPM:
  95.     store_ppm_tga(outname,src,offset,incr,height,0);
  96.     break;
  97. #ifdef DISPLAY
  98.   case T_X11:
  99.     dither(src);
  100.     break;
  101. #endif
  102.   default:
  103.     break;
  104.   }
  105. }
  106. /* separate headerless files for y, u and v */
  107. static void store_yuv(outname,src,offset,incr,height)
  108. char *outname;
  109. unsigned char *src[];
  110. int offset,incr,height;
  111. {
  112.   int hsize;
  113.   char tmpname[FILENAME_LENGTH];
  114.   hsize = horizontal_size;
  115.   sprintf(tmpname,"%s.Y",outname);
  116.   store_yuv1(tmpname,src[0],offset,incr,hsize,height);
  117.   if (chroma_format!=CHROMA444)
  118.   {
  119.     offset>>=1; incr>>=1; hsize>>=1;
  120.   }
  121.   if (chroma_format==CHROMA420)
  122.   {
  123.     height>>=1;
  124.   }
  125.   sprintf(tmpname,"%s.U",outname);
  126.   store_yuv1(tmpname,src[1],offset,incr,hsize,height);
  127.   sprintf(tmpname,"%s.V",outname);
  128.   store_yuv1(tmpname,src[2],offset,incr,hsize,height);
  129. }
  130. /* auxiliary routine */
  131. static void store_yuv1(name,src,offset,incr,width,height)
  132. char *name;
  133. unsigned char *src;
  134. int offset,incr,width,height;
  135. {
  136.   int i, j;
  137.   unsigned char *p;
  138.   if (!Quiet_Flag)
  139.     fprintf(stderr,"saving %sn",name);
  140.   if ((outfile = open(name,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  141.   {
  142.     sprintf(Error_Text,"Couldn't create %sn",name);
  143.     Error(Error_Text);
  144.   }
  145.   optr=obfr;
  146.   for (i=0; i<height; i++)
  147.   {
  148.     p = src + offset + incr*i;
  149.     for (j=0; j<width; j++)
  150.       putbyte(*p++);
  151.   }
  152.   if (optr!=obfr)
  153.     write(outfile,obfr,optr-obfr);
  154.   close(outfile);
  155. }
  156. /*
  157.  * store as headerless file in U,Y,V,Y format
  158.  */
  159. static void store_sif (outname,src,offset,incr,height)
  160. char *outname;
  161. unsigned char *src[];
  162. int offset, incr, height;
  163. {
  164.   int i,j;
  165.   unsigned char *py, *pu, *pv;
  166.   static unsigned char *u422, *v422;
  167.   if (chroma_format==CHROMA444)
  168.     Error("4:4:4 not supported for SIF format");
  169.   if (chroma_format==CHROMA422)
  170.   {
  171.     u422 = src[1];
  172.     v422 = src[2];
  173.   }
  174.   else
  175.   {
  176.     if (!u422)
  177.     {
  178.       if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  179.                                            *Coded_Picture_Height)))
  180.         Error("malloc failed");
  181.       if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  182.                                            *Coded_Picture_Height)))
  183.         Error("malloc failed");
  184.     }
  185.   
  186.     conv420to422(src[1],u422);
  187.     conv420to422(src[2],v422);
  188.   }
  189.   strcat(outname,".SIF");
  190.   if (!Quiet_Flag)
  191.     fprintf(stderr,"saving %sn",outname);
  192.   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  193.   {
  194.     sprintf(Error_Text,"Couldn't create %sn",outname);
  195.     Error(Error_Text);
  196.   }
  197.   optr = obfr;
  198.   for (i=0; i<height; i++)
  199.   {
  200.     py = src[0] + offset + incr*i;
  201.     pu = u422 + (offset>>1) + (incr>>1)*i;
  202.     pv = v422 + (offset>>1) + (incr>>1)*i;
  203.     for (j=0; j<horizontal_size; j+=2)
  204.     {
  205.       putbyte(*pu++);
  206.       putbyte(*py++);
  207.       putbyte(*pv++);
  208.       putbyte(*py++);
  209.     }
  210.   }
  211.   if (optr!=obfr)
  212.     write(outfile,obfr,optr-obfr);
  213.   close(outfile);
  214. }
  215. /*
  216.  * store as PPM (PBMPLUS) or uncompressed Truevision TGA ('Targa') file
  217.  */
  218. static void store_ppm_tga(outname,src,offset,incr,height,tgaflag)
  219. char *outname;
  220. unsigned char *src[];
  221. int offset, incr, height;
  222. int tgaflag;
  223. {
  224.   int i, j;
  225.   int y, u, v, r, g, b;
  226.   int crv, cbu, cgu, cgv;
  227.   unsigned char *py, *pu, *pv;
  228.   static unsigned char tga24[14] = {0,0,2,0,0,0,0, 0,0,0,0,0,24,32};
  229.   char header[FILENAME_LENGTH];
  230.   static unsigned char *u422, *v422, *u444, *v444;
  231.   if (chroma_format==CHROMA444)
  232.   {
  233.     u444 = src[1];
  234.     v444 = src[2];
  235.   }
  236.   else
  237.   {
  238.     if (!u444)
  239.     {
  240.       if (chroma_format==CHROMA420)
  241.       {
  242.         if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  243.                                              *Coded_Picture_Height)))
  244.           Error("malloc failed");
  245.         if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1)
  246.                                              *Coded_Picture_Height)))
  247.           Error("malloc failed");
  248.       }
  249.       if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width
  250.                                            *Coded_Picture_Height)))
  251.         Error("malloc failed");
  252.       if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width
  253.                                            *Coded_Picture_Height)))
  254.         Error("malloc failed");
  255.     }
  256.     if (chroma_format==CHROMA420)
  257.     {
  258.       conv420to422(src[1],u422);
  259.       conv420to422(src[2],v422);
  260.       conv422to444(u422,u444);
  261.       conv422to444(v422,v444);
  262.     }
  263.     else
  264.     {
  265.       conv422to444(src[1],u444);
  266.       conv422to444(src[2],v444);
  267.     }
  268.   }
  269.   strcat(outname,tgaflag ? ".tga" : ".ppm");
  270.   if (!Quiet_Flag)
  271.     fprintf(stderr,"saving %sn",outname);
  272.   if ((outfile = open(outname,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,0666))==-1)
  273.   {
  274.     sprintf(Error_Text,"Couldn't create %sn",outname);
  275.     Error(Error_Text);
  276.   }
  277.   optr = obfr;
  278.   if (tgaflag)
  279.   {
  280.     /* TGA header */
  281.     for (i=0; i<12; i++)
  282.       putbyte(tga24[i]);
  283.     putword(horizontal_size); putword(height);
  284.     putbyte(tga24[12]); putbyte(tga24[13]);
  285.   }
  286.   else
  287.   {
  288.     /* PPM header */
  289.     sprintf(header,"P6n%d %dn255n",horizontal_size,height);
  290.     for (i=0; header[i]!=0; i++)
  291.       putbyte(header[i]);
  292.   }
  293.   /* matrix coefficients */
  294.   crv = Inverse_Table_6_9[matrix_coefficients][0];
  295.   cbu = Inverse_Table_6_9[matrix_coefficients][1];
  296.   cgu = Inverse_Table_6_9[matrix_coefficients][2];
  297.   cgv = Inverse_Table_6_9[matrix_coefficients][3];
  298.   
  299.   for (i=0; i<height; i++)
  300.   {
  301.     py = src[0] + offset + incr*i;
  302.     pu = u444 + offset + incr*i;
  303.     pv = v444 + offset + incr*i;
  304.     for (j=0; j<horizontal_size; j++)
  305.     {
  306.       u = *pu++ - 128;
  307.       v = *pv++ - 128;
  308.       y = 76309 * (*py++ - 16); /* (255/219)*65536 */
  309.       r = Clip[(y + crv*v + 32768)>>16];
  310.       g = Clip[(y - cgu*u - cgv*v + 32768)>>16];
  311.       b = Clip[(y + cbu*u + 32786)>>16];
  312.       if (tgaflag)
  313.       {
  314.         putbyte(b); putbyte(g); putbyte(r);
  315.       }
  316.       else
  317.       {
  318.         putbyte(r); putbyte(g); putbyte(b);
  319.       }
  320.     }
  321.   }
  322.   if (optr!=obfr)
  323.     write(outfile,obfr,optr-obfr);
  324.   close(outfile);
  325. }
  326. static void putbyte(c)
  327. int c;
  328. {
  329.   *optr++ = c;
  330.   if (optr == obfr+OBFRSIZE)
  331.   {
  332.     write(outfile,obfr,OBFRSIZE);
  333.     optr = obfr;
  334.   }
  335. }
  336. static void putword(w)
  337. int w;
  338. {
  339.   putbyte(w); putbyte(w>>8);
  340. }
  341. /* horizontal 1:2 interpolation filter */
  342. static void conv422to444(src,dst)
  343. unsigned char *src,*dst;
  344. {
  345.   int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;
  346.   w = Coded_Picture_Width>>1;
  347.   if (base.MPEG2_Flag)
  348.   {
  349.     for (j=0; j<Coded_Picture_Height; j++)
  350.     {
  351.       for (i=0; i<w; i++)
  352.       {
  353.         i2 = i<<1;
  354.         im2 = (i<2) ? 0 : i-2;
  355.         im1 = (i<1) ? 0 : i-1;
  356.         ip1 = (i<w-1) ? i+1 : w-1;
  357.         ip2 = (i<w-2) ? i+2 : w-1;
  358.         ip3 = (i<w-3) ? i+3 : w-1;
  359.         /* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */
  360.         /* even samples (0 0 256 0 0) */
  361.         dst[i2] = src[i];
  362.         /* odd samples (21 -52 159 159 -52 21) */
  363.         dst[i2+1] = Clip[(int)(21*(src[im2]+src[ip3])
  364.                         -52*(src[im1]+src[ip2]) 
  365.                        +159*(src[i]+src[ip1])+128)>>8];
  366.       }
  367.       src+= w;
  368.       dst+= Coded_Picture_Width;
  369.     }
  370.   }
  371.   else
  372.   {
  373.     for (j=0; j<Coded_Picture_Height; j++)
  374.     {
  375.       for (i=0; i<w; i++)
  376.       {
  377.         i2 = i<<1;
  378.         im3 = (i<3) ? 0 : i-3;
  379.         im2 = (i<2) ? 0 : i-2;
  380.         im1 = (i<1) ? 0 : i-1;
  381.         ip1 = (i<w-1) ? i+1 : w-1;
  382.         ip2 = (i<w-2) ? i+2 : w-1;
  383.         ip3 = (i<w-3) ? i+3 : w-1;
  384.         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
  385.         dst[i2] =   Clip[(int)(  5*src[im3]
  386.                          -21*src[im2]
  387.                          +70*src[im1]
  388.                         +228*src[i]
  389.                          -37*src[ip1]
  390.                          +11*src[ip2]+128)>>8];
  391.        dst[i2+1] = Clip[(int)(  5*src[ip3]
  392.                          -21*src[ip2]
  393.                          +70*src[ip1]
  394.                         +228*src[i]
  395.                          -37*src[im1]
  396.                          +11*src[im2]+128)>>8];
  397.       }
  398.       src+= w;
  399.       dst+= Coded_Picture_Width;
  400.     }
  401.   }
  402. }
  403. /* vertical 1:2 interpolation filter */
  404. static void conv420to422(src,dst)
  405. unsigned char *src,*dst;
  406. {
  407.   int w, h, i, j, j2;
  408.   int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7;
  409.   w = Coded_Picture_Width>>1;
  410.   h = Coded_Picture_Height>>1;
  411.   if (progressive_frame)
  412.   {
  413.     /* intra frame */
  414.     for (i=0; i<w; i++)
  415.     {
  416.       for (j=0; j<h; j++)
  417.       {
  418.         j2 = j<<1;
  419.         jm3 = (j<3) ? 0 : j-3;
  420.         jm2 = (j<2) ? 0 : j-2;
  421.         jm1 = (j<1) ? 0 : j-1;
  422.         jp1 = (j<h-1) ? j+1 : h-1;
  423.         jp2 = (j<h-2) ? j+2 : h-1;
  424.         jp3 = (j<h-3) ? j+3 : h-1;
  425.         /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */
  426.         /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */
  427.         dst[w*j2] =     Clip[(int)(  3*src[w*jm3]
  428.                              -16*src[w*jm2]
  429.                              +67*src[w*jm1]
  430.                             +227*src[w*j]
  431.                              -32*src[w*jp1]
  432.                              +7*src[w*jp2]+128)>>8];
  433.         dst[w*(j2+1)] = Clip[(int)(  3*src[w*jp3]
  434.                              -16*src[w*jp2]
  435.                              +67*src[w*jp1]
  436.                             +227*src[w*j]
  437.                              -32*src[w*jm1]
  438.                              +7*src[w*jm2]+128)>>8];
  439.       }
  440.       src++;
  441.       dst++;
  442.     }
  443.   }
  444.   else
  445.   {
  446.     /* intra field */
  447.     for (i=0; i<w; i++)
  448.     {
  449.       for (j=0; j<h; j+=2)
  450.       {
  451.         j2 = j<<1;
  452.         /* top field */
  453.         jm6 = (j<6) ? 0 : j-6;
  454.         jm4 = (j<4) ? 0 : j-4;
  455.         jm2 = (j<2) ? 0 : j-2;
  456.         jp2 = (j<h-2) ? j+2 : h-2;
  457.         jp4 = (j<h-4) ? j+4 : h-2;
  458.         jp6 = (j<h-6) ? j+6 : h-2;
  459.         /* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */
  460.         /* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */
  461.         dst[w*j2] = Clip[(int)(  1*src[w*jm6]
  462.                          -7*src[w*jm4]
  463.                          +30*src[w*jm2]
  464.                         +248*src[w*j]
  465.                          -21*src[w*jp2]
  466.                           +5*src[w*jp4]+128)>>8];
  467.         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
  468.         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
  469.         dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4]
  470.                              -35*src[w*jm2]
  471.                             +194*src[w*j]
  472.                             +110*src[w*jp2]
  473.                              -24*src[w*jp4]
  474.                               +4*src[w*jp6]+128)>>8];
  475.         /* bottom field */
  476.         jm5 = (j<5) ? 1 : j-5;
  477.         jm3 = (j<3) ? 1 : j-3;
  478.         jm1 = (j<1) ? 1 : j-1;
  479.         jp1 = (j<h-1) ? j+1 : h-1;
  480.         jp3 = (j<h-3) ? j+3 : h-1;
  481.         jp5 = (j<h-5) ? j+5 : h-1;
  482.         jp7 = (j<h-7) ? j+7 : h-1;
  483.         /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */
  484.         /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */
  485.         dst[w*(j2+1)] = Clip[(int)( 7*src[w*jp5]
  486.                              -35*src[w*jp3]
  487.                             +194*src[w*jp1]
  488.                             +110*src[w*jm1]
  489.                              -24*src[w*jm3]
  490.                               +4*src[w*jm5]+128)>>8];
  491.         dst[w*(j2+3)] = Clip[(int)(  1*src[w*jp7]
  492.                              -7*src[w*jp5]
  493.                              +30*src[w*jp3]
  494.                             +248*src[w*jp1]
  495.                              -21*src[w*jm1]
  496.                               +5*src[w*jm3]+128)>>8];
  497.       }
  498.       src++;
  499.       dst++;
  500.     }
  501.   }
  502. }