1 /* readpic.c, read source pictures */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
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.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
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
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
35 /* private prototypes */
36 static void read_y_u_v _ANSI_ARGS_((char *fname, unsigned char *frame[]));
37 static void read_yuv _ANSI_ARGS_((char *fname, unsigned char *frame[]));
38 static void read_ppm _ANSI_ARGS_((char *fname, unsigned char *frame[]));
39 static void border_extend _ANSI_ARGS_((unsigned char *frame, int w1, int h1,
41 static void conv444to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
42 static void conv422to420 _ANSI_ARGS_((unsigned char *src, unsigned char *dst));
44 int pbm_getint(FILE *file); //forward declaration
46 void readframe(fname,frame)
48 unsigned char *frame[];
53 read_y_u_v(fname,frame);
56 read_yuv(fname,frame);
59 read_ppm(fname,frame);
66 static void read_y_u_v(fname,frame)
68 unsigned char *frame[];
71 int chrom_hsize, chrom_vsize;
75 chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
77 chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
80 sprintf(name,"%s.Y",fname);
81 if (!(fd = fopen(name,"rb")))
83 sprintf(errortext,"Couldn't open %s\n",name);
86 for (i=0; i<vertical_size; i++)
87 fread(frame[0]+i*width,1,horizontal_size,fd);
89 border_extend(frame[0],horizontal_size,vertical_size,width,height);
91 sprintf(name,"%s.U",fname);
92 if (!(fd = fopen(name,"rb")))
94 sprintf(errortext,"Couldn't open %s\n",name);
97 for (i=0; i<chrom_vsize; i++)
98 fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
100 border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
102 sprintf(name,"%s.V",fname);
103 if (!(fd = fopen(name,"rb")))
105 sprintf(errortext,"Couldn't open %s\n",name);
108 for (i=0; i<chrom_vsize; i++)
109 fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
111 border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
114 static void read_yuv(fname,frame)
116 unsigned char *frame[];
119 int chrom_hsize, chrom_vsize;
123 chrom_hsize = (chroma_format==CHROMA444) ? horizontal_size
124 : horizontal_size>>1;
125 chrom_vsize = (chroma_format!=CHROMA420) ? vertical_size
128 sprintf(name,"%s.yuv",fname);
129 if (!(fd = fopen(name,"rb")))
131 sprintf(errortext,"Couldn't open %s\n",name);
136 for (i=0; i<vertical_size; i++)
137 fread(frame[0]+i*width,1,horizontal_size,fd);
138 border_extend(frame[0],horizontal_size,vertical_size,width,height);
141 for (i=0; i<chrom_vsize; i++)
142 fread(frame[1]+i*chrom_width,1,chrom_hsize,fd);
143 border_extend(frame[1],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
146 for (i=0; i<chrom_vsize; i++)
147 fread(frame[2]+i*chrom_width,1,chrom_hsize,fd);
148 border_extend(frame[2],chrom_hsize,chrom_vsize,chrom_width,chrom_height);
153 static void read_ppm(fname,frame)
155 unsigned char *frame[];
160 double cr, cg, cb, cu, cv;
163 unsigned char *yp, *up, *vp;
164 static unsigned char *u444, *v444, *u422, *v422;
165 static double coef[7][3] = {
166 {0.2125,0.7154,0.0721}, /* ITU-R Rec. 709 (1990) */
167 {0.299, 0.587, 0.114}, /* unspecified */
168 {0.299, 0.587, 0.114}, /* reserved */
169 {0.30, 0.59, 0.11}, /* FCC */
170 {0.299, 0.587, 0.114}, /* ITU-R Rec. 624-4 System B, G */
171 {0.299, 0.587, 0.114}, /* SMPTE 170M */
172 {0.212, 0.701, 0.087}}; /* SMPTE 240M (1987) */
174 i = matrix_coefficients;
184 if (chroma_format==CHROMA444)
193 if (!(u444 = (unsigned char *)malloc(width*height)))
194 error("malloc failed");
195 if (!(v444 = (unsigned char *)malloc(width*height)))
196 error("malloc failed");
197 if (chroma_format==CHROMA420)
199 if (!(u422 = (unsigned char *)malloc((width>>1)*height)))
200 error("malloc failed");
201 if (!(v422 = (unsigned char *)malloc((width>>1)*height)))
202 error("malloc failed");
207 sprintf(name,"%s.ppm",fname);
209 if (!(fd = fopen(name,"rb")))
211 sprintf(errortext,"Couldn't open %s\n",name);
216 getc(fd); getc(fd); /* magic number (P6) */
217 pbm_getint(fd); pbm_getint(fd); pbm_getint(fd); /* width height maxcolors */
219 for (i=0; i<vertical_size; i++)
221 yp = frame[0] + i*width;
225 for (j=0; j<horizontal_size; j++)
227 r=getc(fd); g=getc(fd); b=getc(fd);
229 y = cr*r + cg*g + cb*b;
232 yp[j] = (unsigned char)((219.0/256.0)*y + 16.5); /* nominal range: 16..235 */
233 up[j] = (unsigned char)((224.0/256.0)*u + 128.5); /* 16..240 */
234 vp[j] = (unsigned char)((224.0/256.0)*v + 128.5); /* 16..240 */
239 border_extend(frame[0],horizontal_size,vertical_size,width,height);
240 border_extend(u444,horizontal_size,vertical_size,width,height);
241 border_extend(v444,horizontal_size,vertical_size,width,height);
243 if (chroma_format==CHROMA422)
245 conv444to422(u444,frame[1]);
246 conv444to422(v444,frame[2]);
249 if (chroma_format==CHROMA420)
251 conv444to422(u444,u422);
252 conv444to422(v444,v422);
253 conv422to420(u422,frame[1]);
254 conv422to420(v422,frame[2]);
258 static void border_extend(frame,w1,h1,w2,h2)
259 unsigned char *frame;
265 /* horizontal pixel replication (right border) */
270 for (i=w1; i<w2; i++)
274 /* vertical pixel replication (bottom border) */
276 for (j=h1; j<h2; j++)
284 /* horizontal filter and 2:1 subsampling */
285 static void conv444to422(src,dst)
286 unsigned char *src, *dst;
288 int i, j, im5, im4, im3, im2, im1, ip1, ip2, ip3, ip4, ip5, ip6;
292 for (j=0; j<height; j++)
294 for (i=0; i<width; i+=2)
296 im5 = (i<5) ? 0 : i-5;
297 im4 = (i<4) ? 0 : i-4;
298 im3 = (i<3) ? 0 : i-3;
299 im2 = (i<2) ? 0 : i-2;
300 im1 = (i<1) ? 0 : i-1;
301 ip1 = (i<width-1) ? i+1 : width-1;
302 ip2 = (i<width-2) ? i+2 : width-1;
303 ip3 = (i<width-3) ? i+3 : width-1;
304 ip4 = (i<width-4) ? i+4 : width-1;
305 ip5 = (i<width-5) ? i+5 : width-1;
306 ip6 = (i<width-5) ? i+6 : width-1;
308 /* FIR filter with 0.5 sample interval phase shift */
309 dst[i>>1] = clp[(int)(228*(src[i]+src[ip1])
310 +70*(src[im1]+src[ip2])
311 -37*(src[im2]+src[ip3])
312 -21*(src[im3]+src[ip4])
313 +11*(src[im4]+src[ip5])
314 + 5*(src[im5]+src[ip6])+256)>>9];
323 for (j=0; j<height; j++)
325 for (i=0; i<width; i+=2)
327 im5 = (i<5) ? 0 : i-5;
328 im3 = (i<3) ? 0 : i-3;
329 im1 = (i<1) ? 0 : i-1;
330 ip1 = (i<width-1) ? i+1 : width-1;
331 ip3 = (i<width-3) ? i+3 : width-1;
332 ip5 = (i<width-5) ? i+5 : width-1;
334 /* FIR filter coefficients (*512): 22 0 -52 0 159 256 159 0 -52 0 22 */
335 dst[i>>1] = clp[(int)( 22*(src[im5]+src[ip5])-52*(src[im3]+src[ip3])
336 +159*(src[im1]+src[ip1])+256*src[i]+256)>>9];
344 /* vertical filter and 2:1 subsampling */
345 static void conv422to420(src,dst)
346 unsigned char *src, *dst;
348 int w, i, j, jm6, jm5, jm4, jm3, jm2, jm1;
349 int jp1, jp2, jp3, jp4, jp5, jp6;
358 for (j=0; j<height; j+=2)
360 jm5 = (j<5) ? 0 : j-5;
361 jm4 = (j<4) ? 0 : j-4;
362 jm3 = (j<3) ? 0 : j-3;
363 jm2 = (j<2) ? 0 : j-2;
364 jm1 = (j<1) ? 0 : j-1;
365 jp1 = (j<height-1) ? j+1 : height-1;
366 jp2 = (j<height-2) ? j+2 : height-1;
367 jp3 = (j<height-3) ? j+3 : height-1;
368 jp4 = (j<height-4) ? j+4 : height-1;
369 jp5 = (j<height-5) ? j+5 : height-1;
370 jp6 = (j<height-5) ? j+6 : height-1;
372 /* FIR filter with 0.5 sample interval phase shift */
373 dst[w*(j>>1)] = clp[(int)(228*(src[w*j]+src[w*jp1])
374 +70*(src[w*jm1]+src[w*jp2])
375 -37*(src[w*jm2]+src[w*jp3])
376 -21*(src[w*jm3]+src[w*jp4])
377 +11*(src[w*jm4]+src[w*jp5])
378 + 5*(src[w*jm5]+src[w*jp6])+256)>>9];
389 for (j=0; j<height; j+=4)
392 jm5 = (j<10) ? 0 : j-10;
393 jm4 = (j<8) ? 0 : j-8;
394 jm3 = (j<6) ? 0 : j-6;
395 jm2 = (j<4) ? 0 : j-4;
396 jm1 = (j<2) ? 0 : j-2;
397 jp1 = (j<height-2) ? j+2 : height-2;
398 jp2 = (j<height-4) ? j+4 : height-2;
399 jp3 = (j<height-6) ? j+6 : height-2;
400 jp4 = (j<height-8) ? j+8 : height-2;
401 jp5 = (j<height-10) ? j+10 : height-2;
402 jp6 = (j<height-12) ? j+12 : height-2;
404 /* FIR filter with 0.25 sample interval phase shift */
405 dst[w*(j>>1)] = clp[(int)(8*src[w*jm5]
416 +2*src[w*jp6]+256)>>9];
419 jm6 = (j<9) ? 1 : j-9;
420 jm5 = (j<7) ? 1 : j-7;
421 jm4 = (j<5) ? 1 : j-5;
422 jm3 = (j<3) ? 1 : j-3;
423 jm2 = (j<1) ? 1 : j-1;
424 jm1 = (j<height-1) ? j+1 : height-1;
425 jp1 = (j<height-3) ? j+3 : height-1;
426 jp2 = (j<height-5) ? j+5 : height-1;
427 jp3 = (j<height-7) ? j+7 : height-1;
428 jp4 = (j<height-9) ? j+9 : height-1;
429 jp5 = (j<height-11) ? j+11 : height-1;
430 jp6 = (j<height-13) ? j+13 : height-1;
432 /* FIR filter with 0.25 sample interval phase shift */
433 dst[w*((j>>1)+1)] = clp[(int)(8*src[w*jp6]
444 +2*src[w*jm6]+256)>>9];
452 /* pbm_getc() and pbm_getint() are essentially taken from
453 * PBMPLUS (C) Jef Poskanzer
454 * but without error/EOF checking
469 while (ch!='\n' && ch!='\r');
485 while (ch==' ' || ch=='\t' || ch=='\n' || ch=='\r');
493 while (ch>='0' && ch<='9');