Reading a PCX file into memory

This is a discussion on Reading a PCX file into memory within the C Programming forums, part of the General Programming Boards category; Hi, I've been trying to create a PCX "object" with some handy members, using the following code (includes and unnecessary ...

  1. #1
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,262

    Exclamation Reading a PCX file into memory

    Hi,

    I've been trying to create a PCX "object" with some handy members, using the following code (includes and unnecessary functions cut):-
    Code:
    typedef struct {
       unsigned char manufacturer; /* = 10 */
       unsigned char version;
       unsigned char encoding;
       unsigned char bitsperpixel;
       int x;
       int y;
       int width;
       int height;
    } t_pcx_header;
    
    typedef struct {
       int width;
       int height;
       unsigned char *picdata;
    } t_pic;
    
    t_pic *load_pcx(char *filename)
    {
       FILE *fp;
       t_pcx_header pcx;
       t_pic *pic;
       int databyte;
       int count;
       long l;
    
       fp = fopen(filename, "rb");
       if (fp == NULL)
       {
          printf("File error\n");
          return NULL;
       }
       fread(&pcx, sizeof(pcx), 1, fp);
       if (pcx.manufacturer != 10)
       {
          printf("Invalid manufacturer value %d\n", pcx.manufacturer);
          return NULL;
       }
       else if (pcx.encoding != 1)
       {
          printf("Invalid encoding value %d\n", pcx.encoding);
          return NULL;
       }
       else if (pcx.bitsperpixel != 8)
       {
          printf("Invalid bits per pixel value %d\n", pcx.bitsperpixel);
          return NULL;
       }
       else if (pcx.x < 0 || pcx.x > 319 || pcx.y < 0 || pcx.y > 199 || pcx.width < 1 || pcx.width > 319 || pcx.height < 1 || pcx.height > 199)
       {
          printf("Invalid image dimensions x=%d, y=%d, width=%d, height=%d\n", pcx.x, pcx.y, pcx.width, pcx.height);
          return NULL;
       }
       fseek(fp, 128, SEEK_SET);
       pic = (t_pic *)malloc(sizeof(t_pic));
       if (pic->picdata == NULL)
       {
          printf("Picture object: Memory allocation error\n");
          return NULL;
       }
       pic->width = pcx.width + 1;
       pic->height = pcx.height + 1;
       pic->picdata = (unsigned char *)malloc((long)pic->width * pic->height);
       if (pic->picdata == NULL)
       {
          printf("Picture data: Memory allocation error.\n");
          return NULL;
       }
       for (l=0;l<(long)pic->width * pic->height;l++)
       {
          databyte = getc(fp);
          if (databyte == EOF)
          {
    	 printf("Image read error\n");
    	 return NULL;
          }
          if (databyte & 0xC0)
          {
    	 unsigned char j;
    
    	 count = databyte & 0x3F;
    	 databyte = getc(fp);
    	 printf("%d\n", count);
    	 for (j=0;j<count;j++)
    	    pic->picdata[l++] = (unsigned char)databyte;
          }
          else
    	 pic->picdata[l] = (unsigned char)databyte;
       }
       fclose(fp);
       return pic;
    }
    I've tried compiling and running this using Borland Turbo C 2.0, but it keeps crashing (none of my amazing error checking being done ), and I imagine it has something to do with the way I handle pointers. Any ideas?

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    Apart from this
    pic = (t_pic *)malloc(sizeof(t_pic));
    if (pic->picdata == NULL)
    {
    printf("Picture object: Memory allocation error\n");
    return NULL;
    }

    Should be
    pic = (t_pic *)malloc(sizeof(t_pic));
    if (pic == NULL)
    {
    printf("Picture object: Memory allocation error\n");
    return NULL;
    }

    > pic->picdata = (unsigned char *)malloc((long)pic->width * pic->height)
    If you're using a 16 bit compiler, you'd better watch this - if length*height is >64K, it will truncate it without warning, and you'll have a lot less memory than you thought you had.

  3. #3
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,262
    Well, I've managed to stop it crashing (and improved its speed a bit, using a memset call instead of a loop for RLE), but when I use my save_raw function:-
    Code:
    void save_raw(t_pic *data)
    {
       FILE *fp;
    
       fp = fopen("save.raw", "wb");
       fwrite(data->picdata, data->width * data->height, 1, fp);
       fclose(fp);
    }
    For some reason I appear to get a dump of an executable part of memory (lots of function names with double underscores, the various error messages the run-time library has, etc.)
    When I do my malloc call is the memory preserved from that function, or is it deallocated?
    Last edited by SMurf; 11-26-2001 at 07:26 AM.

  4. #4
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,494
    > fwrite(data->picdata, data->width * data->height, 1, fp);
    Gotta watch those multipliers - it only takes 256*256 to overflow a short integer

    Add some tracing statements to print out
    &nbsp; printf( "size=%ld\n", (long)width * (long) height );
    wherever you do this multiplication. If its larger than 32768, then you might have a problem, and if its larger than 65536, then you almost certainly have a problem.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-06-2009, 11:27 AM
  2. Replies: 7
    Last Post: 02-02-2009, 06:27 AM
  3. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  4. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  5. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21