Compression

The following section illustrates how to compress raw digital images into a smaller form so they can use less storage space. Follow these steps for compression support:

The IOSET.C file shown in the following example uses the MMEXTENDINFO data structure to set values for the source header, destination header, and other information.

Note: You can only associate one stream or track.

/*************************START OF SPECIFICATIONS ****************//* SOURCE FILE NAME:  IOSET.C                                    */
/*                                                               */
/* DESCRIPTIVE NAME: File Format IOProc routine for MMIOM_SET    */
/*                                                               */
/* COPYRIGHT:     IBM - International Business Machines          */
/*            Copyright (c) IBM Corporation  1991, 1992, 1993    */
/*                        All Rights Reserved                    */
/*                                                               */
/* STATUS: OS/2 Release 2.0                                      */
/*                                                               */
/* FUNCTION: This source module contains the set functions.      */
/* NOTES:                                                        */
/*    DEPENDENCIES: none                                         */
/*    RESTRICTIONS: Runs in 32-bit protect mode (OS/2 2.0)       */
/*                                                               */
/* ENTRY POINTS:                                                 */
/*              IOProcSet                                        */
/*                                                               */
/************************* END OF SPECIFICATIONS *****************/

#include        <stdio.h>
#include        <string.h>
#include        <stdlib.h>
#include        <memory.h>

#define         INCL_DOS             /* #define  INCL_DOSPROCESS.*/
#define         INCL_ERRORS
#define         INCL_WIN
#define         INCL_GPI

#include        <os2.h>              /* OS/2 headers.            */
#include        <pmbitmap.h>

#define         INCL_OS2MM
#define         INCL_MMIO_CODEC
#define         INCL_MMIO_DOSIOPROC

#include        <os2me.h>            /* Multimedia IO extensions. */
#include        <hhpheap.h>
#include        <ioi.h>

/************************** START OF SPECIFICATIONS **********/
/*                                                           */
/* SUBROUTINE NAME: IOProcSet                                */
/*                                                           */
/* DESCRIPTIVE NAME: Set various conditions in IOProc        */
/*                                                           */
/* FUNCTION:                                                 */
/*                                                           */
/* NOTES: None                                               */
/*                                                           */
/* ENTRY POINT: IOProcSet                                    */
/*   LINKAGE:   CALL FAR (00:32)                             */
/*                                                           */
/* INPUT:                                                    */
/*   PMMIOINFO   pmmioinfo - ptr to instance structure       */
/*   LONG        lParam1  - first parameter                  */
/*   LONG        lParam2  - Second parameter                 */
/*                                                           */
/*                                                           */
/* EXIT-NORMAL:                                              */
/*              MMIO_SUCCESS                                 */
/*                                                           */
/* EXIT-ERROR:                                               */
/*              MMIO_ERROR                                   */
/*                                                           */
/* SIDE EFFECTS:                                             */
/*                                                           */
/*************************** END OF SPECIFICATIONS ***********/
LONG IOProcSet ( PMMIOINFO pmmioinfo,
                 LONG lParam1,
                 LONG lParam2 )

