Beispiel #1
0
/* PCX ***********************************************************************
 * This routine reads file with given file name and if it is valid PCX file it
 * loads it into given ImageInfo structure in CroTeam true-color format.
 * (and, if the one exists, loads the palette)
 */
void CImageInfo::LoadPCX_t( const CTFileName &strFileName) // throw char *
{
  PCXHeader *pPCXHdr;
  UBYTE *pPCXBuffer, *pPCXImage, *pPCXDecodedImage, *pTmp;
  UBYTE data, counter;
  SLONG pic_size, PCX_size, slFileSize;
  CTFileStream PCXFile;

  Clear();

  // inconvinent way to determine file size
  PCXFile.Open_t( strFileName, CTStream::OM_READ);
  slFileSize = PCXFile.GetStreamSize();

  // load entire PCX file to memory, as is, and close it (no further usage)
  pPCXBuffer = (UBYTE*)AllocMemory( slFileSize);
  PCXFile.Read_t( pPCXBuffer, slFileSize);
  PCXFile.Close();

  // PCX header starts at the begining of the PCX file
  pPCXHdr = (struct PCXHeader*)pPCXBuffer;
  // PCX image bytes definition follows up
  pPCXImage = pPCXBuffer + sizeof( struct PCXHeader);

  // detremine picture size dimensions
  ii_Width  = (SLONG)(pPCXHdr->Xmax - pPCXHdr->Xmin +1);
  ii_Height = (SLONG)(pPCXHdr->Ymax - pPCXHdr->Ymin +1);
  ii_BitsPerPixel = (SLONG)pPCXHdr->Planes*8;
  pic_size = ii_Width * ii_Height * ii_BitsPerPixel/8;

  // allocate memory for image content
  ii_Picture = (UBYTE*)AllocMemory( pic_size);

  // allocate memory for decoded PCX file that hasn't been converted to CT RAW Image format
  PCX_size = (SLONG)(pPCXHdr->BytesPerLine * ii_Height * ii_BitsPerPixel/8);
  pPCXDecodedImage = (UBYTE*)AllocMemory( PCX_size);
  pTmp = pPCXDecodedImage;  // save pointer for latter usage

  // decode PCX file
  for( INDEX i=0; i<PCX_size; )   // i is incremented by counter value  at the and of the loop
  {
    // read one byte from PCX image in memory
    data = *pPCXImage++;
    // check byte-run mark
    if( (data & 0xC0) == 0xC0) {
      counter = data & 0x3F;              // determine repeat value
      data = *pPCXImage++;                // read repeated data
      // put several bytes of PCX image to decoded image area in memory
      for( INDEX j=0; j<counter; j++)
        *pPCXDecodedImage++ = data;
    } else {
      // put just one byte from PCX image to decoded image area in memory
      counter = 1;
      *pPCXDecodedImage++ = data;
    }

    // increment encoded image counter
    i += counter;
  }
  pPCXDecodedImage = pTmp;  // reset pointer

  // convert decoded PCX image to CroTeam RAW Image Info format
  SLONG slBytesPerPixel = ii_BitsPerPixel/8;
  for( INDEX y=0; y<ii_Height; y++)
  {
    SLONG slYSrcOfs = y * ii_Width * slBytesPerPixel;
    SLONG slYDstOfs = y * pPCXHdr->BytesPerLine * slBytesPerPixel;
    // channel looper
    for( INDEX p=0; p<slBytesPerPixel; p++)
    {
      SLONG slPOffset = p * pPCXHdr->BytesPerLine;
      // byte looper
      for( INDEX x=0; x<ii_Width; x++)
        *(ii_Picture + slYSrcOfs + x*slBytesPerPixel + p) =
        *(pPCXDecodedImage + slYDstOfs + slPOffset + x);
    }
  }

  // free temorary allocated memory for PCX encoded and decoded image
  FreeMemory( pPCXBuffer);
  FreeMemory( pPCXDecodedImage);
}
Beispiel #2
0
void CImageInfo::LoadTGA_t( const CTFileName &strFileName) // throw char *
{
  TGAHeader *pTGAHdr;
  UBYTE *pTGABuffer, *pTGAImage;
  SLONG slFileSize;
  CTFileStream TGAFile;

  Clear();

  // determine file size
  TGAFile.Open_t( strFileName, CTStream::OM_READ);
  slFileSize = TGAFile.GetStreamSize();

  // load entire TGA file to memory, as is, and close it (no further usage)
  pTGABuffer = (UBYTE*)AllocMemory( slFileSize);
  TGAFile.Read_t( pTGABuffer, slFileSize);
  TGAFile.Close();

  // TGA header starts at the begining of the TGA file
  pTGAHdr = (struct TGAHeader*)pTGABuffer;
  // TGA image bytes definition follows up
  pTGAImage = pTGABuffer + sizeof(struct TGAHeader) + pTGAHdr->IdLenght;

  // detremine picture size dimensions
  ii_Width        = (SLONG)pTGAHdr->Width;
  ii_Height       = (SLONG)pTGAHdr->Height;
  ii_BitsPerPixel = (SLONG)pTGAHdr->BitsPerPixel;
  SLONG slBytesPerPixel = ii_BitsPerPixel/8;
  PIX pixBitmapSize     = ii_Width*ii_Height;
  BOOL bAlphaChannel    = (slBytesPerPixel==4);

  // check for supported file types
  ASSERT( slBytesPerPixel==3 || slBytesPerPixel==4);
  if( slBytesPerPixel!=3 && slBytesPerPixel!=4) throw( TRANS("Unsupported BitsPerPixel in TGA format."));

  // allocate memory for image content
  ii_Picture = (UBYTE*)AllocMemory( ii_Width*ii_Height *slBytesPerPixel);
  UBYTE *pubSrc = pTGAImage;  // need 'walking' pointers
  UBYTE *pubDst = ii_Picture;

  // determine TGA image type
  if( pTGAHdr->ImageType==10) {
    // RLE encoded
    UBYTE ubControl;
    INDEX iBlockSize;
    BOOL  bRepeat;
    PIX pixCurrentSize=0;
    // loop thru blocks
    while( pixCurrentSize<pixBitmapSize)
    { // readout control byte
      ubControl  = *pubSrc++;
      bRepeat    =  ubControl&0x80;
      iBlockSize = (ubControl&0x7F) +1;
      // repeat or copy color values
      for( INDEX i=0; i<iBlockSize; i++) {
        *pubDst++ = pubSrc[0]; 
        *pubDst++ = pubSrc[1]; 
        *pubDst++ = pubSrc[2]; 
        if( bAlphaChannel) *pubDst++ = pubSrc[3];
        if( !bRepeat) pubSrc += slBytesPerPixel;
      }
      // advance for next block if repeated
      if( bRepeat) pubSrc += slBytesPerPixel;
      // update image size
      pixCurrentSize += iBlockSize;
    }
    // mark that image was encoded to ImageInfo buffer
    pTGAImage = ii_Picture; 
  } 
  // not true-colored?
  else if( pTGAHdr->ImageType!=2) {
    // whoops!
    ASSERTALWAYS("Unsupported TGA format.");
    throw( TRANS("Unsupported TGA format."));
  }

  // determine image flipping
  INDEX iFlipType;
  switch( (pTGAHdr->Descriptor&0x30)>>4) {
  case 0:  iFlipType = 1;  break; // vertical flipping
  case 1:  iFlipType = 3;  break; // diagonal flipping
  case 3:  iFlipType = 2;  break; // horizontal flipping
  default: iFlipType = 0;  break; // no flipping (just copying)
  }
  // do flipping
  FlipBitmap( pTGAImage, ii_Picture, ii_Width, ii_Height, iFlipType, bAlphaChannel);

  // convert TGA pixel format to CroTeam
  pubSrc = ii_Picture;  // need 'walking' pointer again
  for( INDEX iPix=0; iPix<pixBitmapSize; iPix++)
  { // flip bytes
    Swap( pubSrc[0], pubSrc[2]);  // R & B channels
    pubSrc += slBytesPerPixel; 
  }

  // free temorary allocated memory for TGA image format
  FreeMemory( pTGABuffer);
}