• C

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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
Managing Security & Risk at the Speed of Business

Gartner Research VP, Neil McDonald & AlgoSec CTO, Prof. Avishai Wool, discuss the business-driven approach to automated security policy management, its benefits and how to align security policy management with business processes to address today's security challenges.

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
jhanceCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.