Sign in to follow this  

displaying a PCX file on screen

This topic is 4163 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there I am trying to display a pcx file. My program compiles and builds without error but when I run it I get a tell Microsoft error. Now the PCXfile class and routines were downloaded from a web wiki and they look ok :).
pcx.h file
//////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <memory.h>
 
#define IMG_OK              0x1
#define IMG_ERR_NO_FILE     0x2
#define IMG_ERR_MEM_FAIL    0x4
#define IMG_ERR_BAD_FORMAT  0x8
#define IMG_ERR_UNSUPPORTED 0x40
 
class PCXImg
 {
  public:
   PCXImg();
   ~PCXImg();
   int Load(char* szFilename);
   int GetBPP();
   int GetWidth();
   int GetHeight();
   unsigned char* GetImg();       // Return a pointer to image data
   unsigned char* GetPalette();   // Return a pointer to VGA palette
 
  private:
   short int iWidth,iHeight,iBPP,iPlanes,iBPL;
   long lImageSize;
   char bEnc;
   unsigned char *pImage, *pPalette, *pData;
   
   // Internal workers
   int ReadHeader();
   int LoadRLEData();
   int LoadPalette(unsigned long ulDataSize);
 };
//////////////////////////////////////////////
pcx.cpp file
//////////////////////////////////////////////////////////////
#include<stdio.h>
#include "GL/Glee.h"
#include <stdlib.h>
#include	<fstream>
#include	"pcx.h"
#include <math.h>



PCXImg::PCXImg()
 { 
  pImage=pPalette=pData=NULL;
  iWidth=iHeight=iBPP=iPlanes=iBPL=bEnc=0;
 }
 
 
PCXImg::~PCXImg()
 {
  if(pImage)
   {
    delete [] pImage;
    pImage=NULL;
   }
 
  if(pPalette)
   {
    delete [] pPalette;
    pPalette=NULL;
   }
 
  if(pData)
   {
    delete [] pData;
    pData=NULL;
   }
 }
 
 
int PCXImg::Load(char* szFilename)
 {
  using namespace std;
  ifstream fIn;
  unsigned long ulSize;
  int iRet;
 
  // Clear out any existing image and palette
   if(pImage)
    {
     delete [] pImage;
     pImage=NULL;
    }
 
   if(pPalette)
    {
     delete [] pPalette;
     pPalette=NULL;
    }
 
  // Open the specified file
  fIn.open(szFilename,ios::binary);
    
   if(fIn==NULL)
    return IMG_ERR_NO_FILE;
 
  // Get file size
  fIn.seekg(0,ios_base::end);
  ulSize=fIn.tellg();
  fIn.seekg(0,ios_base::beg);
 
  // Allocate some space
  // Check and clear pDat, just in case
   if(pData)
    delete [] pData; 
 
  pData=new unsigned char[ulSize];
 
   if(pData==NULL)
    {
     fIn.close();
     return IMG_ERR_MEM_FAIL;
    }
 
  // Read the file into memory
  fIn.read((char*)pData,ulSize);
 
  fIn.close();
 
  // Process the header
  iRet=ReadHeader();
 
   if(iRet!=IMG_OK)
    return iRet;
 
   if(iBPP!=8) // We'll only bother with 8 bit indexed and 24 bit RGB images
    return IMG_ERR_UNSUPPORTED;
 
   if(bEnc!=1) // We only know about RLE compressed images
    return IMG_ERR_UNSUPPORTED;
 
  // Get the image data
  iRet=LoadRLEData();
 
   if(iRet!=IMG_OK)
    return iRet;
 
  // Load palette if present
  iRet=LoadPalette(ulSize);
 
   if(iRet!=IMG_OK)
    return iRet;
 
  // Free the file data
  delete [] pData;
  pData=NULL;
 
  // Update the BPP value to reflect the image format
  iBPP*=iPlanes;
 
  return IMG_OK;
 }
 
 
int PCXImg::ReadHeader()
 {
  unsigned short x1,x2,y1,y2;
 
   if(pData==NULL)
    return IMG_ERR_NO_FILE;
 
   if(pData[0]!=0xA) // PCX ID Byte, should be 0xA
    return IMG_ERR_BAD_FORMAT;
 
   if(pData[1]>5)    // Version, we don't know about anything after v5
    return IMG_ERR_UNSUPPORTED;
 
  bEnc=pData[2];     // Encode flag 1 = RLE Compression
 
   if(pData[3]==1 || pData[3]==2 || pData[3]==4 || pData[3]==8)   // BPP value
    iBPP=pData[3];  
   else
    return IMG_ERR_BAD_FORMAT;
 
  // Get image window and produce width & height values
  memcpy(&x1,&pData[4],2);
  memcpy(&y1,&pData[6],2);
  memcpy(&x2,&pData[8],2);
  memcpy(&y2,&pData[10],2);
 
  iWidth=(x2-x1)+1;
  iHeight=(y2-y1)+1;
 
   if(iWidth<1 || iHeight<1)
    return IMG_ERR_BAD_FORMAT;
 
  // Planes byte.  1 = Indexed,  3 = RGB
  iPlanes=pData[65];
 
  // Bits per line for decoding purposes,
  memcpy(&iBPL,&pData[66],2);
 
  return IMG_OK;
 }
 
 
