home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / dib2sprt.c < prev    next >
C/C++ Source or Header  |  2001-02-05  |  14KB  |  595 lines

  1. /*
  2.  * dib2sprt.c
  3.  * Copyright (C) 2000,2001 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Functions to translate dib pictures into sprites
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "wimpt.h"
  12. #include "antiword.h"
  13.  
  14. #if 0 /* defined(DEBUG) */
  15. static int iPicCounter = 0;
  16. #endif /* DEBUG */
  17.  
  18.  
  19. /*
  20.  * iGetByteWidth - compute the number of bytes needed for a row of pixels
  21.  */
  22. static int
  23. iGetByteWidth(const imagedata_type *pImg)
  24. {
  25.     switch (pImg->iBitsPerComponent) {
  26.     case  1:
  27.         return (pImg->iWidth + 31) / 32 * sizeof(int);
  28.     case  4:
  29.         return (pImg->iWidth + 7) / 8 * sizeof(int);
  30.     case  8:
  31.     case 24:
  32.         return (pImg->iWidth + 3) / 4 * sizeof(int);
  33.     default:
  34.         DBG_DEC(pImg->iBitsPerComponent);
  35.         return 0;
  36.     }
  37. } /* end of iGetByteWidth */
  38.  
  39. /*
  40.  * bCreateBlankSprite - Create a blank sprite.
  41.  *
  42.  * Create a blank sprite and add a palette if needed
  43.  *
  44.  * returns a pointer to the sprite when successful, otherwise NULL
  45.  */
  46. static unsigned char *
  47. pucCreateBlankSprite(const imagedata_type *pImg, size_t *ptSize)
  48. {
  49.     sprite_area    *pArea;
  50.     unsigned char    *pucTmp;
  51.     size_t    tSize;
  52.     int    iIndex, iMode, iPaletteEntries, iByteWidth;
  53.  
  54.     DBG_MSG("pCreateBlankSprite");
  55.  
  56.     fail(pImg == NULL);
  57.  
  58.     switch (pImg->iBitsPerComponent) {
  59.     case  1:
  60.         iMode = 18;
  61.         iPaletteEntries = 2;
  62.         break;
  63.     case  4:
  64.         iMode = 20;
  65.         iPaletteEntries = 16;
  66.         break;
  67.     case  8:
  68.     case 24:
  69.         iMode = 21;
  70.         iPaletteEntries = 0;
  71.         break;
  72.     default:
  73.         DBG_DEC(pImg->iBitsPerComponent);
  74.         return NULL;
  75.     }
  76.     fail(iPaletteEntries < 0 || iPaletteEntries > 16);
  77.  
  78.     /* Create the sprite */
  79.  
  80.     iByteWidth = iGetByteWidth(pImg);
  81.  
  82.     tSize = sizeof(sprite_area) +
  83.         sizeof(sprite_header) +
  84.         iPaletteEntries * 8 +
  85.         iByteWidth * pImg->iHeight;
  86.     DBG_DEC(tSize);
  87.     pArea = xmalloc(tSize);
  88.     sprite_area_initialise(pArea, tSize);
  89.  
  90.     wimpt_noerr(sprite_create(pArea, "wordimage",
  91.         iPaletteEntries > 0 ? sprite_haspalette : sprite_nopalette,
  92.         pImg->iWidth, pImg->iHeight, iMode));
  93.  
  94.     /* Add the palette */
  95.  
  96.     pucTmp = (unsigned char *)pArea +
  97.         sizeof(sprite_area) + sizeof(sprite_header);
  98.     for (iIndex = 0; iIndex < iPaletteEntries; iIndex++) {
  99.         /* First color */
  100.         *pucTmp++ = 0;
  101.         *pucTmp++ = pImg->aucPalette[iIndex][0];
  102.         *pucTmp++ = pImg->aucPalette[iIndex][1];
  103.         *pucTmp++ = pImg->aucPalette[iIndex][2];
  104.         /* Second color */
  105.         *pucTmp++ = 0;
  106.         *pucTmp++ = pImg->aucPalette[iIndex][0];
  107.         *pucTmp++ = pImg->aucPalette[iIndex][1];
  108.         *pucTmp++ = pImg->aucPalette[iIndex][2];
  109.     }
  110.  
  111.     if (ptSize != NULL) {
  112.         *ptSize = tSize;
  113.     }
  114.     return (unsigned char *)pArea;
  115. } /* end of pucCreateBlankSprite */
  116.  
  117. /*
  118.  * iReduceColor - reduce from 24 bit to 8 bit color
  119.  *
  120.  * Reduce 24 bit true colors to RISC OS default 256 color palette
  121.  *
  122.  * returns the resulting color
  123.  */
  124. static int
  125. iReduceColor(int iRed, int iGreen, int iBlue)
  126. {
  127.     int    iResult;
  128.  
  129.     iResult = (iBlue & 0x80) ? 0x80 : 0;
  130.     iResult |= (iGreen & 0x80) ? 0x40 : 0;
  131.     iResult |= (iGreen & 0x40) ? 0x20 : 0;
  132.     iResult |= (iRed & 0x80) ? 0x10 : 0;
  133.     iResult |= (iBlue & 0x40) ? 0x08 : 0;
  134.     iResult |= (iRed & 0x40) ? 0x04 : 0;
  135.     iResult |= ((iRed | iGreen | iBlue) & 0x20) ? 0x02 : 0;
  136.     iResult |= ((iRed | iGreen | iBlue) & 0x10) ? 0x01 : 0;
  137.     return iResult;
  138. } /* end of iReduceColor */
  139.  
  140. /*
  141.  * vDecode1bpp - decode an uncompressed 1 bit per pixel image
  142.  */
  143. static void
  144. vDecode1bpp(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  145. {
  146.     int    iX, iY, iByteWidth, iOffset, iTmp, iEighthWidth, iPadding;
  147.     unsigned char    ucTmp;
  148.  
  149.     DBG_MSG("vDecode1bpp");
  150.  
  151.     fail(pFile == NULL);
  152.     fail(pucData == NULL);
  153.     fail(pImg == NULL);
  154.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
  155.  
  156.     iByteWidth = iGetByteWidth(pImg);
  157.  
  158.     iEighthWidth = (pImg->iWidth + 7) / 8;
  159.     iPadding = ROUND4(iEighthWidth) - iEighthWidth;
  160.  
  161.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  162.         for (iX = 0; iX < iEighthWidth; iX++) {
  163.             iTmp = iNextByte(pFile);
  164.             if (iTmp == EOF) {
  165.                 return;
  166.             }
  167.             /* Reverse the bit order */
  168.             ucTmp  = (iTmp & BIT(0)) ? (unsigned char)BIT(7) : 0;
  169.             ucTmp |= (iTmp & BIT(1)) ? (unsigned char)BIT(6) : 0;
  170.             ucTmp |= (iTmp & BIT(2)) ? (unsigned char)BIT(5) : 0;
  171.             ucTmp |= (iTmp & BIT(3)) ? (unsigned char)BIT(4) : 0;
  172.             ucTmp |= (iTmp & BIT(4)) ? (unsigned char)BIT(3) : 0;
  173.             ucTmp |= (iTmp & BIT(5)) ? (unsigned char)BIT(2) : 0;
  174.             ucTmp |= (iTmp & BIT(6)) ? (unsigned char)BIT(1) : 0;
  175.             ucTmp |= (iTmp & BIT(7)) ? (unsigned char)BIT(0) : 0;
  176.             iOffset = iY * iByteWidth + iX;
  177.             *(pucData + iOffset) = ucTmp;
  178.         }
  179.         (void)iSkipBytes(pFile, iPadding);
  180.     }
  181. } /* end of vDecode1bpp */
  182.  
  183. /*
  184.  * vDecode4bpp - decode an uncompressed 4 bits per pixel image
  185.  */
  186. static void
  187. vDecode4bpp(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  188. {
  189.     int    iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth, iPadding;
  190.     unsigned char    ucTmp;
  191.  
  192.     DBG_MSG("vDecode4bpp");
  193.  
  194.     fail(pFile == NULL);
  195.     fail(pucData == NULL);
  196.     fail(pImg == NULL);
  197.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  198.  
  199.     iByteWidth = iGetByteWidth(pImg);
  200.  
  201.     iHalfWidth = (pImg->iWidth + 1) / 2;
  202.     iPadding = ROUND4(iHalfWidth) - iHalfWidth;
  203.  
  204.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  205.         for (iX = 0; iX < iHalfWidth; iX++) {
  206.             iTmp = iNextByte(pFile);
  207.             if (iTmp == EOF) {
  208.                 return;
  209.             }
  210.             /* Reverse the nibble order */
  211.             ucTmp = (iTmp & 0xf0) >> 4;
  212.             ucTmp |= (iTmp & 0x0f) << 4;
  213.             iOffset = iY * iByteWidth + iX;
  214.             *(pucData + iOffset) = ucTmp;
  215.         }
  216.         (void)iSkipBytes(pFile, iPadding);
  217.     }
  218. } /* end of vDecode4bpp */
  219.  
  220. /*
  221.  * vDecode8bpp - decode an uncompressed 8 bits per pixel image
  222.  */
  223. static void
  224. vDecode8bpp(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  225. {
  226.     int    iX, iY, iByteWidth, iOffset, iIndex, iPadding;
  227.  
  228.     DBG_MSG("vDecode8bpp");
  229.  
  230.     fail(pFile == NULL);
  231.     fail(pucData == NULL);
  232.     fail(pImg == NULL);
  233.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  234.  
  235.     iByteWidth = iGetByteWidth(pImg);
  236.  
  237.     iPadding = ROUND4(pImg->iWidth) - pImg->iWidth;
  238.  
  239.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  240.         for (iX = 0; iX < pImg->iWidth; iX++) {
  241.             iIndex = iNextByte(pFile);
  242.             if (iIndex == EOF) {
  243.                 return;
  244.             }
  245.             iOffset = iY * iByteWidth + iX;
  246.             *(pucData + iOffset) = iReduceColor(
  247.                 pImg->aucPalette[iIndex][0],
  248.                 pImg->aucPalette[iIndex][1],
  249.                 pImg->aucPalette[iIndex][2]);
  250.         }
  251.         (void)iSkipBytes(pFile, iPadding);
  252.     }
  253. } /* end of vDecode8bpp */
  254.  
  255. /*
  256.  * vDecode24bpp - decode an uncompressed 24 bits per pixel image
  257.  */
  258. static void
  259. vDecode24bpp(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  260. {
  261.     int    iX, iY, iTripleWidth, iByteWidth, iOffset, iPadding;
  262.     int    iRed, iGreen, iBlue;
  263.  
  264.     DBG_MSG("vDecode24bpp");
  265.  
  266.     fail(pFile == NULL);
  267.     fail(pucData == NULL);
  268.     fail(pImg == NULL);
  269.  
  270.     iByteWidth = iGetByteWidth(pImg);
  271.  
  272.     iTripleWidth = pImg->iWidth * 3;
  273.     iPadding = ROUND4(iTripleWidth) - iTripleWidth;
  274.  
  275.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  276.         for (iX = 0; iX < pImg->iWidth; iX++) {
  277.             iBlue = iNextByte(pFile);
  278.             if (iBlue == EOF) {
  279.                 return;
  280.             }
  281.             iGreen = iNextByte(pFile);
  282.             if (iGreen == EOF) {
  283.                 return;
  284.             }
  285.             iRed = iNextByte(pFile);
  286.             if (iRed == EOF) {
  287.                 return;
  288.             }
  289.             iOffset = iY * iByteWidth + iX;
  290.             *(pucData + iOffset) =
  291.                     iReduceColor(iRed, iGreen, iBlue);
  292.         }
  293.         (void)iSkipBytes(pFile, iPadding);
  294.     }
  295. } /* end of vDecode24bpp */
  296.  
  297. /*
  298.  * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
  299.  */
  300. static void
  301. vDecodeRle4(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  302. {
  303.     int    iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth;
  304.     int    iRun, iRunLength, iHalfRun;
  305.     BOOL    bEOL;
  306.     unsigned char    ucTmp;
  307.  
  308.     DBG_MSG("vDecodeRle4");
  309.  
  310.     fail(pFile == NULL);
  311.     fail(pucData == NULL);
  312.     fail(pImg == NULL);
  313.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  314.  
  315.     DBG_DEC(pImg->iWidth);
  316.     DBG_DEC(pImg->iHeight);
  317.  
  318.     iByteWidth = iGetByteWidth(pImg);
  319.     iHalfWidth = (pImg->iWidth + 1) / 2;
  320.  
  321.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  322.         bEOL = FALSE;
  323.         iX = 0;
  324.         while (!bEOL) {
  325.             iRunLength = iNextByte(pFile);
  326.             if (iRunLength == EOF) {
  327.                 return;
  328.             }
  329.             if (iRunLength != 0) {
  330.                   /*
  331.                  * Encoded packet:
  332.                  * RunLength pixels, all the "same" value
  333.                  */
  334.                 iTmp = iNextByte(pFile);
  335.                 if (iTmp == EOF) {
  336.                     return;
  337.                 }
  338.                 /* Reverse the nibble order */
  339.                 ucTmp = (iTmp & 0xf0) >> 4;
  340.                 ucTmp |= (iTmp & 0x0f) << 4;
  341.                 iHalfRun = (iRunLength + 1) / 2;
  342.                 for (iRun = 0; iRun < iHalfRun; iRun++) {
  343.                     if (iX < iHalfWidth) {
  344.                         iOffset = iY * iByteWidth + iX;
  345.                         *(pucData + iOffset) = ucTmp;
  346.                     }
  347.                     iX++;
  348.                 }
  349.                 continue;
  350.             }
  351.             /* Literal or escape */
  352.             iRunLength = iNextByte(pFile);
  353.             if (iRunLength == EOF) {
  354.                 return;
  355.             }
  356.             if (iRunLength == 0) {        /* End of line escape */
  357.                 bEOL = TRUE;
  358.             } else if (iRunLength == 1) {    /* End of file escape */
  359.                 return;
  360.             } else if (iRunLength == 2) {    /* Delta escape */
  361.                 DBG_MSG("RLE4: encountered delta escape");
  362.                 return;
  363.             } else {            /* Literal packet */
  364.                 iHalfRun = (iRunLength + 1) / 2;
  365.                 for (iRun = 0; iRun < iHalfRun; iRun++) {
  366.                     iTmp = iNextByte(pFile);
  367.                     if (iTmp == EOF) {
  368.                         return;
  369.                     }
  370.                     /* Reverse the nibble order */
  371.                     ucTmp = (iTmp & 0xf0) >> 4;
  372.                     ucTmp |= (iTmp & 0x0f) << 4;
  373.                     if (iX < iHalfWidth) {
  374.                         iOffset = iY * iByteWidth + iX;
  375.                         *(pucData + iOffset) = ucTmp;
  376.                     }
  377.                     iX++;
  378.                 }
  379.                 /* Padding if the number of bytes is odd */
  380.                 if (odd(iHalfRun)) {
  381.                     (void)iSkipBytes(pFile, 1);
  382.                 }
  383.             }
  384.         }
  385.         DBG_DEC_C(iX != iHalfWidth, iX);
  386.     }
  387. } /* end of vDecodeRle4 */
  388.  
  389. /*
  390.  * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
  391.  */
  392. static void
  393. vDecodeRle8(FILE *pFile, unsigned char *pucData, const imagedata_type *pImg)
  394. {
  395.     int    iX, iY, iRun, iRunLength, iOffset, iIndex, iByteWidth;
  396.     BOOL    bEOL;
  397.  
  398.     DBG_MSG("vDecodeRle8");
  399.  
  400.     fail(pFile == NULL);
  401.     fail(pucData == NULL);
  402.     fail(pImg == NULL);
  403.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  404.  
  405.     DBG_DEC(pImg->iWidth);
  406.     DBG_DEC(pImg->iHeight);
  407.  
  408.     iByteWidth = iGetByteWidth(pImg);
  409.  
  410.     for (iY = pImg->iHeight - 1; iY >= 0; iY--) {
  411.         bEOL = FALSE;
  412.         iX = 0;
  413.         while (!bEOL) {
  414.             iRunLength = iNextByte(pFile);
  415.             if (iRunLength == EOF) {
  416.                 return;
  417.             }
  418.             if (iRunLength != 0) {
  419.                   /*
  420.                  * Encoded packet:
  421.                  * RunLength pixels, all the same value
  422.                  */
  423.                 iIndex = iNextByte(pFile);
  424.                 if (iIndex == EOF) {
  425.                     return;
  426.                 }
  427.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  428.                     if (iX < pImg->iWidth) {
  429.                         iOffset = iY * iByteWidth + iX;
  430.                         *(pucData + iOffset) =
  431.                             iReduceColor(
  432.                             pImg->aucPalette[iIndex][0],
  433.                             pImg->aucPalette[iIndex][1],
  434.                             pImg->aucPalette[iIndex][2]);
  435.                     }
  436.                     iX++;
  437.                 }
  438.                 continue;
  439.             }
  440.             /* Literal or escape */
  441.             iRunLength = iNextByte(pFile);
  442.             if (iRunLength == EOF) {
  443.                 return;
  444.             }
  445.             if (iRunLength == 0) {        /* End of line escape */
  446.                 bEOL = TRUE;
  447.             } else if (iRunLength == 1) {    /* End of file escape */
  448.                 return;
  449.             } else if (iRunLength == 2) {    /* Delta escape */
  450.                 DBG_MSG("RLE8: encountered delta escape");
  451.                 return;
  452.             } else {            /* Literal packet */
  453.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  454.                     iIndex = iNextByte(pFile);
  455.                     if (iIndex == EOF) {
  456.                         return;
  457.                     }
  458.                     if (iX < pImg->iWidth) {
  459.                         iOffset = iY * iByteWidth + iX;
  460.                         *(pucData + iOffset) =
  461.                             iReduceColor(
  462.                             pImg->aucPalette[iIndex][0],
  463.                             pImg->aucPalette[iIndex][1],
  464.                             pImg->aucPalette[iIndex][2]);
  465.                     }
  466.                     iX++;
  467.                 }
  468.                 /* Padding if the number of bytes is odd */
  469.                 if (odd(iRunLength)) {
  470.                     (void)iSkipBytes(pFile, 1);
  471.                 }
  472.             }
  473.         }
  474.         DBG_DEC_C(iX != pImg->iWidth, iX);
  475.     }
  476. } /* end of vDecodeRle8 */
  477.  
  478. #if 0 /* defined(DEBUG) */
  479. static void
  480. vCopy2File(unsigned char *pucSprite, size_t tSpriteSize)
  481. {
  482.     FILE    *pOutFile;
  483.     int    iIndex;
  484.     char    szFilename[30];
  485.  
  486.     sprintf(szFilename, "<Wimp$ScrapDir>.sprt%04d", ++iPicCounter);
  487.     pOutFile = fopen(szFilename, "wb");
  488.     if (pOutFile == NULL) {
  489.         return;
  490.     }
  491.     DBG_MSG(szFilename);
  492.     for (iIndex = 4; iIndex < (int)tSpriteSize; iIndex++) {
  493.         if (putc(pucSprite[iIndex], pOutFile) == EOF) {
  494.             break;
  495.         }
  496.     }
  497.     (void)fclose(pOutFile);
  498.     vSetFiletype(szFilename, FILETYPE_SPRITE);
  499. } /* end of vCopy2File */
  500. #endif /* DEBUG */
  501.  
  502. /*
  503.  * vDecodeDIB - decode a dib picture
  504.  */
  505. static void
  506. vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg)
  507. {
  508.     unsigned char    *pucSprite, *pucPalette, *pucData;
  509.     size_t    tSpriteSize;
  510.     int    iHeaderSize;
  511.  
  512.     /* Skip the bitmap info header */
  513.     iHeaderSize = (int)ulNextLong(pFile);
  514.     (void)iSkipBytes(pFile, iHeaderSize - 4);
  515.     /* Skip the colortable */
  516.     if (pImg->iBitsPerComponent <= 8) {
  517.         (void)iSkipBytes(pFile,
  518.             pImg->iColorsUsed * ((iHeaderSize > 12) ? 4 : 3));
  519.     }
  520.  
  521.     /* Create an empty sprite */
  522.     pucSprite = pucCreateBlankSprite(pImg, &tSpriteSize);
  523.     pucPalette = pucSprite + sizeof(sprite_area) + sizeof(sprite_header);
  524.  
  525.     /* Add the pixel information */
  526.     switch (pImg->iBitsPerComponent) {
  527.     case  1:
  528.         fail(pImg->eCompression != compression_none);
  529.         pucData = pucPalette + 2 * 8;
  530.         vDecode1bpp(pFile, pucData, pImg);
  531.         break;
  532.     case  4:
  533.         fail(pImg->eCompression != compression_none &&
  534.                 pImg->eCompression != compression_rle4);
  535.         pucData = pucPalette + 16 * 8;
  536.         if (pImg->eCompression == compression_rle4) {
  537.             vDecodeRle4(pFile, pucData, pImg);
  538.         } else {
  539.             vDecode4bpp(pFile, pucData, pImg);
  540.         }
  541.         break;
  542.     case  8:
  543.         fail(pImg->eCompression != compression_none &&
  544.                 pImg->eCompression != compression_rle8);
  545.         pucData = pucPalette;
  546.         if (pImg->eCompression == compression_rle8) {
  547.             vDecodeRle8(pFile, pucData, pImg);
  548.         } else {
  549.             vDecode8bpp(pFile, pucData, pImg);
  550.         }
  551.         break;
  552.     case 24:
  553.         fail(pImg->eCompression != compression_none);
  554.         pucData = pucPalette;
  555.         vDecode24bpp(pFile, pucData, pImg);
  556.         break;
  557.     default:
  558.         DBG_DEC(pImg->iBitsPerComponent);
  559.         break;
  560.     }
  561.  
  562. #if 0 /* defined(DEBUG) */
  563.     vCopy2File(pucSprite, tSpriteSize);
  564. #endif /* DEBUG */
  565.  
  566.     /* Add the sprite to the Draw file */
  567.     vImage2Diagram(pDiag, pImg,
  568.         pucSprite + sizeof(sprite_area),
  569.         tSpriteSize - sizeof(sprite_area));
  570.  
  571.     /* Clean up before you leave */
  572.     pucSprite = xfree(pucSprite);
  573. } /* end of vDecodeDIB */
  574.  
  575. /*
  576.  * bTranslateDIB - translate a DIB picture
  577.  *
  578.  * This function translates a picture from dib to sprite
  579.  *
  580.  * return TRUE when sucessful, otherwise FALSE
  581.  */
  582. BOOL
  583. bTranslateDIB(diagram_type *pDiag, FILE *pFile,
  584.         long lFileOffset, const imagedata_type *pImg)
  585. {
  586.     /* seek to start position of DIB data */
  587.     if (!bSetDataOffset(pFile, lFileOffset)) {
  588.         return FALSE;
  589.     }
  590.  
  591.     vDecodeDIB(pDiag, pFile, pImg);
  592.  
  593.     return TRUE;
  594. } /* end of bTranslateDIB */
  595.