home *** CD-ROM | disk | FTP | other *** search
- /*===========================================================================*
- * frame.c *
- * *
- * basic frame procedures *
- * *
- * EXPORTED PROCEDURES: *
- * Frame_Init *
- * Frame_Exit *
- * Frame_New *
- * Frame_Free *
- * Frame_AllocPPM *
- * Frame_AllocBlocks *
- * Frame_AllocYCC *
- * Frame_AllocDecoded *
- * Frame_AllocHalf *
- * *
- *===========================================================================*/
-
- /*
- * Copyright (c) 1993 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 FILES *
- *==============*/
-
- #include "all.h"
- #include "mtypes.h"
- #include "frames.h"
- #include "frame.h"
- #include "fsize.h"
- #include "dct.h"
-
-
- /*==================*
- * GLOBAL VARIABLES *
- *==================*/
-
- MpegFrame *frameMemory[3]; /* only need at most 3 frames in memory at once */
-
-
- /*===============================*
- * INTERNAL PROCEDURE prototypes *
- *===============================*/
-
- static void FreeFrame _ANSI_ARGS_((MpegFrame * mf));
- static MpegFrame *GetUnusedFrame _ANSI_ARGS_((void));
- static void ResetFrame _ANSI_ARGS_((int fnumber, int type, MpegFrame *frame));
-
-
- /*=====================*
- * EXPORTED PROCEDURES *
- *=====================*/
-
- /*===========================================================================*
- *
- * Frame_Init
- *
- * initializes the memory associated will all frames ever (since we
- * only need 3 frames in memory at any one time)
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: frameMemory
- *
- *===========================================================================*/
- void
- Frame_Init()
- {
- register int index;
-
- for ( index = 0; index < 3; index++ ) {
- frameMemory[index] = (MpegFrame *) malloc(sizeof(MpegFrame));
- frameMemory[index]->inUse = FALSE;
- frameMemory[index]->ppm_data = NULL;
- frameMemory[index]->rgb_data = NULL;
- frameMemory[index]->orig_y = NULL; /* if NULL, then orig_cr, orig_cb invalid */
- frameMemory[index]->y_blocks = NULL; /* if NULL, then cr_blocks, cb_blocks invalid */
- frameMemory[index]->decoded_y = NULL; /* if NULL, then blah blah */
- frameMemory[index]->halfX = NULL;
- }
- }
-
-
- /*===========================================================================*
- *
- * Frame_Exit
- *
- * frees the memory associated with frames
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: frameMemory
- *
- *===========================================================================*/
- void
- Frame_Exit()
- {
- register int index;
-
- for ( index = 0; index < 3; index++ ) {
- FreeFrame(frameMemory[index]);
- }
- }
-
-
- /*===========================================================================*
- *
- * Frame_Free
- *
- * frees the given frame -- allows it to be re-used
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_Free(frame)
- MpegFrame *frame;
- {
- frame->inUse = FALSE;
- }
-
-
- /*===========================================================================*
- *
- * Frame_New
- *
- * finds a frame that isn't currently being used and resets it
- *
- * RETURNS: the frame
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- MpegFrame *
- Frame_New(id, type)
- int id;
- int type;
- {
- MpegFrame *frame;
-
- frame = GetUnusedFrame();
- ResetFrame(id, type, frame);
-
- return frame;
- }
-
-
- /*===========================================================================*
- *
- * Frame_AllocPPM
- *
- * allocate memory for ppm data for the given frame, if required
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_AllocPPM(frame)
- MpegFrame *frame;
- {
- register int y;
-
- if ( frame->ppm_data != NULL ) { /* already allocated */
- return;
- }
-
- frame->ppm_data = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
- ERRCHK(frame->ppm_data, "malloc");
-
- for ( y = 0; y < Fsize_y; y++ ) {
- frame->ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * Fsize_x);
- ERRCHK(frame->ppm_data[y], "malloc");
- }
- }
-
-
- /*===========================================================================*
- *
- * Frame_AllocBlocks
- *
- * allocate memory for blocks for the given frame, if required
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_AllocBlocks(frame)
- MpegFrame *frame;
- {
- int dctx, dcty;
- int i;
-
- if ( frame->y_blocks != NULL ) { /* already allocated */
- return;
- }
-
- dctx = Fsize_x / DCTSIZE;
- dcty = Fsize_y / DCTSIZE;
-
- frame->y_blocks = (Block **) malloc(sizeof(Block *) * dcty);
- ERRCHK(frame->y_blocks, "malloc");
- for (i = 0; i < dcty; i++) {
- frame->y_blocks[i] = (Block *) malloc(sizeof(Block) * dctx);
- ERRCHK(frame->y_blocks[i], "malloc");
- }
-
- frame->cr_blocks = (Block **) malloc(sizeof(Block *) * dcty / 2);
- frame->cb_blocks = (Block **) malloc(sizeof(Block *) * dcty / 2);
- ERRCHK(frame->cr_blocks, "malloc");
- ERRCHK(frame->cb_blocks, "malloc");
- for (i = 0; i < dcty / 2; i++) {
- frame->cr_blocks[i] = (Block *) malloc(sizeof(Block) * dctx / 2);
- frame->cb_blocks[i] = (Block *) malloc(sizeof(Block) * dctx / 2);
- ERRCHK(frame->cr_blocks[i], "malloc");
- ERRCHK(frame->cb_blocks[i], "malloc");
- }
- }
-
-
- /*===========================================================================*
- *
- * Frame_AllocYCC
- *
- * allocate memory for YCC info for the given frame, if required
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_AllocYCC(frame)
- MpegFrame *frame;
- {
- register int y;
-
- if ( frame->orig_y != NULL ) { /* already allocated */
- return /* nothing */ ;
- }
-
- DBG_PRINT(("ycc_calc:\n"));
- /*
- * first, allocate tons of memory
- */
- frame->orig_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
- ERRCHK(frame->orig_y, "malloc");
- for (y = 0; y < Fsize_y; y++) {
- frame->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
- ERRCHK(frame->orig_y[y], "malloc");
- }
-
- frame->orig_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
- ERRCHK(frame->orig_cr, "malloc");
- for (y = 0; y < Fsize_y / 2; y++) {
- frame->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
- ERRCHK(frame->orig_cr[y], "malloc");
- }
-
- frame->orig_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
- ERRCHK(frame->orig_cb, "malloc");
- for (y = 0; y < Fsize_y / 2; y++) {
- frame->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
- ERRCHK(frame->orig_cb[y], "malloc");
- }
-
- if ( referenceFrame == ORIGINAL_FRAME ) {
- frame->ref_y = frame->orig_y;
- frame->ref_cr = frame->orig_cr;
- frame->ref_cb = frame->orig_cb;
- }
- }
-
-
-
- /*===========================================================================*
- *
- * Frame_AllocHalf
- *
- * allocate memory for half-pixel values for the given frame, if required
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_AllocHalf(frame)
- MpegFrame *frame;
- {
- register int y;
-
- if ( frame->halfX != NULL ) {
- return;
- }
-
- frame->halfX = (uint8 **) malloc(Fsize_y*sizeof(uint8 *));
- ERRCHK(frame->halfX, "malloc");
- frame->halfY = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
- ERRCHK(frame->halfY, "malloc");
- frame->halfBoth = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
- ERRCHK(frame->halfBoth, "malloc");
- for ( y = 0; y < Fsize_y; y++ ) {
- frame->halfX[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
- ERRCHK(frame->halfX[y], "malloc");
- }
- for ( y = 0; y < Fsize_y-1; y++ ) {
- frame->halfY[y] = (uint8 *) malloc(Fsize_x*sizeof(uint8));
- ERRCHK(frame->halfY[y], "malloc");
- }
- for ( y = 0; y < Fsize_y-1; y++ ) {
- frame->halfBoth[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
- ERRCHK(frame->halfBoth[y], "malloc");
- }
- }
-
-
- /*===========================================================================*
- *
- * Frame_AllocDecoded
- *
- * allocate memory for decoded frame for the given frame, if required
- * if makeReference == TRUE, then makes it reference frame
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- void
- Frame_AllocDecoded(frame, makeReference)
- MpegFrame *frame;
- boolean makeReference;
- {
- register int y;
-
- if ( frame->decoded_y != NULL) { /* already allocated */
- return;
- }
-
- /* allocate memory for decoded image */
- /* can probably reuse original image memory, but may decide to use
- it for some reason, so do it this way at least for now -- more
- flexible
- */
- frame->decoded_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
- ERRCHK(frame->decoded_y, "malloc");
- for (y = 0; y < Fsize_y; y++) {
- frame->decoded_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
- ERRCHK(frame->decoded_y[y], "malloc");
- }
-
- frame->decoded_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
- ERRCHK(frame->decoded_cr, "malloc");
- for (y = 0; y < Fsize_y / 2; y++) {
- frame->decoded_cr[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x / 2);
- ERRCHK(frame->decoded_cr[y], "malloc");
- }
-
- frame->decoded_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
- ERRCHK(frame->decoded_cb, "malloc");
- for (y = 0; y < Fsize_y / 2; y++) {
- frame->decoded_cb[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x / 2);
- ERRCHK(frame->decoded_cb[y], "malloc");
- }
-
- if ( makeReference ) {
- frame->ref_y = frame->decoded_y;
- frame->ref_cr = frame->decoded_cr;
- frame->ref_cb = frame->decoded_cb;
- }
- }
-
-
- /*=====================*
- * INTERNAL PROCEDURES *
- *=====================*/
-
-
- /*===========================================================================*
- *
- * GetUnusedFrame
- *
- * return an unused frame
- *
- * RETURNS: the frame
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- static MpegFrame *
- GetUnusedFrame()
- {
- register int index;
-
- for ( index = 0; index < 3; index++ ) {
- if ( ! frameMemory[index]->inUse ) {
- frameMemory[index]->inUse = TRUE;
- return frameMemory[index];
- }
- }
-
- fprintf(stderr, "ERROR: No UNUSED frames!!!\n");
- exit(1);
- }
-
-
- /*===========================================================================*
- *
- * ResetFrame
- *
- * reset a frame to the given id and type
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- static void
- ResetFrame(id, type, frame)
- int id;
- int type;
- MpegFrame *frame;
- {
- switch (type) {
- case 'i':
- frame->type = TYPE_IFRAME;
- break;
- case 'p':
- frame->type = TYPE_PFRAME;
- break;
- case 'b':
- frame->type = TYPE_BFRAME;
- break;
- default:
- fprintf(stderr, "frame type %c: not supported\n", type);
- exit(1);
- }
-
- frame->id = id;
- frame->halfComputed = FALSE;
- }
-
-
- /*===========================================================================*
- *
- * FreeFrame
- *
- * frees the memory associated with the given frame
- *
- * RETURNS: nothing
- *
- * SIDE EFFECTS: none
- *
- *===========================================================================*/
- static void
- FreeFrame(frame)
- MpegFrame *frame;
- {
- int i;
-
- if (!frame) {
- return;
- }
-
- if ( frame->ppm_data ) {
- /* it may be a little bigger than Fsize_y, but that's fine for
- our purposes, since we aren't going to free until we exit anyway,
- so by the time we call this we won't care
- */
- pnm_freearray(frame->ppm_data, Fsize_y);
- frame->ppm_data = NULL;
- }
-
- if (frame->rgb_data) {
- pnm_freearray(frame->rgb_data, Fsize_y);
- }
- if (frame->orig_y) {
- for (i = 0; i < Fsize_y; i++) {
- free(frame->orig_y[i]);
- }
- free(frame->orig_y);
-
- for (i = 0; i < Fsize_y / 2; i++) {
- free(frame->orig_cr[i]);
- }
- free(frame->orig_cr);
-
- for (i = 0; i < Fsize_y / 2; i++) {
- free(frame->orig_cb[i]);
- }
- free(frame->orig_cb);
- }
- if ( frame->decoded_y ) {
- for (i = 0; i < Fsize_y; i++) {
- free(frame->decoded_y[i]);
- }
- free(frame->decoded_y);
-
- for (i = 0; i < Fsize_y / 2; i++) {
- free(frame->decoded_cr[i]);
- }
- free(frame->decoded_cr);
-
- for (i = 0; i < Fsize_y / 2; i++) {
- free(frame->decoded_cb[i]);
- }
- free(frame->decoded_cb);
- }
-
- if (frame->y_blocks) {
- for (i = 0; i < Fsize_y / DCTSIZE; i++) {
- free(frame->y_blocks[i]);
- }
- free(frame->y_blocks);
-
- for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
- free(frame->cr_blocks[i]);
- }
- free(frame->cr_blocks);
-
- for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
- free(frame->cb_blocks[i]);
- }
- free(frame->cb_blocks);
- }
- if ( frame->halfX ) {
- for ( i = 0; i < Fsize_y; i++ ) {
- free(frame->halfX[i]);
- }
- free(frame->halfX);
-
- for ( i = 0; i < Fsize_y-1; i++ ) {
- free(frame->halfY[i]);
- }
- free(frame->halfY);
-
- for ( i = 0; i < Fsize_y-1; i++ ) {
- free(frame->halfBoth[i]);
- }
- free(frame->halfBoth);
- }
-
- free(frame);
- }
-
-
-