home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2001 September / PC-WELT 9-2001.ISO / software / hw / brennen / flask_src.exe / Video / store.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-14  |  14.8 KB  |  601 lines

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