Sign in to follow this  
Michael2006

displaying a PCX file on screen

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

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