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?
LVL 2
kamareyAsked:
Who is Participating?
 
jhanceConnect With a Mentor Commented:
I'll stand by my original answer now that you've posted your code.

Compile and run the following code on each Borland C and DJGPP:

#include <stdio.h>

main()
{
 printf("SIZE = %d\n", sizeof(unsigned short));
}
0
 
kamareyAuthor Commented:
Edited text of question.
0
 
jhanceCommented:
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.
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
kamareyAuthor Commented:
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;
 }


0
 
rbrCommented:
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.
0
 
kamareyAuthor Commented:
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.
0
 
kamareyAuthor Commented:
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?
0
 
jhanceCommented:
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.
0
 
kamareyAuthor Commented:
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?
0
 
kamareyAuthor Commented:
And was mistaken in one thing: the program reads right PCX with NOT even horizontal size and reads wrong with even.
0
 
kamareyAuthor Commented:
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.
0
 
kamareyAuthor Commented:
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.
0
All Courses

From novice to tech pro — start learning today.