📄 readpic.c
字号:
/* readpic.c, read source pictures *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group 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 MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, 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. * */#include <stdio.h>#include <stdlib.h>#include "config.h"#include "global.h"/* private prototypes */static void read_y_u_v _ANSI_ARGS_((char *fname, unsigned char *frame[]));static void read_yuv _ANSI_ARGS_((char *fname, unsigned char *frame[]));static void read_ppm _ANSI_ARGS_((char *fname, unsigned char *frame[]));static void border_extend _ANSI_ARGS_((unsigned char *frame, int w1, int h1, int w2, int h2));static void conv444to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));static void conv422to420 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
//lspseq
//read a frame from the seq file
void readframe2(fname,num,frame)
char *fname;
int num;
unsigned char *frame[];
{
int i;
int chrom_hsize, chrom_vsize;
int frame_size;
FILE *fd;
chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
: horizontal_size>>1;
chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
: vertical_size>>1;
frame_size= horizontal_size*vertical_size+2*chrom_hsize*chrom_vsize;
if (!(fd = fopen(fname,"rb")))
{
sprintf(errortext,"Couldn't open %s\n",fname);
error(errortext);
}
//seek to the target frame
fseek(fd,num*frame_size,SEEK_SET);
/* Y */
for (i=0; i<vertical_size; i++)
fread(frame[0]+i*width,1,horizontal_size,fd);
border_extend(frame[0],horizontal_size,vertical_size,width,height);
/* Cb */
for (i=0; i<chrom_vsize; i++)
fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
/* Cr */
for (i=0; i<chrom_vsize; i++)
fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
fclose(fd);
}
//lspseq end
void readframe(fname,frame)char *fname;unsigned char *frame[];{ switch (inputtype) { case T_Y_U_V: read_y_u_v(fname,frame); break; case T_YUV: read_yuv(fname,frame); break; case T_PPM: read_ppm(fname,frame); break; default: break; }}static void read_y_u_v(fname,frame)char *fname;unsigned char *frame[];{ int i; int chrom_hsize, chrom_vsize; char name[128]; FILE *fd; chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size : horizontal_size>>1; chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size : vertical_size>>1; sprintf(name,"%s.Y",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } for (i=0; i<vertical_size; i++) fread(frame[0]+i*width,1,horizontal_size,fd); fclose(fd); border_extend(frame[0],horizontal_size,vertical_size,width,height); sprintf(name,"%s.U",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } for (i=0; i<chrom_vsize; i++) fread(frame[1]+i*chrom_width,1,chrom_hsize,fd); fclose(fd); border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height); sprintf(name,"%s.V",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } for (i=0; i<chrom_vsize; i++) fread(frame[2]+i*chrom_width,1,chrom_hsize,fd); fclose(fd); border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);}static void read_yuv(fname,frame)char *fname;unsigned char *frame[];{ int i; int chrom_hsize, chrom_vsize; char name[128]; FILE *fd; chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size : horizontal_size>>1; chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size : vertical_size>>1; sprintf(name,"%s.yuv",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } /* Y */ for (i=0; i<vertical_size; i++) fread(frame[0]+i*width,1,horizontal_size,fd); border_extend(frame[0],horizontal_size,vertical_size,width,height); /* Cb */ for (i=0; i<chrom_vsize; i++) fread(frame[1]+i*chrom_width,1,chrom_hsize,fd); border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height); /* Cr */ for (i=0; i<chrom_vsize; i++) fread(frame[2]+i*chrom_width,1,chrom_hsize,fd); border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height); fclose(fd);}static void read_ppm(fname,frame)char *fname;unsigned char *frame[];{ int i, j; int r, g, b; double y, u, v; double cr, cg, cb, cu, cv; char name[128]; FILE *fd; unsigned char *yp, *up, *vp; static unsigned char *u444, *v444, *u422, *v422; static double coef[7][3] = { {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */ {0.299, 0.587, 0.114}, /* unspecified */ {0.299, 0.587, 0.114}, /* reserved */ {0.30, 0.59, 0.11}, /* FCC */ {0.299, 0.587, 0.114}, /* ITU-R Rec. 624-4 System B, G */ {0.299, 0.587, 0.114}, /* SMPTE 170M */ {0.212, 0.701, 0.087}}; /* SMPTE 240M (1987) */ i = matrix_coefficients; if (i>8) i = 3; cr = coef[i-1][0]; cg = coef[i-1][1]; cb = coef[i-1][2]; cu = 0.5/(1.0-cb); cv = 0.5/(1.0-cr); if (chroma_format==CHROMA444) { u444 = frame[1]; v444 = frame[2]; } else { if (!u444) { if (!(u444 = (unsigned char *)malloc(width*height))) error("malloc failed"); if (!(v444 = (unsigned char *)malloc(width*height))) error("malloc failed"); if (chroma_format==CHROMA420) { if (!(u422 = (unsigned char *)malloc((width>>1)*height))) error("malloc failed"); if (!(v422 = (unsigned char *)malloc((width>>1)*height))) error("malloc failed"); } } } sprintf(name,"%s.ppm",fname); if (!(fd = fopen(name,"rb"))) { sprintf(errortext,"Couldn't open %s\n",name); error(errortext); } /* skip header */ getc(fd); getc(fd); /* magic number (P6) */ pbm_getint(fd); pbm_getint(fd); pbm_getint(fd); /* width height maxcolors */ for (i=0; i<vertical_size; i++) { yp = frame[0] + i*width; up = u444 + i*width; vp = v444 + i*width; for (j=0; j<horizontal_size; j++) { r=getc(fd); g=getc(fd); b=getc(fd); /* convert to YUV */ y = cr*r + cg*g + cb*b; u = cu*(b-y); v = cv*(r-y); yp[j] = (219.0/256.0)*y + 16.5; /* nominal range: 16..235 */ up[j] = (224.0/256.0)*u + 128.5; /* 16..240 */ vp[j] = (224.0/256.0)*v + 128.5; /* 16..240 */ } } fclose(fd); border_extend(frame[0],horizontal_size,vertical_size,width,height); border_extend(u444,horizontal_size,vertical_size,width,height); border_extend(v444,horizontal_size,vertical_size,width,height); if (chroma_format==CHROMA422) { conv444to422(u444,frame[1]); conv444to422(v444,frame[2]); } if (chroma_format==CHROMA420) { conv444to422(u444,u422); conv444to422(v444,v422); conv422to420(u422,frame[1]); conv422to420(v422,frame[2]); }}static void border_extend(frame,w1,h1,w2,h2)unsigned char *frame;int w1,h1,w2,h2;{ int i, j; unsigned char *fp; /* horizontal pixel replication (right border) */ for (j=0; j<h1; j++) { fp = frame + j*w2; for (i=w1; i<w2; i++) fp[i] = fp[i-1]; } /* vertical pixel replication (bottom border) */ for (j=h1; j<h2; j++) { fp = frame + j*w2; for (i=0; i<w2; i++) fp[i] = fp[i-w2]; }}/* horizontal filter and 2:1 subsampling */static void conv444to422(src,dst)unsigned char *src, *dst;{ int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6; if (mpeg1) { for (j=0; j<height; j++) { for (i=0; i<width; i+=2) { im5 = (i<5) ? 0 : i-5; im4 = (i<4) ? 0 : i-4; im3 = (i<3) ? 0 : i-3; im2 = (i<2) ? 0 : i-2; im1 = (i<1) ? 0 : i-1; ip1 = (i<width-1) ? i+1 : width-1; ip2 = (i<width-2) ? i+2 : width-1; ip3 = (i<width-3) ? i+3 : width-1; ip4 = (i<width-4) ? i+4 : width-1; ip5 = (i<width-5) ? i+5 : width-1; ip6 = (i<width-5) ? i+6 : width-1; /* FIR filter with 0.5 sample interval phase shift */ dst[i>>1] = clp[(int)(228*(src[i]+src[ip1]) +70*(src[im1]+src[ip2]) -37*(src[im2]+src[ip3]) -21*(src[im3]+src[ip4]) +11*(src[im4]+src[ip5]) + 5*(src[im5]+src[ip6])+256)>>9]; } src+= width; dst+= width>>1; } } else { /* MPEG-2 */ for (j=0; j<height; j++) { for (i=0; i<width; i+=2) { im5 = (i<5) ? 0 : i-5; im3 = (i<3) ? 0 : i-3; im1 = (i<1) ? 0 : i-1; ip1 = (i<width-1) ? i+1 : width-1; ip3 = (i<width-3) ? i+3 : width-1; ip5 = (i<width-5) ? i+5 : width-1; /* FIR filter coefficients (*512): 22 0 -52 0 159 256 159 0 -52 0 22 */ dst[i>>1] = clp[(int)( 22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3]) +159*(src[im1]+src[ip1])+256*src[i]+256)>>9]; } src+= width; dst+= width>>1; } }}/* vertical filter and 2:1 subsampling */static void conv422to420(src,dst)unsigned char *src, *dst;{ int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1; int jp1, jp2, jp3, jp4, jp5, jp6; w = width>>1; if (prog_frame) { /* intra frame */ for (i=0; i<w; i++) { for (j=0; j<height; j+=2) { jm5 = (j<5) ? 0 : j-5; jm4 = (j<4) ? 0 : j-4; jm3 = (j<3) ? 0 : j-3; jm2 = (j<2) ? 0 : j-2; jm1 = (j<1) ? 0 : j-1; jp1 = (j<height-1) ? j+1 : height-1; jp2 = (j<height-2) ? j+2 : height-1; jp3 = (j<height-3) ? j+3 : height-1; jp4 = (j<height-4) ? j+4 : height-1; jp5 = (j<height-5) ? j+5 : height-1; jp6 = (j<height-5) ? j+6 : height-1; /* FIR filter with 0.5 sample interval phase shift */ dst[w*(j>>1)] = clp[(int)(228*(src[w*j]+src[w*jp1]) +70*(src[w*jm1]+src[w*jp2]) -37*(src[w*jm2]+src[w*jp3]) -21*(src[w*jm3]+src[w*jp4]) +11*(src[w*jm4]+src[w*jp5]) + 5*(src[w*jm5]+src[w*jp6])+256)>>9]; } src++; dst++; } } else { /* intra field */ for (i=0; i<w; i++) { for (j=0; j<height; j+=4) { /* top field */ jm5 = (j<10) ? 0 : j-10; jm4 = (j<8) ? 0 : j-8; jm3 = (j<6) ? 0 : j-6; jm2 = (j<4) ? 0 : j-4; jm1 = (j<2) ? 0 : j-2; jp1 = (j<height-2) ? j+2 : height-2; jp2 = (j<height-4) ? j+4 : height-2; jp3 = (j<height-6) ? j+6 : height-2; jp4 = (j<height-8) ? j+8 : height-2; jp5 = (j<height-10) ? j+10 : height-2; jp6 = (j<height-12) ? j+12 : height-2; /* FIR filter with 0.25 sample interval phase shift */ dst[w*(j>>1)] = clp[(int)(8*src[w*jm5] +5*src[w*jm4] -30*src[w*jm3] -18*src[w*jm2] +113*src[w*jm1] +242*src[w*j] +192*src[w*jp1] +35*src[w*jp2] -38*src[w*jp3] -10*src[w*jp4] +11*src[w*jp5] +2*src[w*jp6]+256)>>9]; /* bottom field */ jm6 = (j<9) ? 1 : j-9; jm5 = (j<7) ? 1 : j-7; jm4 = (j<5) ? 1 : j-5; jm3 = (j<3) ? 1 : j-3; jm2 = (j<1) ? 1 : j-1; jm1 = (j<height-1) ? j+1 : height-1; jp1 = (j<height-3) ? j+3 : height-1; jp2 = (j<height-5) ? j+5 : height-1; jp3 = (j<height-7) ? j+7 : height-1; jp4 = (j<height-9) ? j+9 : height-1; jp5 = (j<height-11) ? j+11 : height-1; jp6 = (j<height-13) ? j+13 : height-1; /* FIR filter with 0.25 sample interval phase shift */ dst[w*((j>>1)+1)] = clp[(int)(8*src[w*jp6] +5*src[w*jp5] -30*src[w*jp4] -18*src[w*jp3] +113*src[w*jp2] +242*src[w*jp1] +192*src[w*jm1] +35*src[w*jm2] -38*src[w*jm3] -10*src[w*jm4] +11*src[w*jm5] +2*src[w*jm6]+256)>>9]; } src++; dst++; } }}/* pbm_getc() and pbm_getint() are essentially taken from * PBMPLUS (C) Jef Poskanzer * but without error/EOF checking */char pbm_getc(file)FILE* file;{ char ch; ch = getc(file); if (ch=='#') { do { ch = getc(file); } while (ch!='\n' && ch!='\r'); } return ch;}int pbm_getint(file)FILE* file;{ char ch; int i; do { ch = pbm_getc(file); } while (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r'); i = 0; do { i = i*10 + ch-'0'; ch = pbm_getc(file); } while (ch>='0' && ch<='9'); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -