Link to home
Start Free TrialLog in
Avatar of kamarey
kamarey

asked on

DJGPP Bug?

I have function which reads PCX files.
This function works fine in Borland C for DOS. But if I loading a PCX file with horizontal size that doesn't divide by 2, the function read wrong file header ( sizeX, sizeY etc... ).
Somebody here know, what is the problem?
Avatar of kamarey
kamarey

ASKER

Edited text of question.
Since you've posted no code, we're forced to guess, so I'll do just that.

BC for DOS is a 16-bit compiler.  DJGPP is a 32-bit compiler.  I'll bet you have made some assumptions about data sizes that are not true for the 32-bit compiler.
Avatar of kamarey

ASKER

Here is the sourse code for PCX function that reads 8-bit PCx file and draws it in 16-bit mode to bitmap:

// PCX header structure.
 struct PCXHeader {
        unsigned char Manufacture;        // Constant Flag 10=ZSoft .PCX
        unsigned char Version;            // Version information
        unsigned char Encoding;           // 1=.PCX run lenght encoding
        unsigned char BitsPerPixel;       // Number of bits per pixel
        unsigned short X_min,Y_min,       // Picture Dimensions
                       X_max,Y_max;
        unsigned short H_Resolution;      // Horizontal resolution of creating device
        unsigned short V_Resolution;      // Vertical resolution of creating device
        unsigned char Pallete[48];        // Color palette setting. Used for 16-color images
        unsigned char Reserved;           // Reserved for future use
        unsigned char NPlanes;            // Number of color planes
        unsigned short BytesPerLine;      // Number of bytes per line
        unsigned short Palette_type;      // 2:grayscale pallete, 1:color pallete
        unsigned char Filler[58];         // Set to 0
 };
BITMAP *load_pcx(char *filename) {
      BITMAP *temp_btm;
      PCXHeader header;
      FILE *file;
      PALLETE pal;
      int total_bytes,coded_bytes;
      unsigned char color;

      file=fopen(filename,"rb");
      if (!file) {
         SetTextMode();
         cout << "\n File not found." << endl;
         exit(0);
      }

      fread(&header,sizeof(PCXHeader),1,file);
      total_bytes=(header.X_max+1)*(header.Y_max+1);
      temp_btm=create_bitmap(header.X_max+1,header.Y_max+1);

      for (int i=0;i<total_bytes;i++) {
          color=fgetc(file);
          if (color<192) temp_btm->bitmap[i]=color;
          else {
             coded_bytes=color-192;
             color=fgetc(file);
             for (int n=0;n<coded_bytes;n++,i++)
                 temp_btm->bitmap[i]=color;
             i--;
          }
      }
         
      fseek(file,-768,SEEK_END);
      for (int i=0;i<256;i++) {
          pal[i].red=fgetc(file);
          pal[i].green=fgetc(file);
          pal[i].blue=fgetc(file);
      }

      for (int n=0;n<total_bytes;n++) {
          color=temp_btm->bitmap[n];
          temp_btm->bitmap[n]=makecol(pal[color].red,pal[color].green,pal[color].blue);
      }

      fclose(file);
      return temp_btm;
 }


I don't know the format of the PCX files, but the error will be in the alligment of the structure elements. It is always very dangerous to read in binary data within a structure when you don't have wrote the data with the same structure. Every compiler (OS, ...) uses a different alligment. Read in the whole header in a char array and access the data directly from the array.
Avatar of kamarey

ASKER

I had already done so. It reads right only 5 bytes, so there is the same problem with PCX header of array of bytes.

If you have this compiler you can test this function. I can increase points.
ASKER CERTIFIED SOLUTION
Avatar of jhance
jhance

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kamarey

ASKER

I compiled it:
in every case there was the same number: 2;
But I don't understand how it can help for deciding the problem?
If the problem in my program, so tell me where it is?
Hmmm.  What version of Borland C for DOS are you using?  My copy defines:

char, short as 8-bit
int, long, and *anything as 16-bit

Also, what is the significance of 768 in:

fseek(file,-768,SEEK_END);
     

That seems quite non-portable to me.  

You also may want to check for DATA ALIGNMENT issues.  In a 16-bit DOS program, data can be aligned on a byte (i.e. 8-bit) boundary.  When you move to the 32-bit DJGPP compiler, I believe you get data structure padding by default in order to prevent the CPU from doing (costly in 32-bit protected mode) byte-aligned fetches.  The fact that you say it works with even numbered horiz size but not odd leads me to think this might be a problem as well.

Check the compile options for DJGPP and see if there are alignment options. Set it for 8-bit or BYTE alignment and see if that changes things.
Avatar of kamarey

ASKER

1.
 I'm using Borland C 3.1. There are:
 char as 8-bit
 int,short as 16-bit
 long as 32-bit.

In DJGPP:
 char as 8-bit
 short as 16-bit
 int,long as 32-bit. ( I don't know here difference beetwen int and long ).
2.
 I don't understand what is wrong here:
    fseek(file,-768,SEEK_END);
  the problem starts before this string.
3.
 Why the program reads right PCX with even horizontak size?
Avatar of kamarey

ASKER

And was mistaken in one thing: the program reads right PCX with NOT even horizontal size and reads wrong with even.
Avatar of kamarey

ASKER

After you post your comment I looked in my sourse code and some tutorials by opening PCX file and found the mistake.

Here the two stings were was the problem:
total_bytes=(header.X_max+1)*(header.Y_max+1);
temp_btm=create_bitmap(header.X_max+1,header.Y_max+1);    

And here these right strings:
total_bytes=(header.BytesPerLine)*(header.Y_max+1);
temp_btm=create_bitmap(header.BytesPerLine,header.Y_max+1);

So I should give you the points becouse of two reasons:
1. I have found the mistake after your comments.
2. I must give the points to somebody.
Avatar of kamarey

ASKER

After you post your comment I looked in my sourse code and some tutorials by opening PCX file and found the mistake.

Here the two stings were was the problem:
total_bytes=(header.X_max+1)*(header.Y_max+1);
temp_btm=create_bitmap(header.X_max+1,header.Y_max+1);    

And here these right strings:
total_bytes=(header.BytesPerLine)*(header.Y_max+1);
temp_btm=create_bitmap(header.BytesPerLine,header.Y_max+1);

So I should give you the points becouse of two reasons:
1. I have found the mistake after your comments.
2. I must give the points to somebody.