readpic.c
上传用户:hkgotone
上传日期:2013-02-17
资源大小:293k
文件大小:13k
源码类别:

Windows Mobile

开发平台:

C/C++

  1. /* readpic.c, read source pictures                                          */
  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 "config.h"
  30. #include "global.h"
  31. /* private prototypes */
  32. static void read_y_u_v _ANSI_ARGS_((char *fname, unsigned char *frame[]));
  33. static void read_yuv _ANSI_ARGS_((char *fname, unsigned char *frame[]));
  34. static void read_ppm _ANSI_ARGS_((char *fname, unsigned char *frame[]));
  35. static void border_extend _ANSI_ARGS_((unsigned char *frame, int w1, int h1,
  36.   int w2, int h2));
  37. static void conv444to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  38. static void conv422to420 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
  39. void readframe(fname,frame)
  40. char *fname;
  41. unsigned char *frame[];
  42. {
  43.   switch (inputtype)
  44.   {
  45.   case T_Y_U_V:
  46.     read_y_u_v(fname,frame);
  47.     break;
  48.   case T_YUV:
  49.     read_yuv(fname,frame);
  50.     break;
  51.   case T_PPM:
  52.     read_ppm(fname,frame);
  53.     break;
  54.   default:
  55.     break;
  56.   }
  57. }
  58. static void read_y_u_v(fname,frame)
  59. char *fname;
  60. unsigned char *frame[];
  61. {
  62.   int i;
  63.   int chrom_hsize, chrom_vsize;
  64.   char name[128];
  65.   FILE *fd;
  66.   chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
  67.                                            : horizontal_size>>1;
  68.   chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
  69.                                            : vertical_size>>1;
  70.   sprintf(name,"%s.Y",fname);
  71.   if (!(fd = fopen(name,"rb")))
  72.   {
  73.     sprintf(errortext,"Couldn't open %sn",name);
  74.     error(errortext);
  75.   }
  76.   for (i=0; i<vertical_size; i++)
  77.     fread(frame[0]+i*width,1,horizontal_size,fd);
  78.   fclose(fd);
  79.   border_extend(frame[0],horizontal_size,vertical_size,width,height);
  80.   sprintf(name,"%s.U",fname);
  81.   if (!(fd = fopen(name,"rb")))
  82.   {
  83.     sprintf(errortext,"Couldn't open %sn",name);
  84.     error(errortext);
  85.   }
  86.   for (i=0; i<chrom_vsize; i++)
  87.     fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
  88.   fclose(fd);
  89.   border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
  90.   sprintf(name,"%s.V",fname);
  91.   if (!(fd = fopen(name,"rb")))
  92.   {
  93.     sprintf(errortext,"Couldn't open %sn",name);
  94.     error(errortext);
  95.   }
  96.   for (i=0; i<chrom_vsize; i++)
  97.     fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
  98.   fclose(fd);
  99.   border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
  100. }
  101. static void read_yuv(fname,frame)
  102. char *fname;
  103. unsigned char *frame[];
  104. {
  105.   int i;
  106.   int chrom_hsize, chrom_vsize;
  107.   char name[128];
  108.   FILE *fd;
  109.   chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
  110.                                            : horizontal_size>>1;
  111.   chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
  112.                                            : vertical_size>>1;
  113.   sprintf(name,"%s.yuv",fname);
  114.   if (!(fd = fopen(name,"rb")))
  115.   {
  116.     sprintf(errortext,"Couldn't open %sn",name);
  117.     error(errortext);
  118.   }
  119.   /* Y */
  120.   for (i=0; i<vertical_size; i++)
  121.     fread(frame[0]+i*width,1,horizontal_size,fd);
  122.   border_extend(frame[0],horizontal_size,vertical_size,width,height);
  123.   /* Cb */
  124.   for (i=0; i<chrom_vsize; i++)
  125.     fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
  126.   border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
  127.   /* Cr */
  128.   for (i=0; i<chrom_vsize; i++)
  129.     fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
  130.   border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
  131.   fclose(fd);
  132. }
  133. static void read_ppm(fname,frame)
  134. char *fname;
  135. unsigned char *frame[];
  136. {
  137.   int i, j;
  138.   int r, g, b;
  139.   double y, u, v;
  140.   double cr, cg, cb, cu, cv;
  141.   char name[128];
  142.   FILE *fd;
  143.   unsigned char *yp, *up, *vp;
  144.   static unsigned char *u444, *v444, *u422, *v422;
  145.   static double coef[7][3] = {
  146.     {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */
  147.     {0.299, 0.587, 0.114},  /* unspecified */
  148.     {0.299, 0.587, 0.114},  /* reserved */
  149.     {0.30,  0.59,  0.11},   /* FCC */
  150.     {0.299, 0.587, 0.114},  /* ITU-R Rec. 624-4 System B, G */
  151.     {0.299, 0.587, 0.114},  /* SMPTE 170M */
  152.     {0.212, 0.701, 0.087}}; /* SMPTE 240M (1987) */
  153.   i = matrix_coefficients;
  154.   if (i>8)
  155.     i = 3;
  156.   cr = coef[i-1][0];
  157.   cg = coef[i-1][1];
  158.   cb = coef[i-1][2];
  159.   cu = 0.5/(1.0-cb);
  160.   cv = 0.5/(1.0-cr);
  161.   if (chroma_format==CHROMA444)
  162.   {
  163.     u444 = frame[1];
  164.     v444 = frame[2];
  165.   }
  166.   else
  167.   {
  168.     if (!u444)
  169.     {
  170.       if (!(u444 = (unsigned char *)malloc(width*height)))
  171.         error("malloc failed");
  172.       if (!(v444 = (unsigned char *)malloc(width*height)))
  173.         error("malloc failed");
  174.       if (chroma_format==CHROMA420)
  175.       {
  176.         if (!(u422 = (unsigned char *)malloc((width>>1)*height)))
  177.           error("malloc failed");
  178.         if (!(v422 = (unsigned char *)malloc((width>>1)*height)))
  179.           error("malloc failed");
  180.       }
  181.     }
  182.   }
  183.   sprintf(name,"%s.ppm",fname);
  184.   if (!(fd = fopen(name,"rb")))
  185.   {
  186.     sprintf(errortext,"Couldn't open %sn",name);
  187.     error(errortext);
  188.   }
  189.   /* skip header */
  190.   getc(fd); getc(fd); /* magic number (P6) */
  191.   pbm_getint(fd); pbm_getint(fd); pbm_getint(fd); /* width height maxcolors */
  192.   for (i=0; i<vertical_size; i++)
  193.   {
  194.     yp = frame[0] + i*width;
  195.     up = u444 + i*width;
  196.     vp = v444 + i*width;
  197.     for (j=0; j<horizontal_size; j++)
  198.     {
  199.       r=getc(fd); g=getc(fd); b=getc(fd);
  200.       /* convert to YUV */
  201.       y = cr*r + cg*g + cb*b;
  202.       u = cu*(b-y);
  203.       v = cv*(r-y);
  204.       yp[j] = (219.0/256.0)*y + 16.5;  /* nominal range: 16..235 */
  205.       up[j] = (224.0/256.0)*u + 128.5; /* 16..240 */
  206.       vp[j] = (224.0/256.0)*v + 128.5; /* 16..240 */
  207.     }
  208.   }
  209.   fclose(fd);
  210.   border_extend(frame[0],horizontal_size,vertical_size,width,height);
  211.   border_extend(u444,horizontal_size,vertical_size,width,height);
  212.   border_extend(v444,horizontal_size,vertical_size,width,height);
  213.   if (chroma_format==CHROMA422)
  214.   {
  215.     conv444to422(u444,frame[1]);
  216.     conv444to422(v444,frame[2]);
  217.   }
  218.   if (chroma_format==CHROMA420)
  219.   {
  220.     conv444to422(u444,u422);
  221.     conv444to422(v444,v422);
  222.     conv422to420(u422,frame[1]);
  223.     conv422to420(v422,frame[2]);
  224.   }
  225. }
  226. static void border_extend(frame,w1,h1,w2,h2)
  227. unsigned char *frame;
  228. int w1,h1,w2,h2;
  229. {
  230.   int i, j;
  231.   unsigned char *fp;
  232.   /* horizontal pixel replication (right border) */
  233.   for (j=0; j<h1; j++)
  234.   {
  235.     fp = frame + j*w2;
  236.     for (i=w1; i<w2; i++)
  237.       fp[i] = fp[i-1];
  238.   }
  239.   /* vertical pixel replication (bottom border) */
  240.   for (j=h1; j<h2; j++)
  241.   {
  242.     fp = frame + j*w2;
  243.     for (i=0; i<w2; i++)
  244.       fp[i] = fp[i-w2];
  245.   }
  246. }
  247. /* horizontal filter and 2:1 subsampling */
  248. static void conv444to422(src,dst)
  249. unsigned char *src, *dst;
  250. {
  251.   int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6;
  252.   if (mpeg1)
  253.   {
  254.     for (j=0; j<height; j++)
  255.     {
  256.       for (i=0; i<width; i+=2)
  257.       {
  258.         im5 = (i<5) ? 0 : i-5;
  259.         im4 = (i<4) ? 0 : i-4;
  260.         im3 = (i<3) ? 0 : i-3;
  261.         im2 = (i<2) ? 0 : i-2;
  262.         im1 = (i<1) ? 0 : i-1;
  263.         ip1 = (i<width-1) ? i+1 : width-1;
  264.         ip2 = (i<width-2) ? i+2 : width-1;
  265.         ip3 = (i<width-3) ? i+3 : width-1;
  266.         ip4 = (i<width-4) ? i+4 : width-1;
  267.         ip5 = (i<width-5) ? i+5 : width-1;
  268.         ip6 = (i<width-5) ? i+6 : width-1;
  269.         /* FIR filter with 0.5 sample interval phase shift */
  270.         dst[i>>1] = clp[(int)(228*(src[i]+src[ip1])
  271.                          +70*(src[im1]+src[ip2])
  272.                          -37*(src[im2]+src[ip3])
  273.                          -21*(src[im3]+src[ip4])
  274.                          +11*(src[im4]+src[ip5])
  275.                          + 5*(src[im5]+src[ip6])+256)>>9];
  276.       }
  277.       src+= width;
  278.       dst+= width>>1;
  279.     }
  280.   }
  281.   else
  282.   {
  283.     /* MPEG-2 */
  284.     for (j=0; j<height; j++)
  285.     {
  286.       for (i=0; i<width; i+=2)
  287.       {
  288.         im5 = (i<5) ? 0 : i-5;
  289.         im3 = (i<3) ? 0 : i-3;
  290.         im1 = (i<1) ? 0 : i-1;
  291.         ip1 = (i<width-1) ? i+1 : width-1;
  292.         ip3 = (i<width-3) ? i+3 : width-1;
  293.         ip5 = (i<width-5) ? i+5 : width-1;
  294.         /* FIR filter coefficients (*512): 22 0 -52 0 159 256 159 0 -52 0 22 */
  295.         dst[i>>1] = clp[(int)(  22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3])
  296.                          +159*(src[im1]+src[ip1])+256*src[i]+256)>>9];
  297.       }
  298.       src+= width;
  299.       dst+= width>>1;
  300.     }
  301.   }
  302. }
  303. /* vertical filter and 2:1 subsampling */
  304. static void conv422to420(src,dst)
  305. unsigned char *src, *dst;
  306. {
  307.   int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1;
  308.   int jp1, jp2, jp3, jp4, jp5, jp6;
  309.   w = width>>1;
  310.   if (prog_frame)
  311.   {
  312.     /* intra frame */
  313.     for (i=0; i<w; i++)
  314.     {
  315.       for (j=0; j<height; j+=2)
  316.       {
  317.         jm5 = (j<5) ? 0 : j-5;
  318.         jm4 = (j<4) ? 0 : j-4;
  319.         jm3 = (j<3) ? 0 : j-3;
  320.         jm2 = (j<2) ? 0 : j-2;
  321.         jm1 = (j<1) ? 0 : j-1;
  322.         jp1 = (j<height-1) ? j+1 : height-1;
  323.         jp2 = (j<height-2) ? j+2 : height-1;
  324.         jp3 = (j<height-3) ? j+3 : height-1;
  325.         jp4 = (j<height-4) ? j+4 : height-1;
  326.         jp5 = (j<height-5) ? j+5 : height-1;
  327.         jp6 = (j<height-5) ? j+6 : height-1;
  328.         /* FIR filter with 0.5 sample interval phase shift */
  329.         dst[w*(j>>1)] = clp[(int)(228*(src[w*j]+src[w*jp1])
  330.                              +70*(src[w*jm1]+src[w*jp2])
  331.                              -37*(src[w*jm2]+src[w*jp3])
  332.                              -21*(src[w*jm3]+src[w*jp4])
  333.                              +11*(src[w*jm4]+src[w*jp5])
  334.                              + 5*(src[w*jm5]+src[w*jp6])+256)>>9];
  335.       }
  336.       src++;
  337.       dst++;
  338.     }
  339.   }
  340.   else
  341.   {
  342.     /* intra field */
  343.     for (i=0; i<w; i++)
  344.     {
  345.       for (j=0; j<height; j+=4)
  346.       {
  347.         /* top field */
  348.         jm5 = (j<10) ? 0 : j-10;
  349.         jm4 = (j<8) ? 0 : j-8;
  350.         jm3 = (j<6) ? 0 : j-6;
  351.         jm2 = (j<4) ? 0 : j-4;
  352.         jm1 = (j<2) ? 0 : j-2;
  353.         jp1 = (j<height-2) ? j+2 : height-2;
  354.         jp2 = (j<height-4) ? j+4 : height-2;
  355.         jp3 = (j<height-6) ? j+6 : height-2;
  356.         jp4 = (j<height-8) ? j+8 : height-2;
  357.         jp5 = (j<height-10) ? j+10 : height-2;
  358.         jp6 = (j<height-12) ? j+12 : height-2;
  359.         /* FIR filter with 0.25 sample interval phase shift */
  360.         dst[w*(j>>1)] = clp[(int)(8*src[w*jm5]
  361.                             +5*src[w*jm4]
  362.                            -30*src[w*jm3]
  363.                            -18*src[w*jm2]
  364.                           +113*src[w*jm1]
  365.                           +242*src[w*j]
  366.                           +192*src[w*jp1]
  367.                            +35*src[w*jp2]
  368.                            -38*src[w*jp3]
  369.                            -10*src[w*jp4]
  370.                            +11*src[w*jp5]
  371.                             +2*src[w*jp6]+256)>>9];
  372.         /* bottom field */
  373.         jm6 = (j<9) ? 1 : j-9;
  374.         jm5 = (j<7) ? 1 : j-7;
  375.         jm4 = (j<5) ? 1 : j-5;
  376.         jm3 = (j<3) ? 1 : j-3;
  377.         jm2 = (j<1) ? 1 : j-1;
  378.         jm1 = (j<height-1) ? j+1 : height-1;
  379.         jp1 = (j<height-3) ? j+3 : height-1;
  380.         jp2 = (j<height-5) ? j+5 : height-1;
  381.         jp3 = (j<height-7) ? j+7 : height-1;
  382.         jp4 = (j<height-9) ? j+9 : height-1;
  383.         jp5 = (j<height-11) ? j+11 : height-1;
  384.         jp6 = (j<height-13) ? j+13 : height-1;
  385.         /* FIR filter with 0.25 sample interval phase shift */
  386.         dst[w*((j>>1)+1)] = clp[(int)(8*src[w*jp6]
  387.                                 +5*src[w*jp5]
  388.                                -30*src[w*jp4]
  389.                                -18*src[w*jp3]
  390.                               +113*src[w*jp2]
  391.                               +242*src[w*jp1]
  392.                               +192*src[w*jm1]
  393.                                +35*src[w*jm2]
  394.                                -38*src[w*jm3]
  395.                                -10*src[w*jm4]
  396.                                +11*src[w*jm5]
  397.                                 +2*src[w*jm6]+256)>>9];
  398.       }
  399.       src++;
  400.       dst++;
  401.     }
  402.   }
  403. }
  404. /* pbm_getc() and pbm_getint() are essentially taken from
  405.  * PBMPLUS (C) Jef Poskanzer
  406.  * but without error/EOF checking
  407.  */
  408. char pbm_getc(file)
  409. FILE* file;
  410. {
  411.   char ch;
  412.   ch = getc(file);
  413.   if (ch=='#')
  414.   {
  415.     do
  416.     {
  417.       ch = getc(file);
  418.     }
  419.     while (ch!='n' && ch!='r');
  420.   }
  421.   return ch;
  422. }
  423. int pbm_getint(file)
  424. FILE* file;
  425. {
  426.   char ch;
  427.   int i;
  428.   do
  429.   {
  430.     ch = pbm_getc(file);
  431.   }
  432.   while (ch==' ' || ch=='t' || ch=='n' || ch=='r');
  433.   i = 0;
  434.   do
  435.   {
  436.     i = i*10 + ch-'0';
  437.     ch = pbm_getc(file);
  438.   }
  439.   while (ch>='0' && ch<='9');
  440.   return i;
  441. }