home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / beehive / pcxload.c < prev    next >
Text File  |  1999-05-11  |  10KB  |  352 lines

  1.  
  2. /***************************************************************************
  3. *
  4. * File name        : PCXLOAD.C
  5. *
  6. * Description      : This module contains procedures that can be used for
  7. *                    loading and processing PCX image files
  8. *
  9. *
  10. * Copyright        : COPYRIGHT IBM CORPORATION, 1991, 1992, 1993, 1994, 1995
  11. *
  12. *        DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  13. *        sample code created by IBM Corporation. This sample code is not
  14. *        part of any standard or IBM product and is provided to you solely
  15. *        for  the purpose of assisting you in the development of your
  16. *        applications.  The code is provided "AS IS", without
  17. *        warranty of any kind.  IBM shall not be liable for any damages
  18. *        arising out of your use of the sample code, even if they have been
  19. *        advised of the possibility of such damages.
  20. *
  21. ****************************************************************************/
  22.  
  23. #define INCL_DOS
  24.  
  25. #include <os2.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <mmioos2.h>
  30. #include <dive.h>
  31. #include <fourcc.h>
  32. #include "beehive.h"
  33.  
  34.  
  35. extern DIVE_CAPS DiveCaps;
  36. extern HDIVE     hDive;
  37.  
  38. ULONG    ulrc;
  39.  
  40. //***************************************************************************
  41. //
  42. // Each PCX image file contains palette information. This procedure
  43. // will extract this information from the image file passed and store
  44. // it in a global buffer called pbPalette. The pbPalette buffer is
  45. // a 1024 byte standard OS/2 BMP palette that must be allocated by
  46. // the calling routine.
  47. //
  48. //***************************************************************************
  49.  
  50. ULONG ExtractPalette( PSZ pszFile, PBYTE pbPalette )
  51. {
  52.    PBYTE    pbTmpPalette,
  53.             pbRawPalette,
  54.             pbTmpRawPalette;
  55.    FILE     *pFile;
  56.    ULONG    i;
  57.  
  58.  
  59.    // Open image file
  60.    //
  61.    if( ( pFile = fopen ( pszFile, "rb" ) ) == NULL )
  62.       return( 1 );
  63.  
  64.    // Seek to the beginning of the palette data
  65.    //
  66.    i = fseek ( pFile, -768L, SEEK_END );
  67.  
  68.    // Allocate temp buffers for palette data
  69.    //
  70.    ulrc = DosAllocMem ( (PPVOID)&pbRawPalette, 768, MY_ALLOC_FLAGS );
  71.    if( ulrc ) return( ulrc );
  72.  
  73.    // Save buffer pointers
  74.    //
  75.    pbTmpPalette = pbPalette;
  76.    pbTmpRawPalette = pbRawPalette;
  77.  
  78.    // Read raw palette data
  79.    fread( pbTmpRawPalette, sizeof( CHAR ), 768L, pFile );
  80.  
  81.    // Convert to 4 bytes per color
  82.    //
  83.    for( i = 0; i < 256; i++ )
  84.    {
  85.       *pbTmpPalette++ = *(pbTmpRawPalette + 2);
  86.       *pbTmpPalette++ = *(pbTmpRawPalette + 1);
  87.       *pbTmpPalette++ = *pbTmpRawPalette;
  88.       *pbTmpPalette++ = 0;
  89.  
  90.       pbTmpRawPalette += 3;
  91.    }
  92.  
  93.    // Clean up and close file
  94.    //
  95.    DosFreeMem( pbRawPalette );
  96.  
  97.    fclose( pFile );
  98.  
  99.    return( 0 );
  100. }
  101.  
  102.  
  103.  
  104. //**********************************************************************
  105. //
  106. // When dive blits an image to the screen, the color space translation
  107. // can slow down the blitter. By prepocessing all of the images before
  108. // blitting them to the screen, this overhead is eliminated.
  109. //
  110. // Note: This is only relavent when the display color depth is set to 8
  111. //       8 bit.
  112. //
  113. //**********************************************************************
  114.  
  115. ULONG  ConvertImage( PBMPDATA pbmpData, PBYTE pbPalette )
  116. {
  117.    SETUP_BLITTER     SetupBlitter;
  118.    RECTL             rcl;
  119.    extern HDIVE      hDive;
  120.    PBYTE             pbTargetBuffer;
  121.    ULONG             ulTargetImage;
  122.  
  123.  
  124.    // Associate source buffer with dive
  125.    //
  126.    pbmpData->ulImage = 0;
  127.    ulrc = DiveAllocImageBuffer ( hDive,
  128.                           &pbmpData->ulImage,
  129.                           FOURCC_LUT8,
  130.                           pbmpData->ulWidth,
  131.                           pbmpData->ulHeight,
  132.                           0,
  133.                           pbmpData->pbBuffer );
  134.    if( ulrc ) return( ulrc );
  135.  
  136.    // Allocate and associate target buffer with dive. The size of the
  137.    // target buffers are dictated by the size of the scene buffer.
  138.    //
  139.    ulrc = DosAllocMem ( (PPVOID)&pbTargetBuffer,
  140.                         pbmpData->ulWidth * pbmpData->ulHeight,
  141.                         MY_ALLOC_FLAGS );
  142.    if( ulrc ) return( ulrc );
  143.  
  144.  
  145.    ulTargetImage = 0;
  146.    ulrc = DiveAllocImageBuffer ( hDive,
  147.                           &ulTargetImage,
  148.                           FOURCC_SCRN,
  149.                           pbmpData->ulWidth,
  150.                           pbmpData->ulHeight,
  151.                           0,
  152.                           pbTargetBuffer );
  153.    if( ulrc ) return( ulrc );
  154.  
  155.    rcl.xLeft = 0;
  156.    rcl.yBottom = 0;
  157.    rcl.xRight = pbmpData->ulWidth;
  158.    rcl.yTop= pbmpData->ulHeight;
  159.  
  160.    // Setup the blitter
  161.    //
  162.    SetupBlitter.ulStructLen = sizeof ( SETUP_BLITTER );
  163.    SetupBlitter.fccSrcColorFormat = FOURCC_LUT8;
  164.    SetupBlitter.ulSrcWidth = pbmpData->ulWidth;
  165.    SetupBlitter.ulSrcHeight = pbmpData->ulHeight;
  166.    SetupBlitter.ulSrcPosX = 0;
  167.    SetupBlitter.ulSrcPosY = 0;
  168.    SetupBlitter.fInvert = FALSE;
  169.    SetupBlitter.ulDitherType = 1;
  170.  
  171.    SetupBlitter.fccDstColorFormat = FOURCC_SCRN;
  172.    SetupBlitter.ulDstWidth = pbmpData->ulWidth;
  173.    SetupBlitter.ulDstHeight = pbmpData->ulHeight;
  174.    SetupBlitter.lDstPosX = 0;
  175.    SetupBlitter.lDstPosY = 0;
  176.    SetupBlitter.lScreenPosX = 0;
  177.    SetupBlitter.lScreenPosY = 0;
  178.    SetupBlitter.ulNumDstRects = 1;
  179.    SetupBlitter.pVisDstRects = &rcl;
  180.    DiveSetupBlitter ( hDive, &SetupBlitter );
  181.  
  182.    // Setup the palette
  183.    //
  184.    DiveSetSourcePalette ( hDive, 0, 256, pbPalette );
  185.  
  186.    // Blit the image
  187.    //
  188.    DiveBlitImage( hDive, pbmpData->ulImage, ulTargetImage );
  189.  
  190.    // Disassociate buffers from dive
  191.    //
  192.    DiveFreeImageBuffer( hDive, ulTargetImage );
  193.    DiveFreeImageBuffer( hDive, pbmpData->ulImage );
  194.  
  195.    // Copy the converted image to the old buffer and free the temp buffer
  196.    //
  197.    memcpy( pbmpData->pbBuffer,
  198.             pbTargetBuffer,
  199.             pbmpData->ulWidth * pbmpData->ulHeight );
  200.  
  201.    DosFreeMem( pbTargetBuffer );
  202.  
  203.    // Reset the dive palette
  204.    //
  205.    DiveSetSourcePalette( hDive, 0, 0, 0 );
  206.  
  207.    return( 0 );
  208. }
  209.  
  210.  
  211. /****************************************************************************
  212.  *
  213.  * Name          : ReadFile
  214.  *
  215.  *
  216.  * Parameters    : Index for the file to open
  217.  *                 Pointer to the file name to open
  218.  *                 Pointer to window data
  219.  *
  220.  * Return        : 0 - succeed
  221.  *                 1 - fail
  222.  *
  223.  ****************************************************************************/
  224.  
  225.  
  226. ULONG ReadFile ( PSZ pszFile, PBMPDATA pbmpData )
  227.  
  228.    {
  229.    ULONG       i;
  230.    PCX_HEADER  pcxHeader;
  231.    ULONG       ulOpenParms;
  232.    FILE       *pFile;
  233.    ULONG       ulBytesRead;
  234.    ULONG       ulDataSize;
  235.    CHAR        chData;
  236.    ULONG       ulRunLength;
  237.    ULONG       ulRemBytesInLine;
  238.    ULONG       ulLinesToRead;
  239.    ULONG       ulBytesToRead;
  240.    ULONG       ulError;
  241.    PBYTE       pbTmpDest;
  242.    PBYTE       pbPalette;
  243.  
  244.    // Open image file
  245.    //
  246.    if( ( pFile = fopen ( pszFile, "rb" ) ) == NULL )
  247.       return( 1 );
  248.  
  249.    // Read PCX header from image file
  250.    //
  251.    ulBytesRead = fread( (VOID *)&pcxHeader, sizeof( CHAR ),
  252.                         sizeof( PCX_HEADER ), pFile );
  253.  
  254.    if( ulBytesRead != sizeof( PCX_HEADER ) )
  255.       {
  256.       fclose( pFile );
  257.       return( 1 );
  258.       }
  259.  
  260.    // Set bitmap width and height in pels
  261.    //
  262.    pbmpData->ulHeight = pcxHeader.shHeight + 1;
  263.    pbmpData->ulWidth = (ULONG)pcxHeader.shBytesPerLine;
  264.  
  265.    ulDataSize = pbmpData->ulWidth * pbmpData->ulHeight;
  266.  
  267.    // Allcate buffer for image data
  268.    //
  269.    ulrc = DosAllocMem ( (PPVOID)&pbmpData->pbBuffer, ulDataSize, MY_ALLOC_FLAGS );
  270.  
  271.    if( ulrc )
  272.       {
  273.       fclose( pFile );
  274.       return( ulrc );
  275.       }
  276.  
  277.    // Clear the image buffer
  278.    //
  279.    memset( pbmpData->pbBuffer, 0, pbmpData->ulWidth * pbmpData->ulHeight );
  280.  
  281.    pbTmpDest = pbmpData->pbBuffer;
  282.    ulBytesRead = 0;
  283.  
  284.    // Read and convert PCX data
  285.    //
  286.    while( ulBytesRead < pbmpData->ulWidth * pbmpData->ulHeight )
  287.       {
  288.  
  289.       if( ( chData = fgetc( pFile ) ) == EOF ) break;
  290.  
  291.       // Check if this byte is the beginning of a data run
  292.       //
  293.       if( chData > 192 )
  294.          {
  295.          ulRunLength = chData - 192;
  296.  
  297.          // Get color data
  298.          //
  299.          chData = fgetc( pFile );
  300.  
  301.          // Duplicate color for length of run
  302.          //
  303.          for( i = 0; i < ulRunLength; i++ )
  304.             {
  305.             *pbTmpDest++ = chData;
  306.             ulBytesRead++;
  307.             }
  308.          }
  309.       else
  310.          {
  311.          *pbTmpDest++ = chData;
  312.          ulBytesRead++;
  313.          }
  314.       }
  315.  
  316.    if( ulBytesRead != ulDataSize )
  317.       {
  318.       fclose( pFile );
  319.       DosFreeMem( pbmpData->pbBuffer );
  320.       return( 1 );
  321.       }
  322.  
  323.    // Done extracting image data.. close file
  324.    //
  325.    fclose( pFile );
  326.  
  327.    // Allocate a 1024 byte buffer for an OS/2 palette and fill it
  328.    // with the palette data from the passed image.
  329.    //
  330.    ulrc = DosAllocMem ( (PPVOID)&pbPalette, 1024, MY_ALLOC_FLAGS );
  331.    if( ulrc ) return( ulrc );
  332.  
  333.    ExtractPalette( pszFile, pbPalette );
  334.  
  335.    // Use the extracted palette to convert the image to the current
  336.    // OS/2 palette.
  337.    //
  338.    if( DiveCaps.ulDepth == 8 )
  339.    {
  340.       ConvertImage( pbmpData, pbPalette );
  341.  
  342.       // Free the palette buffer
  343.       //
  344.       DosFreeMem( pbPalette );
  345.    }
  346.    else
  347.       DiveSetSourcePalette ( hDive, 0, 256, pbPalette );
  348.  
  349.    return( 0 );
  350.    }
  351.  
  352.