home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / 3DTOSHI2.ZIP / mpgfx / source / gfxbmp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-18  |  11.3 KB  |  454 lines

  1.  
  2. // gfxbmp.cpp
  3. //
  4. // Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.
  5.  
  6. #include "stdgfx.h"
  7. #include "gfxbmp.h"
  8.  
  9. BMPFILETOOL::BMPFILETOOL ( FILEHANDLE f ) : IMAGEFILETOOL ( f )
  10.   {
  11.     DataBuffer = NULL;
  12.   } // End of Constructor for BMPFILETOOL
  13.  
  14. BMPFILETOOL::~BMPFILETOOL ()
  15.   {
  16.     if (DataBuffer!=NULL)
  17.       delete DataBuffer;
  18.     DataBuffer = NULL;
  19.   } // End of Destructor for BMPFILETOOL
  20.  
  21. BOOLEAN BMPFILETOOL::ReadHeader ()
  22.   {
  23.     INT ID;
  24.  
  25.     ID = ((INT)'M'<< 8) + (INT)'B';
  26.  
  27.     File.Seek ( fp, 0, FROM_BEGIN );
  28.  
  29.     #if defined (__FORWINDOWS__)
  30.       if (File.Read ( fp, &FileHeader, 14 )==FAILURE)
  31.         return FAILURE;
  32.       if (FileHeader.bfType!=ID)
  33.         return FAILURE;
  34.     #elif defined (__FORDOS__)
  35.       if (File.Read ( fp, &FileHeader, 14 )==FAILURE)
  36.         return FAILURE;
  37.       if (FileHeader.bfType!=ID)
  38.         return FAILURE;
  39.     #elif defined (__FORUNIX__)
  40.       if (File.Read ( fp, &FileHeader, 14 )==FAILURE)
  41.         return FAILURE;
  42.       #if defined (__MSBFIRST__)
  43.         SwapWord ( (WORD*)&FileHeader.bfType );
  44.         SwapDWord ( (DWORD*)&FileHeader.bfSize );
  45.         SwapDWord ( (DWORD*)&FileHeader.bfOffBits );
  46.       #endif
  47.       if (FileHeader.bfType!=ID)
  48.         return FAILURE;
  49.     #endif
  50.  
  51.     return SUCCESS;
  52.   } // End of ReadHeader for BMPFILETOOL
  53.  
  54. BOOLEAN BMPFILETOOL::ReadInfo ()
  55.   {
  56.     if (File.Read ( fp, &InfoHeader, 40 )==FAILURE)
  57.       return FAILURE;
  58.       #if defined (__MSBFIRST__)
  59.         SwapDWord ( (DWORD*)&InfoHeader.biSize );
  60.         SwapDWord ( (DWORD*)&InfoHeader.biWidth );
  61.         SwapDWord ( (DWORD*)&InfoHeader.biHeight );
  62.         SwapWord ( (WORD*)&InfoHeader.biPlanes );
  63.         SwapWord ( (WORD*)&InfoHeader.biBitCount );
  64.         SwapDWord ( (DWORD*)&InfoHeader.biCompression );
  65.         SwapDWord ( (DWORD*)&InfoHeader.biSizeImage );
  66.         SwapDWord ( (DWORD*)&InfoHeader.biXPelsPerMeter );
  67.         SwapDWord ( (DWORD*)&InfoHeader.biYPelsPerMeter );
  68.         SwapDWord ( (DWORD*)&InfoHeader.biClrUsed );
  69.         SwapDWord ( (DWORD*)&InfoHeader.biClrImportant );
  70.      #endif
  71.     return SUCCESS;
  72.   } // End of ReadInfo for BMPFILETOOL
  73.  
  74. BOOLEAN BMPFILETOOL::ReadRowBW ( IMAGE *Image, INT Row )
  75.   {
  76.     BYTE *Buffer;
  77.  
  78.     if (!File.Read ( fp,DataBuffer,Size))
  79.       return FAILURE;
  80.  
  81.     Buffer = Image->SetOffset ( 0, Row );
  82.  
  83.     INT i;
  84.     INT BitShift= 1 << 7;
  85.     BYTE Byte;
  86.  
  87.     for (i=0;i<Image->GetWidth();i++)
  88.       {
  89.         Byte = DataBuffer[i>>3];
  90.         if (Byte&BitShift)
  91.           Buffer[i] = 1;
  92.         else
  93.           Buffer[i] = 0;
  94.         if (BitShift==1)
  95.           BitShift = 1 << 7;
  96.         else
  97.           BitShift >>= 1;
  98.       } // End for
  99.  
  100.     return TRUE;
  101.   } // End of ReadRowBW for BMPFILETOOL
  102.  
  103. BOOLEAN BMPFILETOOL::ReadRow16 ( IMAGE *Image, INT Row )
  104.   {
  105.     BYTE *Buffer;
  106.  
  107.     if (!File.Read (fp,DataBuffer,Size))
  108.       return FAILURE;
  109.  
  110.     Buffer = Image->SetOffset ( 0, Row );
  111.  
  112.     INT i;
  113.  
  114.     for (i=0;i<Image->GetWidth();i++)
  115.       {
  116.         if (i&0x01) // If odds, take lower 4 bits
  117.           Buffer[i] = (BYTE)(DataBuffer[i>>1] & 0xFF);
  118.         else  // Else, take higher 4 bits
  119.           Buffer[i] = (BYTE)(DataBuffer[i>>1] >> 4);
  120.       } // End for
  121.  
  122.     return SUCCESS;
  123.   } // End of ReadRow16 for BMPFILETOOL
  124.  
  125. BOOLEAN BMPFILETOOL::ReadRow256 ( IMAGE *Image, INT Row )
  126.   {
  127.     BYTE *Buffer;
  128.  
  129.     Buffer = Image->SetOffset ( 0, Row );
  130.     if (!File.Read ( fp, DataBuffer, Size ))
  131.       return FAILURE;
  132.  
  133.     memcpy ( Buffer, DataBuffer, Image->GetWidth() );
  134.  
  135.     return SUCCESS;
  136.   } // End of ReadRow256 for BMPFILETOOL
  137.  
  138. BOOLEAN BMPFILETOOL::ReadImage ( IMAGE *Image )
  139.   {
  140.     INT i;
  141.     BOOLEAN Ok;
  142.  
  143.     #if defined (__FOROS2__)
  144.       BmWd = InfoHeader.cx;
  145.       BmHt = InfoHeader.cy;
  146.       BmBits = InfoHeader.cBitCount;
  147.     #else
  148.       BmWd = InfoHeader.biWidth;
  149.       BmHt = InfoHeader.biHeight;
  150.       BmBits = InfoHeader.biBitCount;
  151.     #endif
  152.  
  153.     Ok = Image->Create ( IMAGE_8BIT, BmWd, BmHt);
  154.  
  155.     if (!Ok)
  156.       return FAILURE;
  157.  
  158.     Width = Image->GetWidth();
  159.  
  160.     Width = (Width+3)/4;
  161.     Width = Width*4;
  162.  
  163.     switch (BmBits)
  164.       {
  165.         case 1 :
  166.           Size = (Width+7)/8;
  167.           DataBuffer = new BYTE [Size];
  168.           break;
  169.         case 4 :
  170.           Size = (Width+1)/2;
  171.           DataBuffer = new BYTE [Size];
  172.           break;
  173.         case 8 :
  174.           Size = Width;
  175.           DataBuffer = new BYTE [Size];
  176.           break;
  177.         default :
  178.           return FAILURE;
  179.       } // End switch
  180.  
  181.     if (DataBuffer==NULL)
  182.       return FAILURE;
  183.  
  184.     for (i=0;i<Image->GetHeight();i++)
  185.       {
  186.         switch (BmBits)
  187.           {
  188.             case 1 :
  189.               Ok = ReadRowBW ( Image, Image->GetHeight()-i-1 );
  190.               break;
  191.             case 4 :
  192.               Ok = ReadRow16 ( Image, Image->GetHeight()-i-1  );
  193.               break;
  194.             case 8 :
  195.               Ok = ReadRow256 ( Image, Image->GetHeight()-i-1  );
  196.               break;
  197.           } // End of switch
  198.  
  199.         if (!Ok)
  200.           break;
  201.       } // End for
  202.  
  203.     delete DataBuffer;
  204.  
  205.     return SUCCESS;
  206.   } // End of ReadImage for BMPFILETOOL
  207.  
  208. BOOLEAN BMPFILETOOL::ReadPalette ( RGBPALETTE *Pal )
  209.   {
  210.     INT i;
  211.     INT NumColors;
  212.     RGBCOLOR *Entry;
  213.  
  214.     if (BmBits>8) // If 24-bit image, skip it.
  215.       return SUCCESS;
  216.  
  217.     #if defined (__FOROS2__)
  218.       NumColors = 0;
  219.     #else
  220.       NumColors = InfoHeader.biClrUsed;
  221.     #endif
  222.  
  223.     if (NumColors==0)
  224.       NumColors = 256;
  225.  
  226.     if (Pal==NULL)
  227.       {
  228.         File.Seek ( fp, NumColors*sizeof(RGBQUAD), FROM_CURRENT );
  229.         return SUCCESS;
  230.       } // End if
  231.  
  232.     Entry = Pal->GetEntry ();
  233.  
  234.     for (i=0;i<NumColors;i++)
  235.       {
  236.         BYTE Flags;  
  237.         Entry[i].Blue = (BYTE)File.GetCh ( fp );
  238.         Entry[i].Green = (BYTE)File.GetCh ( fp );
  239.         Entry[i].Red = (BYTE)File.GetCh ( fp );
  240.         Flags = (BYTE)File.GetCh ( fp );
  241.         if (Flags)
  242.           {}
  243.       } // End for
  244.  
  245.     return SUCCESS;
  246.   } // End of ReadPalette for BMPFILETOOL
  247.  
  248. BOOLEAN BMPFILETOOL::LoadImage ( IMAGE *Image, RGBPALETTE *Pal )
  249.   {
  250.     BOOLEAN Ok;
  251.  
  252.     Ok = ReadHeader ();
  253.     if (!Ok)
  254.       return FAILURE;
  255.  
  256.     Ok = ReadInfo ();
  257.     if (!Ok)
  258.       return FAILURE;
  259.  
  260.     Ok = ReadPalette ( Pal );
  261.     if (!Ok)
  262.       return FAILURE;
  263.  
  264.     Ok = ReadImage ( Image );
  265.     if (!Ok)
  266.       return FAILURE;
  267.  
  268.     return SUCCESS;
  269.   } // End of LoadImage for BMPFILETOOL
  270.  
  271. BOOLEAN BMPFILETOOL::WriteHeader ()
  272.   {
  273.     #if defined (__FOROS2__)
  274.       FileHeader.usType = ((INT)'M'<< 8) + (INT)'B';
  275.     #else
  276.       FileHeader.bfType = ((INT)'M'<< 8) + (INT)'B';
  277.       FileHeader.bfReserved1 = 0;
  278.       FileHeader.bfReserved2 = 0;
  279.     #endif
  280.     File.Seek ( fp, 0, FROM_BEGIN );
  281.  
  282.     #if defined (__MSBFIRST__)
  283.       SwapWord ( (WORD*)&FileHeader.bfType );
  284.       SwapDWord ( (DWORD*)&FileHeader.bfSize );
  285.       SwapDWord ( (DWORD*)&FileHeader.bfOffBits );
  286.     #endif
  287.  
  288.     if (File.Write ( fp, &FileHeader, 14 )==FAILURE)
  289.       return FAILURE;
  290.     return SUCCESS;
  291.   } // End of WriteHeader for BMPFILETOOL
  292.  
  293. BOOLEAN BMPFILETOOL::WriteInfo ( INT Wd, INT Ht )
  294.   {
  295.     #if defined (__FOROS2__)
  296.       InfoHeader.cbFix = sizeof(BITMAPINFOHEADER);
  297.       InfoHeader.cx = Wd;
  298.       InfoHeader.cy = Ht;
  299.       InfoHeader.cPlanes = 1;
  300.       InfoHeader.cBitCount = 8;
  301.       if (File.Write ( fp, &InfoHeader, 12 )==FAILURE)
  302.         return FAILURE;
  303.     #else
  304.       InfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  305.       InfoHeader.biWidth = Wd;
  306.       InfoHeader.biHeight = Ht;
  307.       InfoHeader.biPlanes = 1;
  308.       InfoHeader.biBitCount = 8;
  309.       InfoHeader.biCompression = 0;
  310.       InfoHeader.biXPelsPerMeter = 0;
  311.       InfoHeader.biYPelsPerMeter = 0;
  312.       InfoHeader.biClrUsed = 0;
  313.       InfoHeader.biClrImportant = 0;
  314.       InfoHeader.biSizeImage = (LONG)Wd*(LONG)Ht;
  315.  
  316.       #if defined (__MSBFIRST__)
  317.         SwapDWord ( (DWORD*)&InfoHeader.biSize );
  318.         SwapDWord ( (DWORD*)&InfoHeader.biWidth );
  319.         SwapDWord ( (DWORD*)&InfoHeader.biHeight );
  320.         SwapWord ( (WORD*)&InfoHeader.biPlanes );
  321.         SwapWord ( (DWORD*)&InfoHeader.biBitCount );
  322.         SwapDWord ( (DWORD*)&InfoHeader.biCompression );
  323.         SwapDWord ( (DWORD*)&InfoHeader.biSizeImage );
  324.         SwapDWord ( (DWORD*)&InfoHeader.biXPelsPerMeter );
  325.         SwapDWord ( (DWORD*)&InfoHeader.biYPelsPerMeter );
  326.         SwapDWord ( (DWORD*)&InfoHeader.biClrUsed );
  327.         SwapDWord ( (DWORD*)&InfoHeader.biClrImportant );
  328.       #endif
  329.       if (File.Write ( fp, &InfoHeader, 40 )==FAILURE)
  330.         return FAILURE;
  331.     #endif
  332.     return SUCCESS;
  333.   } // End of WriteInfo for BMPFILETOOL
  334.  
  335. BOOLEAN BMPFILETOOL::WritePalette ( RGBPALETTE *Pal )
  336.   {
  337.     RGBQUAD RGBQ;
  338.     RGBCOLOR *Entry;
  339.     INT i;
  340.  
  341.     if (Pal==NULL)
  342.       return FAILURE;
  343.  
  344.     Entry = Pal->GetEntry ();
  345.  
  346.     for (i=0;i<256;i++)
  347.       {
  348.         RGBQ.rgbBlue = Entry[i].Blue;
  349.         RGBQ.rgbGreen = Entry[i].Green;
  350.         RGBQ.rgbRed = Entry[i].Red;
  351.         RGBQ.rgbReserved = 0;
  352.  
  353.         File.Write ( fp, &RGBQ, 4 );
  354.       } // End for
  355.  
  356.     return SUCCESS;
  357.   } // End of WritePalette for BMPFILETOOL
  358.  
  359. BOOLEAN BMPFILETOOL::WriteImageRow ( IMAGE *Image, INT Row, INT Sx )
  360.   {
  361.     BOOLEAN Ok;
  362.     memcpy ( DataBuffer, Image->SetOffset ( 0, Row ), Image->GetWidth() );
  363.     Ok = File.Write ( fp, DataBuffer+Sx, Width );
  364.     if (!Ok)
  365.       return FAILURE;
  366.     return SUCCESS;
  367.   } // End for WriteImageRow for BMPFILETOOL
  368.  
  369. BOOLEAN BMPFILETOOL::WriteImage ( IMAGE *Image, INT Sx, INT Sy, INT Ht )
  370.   {
  371.     INT i;
  372.     BOOLEAN Ok;
  373.     for (i=Sy;i<Sy+Ht;i++)
  374.       {
  375.         Ok = WriteImageRow ( Image, Image->GetHeight()-i-1, Sx );
  376.         if (!Ok)
  377.           return FAILURE;
  378.       } // End for
  379.     return SUCCESS;
  380.   } // End of WriteImage for BMPFILETOOL
  381.  
  382. BOOLEAN BMPFILETOOL::SaveImage ( IMAGE *Image, LONG Sx, LONG Sy,
  383.                                  LONG Wd, LONG Ht, RGBPALETTE *Pal )
  384.   {
  385.     BOOLEAN Ok;
  386.  
  387.     if (DataBuffer!=NULL)
  388.       delete DataBuffer;
  389.  
  390.     DataBuffer = NULL;
  391.     if (Image==NULL)
  392.       {
  393.         return FAILURE;
  394.       } // End if
  395.  
  396.     Ok = WriteHeader ();
  397.     if (!Ok)
  398.       return FAILURE;
  399.  
  400.     Ok = WriteInfo ( Wd, Ht );
  401.     if (!Ok)
  402.       return FAILURE;
  403.  
  404.     Ok = WritePalette ( Pal );
  405.     if (!Ok)
  406.       return FAILURE;
  407.  
  408.     Width = Wd;
  409.  
  410.     Width = (Width+3)/4;
  411.     Width = Width*4;
  412.  
  413.     if (Width>Image->GetWidth())
  414.       DataBuffer = new BYTE [Width];
  415.     else
  416.       DataBuffer = new BYTE [Image->GetWidth()];
  417.  
  418.     if (DataBuffer==NULL)
  419.       return FAILURE;
  420.  
  421.     Ok = WriteImage ( Image, Sx, Sy, Ht );
  422.     if (!Ok)
  423.       return FAILURE;
  424.  
  425.     delete DataBuffer;
  426.  
  427.     DWORD Size;
  428.  
  429.     Size = File.GetPos ( fp );
  430.  
  431.     #if defined (__FOROS2__)
  432.       FileHeader.cbSize = Size;
  433.       FileHeader.offBits = sizeof (BITMAPFILEHEADER) +
  434.                               sizeof (BITMAPINFOHEADER) +
  435.                                sizeof (RGBQUAD)*256;
  436.     #else
  437.       FileHeader.bfSize = Size;
  438.       FileHeader.bfOffBits = sizeof (BITMAPFILEHEADER) +
  439.                               sizeof (BITMAPINFOHEADER) +
  440.                                sizeof (RGBQUAD)*256;
  441.     #endif
  442.  
  443.     Ok = WriteHeader ();
  444.     if (!Ok)
  445.       return FAILURE;
  446.  
  447.     DataBuffer = NULL;
  448.     return SUCCESS;
  449.   } // End of SaveImage for BMPFILETOOL
  450.  
  451.  
  452.  
  453.  
  454.