⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 store.c

📁 H.263的压缩算法
💻 C
字号:
/************************************************************************ * *  store.c, picture output routines for tmndecode (H.263 decoder) *  Copyright (C) 1995, 1996  Telenor R&D, Norway * *  Contacts: *  Robert Danielsen                  <Robert.Danielsen@nta.no> * *  Telenor Research and Development  http://www.nta.no/brukere/DVC/ *  P.O.Box 83                        tel.:   +47 63 84 84 00 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76 * *  Copyright (C) 1997  University of BC, Canada *  Modified by: Michael Gallant <mikeg@ee.ubc.ca> *               Guy Cote <guyc@ee.ubc.ca> *               Berna Erol <bernae@ee.ubc.ca> * *  Contacts: *  Michael Gallant                   <mikeg@ee.ubc.ca> * *  UBC Image Processing Laboratory   http://www.ee.ubc.ca/image *  2356 Main Mall                    tel.: +1 604 822 4051 *  Vancouver BC Canada V6T1Z4        fax.: +1 604 822 5949 * ************************************************************************//* Disclaimer of Warranty *  * These software programs are available to the user without any license fee * or royalty on an "as is" basis. The University of British Columbia * disclaims any and all warranties, whether express, implied, or * statuary, including any implied warranties or merchantability or of * fitness for a particular purpose.  In no event shall the * copyright-holder be liable for any incidental, punitive, or * consequential damages of any kind whatsoever arising from the use of * these programs. *  * This disclaimer of warranty extends to the user of these programs and * user's customers, employees, agents, transferees, successors, and * assigns. *  * The University of British Columbia does not represent or warrant that the * programs furnished hereunder are free of infringement of any * third-party patents. *  * Commercial implementations of H.263, including shareware, are subject to * royalty fees to patent holders.  Many of these patents are general * enough such that they are unavoidable regardless of implementation * design. *  *//* based on mpeg2decode, (C) 1994, MPEG Software Simulation Group and * mpeg2play, (C) 1994 Stefan Eckart <stefan@lis.e-technik.tu-muenchen.de> *  */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#ifdef WIN32#include <io.h>#endif#include "config.h"#include "tmndec.h"#include "global.h"#ifdef WINDOWSint displayImage (unsigned char *lum, unsigned char *Cr, unsigned char *Cb);#endif/* private prototypes */static void store_yuv _ANSI_ARGS_ ((char *outname, unsigned char *src[],                                     int offset, int incr, int height));static void store_yuv_append _ANSI_ARGS_ ((char *outname, unsigned char *src[],                                      int offset, int incr, int height));static void store_sif _ANSI_ARGS_ ((char *outname, unsigned char *src[],                                     int offset, int incr, int height));static void store_ppm_tga _ANSI_ARGS_ ((char *outname, unsigned char *src[],                         int offset, int incr, int height, int tgaflag));static void store_yuv1 _ANSI_ARGS_ ((char *name, unsigned char *src,               int offset, int incr, int width, int height, int append));static void putbyte _ANSI_ARGS_ ((int c));static void putword _ANSI_ARGS_ ((int w));static void conv422to444 _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst));static void conv420to422 _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst));#define OBFRSIZE 4096static unsigned char obfr[OBFRSIZE];static unsigned char *optr;static int outfile;/* store a picture as either one frame or two fields */void storeframe (unsigned char *src[], int frame){  char outname[32];  /* progressive */  sprintf (outname, outputname, frame, 'f');  store_one (outname, src, 0, coded_picture_width, vertical_size);}/* store one frame or one field */void store_one (char *outname, unsigned char *src[], int offset, int incr, int height){  switch (outtype)  {    case T_YUV:      store_yuv (outname, src, offset, incr, height);      break;    case T_YUV_CONC:      store_yuv_append (outname, src, offset, incr, height);      break;    case T_SIF:      store_sif (outname, src, offset, incr, height);      break;    case T_TGA:      store_ppm_tga (outname, src, offset, incr, height, 1);      break;    case T_PPM:      store_ppm_tga (outname, src, offset, incr, height, 0);      break;#ifdef DISPLAY    case T_X11:      if (enhancement_layer_num == 1)        dither (src);      break;#endif#ifdef WINDOWS    case T_WIN:      if (enhancement_layer_num == 1)        displayImage (src[0], src[2], src[1]);      break;#endif    default:      break;  }}/* separate headerless files for y, u and v */static void store_yuv (char *outname, unsigned char *src[], int offset, int incr, int height){  int hsize;  char tmpname[32];  hsize = horizontal_size;  sprintf (tmpname, "%s.Y", outname);  store_yuv1 (tmpname, src[0], offset, incr, hsize, height, 0);  offset >>= 1;  incr >>= 1;  hsize >>= 1;  height >>= 1;  sprintf (tmpname, "%s.U", outname);  store_yuv1 (tmpname, src[1], offset, incr, hsize, height, 0);  sprintf (tmpname, "%s.V", outname);  store_yuv1 (tmpname, src[2], offset, incr, hsize, height, 0);}/* concatenated headerless file for y, u and v */static void store_yuv_append (outname, src, offset, incr, height)  char *outname;  unsigned char *src[];int offset, incr, height;{  int hsize;  hsize = horizontal_size;  store_yuv1 (outname, src[0], offset, incr, hsize, height, 1);  offset >>= 1;  incr >>= 1;  hsize >>= 1;  height >>= 1;  store_yuv1 (outname, src[1], offset, incr, hsize, height, 1);  store_yuv1 (outname, src[2], offset, incr, hsize, height, 1);}/* auxiliary routine */static void store_yuv1 (char *name, unsigned char *src, int offset,                         int incr, int width, int height, int append){  int i, j;  unsigned char *p;  if (append)  {    if ((outfile = open (name, O_APPEND | O_WRONLY | O_BINARY, 0666)) == -1)    {      sprintf (errortext, "Couldn't append to %s\n", name);      error (errortext);    }  } else  {    if ((outfile = open (name, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)    {      sprintf (errortext, "Couldn't create %s\n", name);      error (errortext);    }  }  if (!quiet)    fprintf (stderr, "saving %s\n", name);  optr = obfr;  for (i = 0; i < height; i++)  {    p = src + offset + incr * i;    for (j = 0; j < width; j++)      putbyte (*p++);  }  if (optr != obfr)    write (outfile, obfr, optr - obfr);  close (outfile);}/* store as headerless file in U,Y,V,Y format */static void store_sif (char *outname, unsigned char *src[], int offset, int incr, int height){  int i, j;  unsigned char *py, *pu, *pv;  static unsigned char *u422, *v422;  if (!u422)  {    if (!(u422 = (unsigned char *) malloc ((coded_picture_width >> 1)                                           * coded_picture_height)))      error ("malloc failed");    if (!(v422 = (unsigned char *) malloc ((coded_picture_width >> 1)                                           * coded_picture_height)))      error ("malloc failed");  }  conv420to422 (src[1], u422);  conv420to422 (src[2], v422);  strcat (outname, ".SIF");  if (!quiet)    fprintf (stderr, "saving %s\n", outname);  if ((outfile = open (outname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)  {    sprintf (errortext, "Couldn't create %s\n", outname);    error (errortext);  }  optr = obfr;  for (i = 0; i < height; i++)  {    py = src[0] + offset + incr * i;    pu = u422 + (offset >> 1) + (incr >> 1) * i;    pv = v422 + (offset >> 1) + (incr >> 1) * i;    for (j = 0; j < horizontal_size; j += 2)    {      putbyte (*pu++);      putbyte (*py++);      putbyte (*pv++);      putbyte (*py++);    }  }  if (optr != obfr)    write (outfile, obfr, optr - obfr);  close (outfile);}/* store as PPM (PBMPLUS) or uncompressed Truevision TGA ('Targa') file */static void store_ppm_tga (char *outname, unsigned char *src[], int offset, int incr,                            int height, int tgaflag){  int i, j;  int y, u, v, r, g, b;  int crv, cbu, cgu, cgv;  unsigned char *py, *pu, *pv;  static unsigned char tga24[14] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 32};  char header[32];  static unsigned char *u422, *v422, *u444, *v444;  if (!u444)  {    if (!(u422 = (unsigned char *) malloc ((coded_picture_width >> 1)                                           * coded_picture_height)))      error ("malloc failed");    if (!(v422 = (unsigned char *) malloc ((coded_picture_width >> 1)                                           * coded_picture_height)))      error ("malloc failed");    if (!(u444 = (unsigned char *) malloc (coded_picture_width                                           * coded_picture_height)))      error ("malloc failed");    if (!(v444 = (unsigned char *) malloc (coded_picture_width                                           * coded_picture_height)))      error ("malloc failed");  }  conv420to422 (src[1], u422);  conv420to422 (src[2], v422);  conv422to444 (u422, u444);  conv422to444 (v422, v444);  strcat (outname, tgaflag ? ".tga" : ".ppm");  if (!quiet)    fprintf (stderr, "saving %s\n", outname);  if ((outfile = open (outname, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) == -1)  {    sprintf (errortext, "Couldn't create %s\n", outname);    error (errortext);  }  optr = obfr;  if (tgaflag)  {    /* TGA header */    for (i = 0; i < 12; i++)      putbyte (tga24[i]);    putword (horizontal_size);    putword (height);    putbyte (tga24[12]);    putbyte (tga24[13]);  } else  {    /* PPM header */    sprintf (header, "P6\n%d %d\n255\n", horizontal_size, height);    for (i = 0; header[i] != 0; i++)      putbyte (header[i]);  }  /* matrix coefficients */  crv = convmat[matrix_coefficients][0];  cbu = convmat[matrix_coefficients][1];  cgu = convmat[matrix_coefficients][2];  cgv = convmat[matrix_coefficients][3];  for (i = 0; i < height; i++)  {    py = src[0] + offset + incr * i;    pu = u444 + offset + incr * i;    pv = v444 + offset + incr * i;    for (j = 0; j < horizontal_size; j++)    {      u = *pu++ - 128;      v = *pv++ - 128;      y = 76309 * (*py++ - 16); /* (255/219)*65536 */      r = clp[(y + crv * v + 32768) >> 16];      g = clp[(y - cgu * u - cgv * v + 32768) >> 16];      b = clp[(y + cbu * u + 32786) >> 16];      if (tgaflag)      {        putbyte (b);        putbyte (g);        putbyte (r);      } else      {        putbyte (r);        putbyte (g);        putbyte (b);      }    }  }  if (optr != obfr)    write (outfile, obfr, optr - obfr);  close (outfile);}static void putbyte (int c){  *optr++ = c;  if (optr == obfr + OBFRSIZE)  {    write (outfile, obfr, OBFRSIZE);    optr = obfr;  }}static void putword (int w){  putbyte (w);  putbyte (w >> 8);}/* horizontal 1:2 interpolation filter */static void conv422to444 (unsigned char *src, unsigned char *dst){  int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3;  w = coded_picture_width >> 1;  for (j = 0; j < coded_picture_height; j++)  {    for (i = 0; i < w; i++)    {      i2 = i << 1;      im3 = (i < 3) ? 0 : i - 3;      im2 = (i < 2) ? 0 : i - 2;      im1 = (i < 1) ? 0 : i - 1;      ip1 = (i < w - 1) ? i + 1 : w - 1;      ip2 = (i < w - 2) ? i + 2 : w - 1;      ip3 = (i < w - 3) ? i + 3 : w - 1;      /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */      dst[i2] = clp[(int) (5 * src[im3]                           - 21 * src[im2]                           + 70 * src[im1]                           + 228 * src[i]                           - 37 * src[ip1]                           + 11 * src[ip2] + 128) >> 8];      dst[i2 + 1] = clp[(int) (5 * src[ip3]                               - 21 * src[ip2]                               + 70 * src[ip1]                               + 228 * src[i]                               - 37 * src[im1]                               + 11 * src[im2] + 128) >> 8];    }    src += w;    dst += coded_picture_width;  }}/* vertical 1:2 interpolation filter */static void conv420to422 (unsigned char *src, unsigned char *dst){  int w, h, i, j, j2;  int jm3, jm2, jm1, jp1, jp2, jp3;  w = coded_picture_width >> 1;  h = coded_picture_height >> 1;  /* intra frame */  for (i = 0; i < w; i++)  {    for (j = 0; j < h; j++)    {      j2 = j << 1;      jm3 = (j < 3) ? 0 : j - 3;      jm2 = (j < 2) ? 0 : j - 2;      jm1 = (j < 1) ? 0 : j - 1;      jp1 = (j < h - 1) ? j + 1 : h - 1;      jp2 = (j < h - 2) ? j + 2 : h - 1;      jp3 = (j < h - 3) ? j + 3 : h - 1;      /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */      /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */      dst[w * j2] = clp[(int) (3 * src[w * jm3]                               - 16 * src[w * jm2]                               + 67 * src[w * jm1]                               + 227 * src[w * j]                               - 32 * src[w * jp1]                               + 7 * src[w * jp2] + 128) >> 8];      dst[w * (j2 + 1)] = clp[(int) (3 * src[w * jp3]                                     - 16 * src[w * jp2]                                     + 67 * src[w * jp1]                                     + 227 * src[w * j]                                     - 32 * src[w * jm1]                                     + 7 * src[w * jm2] + 128) >> 8];    }    src++;    dst++;  }}/* Stores 1 frame to a file in a raw format */void save_frame (unsigned char *src[], int framenum, FILE *file){  unsigned char *lum;  unsigned char *Cr;  unsigned char *Cb;  lum = src[0];  Cb = src[1];  Cr = src[2];  if ((int) fwrite (lum, sizeof (unsigned char), coded_picture_height * coded_picture_width,                    file) != coded_picture_height * coded_picture_width)  {    fprintf (stdout, "Error occured when writing reconstructed data\n");    exit (-1);  }  if ((int) fwrite (Cb, sizeof (unsigned char), coded_picture_height * coded_picture_width / 4,                 file) != coded_picture_height * coded_picture_width / 4)  {    fprintf (stdout, "Error occured when writing reconstructed data\n");    exit (-1);  }  if ((int) fwrite (Cr, sizeof (unsigned char), coded_picture_height * coded_picture_width / 4,                 file) != coded_picture_height * coded_picture_width / 4)  {    fprintf (stdout, "Error occured when writing reconstructed data\n");    exit (-1);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -