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?
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?
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.
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.
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(PCXHe ader),1,fi le);
total_bytes=(header.X_max+ 1)*(header .Y_max+1);
temp_btm=create_bitmap(hea der.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]=makeco l(pal[colo r].red,pal [color].gr een,pal[co lor].blue) ;
}
fclose(file);
return temp_btm;
}
// 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(PCXHe
total_bytes=(header.X_max+
temp_btm=create_bitmap(hea
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]=makeco
}
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.
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.
If you have this compiler you can test this function. I can increase points.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?
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.
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.
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?
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?
ASKER
And was mistaken in one thing: the program reads right PCX with NOT even horizontal size and reads wrong with even.
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(hea der.X_max+ 1,header.Y _max+1);
And here these right strings:
total_bytes=(header.BytesP erLine)*(h eader.Y_ma x+1);
temp_btm=create_bitmap(hea der.BytesP erLine,hea der.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.
Here the two stings were was the problem:
total_bytes=(header.X_max+
temp_btm=create_bitmap(hea
And here these right strings:
total_bytes=(header.BytesP
temp_btm=create_bitmap(hea
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.
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(hea der.X_max+ 1,header.Y _max+1);
And here these right strings:
total_bytes=(header.BytesP erLine)*(h eader.Y_ma x+1);
temp_btm=create_bitmap(hea der.BytesP erLine,hea der.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.
Here the two stings were was the problem:
total_bytes=(header.X_max+
temp_btm=create_bitmap(hea
And here these right strings:
total_bytes=(header.BytesP
temp_btm=create_bitmap(hea
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.
ASKER