{
   PINSTANCE       pinstance;
   LONG            rc = MMIO_SUCCESS;
   PMMEXTENDINFO   pmmextendinfo = (PMMEXTENDINFO)lParam1;
   PCCB            pccb;
   ULONG           ulCCBCount;
   PCODECASSOC     pcodecassoc;
   ULONG           ulSize;
   PVOID           PtrNextAvail;

   if (rc = ioGetPtrInstance(pmmioinfo,&pinstance))
      return(rc);

   switch(lParam2){
      /*************************/
      /* SET INFO              */
      /*************************/
      case MMIO_SET_EXTENDEDINFO:   /* Set extended information */
         if (pmmextendinfo) {     /* error check */

            /********************/
            /* Set active track */
            /********************/
            if (pmmextendinfo->ulFlags & MMIO_TRACK) {

               if (pmmextendinfo->ulTrackID == (ULONG)MMIO_RESETTRACKS) {
                  pinstance->lCurrentTrack = pmmextendinfo->ulTrackID;
                  }
               else {
                 if (pinstance->ulFlags & OPENED_READONLY) {
                   if (ioFindTracki(pinstance,pmmextendinfo->ulTrackID)) {
                      pinstance->lCurrentTrack = pmmextendinfo->ulTrackID;
                       }
                     else {
                        pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
                        rc = MMIO_ERROR;
                        break;
                        }
                     }

                  else if (pinstance->ulFlags &
                          (OPENED_READWRITE | OPENED_WRITECREATE)) {
                     pinstance->lCurrentTrack = pmmextendinfo->ulTrackID;
                     }

                  else {
                     pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
                     rc = MMIO_ERROR;
                     break;
                     }
                  } /* else */
               }  /* MMIO_TRACK */

            /**********************************************************/
            /* Reset all Non-normal reading modes.  All request audio */
            /* and video frames are returned.                         */
            /**********************************************************/
            if (pmmextendinfo->ulFlags & MMIO_NORMAL_READ) {
               pinstance->ulMode = MODE_NORMALREAD;
               } /* MMIO_NORMAL_READ */

            /***********************************************************/
            /* Set IOProc into SCAN mode for the active track. Reading */
            /* will now be done, but only Key frames are returned for  */
            /* video.                                                  */
            /***********************************************************/
            else if (pmmextendinfo->ulFlags & MMIO_SCAN_READ) {
               pinstance->ulMode = MODE_SCANREAD;
               } /* MMIO_SCAN_READ */

            /***********************************************************/
            /* Set IOProc into REVERSE mode for the active track.      */
            /* Reading will now be done, but only Key frames are       */
            /* returned for video                                      */
            /***********************************************************/
            else if (pmmextendinfo->ulFlags & MMIO_REVERSE_READ) {
               pinstance->ulMode = MODE_REVERSEREAD;
               } /* MMIO_REVERSE_READ */

            /****************************************************/
            /* Associate CODEC information for recording        */
            /****************************************************/
            if (pmmextendinfo->ulFlags & MMIO_CODEC_ASSOC) {

               /* Don't alow a CODEC association for read only files */
               if (pinstance->ulFlags & OPENED_READONLY) {
                  pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
                  rc = MMIO_ERROR;
                  break;
                  }

               /* Can only associate 1 CODEC for record */
               if (pmmextendinfo->ulNumCODECs == 1) {
                  if (rc = ioAssociateCodec(pmmioinfo,
                                            pinstance,
                                            pmmextendinfo->pCODECAssoc)) {
                     pmmioinfo->ulErrorRet = rc;
                     rc = MMIO_ERROR;
                     }
                  }
               else {
                  pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
                  rc = MMIO_ERROR;
                  }
               } /* MMIO_CODEC_ASSOC */
            } /* pmmextendedinfo */

         else { /* error - data structure missing */
            pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
            rc = MMIO_ERROR;
            }
         break;
      /********************************/
      /* QUERY BASE AND CODEC INFO    */
      /********************************/
      case MMIO_QUERY_EXTENDEDINFO_ALL:
        /* Query Also CODEC associated info */

       /* Create the array of codecassoc structures to return to caller */
       pcodecassoc = pmmextendinfo->pCODECAssoc;  /* Point to beginning */
       for (pccb = pinstance->pccbList; pccb; pccb = pccb->pccbNext) {
          pcodecassoc->pCodecOpen = NULL;
          pcodecassoc->pCODECIniFileInfo = NULL;
          pcodecassoc++;
          }
        PtrNextAvail = (PVOID)pcodecassoc;

        /* Fill in pointers to the CODECIniFileInfo structures to follow */
        ulSize = 0L;
        pcodecassoc = pmmextendinfo->pCODECAssoc;  /* Point to beginning */
        for (pccb = pinstance->pccbList; pccb; pccb = pccb->pccbNext) {

          /* Create and copy CODECINIFILEINFO structure */
          pcodecassoc->pCODECIniFileInfo = (PCODECINIFILEINFO)PtrNextAvail;
          memcpy(pcodecassoc->pCODECIniFileInfo,&pccb->
             cifi,sizeof(CODECINIFILEINFO));
          PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail)
             + sizeof(CODECINIFILEINFO));

           /* Create and copy CODECOPEN structure */
           pcodecassoc->pCodecOpen = PtrNextAvail;
           memcpy(pcodecassoc->pCodecOpen,&pccb->codecopen,
              sizeof(CODECOPEN));
           PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail)
              + sizeof(CODECOPEN));

            /* Create and copy Pointers to structures   */
            /* in the CODECOPEN structure.              */
            if (pccb->codecopen.pControlHdr) {
               ulSize = *((PULONG)pccb->codecopen.pControlHdr);
               ((PCODECOPEN)pcodecassoc->pCodecOpen)->pControlHdr =
                  (PVOID)PtrNextAvail;
               memcpy(((PCODECOPEN)pcodecassoc->pCodecOpen)->pControlHdr,
                      pccb->codecopen.pControlHdr,
                      ulSize);
               PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail) + ulSize);
               }
            if (pccb->codecopen.pSrcHdr) {
               ulSize = *((PULONG)pccb->codecopen.pSrcHdr);
               ((PCODECOPEN)pcodecassoc->pCodecOpen)->pSrcHdr
                   = PtrNextAvail;
               memcpy(((PCODECOPEN)pcodecassoc->pCodecOpen)->pSrcHdr,
                      pccb->codecopen.pSrcHdr,
                      ulSize);
               PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail) + ulSize);
               }

            if (pccb->codecopen.pDstHdr) {
               ulSize = *((PULONG)pccb->codecopen.pDstHdr);
               ((PCODECOPEN)pcodecassoc->pCodecOpen)->pDstHdr
                   = PtrNextAvail;
               memcpy(((PCODECOPEN)pcodecassoc->pCodecOpen)->pDstHdr,
                      pccb->codecopen.pDstHdr,
                      ulSize);
               PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail) + ulSize);
               }

            if (pccb->codecopen.pOtherInfo) {
               ulSize = *((PULONG)pccb->codecopen.pOtherInfo);
               ((PCODECOPEN)pcodecassoc->pCodecOpen)->pOtherInfo
                    = PtrNextAvail;
               memcpy(((PCODECOPEN)pcodecassoc->pCodecOpen)->pOtherInfo,
                      pccb->codecopen.pOtherInfo,
                      ulSize);
               PtrNextAvail = (PVOID) (((ULONG)PtrNextAvail) + ulSize);
               }
            pcodecassoc++;
            }

      /*************************************************/
      /* QUERY BASE INFO  (NOTE: Fall through    */
      /* from previous case!)                          */
      /*************************************************/
      case MMIO_QUERY_EXTENDEDINFO_BASE: /* Query only MMEXTENDINFO info */
         pmmextendinfo->ulStructLen = sizeof(MMEXTENDINFO);
         pmmextendinfo->ulTrackID = (ULONG)pinstance->lCurrentTrack;
         /* pmmextendinfo->pCODECAssoc = NULL;  */

         /* Compute ulBufSize for complete information return */
         ulSize = 0L;
         for (pccb = pinstance->pccbList, ulCCBCount = 0; /* Count CCB's */
              pccb;
              ulCCBCount++, pccb = pccb->pccbNext) {
            ulSize += sizeof(CODECASSOC)+sizeof(CODECOPEN)
                +sizeof(CODECINIFILEINFO); /* static stuff */

            /* Extract ulStructLen as first field of structure  */
            /* that ptr points to.                              */
            if (pccb->codecopen.pControlHdr) {
               ulSize += *((PULONG)pccb->codecopen.pControlHdr);
               }
            if (pccb->codecopen.pSrcHdr) {
               ulSize += *((PULONG)pccb->codecopen.pSrcHdr);
               }
            if (pccb->codecopen.pDstHdr) {
               ulSize += *((PULONG)pccb->codecopen.pDstHdr);
               }
            if (pccb->codecopen.pOtherInfo) {
               ulSize += *((PULONG)pccb->codecopen.pOtherInfo);
               }
            }

         pmmextendinfo->ulNumCODECs = ulCCBCount;
         pmmextendinfo->ulBufSize = ulSize;
         break;

      /*********/
      /* ERROR */
      /*********/
      default:
         pmmioinfo->ulErrorRet = MMIOERR_INVALID_PARAMETER;
         rc = MMIO_ERROR;
         break;
      }/* end switch */

   return(rc);
}


[Back: Loading the CODEC Procedure]
[Next: Associating a CODEC with a File]