home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / src / frame.c < prev    next >
C/C++ Source or Header  |  1993-09-27  |  15KB  |  572 lines

  1. /*===========================================================================*
  2.  * frame.c                                     *
  3.  *                                         *
  4.  *    basic frame procedures                             *
  5.  *                                         *
  6.  * EXPORTED PROCEDURES:                                 *
  7.  *    Frame_Init                                 *
  8.  *    Frame_Exit                                 *
  9.  *    Frame_New                                 *
  10.  *    Frame_Free                                 *
  11.  *    Frame_AllocPPM                                 *
  12.  *    Frame_AllocBlocks                             *
  13.  *    Frame_AllocYCC                                 *
  14.  *    Frame_AllocDecoded                             *
  15.  *    Frame_AllocHalf                                     *
  16.  *                                         *
  17.  *===========================================================================*/
  18.  
  19. /*
  20.  * Copyright (c) 1993 The Regents of the University of California.
  21.  * All rights reserved.
  22.  *
  23.  * Permission to use, copy, modify, and distribute this software and its
  24.  * documentation for any purpose, without fee, and without written agreement is
  25.  * hereby granted, provided that the above copyright notice and the following
  26.  * two paragraphs appear in all copies of this software.
  27.  *
  28.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  29.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  30.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  31.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.  *
  33.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  34.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  35.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  36.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  37.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  38.  */
  39.  
  40.  
  41. /*==============*
  42.  * HEADER FILES *
  43.  *==============*/
  44.  
  45. #include "all.h"
  46. #include "mtypes.h"
  47. #include "frames.h"
  48. #include "frame.h"
  49. #include "fsize.h"
  50. #include "dct.h"
  51.  
  52.  
  53. /*==================*
  54.  * GLOBAL VARIABLES *
  55.  *==================*/
  56.  
  57. MpegFrame  *frameMemory[3];  /* only need at most 3 frames in memory at once */
  58.  
  59.  
  60. /*===============================*
  61.  * INTERNAL PROCEDURE prototypes *
  62.  *===============================*/
  63.  
  64. static void FreeFrame _ANSI_ARGS_((MpegFrame * mf));
  65. static MpegFrame *GetUnusedFrame _ANSI_ARGS_((void));
  66. static void ResetFrame _ANSI_ARGS_((int fnumber, char type, MpegFrame *frame));
  67.  
  68.  
  69. /*=====================*
  70.  * EXPORTED PROCEDURES *
  71.  *=====================*/
  72.  
  73. /*===========================================================================*
  74.  *
  75.  * Frame_Init
  76.  *
  77.  *    initializes the memory associated will all frames ever (since we
  78.  *    only need 3 frames in memory at any one time)
  79.  *
  80.  * RETURNS:    nothing
  81.  *
  82.  * SIDE EFFECTS:    frameMemory
  83.  *
  84.  *===========================================================================*/
  85. void
  86. Frame_Init()
  87. {
  88.     register int index;
  89.  
  90.     for ( index = 0; index < 3; index++ ) {
  91.     frameMemory[index] = (MpegFrame *) malloc(sizeof(MpegFrame));
  92.     frameMemory[index]->inUse = FALSE;
  93.     frameMemory[index]->ppm_data = NULL;
  94.     frameMemory[index]->rgb_data = NULL;
  95.     frameMemory[index]->orig_y = NULL;    /* if NULL, then orig_cr, orig_cb invalid */
  96.     frameMemory[index]->y_blocks = NULL; /* if NULL, then cr_blocks, cb_blocks invalid */
  97.     frameMemory[index]->decoded_y = NULL;    /* if NULL, then blah blah */
  98.     frameMemory[index]->halfX = NULL;
  99.     }
  100. }
  101.  
  102.  
  103. /*===========================================================================*
  104.  *
  105.  * Frame_Exit
  106.  *
  107.  *    frees the memory associated with frames
  108.  *
  109.  * RETURNS:    nothing
  110.  *
  111.  * SIDE EFFECTS:    frameMemory
  112.  *
  113.  *===========================================================================*/
  114. void
  115. Frame_Exit()
  116. {
  117.     register int index;
  118.  
  119.     for ( index = 0; index < 3; index++ ) {
  120.     FreeFrame(frameMemory[index]);
  121.     }
  122. }
  123.  
  124.  
  125. /*===========================================================================*
  126.  *
  127.  * Frame_Free
  128.  *
  129.  *    frees the given frame -- allows it to be re-used
  130.  *
  131.  * RETURNS:    nothing
  132.  *
  133.  * SIDE EFFECTS:    none
  134.  *
  135.  *===========================================================================*/
  136. void
  137. Frame_Free(frame)
  138.     MpegFrame *frame;
  139. {
  140.     frame->inUse = FALSE;
  141. }
  142.  
  143.  
  144. /*===========================================================================*
  145.  *
  146.  * Frame_New
  147.  *
  148.  *    finds a frame that isn't currently being used and resets it
  149.  *
  150.  * RETURNS:    the frame
  151.  *
  152.  * SIDE EFFECTS:    none
  153.  *
  154.  *===========================================================================*/
  155. MpegFrame *
  156. Frame_New(id, type)
  157.     int id;
  158.     char type;
  159. {
  160.     MpegFrame *frame;
  161.  
  162.     frame = GetUnusedFrame();
  163.     ResetFrame(id, type, frame);
  164.  
  165.     return frame;
  166. }
  167.  
  168.  
  169. /*===========================================================================*
  170.  *
  171.  * Frame_AllocPPM
  172.  *
  173.  *    allocate memory for ppm data for the given frame, if required
  174.  *
  175.  * RETURNS:    nothing
  176.  *
  177.  * SIDE EFFECTS:    none
  178.  *
  179.  *===========================================================================*/
  180. void
  181. Frame_AllocPPM(frame)
  182.     MpegFrame *frame;
  183. {
  184.     register int y;
  185.  
  186.     if ( frame->ppm_data != NULL ) {    /* already allocated */
  187.     return;
  188.     }
  189.  
  190.     frame->ppm_data = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
  191.     ERRCHK(frame->ppm_data, "malloc");
  192.  
  193.     for ( y = 0; y < Fsize_y; y++ ) {
  194.     frame->ppm_data[y] = (uint8 *) malloc(3*sizeof(uint8) * Fsize_x);
  195.     ERRCHK(frame->ppm_data[y], "malloc");
  196.     }
  197. }
  198.  
  199.  
  200. /*===========================================================================*
  201.  *
  202.  * Frame_AllocBlocks
  203.  *
  204.  *    allocate memory for blocks for the given frame, if required
  205.  *
  206.  * RETURNS:    nothing
  207.  *
  208.  * SIDE EFFECTS:    none
  209.  *
  210.  *===========================================================================*/
  211. void
  212. Frame_AllocBlocks(frame)
  213.     MpegFrame *frame;
  214. {
  215.     int dctx, dcty;
  216.     int i;
  217.  
  218.     if ( frame->y_blocks != NULL ) {        /* already allocated */
  219.     return;
  220.     }
  221.  
  222.     dctx = Fsize_x / DCTSIZE;
  223.     dcty = Fsize_y / DCTSIZE;
  224.  
  225.     frame->y_blocks = (Block **) malloc(sizeof(Block *) * dcty);
  226.     ERRCHK(frame->y_blocks, "malloc");
  227.     for (i = 0; i < dcty; i++) {
  228.     frame->y_blocks[i] = (Block *) malloc(sizeof(Block) * dctx);
  229.     ERRCHK(frame->y_blocks[i], "malloc");
  230.     }
  231.  
  232.     frame->cr_blocks = (Block **) malloc(sizeof(Block *) * dcty / 2);
  233.     frame->cb_blocks = (Block **) malloc(sizeof(Block *) * dcty / 2);
  234.     ERRCHK(frame->cr_blocks, "malloc");
  235.     ERRCHK(frame->cb_blocks, "malloc");
  236.     for (i = 0; i < dcty / 2; i++) {
  237.     frame->cr_blocks[i] = (Block *) malloc(sizeof(Block) * dctx / 2);
  238.     frame->cb_blocks[i] = (Block *) malloc(sizeof(Block) * dctx / 2);
  239.     ERRCHK(frame->cr_blocks[i], "malloc");
  240.     ERRCHK(frame->cb_blocks[i], "malloc");
  241.     }
  242. }
  243.  
  244.  
  245. /*===========================================================================*
  246.  *
  247.  * Frame_AllocYCC
  248.  *
  249.  *    allocate memory for YCC info for the given frame, if required
  250.  *
  251.  * RETURNS:    nothing
  252.  *
  253.  * SIDE EFFECTS:    none
  254.  *
  255.  *===========================================================================*/
  256. void
  257. Frame_AllocYCC(frame)
  258.     MpegFrame *frame;
  259. {
  260.     register int y;
  261.  
  262.     if ( frame->orig_y != NULL ) {    /* already allocated */
  263.     return /* nothing */ ;
  264.     }
  265.  
  266.     DBG_PRINT(("ycc_calc:\n"));
  267.     /*
  268.      * first, allocate tons of memory
  269.      */
  270.     frame->orig_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
  271.     ERRCHK(frame->orig_y, "malloc");
  272.     for (y = 0; y < Fsize_y; y++) {
  273.     frame->orig_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
  274.     ERRCHK(frame->orig_y[y], "malloc");
  275.     }
  276.  
  277.     frame->orig_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
  278.     ERRCHK(frame->orig_cr, "malloc");
  279.     for (y = 0; y < Fsize_y / 2; y++) {
  280.     frame->orig_cr[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
  281.     ERRCHK(frame->orig_cr[y], "malloc");
  282.     }
  283.  
  284.     frame->orig_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
  285.     ERRCHK(frame->orig_cb, "malloc");
  286.     for (y = 0; y < Fsize_y / 2; y++) {
  287.     frame->orig_cb[y] = (uint8 *) malloc(sizeof(int8) * Fsize_x / 2);
  288.     ERRCHK(frame->orig_cb[y], "malloc");
  289.     }
  290.  
  291.     if ( referenceFrame == ORIGINAL_FRAME ) {
  292.     frame->ref_y = frame->orig_y;
  293.     frame->ref_cr = frame->orig_cr;
  294.     frame->ref_cb = frame->orig_cb;
  295.     }
  296. }
  297.  
  298.  
  299.  
  300. /*===========================================================================*
  301.  *
  302.  * Frame_AllocHalf
  303.  *
  304.  *    allocate memory for half-pixel values for the given frame, if required
  305.  *
  306.  * RETURNS:    nothing
  307.  *
  308.  * SIDE EFFECTS:    none
  309.  *
  310.  *===========================================================================*/
  311. void
  312. Frame_AllocHalf(frame)
  313.     MpegFrame *frame;
  314. {
  315.     register int y;
  316.  
  317.     if ( frame->halfX != NULL ) {
  318.         return;
  319.     }
  320.  
  321.     frame->halfX = (uint8 **) malloc(Fsize_y*sizeof(uint8 *));
  322.     ERRCHK(frame->halfX, "malloc");
  323.     frame->halfY = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
  324.     ERRCHK(frame->halfY, "malloc");
  325.     frame->halfBoth = (uint8 **) malloc((Fsize_y-1)*sizeof(uint8 *));
  326.     ERRCHK(frame->halfBoth, "malloc");
  327.     for ( y = 0; y < Fsize_y; y++ ) {
  328.         frame->halfX[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
  329.         ERRCHK(frame->halfX[y], "malloc");
  330.     }
  331.     for ( y = 0; y < Fsize_y-1; y++ ) {
  332.         frame->halfY[y] = (uint8 *) malloc(Fsize_x*sizeof(uint8));
  333.         ERRCHK(frame->halfY[y], "malloc");
  334.     }
  335.     for ( y = 0; y < Fsize_y-1; y++ ) {
  336.         frame->halfBoth[y] = (uint8 *) malloc((Fsize_x-1)*sizeof(uint8));
  337.         ERRCHK(frame->halfBoth[y], "malloc");
  338.     }
  339. }
  340.  
  341.  
  342. /*===========================================================================*
  343.  *
  344.  * Frame_AllocDecoded
  345.  *
  346.  *    allocate memory for decoded frame for the given frame, if required
  347.  *    if makeReference == TRUE, then makes it reference frame
  348.  * 
  349.  * RETURNS:    nothing
  350.  *
  351.  * SIDE EFFECTS:    none
  352.  *
  353.  *===========================================================================*/
  354. void
  355. Frame_AllocDecoded(frame, makeReference)
  356.     MpegFrame *frame;
  357.     boolean makeReference;
  358. {
  359.     register int y;
  360.  
  361.     if ( frame->decoded_y != NULL) {    /* already allocated */
  362.     return;
  363.     }
  364.  
  365.     /* allocate memory for decoded image */
  366.     /* can probably reuse original image memory, but may decide to use
  367.        it for some reason, so do it this way at least for now -- more
  368.        flexible
  369.      */
  370.     frame->decoded_y = (uint8 **) malloc(sizeof(uint8 *) * Fsize_y);
  371.     ERRCHK(frame->decoded_y, "malloc");
  372.     for (y = 0; y < Fsize_y; y++) {
  373.     frame->decoded_y[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x);
  374.     ERRCHK(frame->decoded_y[y], "malloc");
  375.     }
  376.  
  377.     frame->decoded_cr = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
  378.     ERRCHK(frame->decoded_cr, "malloc");
  379.     for (y = 0; y < Fsize_y / 2; y++) {
  380.     frame->decoded_cr[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x / 2);
  381.     ERRCHK(frame->decoded_cr[y], "malloc");
  382.     }
  383.  
  384.     frame->decoded_cb = (uint8 **) malloc(sizeof(int8 *) * Fsize_y / 2);
  385.     ERRCHK(frame->decoded_cb, "malloc");
  386.     for (y = 0; y < Fsize_y / 2; y++) {
  387.     frame->decoded_cb[y] = (uint8 *) malloc(sizeof(uint8) * Fsize_x / 2);
  388.     ERRCHK(frame->decoded_cb[y], "malloc");
  389.     }
  390.  
  391.     if ( makeReference ) {
  392.     frame->ref_y = frame->decoded_y;
  393.     frame->ref_cr = frame->decoded_cr;
  394.     frame->ref_cb = frame->decoded_cb;
  395.     }
  396. }
  397.  
  398.  
  399. /*=====================*
  400.  * INTERNAL PROCEDURES *
  401.  *=====================*/
  402.  
  403.  
  404. /*===========================================================================*
  405.  *
  406.  * GetUnusedFrame
  407.  *
  408.  *    return an unused frame
  409.  *
  410.  * RETURNS:    the frame
  411.  *
  412.  * SIDE EFFECTS:    none
  413.  *
  414.  *===========================================================================*/
  415. static MpegFrame *
  416. GetUnusedFrame()
  417. {
  418.     register int index;
  419.  
  420.     for ( index = 0; index < 3; index++ ) {
  421.     if ( ! frameMemory[index]->inUse ) {
  422.         frameMemory[index]->inUse = TRUE;
  423.         return frameMemory[index];
  424.     }
  425.     }
  426.  
  427.     fprintf(stderr, "ERROR:  No UNUSED frames!!!\n");
  428.     exit(1);
  429. }
  430.  
  431.  
  432. /*===========================================================================*
  433.  *
  434.  * ResetFrame
  435.  *
  436.  *    reset a frame to the given id and type
  437.  *
  438.  * RETURNS:    nothing
  439.  *
  440.  * SIDE EFFECTS:    none
  441.  *
  442.  *===========================================================================*/
  443. static void
  444. ResetFrame(id, type, frame)
  445.     int id;
  446.     char type;
  447.     MpegFrame *frame;
  448. {
  449.     switch (type) {
  450.     case 'i':
  451.     frame->type = TYPE_IFRAME;
  452.     break;
  453.     case 'p':
  454.     frame->type = TYPE_PFRAME;
  455.     break;
  456.     case 'b':
  457.     frame->type = TYPE_BFRAME;
  458.     break;
  459.     default:
  460.     fprintf(stderr, "frame type %c: not supported\n", type);
  461.     exit(1);
  462.     }
  463.  
  464.     frame->id = id;
  465.     frame->halfComputed = FALSE;
  466. }
  467.  
  468.  
  469. /*===========================================================================*
  470.  *
  471.  * FreeFrame
  472.  *
  473.  *    frees the memory associated with the given frame
  474.  *
  475.  * RETURNS:    nothing
  476.  *
  477.  * SIDE EFFECTS:    none
  478.  *
  479.  *===========================================================================*/
  480. static void
  481. FreeFrame(frame)
  482.     MpegFrame *frame;
  483. {
  484.     int i;
  485.  
  486.     if (!frame) {
  487.     return;
  488.     }
  489.  
  490.     if ( frame->ppm_data ) {
  491.     /* it may be a little bigger than Fsize_y, but that's fine for
  492.        our purposes, since we aren't going to free until we exit anyway,
  493.        so by the time we call this we won't care
  494.      */
  495.     pnm_freearray(frame->ppm_data, Fsize_y);
  496.     frame->ppm_data = NULL;
  497.     }
  498.  
  499.     if (frame->rgb_data) {
  500.     pnm_freearray(frame->rgb_data, Fsize_y);
  501.     }
  502.     if (frame->orig_y) {
  503.     for (i = 0; i < Fsize_y; i++) {
  504.         free(frame->orig_y[i]);
  505.     }
  506.     free(frame->orig_y);
  507.  
  508.     for (i = 0; i < Fsize_y / 2; i++) {
  509.         free(frame->orig_cr[i]);
  510.     }
  511.     free(frame->orig_cr);
  512.  
  513.     for (i = 0; i < Fsize_y / 2; i++) {
  514.         free(frame->orig_cb[i]);
  515.     }
  516.     free(frame->orig_cb);
  517.     }
  518.     if ( frame->decoded_y ) {
  519.     for (i = 0; i < Fsize_y; i++) {
  520.         free(frame->decoded_y[i]);
  521.     }
  522.     free(frame->decoded_y);
  523.  
  524.     for (i = 0; i < Fsize_y / 2; i++) {
  525.         free(frame->decoded_cr[i]);
  526.     }
  527.     free(frame->decoded_cr);
  528.  
  529.     for (i = 0; i < Fsize_y / 2; i++) {
  530.         free(frame->decoded_cb[i]);
  531.     }
  532.     free(frame->decoded_cb);
  533.     }
  534.  
  535.     if (frame->y_blocks) {
  536.     for (i = 0; i < Fsize_y / DCTSIZE; i++) {
  537.         free(frame->y_blocks[i]);
  538.     }
  539.     free(frame->y_blocks);
  540.  
  541.     for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
  542.         free(frame->cr_blocks[i]);
  543.     }
  544.     free(frame->cr_blocks);
  545.  
  546.     for (i = 0; i < Fsize_y / (2 * DCTSIZE); i++) {
  547.         free(frame->cb_blocks[i]);
  548.     }
  549.     free(frame->cb_blocks);
  550.     }
  551.     if ( frame->halfX ) {
  552.     for ( i = 0; i < Fsize_y; i++ ) {
  553.         free(frame->halfX[i]);
  554.     }
  555.     free(frame->halfX);
  556.  
  557.     for ( i = 0; i < Fsize_y-1; i++ ) {
  558.         free(frame->halfY[i]);
  559.     }
  560.     free(frame->halfY);
  561.  
  562.     for ( i = 0; i < Fsize_y-1; i++ ) {
  563.         free(frame->halfBoth[i]);
  564.     }
  565.     free(frame->halfBoth);
  566.     }
  567.  
  568.     free(frame);
  569. }
  570.  
  571.  
  572.