int PCXImg::LoadRLEData()
 {
  int iLineCount,iBufferLineLen,iImageLineLen;
  long lLinePos=0;
  unsigned char bRunLen;
  unsigned char *pCur,*pLine,*pInterLine;
 
  // Set our pointer to the beginning of the image data
  pCur=&pData[128];
 
  // Calculate line lengths for image and buffer, Allocate the buffer scan line
  iBufferLineLen=iBPL*iPlanes;
  iImageLineLen =iWidth*iPlanes;
  pLine=new unsigned char[iBufferLineLen];
   
   if(pLine==NULL)
    return IMG_ERR_MEM_FAIL;
 
  // Allocate space for the image data
   if(pImage!=NULL)
    delete [] pImage;
 
  pImage=new unsigned char[(iImageLineLen * iHeight)+1];
 
   if(pImage==NULL)
    return IMG_ERR_MEM_FAIL;
 
   // Decode each scanline
   for(iLineCount=0;iLineCount<iHeight;++iLineCount)
    {
     lLinePos=0;
      while(lLinePos<iBufferLineLen)
       {
         if(*pCur > 0xC0) // First 2 bits indicate run of next byte value
          {
           bRunLen=*pCur & 0x3F; // Remaining 6 bits indicate run length
           ++pCur;  // Repeated value 
            for( ;bRunLen!=0;bRunLen--,lLinePos++)
             pLine[lLinePos]=*pCur;
     
           ++pCur; 
          } 
         else
          {
           pLine[lLinePos]=*pCur; // Other bytes are directly copied
           ++lLinePos;
           ++pCur;
          }
       }
 
     // Once we've decoded a line, copy it to the image.
     // This disregards any end-of-line padding inserted during the compression
 
      if(iPlanes==1) // 8 bit images, straight copy
       {
        memcpy(&pImage[iLineCount*iImageLineLen],pLine,iImageLineLen);
       }
      else if(iPlanes==3) // for 24 bit, We have to interleave the RGB values
       {
        pInterLine=&pImage[iLineCount*iImageLineLen];
         for(lLinePos=0;lLinePos!=iWidth;++lLinePos,pInterLine+=3)
          { 
           pInterLine[0]=pLine[lLinePos];
           pInterLine[1]=pLine[lLinePos+iWidth];
           pInterLine[2]=pLine[lLinePos+(iWidth*2)];
          }
       }
 
    } 
 
  return IMG_OK;
 }
 
 
int PCXImg::LoadPalette(unsigned long ulDataSize)
 {
  // Load a 256 color palette
  
   if(pPalette)
    {
     delete [] pPalette;
     pPalette=NULL;
    }
 
   if(iPlanes==3) // NULL Palette for RGB images
    return IMG_OK;
 
  // Create space for palette
  pPalette=new unsigned char[768];
 
   if(pPalette==NULL)
    return IMG_ERR_MEM_FAIL;
 
  // Start of palette entries should be 769 bytes back from the end of the file
  // First byte is 0x0C
   if(pData[ulDataSize-769]!=0x0C)
    return IMG_ERR_BAD_FORMAT;
 
  memcpy(pPalette,&pData[ulDataSize-768],768);
 
  return IMG_OK;
 }
 
 
int PCXImg::GetBPP()
 {
  return iBPP;
 }
 
 
int PCXImg::GetWidth()
 {
  return iWidth;
 }
 
 
int PCXImg::GetHeight()
 {
  return iHeight;
 }
 
 
unsigned char* PCXImg::GetImg()
 {
  return pImage;
 }
 
 
unsigned char* PCXImg::GetPalette()
 {
  return pPalette;
 }

///////////////////////////////////////

This is my function to display the PCX file
/////////////////////////////////////////////
void CGfxOpenGL::Render()
{
	// clear screen and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// load the identity matrix (clear to default position and orientation)
	glLoadIdentity();

	//i think this is where the problem is but dont know another way
	glDrawPixels((int)(m_pcx->GetWidth()), (int)(m_pcx->GetHeight()), 
					GL_RGB, GL_SHORT, m_pcx->GetImg());

	
}
////////////////////////////////////////////
my initialisation routine is
/////////////////////////////////////////////////////////
bool CGfxOpenGL::Init()
{	
	glClearColor(0.0, 0.0, 0.0, 0.0);

	if (m_pcx->Load("Centaur.pcx" ))
		return false;

	return true;
}
////////////////////////////////////


You can call me a noob but can anyone help to set me in the right direction. I am going through the Beginning OpenGL Game Programming and finding it tough but extremely good. If you can help I will be delighted to hear from you. [edit: added source tags -SiCrane]

Share this post


Link to post
Share on other sites

This topic is 4163 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this