/*===========================================================================* * readframe.c * * procedures to read in frames * * EXPORTED PROCEDURES: * ReadFrame * SetFileType * SetFileFormat * *===========================================================================*/ /* COPYRIGHT INFORMATION IS AT THE END OF THIS FILE */ /*==============* * HEADER FILES * *==============*/ #define _DEFAULT_SOURCE /* New name for SVID & BSD source defines */ #define _BSD_SOURCE /* Make sure popen() is in stdio.h */ #include "all.h" #include #include #include #include #include #include #include #include "ppm.h" #include "nstring.h" #include "mtypes.h" #include "frames.h" #include "prototypes.h" #include "parallel.h" #include "param.h" #include "input.h" #include "fsize.h" #include "rgbtoycc.h" #include "jpeg.h" #include "opts.h" #include "readframe.h" /*==================* * STATIC VARIABLES * *==================*/ static int fileType = BASE_FILE_TYPE; struct YuvLine { uint8 data[3072]; uint8 y[1024]; int8 cr[1024]; int8 cb[1024]; }; /*==================* * Portability * *==================*/ #ifdef __OS2__ #define popen _popen #endif /*==================* * Global VARIABLES * *==================*/ boolean resizeFrame; const char *CurrFile; /*===============================* * INTERNAL PROCEDURE prototypes * *===============================*/ static void ReadEYUV (MpegFrame * mf, FILE *fpointer, int width, int height); static void ReadAYUV (MpegFrame * mf, FILE *fpointer, int width, int height); static void SeparateLine (FILE *fpointer, struct YuvLine *lineptr, int width); static void ReadY (MpegFrame * mf, FILE *fpointer, int width, int height); static void ReadSub4 (MpegFrame * mf, FILE *fpointer, int width, int height); static void DoGamma (MpegFrame *mf, int width, int height); static void DoKillDim (MpegFrame *mf, int w, int h); #define safe_fread(ptr,sz,len,fileptr) \ if ((safe_read_count=fread(ptr,sz,len,fileptr))!=sz*len) { \ fprintf(stderr,"Input file too small! (%s)\n",CurrFile); \ exit(1);} \ /*=====================* * EXPORTED PROCEDURES * *=====================*/ void SetResize(bool const set) { resizeFrame = set; } static void ReadPNM(MpegFrame * const mpegFrameP, FILE * const fp) { /*---------------------------------------------------------------------------- Read a PPM file containing one movie frame. -----------------------------------------------------------------------------*/ int pnmCols, pnmRows; xelval maxval; xel ** xels; xels = ppm_readppm(fp, &pnmCols, &pnmRows, &maxval); ERRCHK(mpegFrameP, "ppm_readppm"); /* * if this is the first frame read, set the global frame size */ Fsize_Note(mpegFrameP->id, pnmCols, pnmRows); PNMtoYUV(mpegFrameP, xels, Fsize_x, Fsize_y, maxval); ppm_freearray(xels, pnmRows); } static void openFile(struct inputSource * const inputSourceP, unsigned int const frameNumber, const char * const conversion, FILE ** const ifPP) { if (inputSourceP->stdinUsed) { if (fileType == ANY_FILE_TYPE) pm_error( "ERROR : You cannot use a converter on frames when " "you supply them as Standard Input. Either specify " "INPUT_CONVERTER * in the parameter file or supply the " "frames in files by specifying a directory with " "INPUT_DIRECTORY in the parameter file."); *ifPP = stdin; } else { const char * fileName; const char * fullFileName; GetNthInputFileName(inputSourceP, frameNumber, &fileName); pm_asprintf(&fullFileName, "%s/%s", currentPath, fileName); CurrFile = fullFileName; if (fileType == ANY_FILE_TYPE) { char command[1024]; const char * convertPtr; char * commandPtr; const char * charPtr; /* replace every occurrence of '*' with fullFileName */ convertPtr = conversion; commandPtr = command; while (*convertPtr != '\0') { while ((*convertPtr != '\0') && (*convertPtr != '*')) { *commandPtr = *convertPtr; ++commandPtr; ++convertPtr; } if (*convertPtr == '*') { /* copy fullFileName */ charPtr = fullFileName; while (*charPtr != '\0') { *commandPtr = *charPtr; ++commandPtr; ++charPtr; } ++convertPtr; /* go past '*' */ } } *commandPtr = '\0'; *ifPP = popen(command, "r"); if (*ifPP == NULL) { pm_message( "ERROR: Couldn't execute input conversion command " "'%s'. errno=%d (%s)", command, errno, strerror(errno)); if (ioServer) pm_error("IO SERVER: EXITING!!!"); else pm_error("SLAVE EXITING!!!"); } } else { *ifPP = fopen(fullFileName, "rb"); if (*ifPP == NULL) pm_error("Couldn't open input file '%s'", fullFileName); if (baseFormat == JMOVIE_FILE_TYPE) unlink(fullFileName); } pm_strfree(fullFileName); pm_strfree(fileName); } } static void closeFile(struct inputSource * const inputSourceP, FILE * const ifP) { if (!inputSourceP->stdinUsed) { if (fileType == ANY_FILE_TYPE) { int rc; rc = pclose(ifP); if (rc != 0) pm_message("WARNING: pclose() failed with errno %d (%s)", errno, strerror(errno)); } else fclose(ifP); } } static bool fileIsAtEnd(FILE * const ifP) { int c; bool eof; c = getc(ifP); if (c == EOF) { if (feof(ifP)) eof = TRUE; else pm_error("File error on getc() to position to image"); } else { int rc; eof = FALSE; rc = ungetc(c, ifP); if (rc == EOF) pm_error("File error doing ungetc() to position to image."); } return eof; } void ReadFrameFile(MpegFrame * const frameP, FILE * const ifP, const char * const conversion, bool * const eofP) { /*---------------------------------------------------------------------------- Read a frame from the file 'ifP', doing adjustments as indicated. Return *eofP == TRUE iff we encounter EOF before we can get the frame. -----------------------------------------------------------------------------*/ /* To make this code fit Netpbm properly, we should remove handling of all types except PNM and use pm_nextimage() to handle sensing of end of stream. */ if (fileIsAtEnd(ifP)) *eofP = TRUE; else { MpegFrame preResizeFrame; /* The frame object that holds the frame before resizing */ MpegFrame * rawFrameP; /* The frame object with which we read in the raw frame */ *eofP = FALSE; if (resizeFrame) { preResizeFrame.inUse = FALSE; preResizeFrame.orig_y = NULL; preResizeFrame.y_blocks = NULL; preResizeFrame.decoded_y = NULL; preResizeFrame.halfX = NULL; rawFrameP = &preResizeFrame; } else rawFrameP = frameP; switch(baseFormat) { case YUV_FILE_TYPE: /* Encoder YUV */ if ((strncmp (yuvConversion, "EYUV", 4) == 0) || (strncmp (yuvConversion, "UCB", 3) == 0)) ReadEYUV(rawFrameP, ifP, realWidth, realHeight); else /* Abekas-type (interlaced) YUV */ ReadAYUV(rawFrameP, ifP, realWidth, realHeight); break; case Y_FILE_TYPE: ReadY(rawFrameP, ifP, realWidth, realHeight); break; case PNM_FILE_TYPE: ReadPNM(rawFrameP, ifP); break; case SUB4_FILE_TYPE: ReadSub4(rawFrameP, ifP, yuvWidth, yuvHeight); break; case JPEG_FILE_TYPE: case JMOVIE_FILE_TYPE: ReadJPEG(rawFrameP, ifP); break; default: break; } if (resizeFrame) { assert(rawFrameP == &preResizeFrame); Frame_Resize(frameP, &preResizeFrame, Fsize_x, Fsize_y, outputWidth, outputHeight); } if (GammaCorrection) DoGamma(frameP, Fsize_x, Fsize_y); if (kill_dim) DoKillDim(frameP, Fsize_x, Fsize_y); MotionSearchPreComputation(frameP); } } void ReadFrame(MpegFrame * const frameP, struct inputSource * const inputSourceP, unsigned int const frameNumber, const char * const conversion, bool * const endOfStreamP) { /*---------------------------------------------------------------------------- Read the given frame, performing conversion as necessary. -----------------------------------------------------------------------------*/ FILE * ifP; openFile(inputSourceP, frameNumber, conversion, &ifP); ReadFrameFile(frameP, ifP, conversion, endOfStreamP); if (*endOfStreamP && !inputSourceP->stdinUsed) pm_error("Premature EOF on file containing Frame %u", frameNumber); closeFile(inputSourceP, ifP); } /*===========================================================================* * * SetFileType * * set the file type to be either a base type (no conversion), or * any type (conversion required) * * RETURNS: nothing * * SIDE EFFECTS: fileType * *===========================================================================*/ void SetFileType(const char * const conversion) { if (streq(conversion, "*")) { fileType = BASE_FILE_TYPE; } else { fileType = ANY_FILE_TYPE; } } /*===========================================================================* * * SetFileFormat * * set the file format (PNM, YUV, JPEG) * * RETURNS: nothing * * SIDE EFFECTS: baseFormat * *===========================================================================*/ void SetFileFormat(const char * const format) { if (streq(format, "PPM")) { baseFormat = PNM_FILE_TYPE; } else if (streq(format, "YUV")) { baseFormat = YUV_FILE_TYPE; } else if (streq(format, "Y")) { baseFormat = Y_FILE_TYPE; } else if (streq(format, "PNM")) { baseFormat = PNM_FILE_TYPE; } else if (streq(format, "JPEG") || streq(format, "JPG")) { baseFormat = JPEG_FILE_TYPE; } else if (streq(format, "JMOVIE")) { baseFormat = JMOVIE_FILE_TYPE; } else if (streq(format, "SUB4")) { baseFormat = SUB4_FILE_TYPE; } else { fprintf(stderr, "ERROR: Invalid file format: %s\n", format); exit(1); } } FILE * ReadIOConvert(struct inputSource * const inputSourceP, unsigned int const frameNumber) { /*---------------------------------------------------------------------------- Do conversion; return handle to the appropriate file. -----------------------------------------------------------------------------*/ FILE *ifp; char command[1024]; const char * fullFileName; char *convertPtr, *commandPtr; const char * fileName; GetNthInputFileName(inputSourceP, frameNumber, &fileName); pm_asprintf(&fullFileName, "%s/%s", currentPath, fileName); if (streq(ioConversion, "*")) { char buff[1024]; ifp = fopen(fullFileName, "rb"); sprintf(buff,"fopen \"%s\"",fullFileName); ERRCHK(ifp, buff); return ifp; } /* replace every occurrence of '*' with fullFileName */ convertPtr = ioConversion; commandPtr = command; while ( *convertPtr != '\0' ) { while ( (*convertPtr != '\0') && (*convertPtr != '*') ) { *commandPtr = *convertPtr; commandPtr++; convertPtr++; } if ( *convertPtr == '*' ) { /* copy fullFileName */ const char * charPtr; charPtr = fullFileName; while ( *charPtr != '\0' ) { *commandPtr = *charPtr; commandPtr++; charPtr++; } convertPtr++; /* go past '*' */ } } *commandPtr = '\0'; if ( (ifp = popen(command, "r")) == NULL ) { fprintf(stderr, "ERROR: " "Couldn't execute input conversion command:\n"); fprintf(stderr, "\t%s\n", command); fprintf(stderr, "errno = %d\n", errno); if ( ioServer ) { fprintf(stderr, "IO SERVER: EXITING!!!\n"); } else { fprintf(stderr, "SLAVE EXITING!!!\n"); } exit(1); } pm_strfree(fullFileName); pm_strfree(fileName); return ifp; } /*===========================================================================* * * ReadEYUV * * read a Encoder-YUV file (concatenated Y, U, and V) * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/ static void ReadEYUV(mf, fpointer, width, height) MpegFrame *mf; FILE *fpointer; int width; int height; { register int y; uint8 junk[4096]; int safe_read_count; Fsize_Note(mf->id, width, height); Frame_AllocYCC(mf); for (y = 0; y < Fsize_y; y++) { /* Y */ safe_fread(mf->orig_y[y], 1, Fsize_x, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { safe_fread(junk, 1, width-Fsize_x, fpointer); } } /* read the leftover stuff on the bottom */ for (y = Fsize_y; y < height; y++) { safe_fread(junk, 1, width, fpointer); } for (y = 0; y < (Fsize_y >> 1); y++) { /* U */ safe_fread(mf->orig_cb[y], 1, Fsize_x >> 1, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { safe_fread(junk, 1, (width-Fsize_x)>>1, fpointer); } } /* read the leftover stuff on the bottom */ for (y = (Fsize_y >> 1); y < (height >> 1); y++) { safe_fread(junk, 1, width>>1, fpointer); } for (y = 0; y < (Fsize_y >> 1); y++) { /* V */ safe_fread(mf->orig_cr[y], 1, Fsize_x >> 1, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { safe_fread(junk, 1, (width-Fsize_x)>>1, fpointer); } } /* ignore leftover stuff on the bottom */ } /*===========================================================================* * * ReadAYUV * * read an Abekas-YUV file * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/ static void ReadAYUV(mf, fpointer, width, height) MpegFrame *mf; FILE *fpointer; int width; int height; { register int x, y; struct YuvLine line1, line2; uint8 junk[4096]; uint8 *cbptr, *crptr; int safe_read_count; Fsize_Note(mf->id, width, height); Frame_AllocYCC(mf); for (y = 0; y < Fsize_y; y += 2) { SeparateLine(fpointer, &line1, width); SeparateLine(fpointer, &line2, width); /* Copy the Y values for each line to the frame */ for (x = 0; x < Fsize_x; x++) { mf->orig_y[y][x] = line1.y[x]; mf->orig_y[y+1][x] = line2.y[x]; } cbptr = &(mf->orig_cb[y>>1][0]); crptr = &(mf->orig_cr[y>>1][0]); /* One U and one V for each two pixels horizontal as well */ /* Toss the second line of Cr/Cb info, averaging was worse, so just subsample */ for (x = 0; x < (Fsize_x >> 1); x ++) { cbptr[x] = line1.cb[x]; crptr[x] = line1.cr[x]; } } /* read the leftover stuff on the bottom */ for (y = Fsize_y; y < height; y++) { safe_fread(junk, 1, width<<1, fpointer); } } /*===========================================================================* * * SeparateLine * * Separates one line of pixels into Y, U, and V components * * RETURNS: lineptr modified * * SIDE EFFECTS: none * *===========================================================================*/ static void SeparateLine(fpointer, lineptr, width) FILE *fpointer; struct YuvLine *lineptr; int width; { uint8 junk[4096]; int8 *crptr, *cbptr; uint8 *yptr; int num, length; int safe_read_count; /* Sets the deinterlacing pattern */ /* shorthand for UYVY */ if (strncmp(yuvConversion, "ABEKAS", 6) == 0) { strcpy(yuvConversion, "UYVY"); /* shorthand for YUYV */ } else if (strncmp(yuvConversion, "PHILLIPS", 8) == 0) { strcpy(yuvConversion, "YUYV"); } length = strlen (yuvConversion); if ((length % 2) != 0) { fprintf (stderr, "ERROR : YUV_FORMAT must represent two pixels, hence must be even in length.\n"); exit(1); } /* each line in 4:2:2 chroma format takes 2X bytes to represent X pixels. * each line in 4:4:4 chroma format takes 3X bytes to represent X pixels. * Therefore, half of the length of the YUV_FORMAT represents 1 pixel. */ safe_fread(lineptr->data, 1, Fsize_x*(length>>1), fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { safe_fread(junk, 1, (width-Fsize_x)*(length>>1), fpointer); } crptr = &(lineptr->cr[0]); cbptr = &(lineptr->cb[0]); yptr = &(lineptr->y[0]); for (num = 0; num < (Fsize_x*(length>>1)); num++) { switch (yuvConversion[num % length]) { case 'U': case 'u': *(cbptr++) = (lineptr->data[num]); break; case 'V': case 'v': *(crptr++) = (lineptr->data[num]); break; case 'Y': case 'y': *(yptr++) = (lineptr->data[num]); break; default: fprintf(stderr, "ERROR: YUV_FORMAT must be one of the following:\n"); fprintf(stderr, " ABEKAS\n"); fprintf(stderr, " EYUV\n"); fprintf(stderr, " PHILLIPS\n"); fprintf(stderr, " UCB\n"); fprintf(stderr, " or any even-length string consisting of the letters U, V, and Y.\n"); exit(1); } } } /*===========================================================================* * * ReadY * * read a Y file * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/ static void ReadY(mf, fpointer, width, height) MpegFrame *mf; FILE *fpointer; int width; int height; { register int y; uint8 junk[4096]; int safe_read_count; Fsize_Note(mf->id, width, height); Frame_AllocYCC(mf); for (y = 0; y < Fsize_y; y++) { /* Y */ safe_fread(mf->orig_y[y], 1, Fsize_x, fpointer); /* read the leftover stuff on the right side */ if ( width != Fsize_x ) { safe_fread(junk, 1, width-Fsize_x, fpointer); } } /* read the leftover stuff on the bottom */ for (y = Fsize_y; y < height; y++) { safe_fread(junk, 1, width, fpointer); } for (y = 0 ; y < (Fsize_y >> 1); y++) { memset(mf->orig_cb[y], 128, (Fsize_x>>1)); memset(mf->orig_cr[y], 128, (Fsize_x>>1)); } } /*===========================================================================* * * ReadSub4 * * read a YUV file (subsampled even further by 4:1 ratio) * * RETURNS: mf modified * * SIDE EFFECTS: none * *===========================================================================*/ static void ReadSub4(mf, fpointer, width, height) MpegFrame *mf; FILE *fpointer; int width; int height; { register int y; register int x; uint8 buffer[1024]; int safe_read_count; Fsize_Note(mf->id, width, height); Frame_AllocYCC(mf); for (y = 0; y < (height>>1); y++) { /* Y */ safe_fread(buffer, 1, width>>1, fpointer); for ( x = 0; x < (width>>1); x++ ) { mf->orig_y[2*y][2*x] = buffer[x]; mf->orig_y[2*y][2*x+1] = buffer[x]; mf->orig_y[2*y+1][2*x] = buffer[x]; mf->orig_y[2*y+1][2*x+1] = buffer[x]; } } for (y = 0; y < (height >> 2); y++) { /* U */ safe_fread(buffer, 1, width>>2, fpointer); for ( x = 0; x < (width>>2); x++ ) { mf->orig_cb[2*y][2*x] = buffer[x]; mf->orig_cb[2*y][2*x+1] = buffer[x]; mf->orig_cb[2*y+1][2*x] = buffer[x]; mf->orig_cb[2*y+1][2*x+1] = buffer[x]; } } for (y = 0; y < (height >> 2); y++) { /* V */ safe_fread(buffer, 1, width>>2, fpointer); for ( x = 0; x < (width>>2); x++ ) { mf->orig_cr[2*y][2*x] = buffer[x]; mf->orig_cr[2*y][2*x+1] = buffer[x]; mf->orig_cr[2*y+1][2*x] = buffer[x]; mf->orig_cr[2*y+1][2*x+1] = buffer[x]; } } } /*=====================* * INTERNAL PROCEDURES * *=====================*/ /*===========================================================================* * * DoGamma * * Gamma Correct the Lum values * * RETURNS: nothing * * SIDE EFFECTS: Raises Y values to power gamma. * *===========================================================================*/ static void DoGamma(mf, w, h) MpegFrame *mf; int w,h; { static int GammaVal[256]; static bool init_done=FALSE; int i,j; if (!init_done) { for(i=0; i<256; i++) GammaVal[i]=(unsigned char) (pow(((double) i)/255.0,GammaValue)*255.0+0.5); init_done=TRUE; } for (i=0; i< h; i++) { /* For each line */ for (j=0; jorig_y[i][j] = GammaVal[mf->orig_y[i][j]]; }} } /*===========================================================================* * * DoKillDim * * Applies an input filter to small Y values. * * RETURNS: nothing * * SIDE EFFECTS: Changes Y values: * * Output | / | / | / | ! | / | ! | / | - | / | -- | / | -- | / ------------------------ ^ kill_dim_break ^kill_dim_end kill_dim_slope gives the slope (y = kill_dim_slope * x +0) from 0 to kill_dim_break * *===========================================================================*/ static void DoKillDim(mf, w, h) MpegFrame *mf; int w,h; { static bool init_done=FALSE; static unsigned char mapper[256]; register int i,j; double slope, intercept; slope = (kill_dim_end - kill_dim_break*kill_dim_slope)*1.0 / (kill_dim_end - kill_dim_break); intercept = kill_dim_end * (1.0-slope); if (!init_done) { for(i=0; i<256; i++) { if (i >= kill_dim_end) { mapper[i] = (char) i; } else if (i >= kill_dim_break) { mapper[i] = (char) (slope*i + intercept); } else { /* i <= kill_dim_break */ mapper[i] = (char) floor(i*kill_dim_slope + 0.49999); } } init_done = TRUE; } for (i=0; i < h; i++) { /* For each line */ for (j=0; j < w; j++) { /* For each Y value */ mf->orig_y[i][j] = mapper[mf->orig_y[i][j]]; }} } /* * Copyright (c) 1995 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ /* * $Header: /n/picasso/project/mpeg/mpeg_dist/mpeg_encode/RCS/readframe.c,v 1.27 1995/08/14 22:31:40 smoot Exp $ * $Log: readframe.c,v $ * Revision 1.27 1995/08/14 22:31:40 smoot * reads training info from PPms now (needed for piping reads) * * Revision 1.26 1995/08/07 21:48:36 smoot * better error reporting, JPG == JPEG now * * Revision 1.25 1995/06/12 20:30:12 smoot * added popen for OS2 * * Revision 1.24 1995/06/08 20:34:36 smoot * added "b"'s to fopen calls to make MSDOS happy * * Revision 1.23 1995/05/03 10:16:01 smoot * minor compile bug with static f * * Revision 1.22 1995/05/02 22:00:12 smoot * added TUNEing, setting near-black values to black * * Revision 1.21 1995/03/27 21:00:01 eyhung * fixed bug with some long jpeg names * * Revision 1.20 1995/02/02 01:05:54 eyhung * Fixed a Added error checking for stdin * * Revision 1.19 1995/02/01 05:01:12 eyhung * Removed troubleshooting printf * * Revision 1.18 1995/01/31 21:08:16 eyhung * Improved YUV_FORMAT strings with better algorithm * * Revision 1.17 1995/01/27 23:34:09 eyhung * Removed temporary JPEG files created by JMOVIE input * * Revision 1.16 1995/01/27 21:57:43 eyhung * Added case for reading original JMOVIES * * Revision 1.14 1995/01/24 23:47:51 eyhung * Confusion with Abekas format fixed : all other YUV revisions are wrong * * Revision 1.13 1995/01/20 00:02:30 smoot * added gamma correction * * Revision 1.12 1995/01/19 23:09:21 eyhung * Changed copyrights * * Revision 1.11 1995/01/17 22:23:07 aswan * AbekasYUV chrominance implementation fixed * * Revision 1.10 1995/01/17 21:26:25 smoot * Tore our average on Abekus/Phillips reconstruct * * Revision 1.9 1995/01/17 08:22:34 eyhung * Debugging of ReadAYUV * * Revision 1.8 1995/01/16 13:18:24 eyhung * Interlaced YUV format (e.g. Abekas) capability added (slightly buggy) * * Revision 1.7 1995/01/16 06:58:23 eyhung * Added skeleton of ReadAYUV (for Abekas YUV files) * * Revision 1.6 1995/01/13 23:22:23 smoot * Added ReadY, so we can make black&white movies (how artsy!) * * Revision 1.5 1994/12/16 00:20:40 smoot * Now errors out on too small an input file * * Revision 1.4 1994/11/12 02:11:59 keving * nothing * * Revision 1.3 1994/03/15 00:27:11 keving * nothing * * Revision 1.2 1993/12/22 19:19:01 keving * nothing * * Revision 1.1 1993/07/22 22:23:43 keving * nothing * */