Added code to read BMP files from memory (GitHub issue #33, 1/2)
This commit is contained in:
parent
462b681679
commit
86893a90cb
@ -31,7 +31,13 @@ class FL_EXPORT Fl_BMP_Image : public Fl_RGB_Image {
|
||||
|
||||
public:
|
||||
|
||||
Fl_BMP_Image(const char* filename);
|
||||
Fl_BMP_Image(const char* filename);
|
||||
Fl_BMP_Image(const char* filename, const unsigned char *data);
|
||||
|
||||
protected:
|
||||
|
||||
void read(class BMPReader &rdr);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -45,12 +45,108 @@
|
||||
|
||||
|
||||
//
|
||||
// Local functions...
|
||||
// Local reader class...
|
||||
//
|
||||
|
||||
static int read_long(FILE *fp);
|
||||
static unsigned short read_word(FILE *fp);
|
||||
static unsigned int read_dword(FILE *fp);
|
||||
class BMPReader
|
||||
{
|
||||
public:
|
||||
BMPReader() :
|
||||
pIsFile(0), pIsData(0),
|
||||
pFile(0L), pData(0L), pStart(0L),
|
||||
pName(0L)
|
||||
{ }
|
||||
int open(const char *filename) {
|
||||
if (filename)
|
||||
pName = strdup(filename);
|
||||
if ((pFile = fl_fopen(filename, "rb")) == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
pIsFile = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int open(const char *imagename, const unsigned char *data) {
|
||||
if (imagename)
|
||||
pName = strdup(imagename);
|
||||
if (data) {
|
||||
pStart = pData = data;
|
||||
pIsData = 1;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
~BMPReader() {
|
||||
if (pIsFile && pFile) {
|
||||
fclose(pFile);
|
||||
}
|
||||
if (pName)
|
||||
::free(pName);
|
||||
}
|
||||
uchar read_byte() {
|
||||
if (pIsFile) {
|
||||
return getc(pFile);
|
||||
} else if (pIsData) {
|
||||
return *pData++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// 'read_word()' - Read a 16-bit unsigned integer.
|
||||
unsigned short read_word() {
|
||||
unsigned char b0, b1; // Bytes from file
|
||||
if (pIsFile) {
|
||||
b0 = (uchar)getc(pFile);
|
||||
b1 = (uchar)getc(pFile);
|
||||
return ((b1 << 8) | b0);
|
||||
} else if (pIsData) {
|
||||
b0 = *pData++;
|
||||
b1 = *pData++;
|
||||
return ((b1 << 8) | b0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// 'read_dword()' - Read a 32-bit unsigned integer.
|
||||
unsigned int read_dword() {
|
||||
unsigned char b0, b1, b2, b3; // Bytes from file
|
||||
if (pIsFile) {
|
||||
b0 = (uchar)getc(pFile);
|
||||
b1 = (uchar)getc(pFile);
|
||||
b2 = (uchar)getc(pFile);
|
||||
b3 = (uchar)getc(pFile);
|
||||
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
||||
} else if (pIsData) {
|
||||
b0 = *pData++;
|
||||
b1 = *pData++;
|
||||
b2 = *pData++;
|
||||
b3 = *pData++;
|
||||
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// 'read_long()' - Read a 32-bit signed integer.
|
||||
int read_long() {
|
||||
return (int)read_dword();
|
||||
};
|
||||
void seek(unsigned int n) {
|
||||
if (pIsFile) {
|
||||
fseek(pFile, n , SEEK_SET);
|
||||
} else if (pIsData) {
|
||||
pData = pStart + n;
|
||||
}
|
||||
}
|
||||
const char *name() { return pName; }
|
||||
private:
|
||||
char pIsFile;
|
||||
char pIsData;
|
||||
FILE *pFile;
|
||||
const unsigned char *pData;
|
||||
const unsigned char *pStart;
|
||||
char *pName;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -65,55 +161,79 @@ static unsigned int read_dword(FILE *fp);
|
||||
be loaded for another reason.
|
||||
*/
|
||||
Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
: Fl_RGB_Image(0,0,0) {
|
||||
FILE *fp; // File pointer
|
||||
int info_size, // Size of info header
|
||||
depth, // Depth of image (bits)
|
||||
bDepth = 3, // Depth of image (bytes)
|
||||
compression, // Type of compression
|
||||
colors_used, // Number of colors used
|
||||
x, y, // Looping vars
|
||||
color, // Color of RLE pixel
|
||||
repcount, // Number of times to repeat
|
||||
temp, // Temporary color
|
||||
align, // Alignment bytes
|
||||
dataSize, // number of bytes in image data set
|
||||
row_order, // 1 = normal; -1 = flipped row order
|
||||
start_y, // Beginning Y
|
||||
end_y; // Ending Y
|
||||
long offbits; // Offset to image data
|
||||
uchar bit, // Bit in image
|
||||
byte; // Byte in image
|
||||
uchar *ptr; // Pointer into pixels
|
||||
uchar colormap[256][3];// Colormap
|
||||
uchar havemask; // Single bit mask follows image data
|
||||
int use_5_6_5; // Use 5:6:5 for R:G:B channels in 16 bit images
|
||||
|
||||
|
||||
// Open the file...
|
||||
if ((fp = fl_fopen(bmp, "rb")) == NULL) {
|
||||
ld(ERR_FILE_ACCESS);
|
||||
return;
|
||||
: Fl_RGB_Image(0,0,0)
|
||||
{
|
||||
BMPReader f;
|
||||
if (f.open(bmp)==-1) {
|
||||
ld(ERR_FORMAT);
|
||||
} else {
|
||||
read(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The constructor loads the named BMP image from the given memory address.
|
||||
|
||||
\param[in] bmp the name of the bitmap
|
||||
\param[in] data a pointer to the BMP data in memory. There is no checking for buffer overruns
|
||||
|
||||
\see Fl_BMP_Image::Fl_BMP_Image(const char *bmp)
|
||||
*/
|
||||
Fl_BMP_Image::Fl_BMP_Image(const char *bmp, const unsigned char *data)
|
||||
: Fl_RGB_Image(0,0,0)
|
||||
{
|
||||
BMPReader d;
|
||||
if (d.open(bmp, data)==-1) {
|
||||
ld(ERR_FORMAT);
|
||||
} else {
|
||||
read(d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Fl_BMP_Image::read(class BMPReader &rdr)
|
||||
{
|
||||
int info_size, // Size of info header
|
||||
depth, // Depth of image (bits)
|
||||
bDepth = 3, // Depth of image (bytes)
|
||||
compression, // Type of compression
|
||||
colors_used, // Number of colors used
|
||||
x, y, // Looping vars
|
||||
color, // Color of RLE pixel
|
||||
repcount, // Number of times to repeat
|
||||
temp, // Temporary color
|
||||
align, // Alignment bytes
|
||||
dataSize, // number of bytes in image data set
|
||||
row_order, // 1 = normal; -1 = flipped row order
|
||||
start_y, // Beginning Y
|
||||
end_y; // Ending Y
|
||||
long offbits; // Offset to image data
|
||||
uchar bit, // Bit in image
|
||||
byte; // Byte in image
|
||||
uchar *ptr; // Pointer into pixels
|
||||
uchar colormap[256][3]; // Colormap
|
||||
uchar havemask; // Single bit mask follows image data
|
||||
int use_5_6_5; // Use 5:6:5 for R:G:B channels in 16 bit images
|
||||
|
||||
// Reader is already open at this point.
|
||||
|
||||
// Get the header...
|
||||
byte = (uchar)getc(fp); // Check "BM" sync chars
|
||||
bit = (uchar)getc(fp);
|
||||
byte = rdr.read_byte(); // Check "BM" sync chars
|
||||
bit = rdr.read_byte();
|
||||
if (byte != 'B' || bit != 'M') {
|
||||
fclose(fp);
|
||||
ld(ERR_FORMAT);
|
||||
return;
|
||||
}
|
||||
|
||||
read_dword(fp); // Skip size
|
||||
read_word(fp); // Skip reserved stuff
|
||||
read_word(fp);
|
||||
offbits = (long)read_dword(fp);// Read offset to image data
|
||||
rdr.read_dword(); // Skip size
|
||||
rdr.read_word(); // Skip reserved stuff
|
||||
rdr.read_word();
|
||||
offbits = (long)rdr.read_dword();// Read offset to image data
|
||||
|
||||
// Then the bitmap information...
|
||||
info_size = read_dword(fp);
|
||||
info_size = rdr.read_dword();
|
||||
|
||||
// printf("offbits = %ld, info_size = %d\n", offbits, info_size);
|
||||
// printf("offbits = %ld, info_size = %d\n", offbits, info_size);
|
||||
|
||||
havemask = 0;
|
||||
row_order = -1;
|
||||
@ -121,29 +241,29 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
|
||||
if (info_size < 40) {
|
||||
// Old Windows/OS2 BMP header...
|
||||
w(read_word(fp));
|
||||
h(read_word(fp));
|
||||
read_word(fp);
|
||||
depth = read_word(fp);
|
||||
w(rdr.read_word());
|
||||
h(rdr.read_word());
|
||||
rdr.read_word();
|
||||
depth = rdr.read_word();
|
||||
compression = BI_RGB;
|
||||
colors_used = 0;
|
||||
|
||||
repcount = info_size - 12;
|
||||
} else {
|
||||
// New BMP header...
|
||||
w(read_long(fp));
|
||||
w(rdr.read_long());
|
||||
// If the height is negative, the row order is flipped
|
||||
temp = read_long(fp);
|
||||
temp = rdr.read_long();
|
||||
if (temp < 0) row_order = 1;
|
||||
h(abs(temp));
|
||||
read_word(fp);
|
||||
depth = read_word(fp);
|
||||
compression = read_dword(fp);
|
||||
dataSize = read_dword(fp);
|
||||
read_long(fp);
|
||||
read_long(fp);
|
||||
colors_used = read_dword(fp);
|
||||
read_dword(fp);
|
||||
rdr.read_word();
|
||||
depth = rdr.read_word();
|
||||
compression = rdr.read_dword();
|
||||
dataSize = rdr.read_dword();
|
||||
rdr.read_long();
|
||||
rdr.read_long();
|
||||
colors_used = rdr.read_dword();
|
||||
rdr.read_dword();
|
||||
|
||||
repcount = info_size - 40;
|
||||
|
||||
@ -152,24 +272,23 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
int maskSize = (((w()*Bpp+3)&~3)*h()) + (((((w()+7)/8)+3)&~3)*h());
|
||||
if (maskSize==2*dataSize) {
|
||||
havemask = 1;
|
||||
h(h()/2);
|
||||
bDepth = 4;
|
||||
h(h()/2);
|
||||
bDepth = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("w() = %d, h() = %d, depth = %d, compression = %d, colors_used = %d, repcount = %d\n",
|
||||
// w(), h(), depth, compression, colors_used, repcount);
|
||||
// printf("w() = %d, h() = %d, depth = %d, compression = %d, colors_used = %d, repcount = %d\n",
|
||||
// w(), h(), depth, compression, colors_used, repcount);
|
||||
|
||||
// Skip remaining header bytes...
|
||||
while (repcount > 0) {
|
||||
getc(fp);
|
||||
rdr.read_byte();
|
||||
repcount --;
|
||||
}
|
||||
|
||||
// Check header data...
|
||||
if (!w() || !h() || !depth) {
|
||||
fclose(fp);
|
||||
w(0); h(0); d(0); ld(ERR_FORMAT);
|
||||
return;
|
||||
}
|
||||
@ -180,15 +299,17 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
|
||||
for (repcount = 0; repcount < colors_used; repcount ++) {
|
||||
// Read BGR color...
|
||||
if (fread(colormap[repcount], 1, 3, fp)==0) { /* ignore */ }
|
||||
colormap[repcount][0] = rdr.read_byte();
|
||||
colormap[repcount][1] = rdr.read_byte();
|
||||
colormap[repcount][2] = rdr.read_byte();
|
||||
|
||||
// Skip pad byte for new BMP files...
|
||||
if (info_size > 12) getc(fp);
|
||||
if (info_size > 12) rdr.read_byte();
|
||||
}
|
||||
|
||||
// Read first dword of colormap. It tells us if 5:5:5 or 5:6:5 for 16 bit
|
||||
if (depth == 16)
|
||||
use_5_6_5 = (read_dword(fp) == 0xf800);
|
||||
use_5_6_5 = (rdr.read_dword() == 0xf800);
|
||||
|
||||
// Set byte depth for RGBA images
|
||||
if (depth == 32)
|
||||
@ -196,11 +317,10 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
|
||||
// Setup image and buffers...
|
||||
d(bDepth);
|
||||
if (offbits) fseek(fp, offbits, SEEK_SET);
|
||||
if (offbits) rdr.seek(offbits);
|
||||
|
||||
if (((size_t)w()) * h() * d() > max_size() ) {
|
||||
Fl::warning("BMP file \"%s\" is too large!\n", bmp);
|
||||
fclose(fp);
|
||||
Fl::warning("BMP file \"%s\" is too large!\n", rdr.name());
|
||||
w(0); h(0); d(0); ld(ERR_FORMAT);
|
||||
return;
|
||||
}
|
||||
@ -228,199 +348,199 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
switch (depth)
|
||||
{
|
||||
case 1 : // Bitmap
|
||||
for (x = w(), bit = 128; x > 0; x --) {
|
||||
if (bit == 128) byte = (uchar)getc(fp);
|
||||
for (x = w(), bit = 128; x > 0; x --) {
|
||||
if (bit == 128) byte = rdr.read_byte();
|
||||
|
||||
if (byte & bit) {
|
||||
*ptr++ = colormap[1][2];
|
||||
*ptr++ = colormap[1][1];
|
||||
*ptr++ = colormap[1][0];
|
||||
} else {
|
||||
*ptr++ = colormap[0][2];
|
||||
*ptr++ = colormap[0][1];
|
||||
*ptr++ = colormap[0][0];
|
||||
}
|
||||
if (byte & bit) {
|
||||
*ptr++ = colormap[1][2];
|
||||
*ptr++ = colormap[1][1];
|
||||
*ptr++ = colormap[1][0];
|
||||
} else {
|
||||
*ptr++ = colormap[0][2];
|
||||
*ptr++ = colormap[0][1];
|
||||
*ptr++ = colormap[0][0];
|
||||
}
|
||||
|
||||
if (bit > 1)
|
||||
bit >>= 1;
|
||||
else
|
||||
bit = 128;
|
||||
}
|
||||
if (bit > 1)
|
||||
bit >>= 1;
|
||||
else
|
||||
bit = 128;
|
||||
}
|
||||
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = (w() + 7) / 8; temp & 3; temp ++) {
|
||||
getc(fp);
|
||||
}
|
||||
break;
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = (w() + 7) / 8; temp & 3; temp ++) {
|
||||
rdr.read_byte();
|
||||
}
|
||||
break;
|
||||
|
||||
case 4 : // 16-color
|
||||
for (x = w(), bit = 0xf0; x > 0; x --) {
|
||||
// Get a new repcount as needed...
|
||||
if (repcount == 0) {
|
||||
if (compression != BI_RLE4) {
|
||||
repcount = 2;
|
||||
color = -1;
|
||||
} else {
|
||||
while (align > 0) {
|
||||
align --;
|
||||
getc(fp);
|
||||
}
|
||||
|
||||
if ((repcount = getc(fp)) == 0) {
|
||||
if ((repcount = getc(fp)) == 0) {
|
||||
// End of line...
|
||||
x ++;
|
||||
continue;
|
||||
} else if (repcount == 1) {
|
||||
// End of image...
|
||||
break;
|
||||
} else if (repcount == 2) {
|
||||
// Delta...
|
||||
repcount = getc(fp) * getc(fp) * w();
|
||||
color = 0;
|
||||
} else {
|
||||
// Absolute...
|
||||
color = -1;
|
||||
align = ((4 - (repcount & 3)) / 2) & 1;
|
||||
}
|
||||
} else {
|
||||
color = getc(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get a new color as needed...
|
||||
repcount --;
|
||||
|
||||
// Extract the next pixel...
|
||||
if (bit == 0xf0) {
|
||||
// Get the next color byte as needed...
|
||||
if (color < 0) temp = getc(fp);
|
||||
else temp = color;
|
||||
|
||||
// Copy the color value...
|
||||
*ptr++ = colormap[(temp >> 4) & 15][2];
|
||||
*ptr++ = colormap[(temp >> 4) & 15][1];
|
||||
*ptr++ = colormap[(temp >> 4) & 15][0];
|
||||
|
||||
bit = 0x0f;
|
||||
} else {
|
||||
bit = 0xf0;
|
||||
|
||||
// Copy the color value...
|
||||
*ptr++ = colormap[temp & 15][2];
|
||||
*ptr++ = colormap[temp & 15][1];
|
||||
*ptr++ = colormap[temp & 15][0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!compression) {
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = (w() + 1) / 2; temp & 3; temp ++) {
|
||||
getc(fp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8 : // 256-color
|
||||
for (x = w(); x > 0; x --) {
|
||||
// Get a new repcount as needed...
|
||||
if (compression != BI_RLE8) {
|
||||
repcount = 1;
|
||||
color = -1;
|
||||
}
|
||||
|
||||
if (repcount == 0) {
|
||||
while (align > 0) {
|
||||
align --;
|
||||
getc(fp);
|
||||
for (x = w(), bit = 0xf0; x > 0; x --) {
|
||||
// Get a new repcount as needed...
|
||||
if (repcount == 0) {
|
||||
if (compression != BI_RLE4) {
|
||||
repcount = 2;
|
||||
color = -1;
|
||||
} else {
|
||||
while (align > 0) {
|
||||
align --;
|
||||
rdr.read_byte();
|
||||
}
|
||||
|
||||
if ((repcount = getc(fp)) == 0) {
|
||||
if ((repcount = getc(fp)) == 0) {
|
||||
// End of line...
|
||||
if ((repcount = rdr.read_byte()) == 0) {
|
||||
if ((repcount = rdr.read_byte()) == 0) {
|
||||
// End of line...
|
||||
x ++;
|
||||
continue;
|
||||
} else if (repcount == 1) {
|
||||
// End of image...
|
||||
break;
|
||||
} else if (repcount == 2) {
|
||||
// Delta...
|
||||
repcount = getc(fp) * getc(fp) * w();
|
||||
color = 0;
|
||||
} else {
|
||||
// Absolute...
|
||||
color = -1;
|
||||
align = (2 - (repcount & 1)) & 1;
|
||||
}
|
||||
} else {
|
||||
color = getc(fp);
|
||||
continue;
|
||||
} else if (repcount == 1) {
|
||||
// End of image...
|
||||
break;
|
||||
} else if (repcount == 2) {
|
||||
// Delta...
|
||||
repcount = rdr.read_byte() * rdr.read_byte() * w();
|
||||
color = 0;
|
||||
} else {
|
||||
// Absolute...
|
||||
color = -1;
|
||||
align = ((4 - (repcount & 3)) / 2) & 1;
|
||||
}
|
||||
} else {
|
||||
color = rdr.read_byte();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get a new color as needed...
|
||||
if (color < 0) temp = getc(fp);
|
||||
else temp = color;
|
||||
// Get a new color as needed...
|
||||
repcount --;
|
||||
|
||||
repcount --;
|
||||
// Extract the next pixel...
|
||||
if (bit == 0xf0) {
|
||||
// Get the next color byte as needed...
|
||||
if (color < 0) temp = rdr.read_byte();
|
||||
else temp = color;
|
||||
|
||||
// Copy the color value...
|
||||
*ptr++ = colormap[temp][2];
|
||||
*ptr++ = colormap[temp][1];
|
||||
*ptr++ = colormap[temp][0];
|
||||
if (havemask) ptr++;
|
||||
}
|
||||
*ptr++ = colormap[(temp >> 4) & 15][2];
|
||||
*ptr++ = colormap[(temp >> 4) & 15][1];
|
||||
*ptr++ = colormap[(temp >> 4) & 15][0];
|
||||
|
||||
if (!compression) {
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w(); temp & 3; temp ++) {
|
||||
getc(fp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
bit = 0x0f;
|
||||
} else {
|
||||
bit = 0xf0;
|
||||
|
||||
// Copy the color value...
|
||||
*ptr++ = colormap[temp & 15][2];
|
||||
*ptr++ = colormap[temp & 15][1];
|
||||
*ptr++ = colormap[temp & 15][0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!compression) {
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = (w() + 1) / 2; temp & 3; temp ++) {
|
||||
rdr.read_byte();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8 : // 256-color
|
||||
for (x = w(); x > 0; x --) {
|
||||
// Get a new repcount as needed...
|
||||
if (compression != BI_RLE8) {
|
||||
repcount = 1;
|
||||
color = -1;
|
||||
}
|
||||
|
||||
if (repcount == 0) {
|
||||
while (align > 0) {
|
||||
align --;
|
||||
rdr.read_byte();
|
||||
}
|
||||
|
||||
if ((repcount = rdr.read_byte()) == 0) {
|
||||
if ((repcount = rdr.read_byte()) == 0) {
|
||||
// End of line...
|
||||
x ++;
|
||||
continue;
|
||||
} else if (repcount == 1) {
|
||||
// End of image...
|
||||
break;
|
||||
} else if (repcount == 2) {
|
||||
// Delta...
|
||||
repcount = rdr.read_byte() * rdr.read_byte() * w();
|
||||
color = 0;
|
||||
} else {
|
||||
// Absolute...
|
||||
color = -1;
|
||||
align = (2 - (repcount & 1)) & 1;
|
||||
}
|
||||
} else {
|
||||
color = rdr.read_byte();
|
||||
}
|
||||
}
|
||||
|
||||
// Get a new color as needed...
|
||||
if (color < 0) temp = rdr.read_byte();
|
||||
else temp = color;
|
||||
|
||||
repcount --;
|
||||
|
||||
// Copy the color value...
|
||||
*ptr++ = colormap[temp][2];
|
||||
*ptr++ = colormap[temp][1];
|
||||
*ptr++ = colormap[temp][0];
|
||||
if (havemask) ptr++;
|
||||
}
|
||||
|
||||
if (!compression) {
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w(); temp & 3; temp ++) {
|
||||
rdr.read_byte();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 16 : // 16-bit 5:5:5 or 5:6:5 RGB
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
uchar b = getc(fp), a = getc(fp) ;
|
||||
if (use_5_6_5) {
|
||||
ptr[2] = (uchar)(( b << 3 ) & 0xf8);
|
||||
ptr[1] = (uchar)(((a << 5) & 0xe0) | ((b >> 3) & 0x1c));
|
||||
ptr[0] = (uchar)(a & 0xf8);
|
||||
} else {
|
||||
ptr[2] = (uchar)((b << 3) & 0xf8);
|
||||
ptr[1] = (uchar)(((a << 6) & 0xc0) | ((b >> 2) & 0x38));
|
||||
ptr[0] = (uchar)((a<<1) & 0xf8);
|
||||
}
|
||||
}
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
uchar b = rdr.read_byte(), a = rdr.read_byte() ;
|
||||
if (use_5_6_5) {
|
||||
ptr[2] = (uchar)(( b << 3 ) & 0xf8);
|
||||
ptr[1] = (uchar)(((a << 5) & 0xe0) | ((b >> 3) & 0x1c));
|
||||
ptr[0] = (uchar)(a & 0xf8);
|
||||
} else {
|
||||
ptr[2] = (uchar)((b << 3) & 0xf8);
|
||||
ptr[1] = (uchar)(((a << 6) & 0xc0) | ((b >> 2) & 0x38));
|
||||
ptr[0] = (uchar)((a<<1) & 0xf8);
|
||||
}
|
||||
}
|
||||
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w() * 2; temp & 3; temp ++) {
|
||||
getc(fp);
|
||||
}
|
||||
break;
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w() * 2; temp & 3; temp ++) {
|
||||
rdr.read_byte();
|
||||
}
|
||||
break;
|
||||
|
||||
case 24 : // 24-bit RGB
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
ptr[2] = (uchar)getc(fp);
|
||||
ptr[1] = (uchar)getc(fp);
|
||||
ptr[0] = (uchar)getc(fp);
|
||||
}
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
ptr[2] = rdr.read_byte();
|
||||
ptr[1] = rdr.read_byte();
|
||||
ptr[0] = rdr.read_byte();
|
||||
}
|
||||
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w() * 3; temp & 3; temp ++) {
|
||||
rdr.read_byte();
|
||||
}
|
||||
break;
|
||||
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = w() * 3; temp & 3; temp ++) {
|
||||
getc(fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 32 : // 32-bit RGBA
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
ptr[2] = (uchar)getc(fp);
|
||||
ptr[1] = (uchar)getc(fp);
|
||||
ptr[0] = (uchar)getc(fp);
|
||||
ptr[3] = (uchar)getc(fp);
|
||||
}
|
||||
break;
|
||||
for (x = w(); x > 0; x --, ptr += bDepth) {
|
||||
ptr[2] = rdr.read_byte();
|
||||
ptr[1] = rdr.read_byte();
|
||||
ptr[0] = rdr.read_byte();
|
||||
ptr[3] = rdr.read_byte();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,73 +548,22 @@ Fl_BMP_Image::Fl_BMP_Image(const char *bmp) // I - File to read
|
||||
for (y = h() - 1; y >= 0; y --) {
|
||||
ptr = (uchar *)array + y * w() * d() + 3;
|
||||
for (x = w(), bit = 128; x > 0; x --, ptr+=bDepth) {
|
||||
if (bit == 128) byte = (uchar)getc(fp);
|
||||
if (byte & bit)
|
||||
*ptr = 0;
|
||||
else
|
||||
*ptr = 255;
|
||||
if (bit > 1)
|
||||
bit >>= 1;
|
||||
else
|
||||
bit = 128;
|
||||
if (bit == 128) byte = rdr.read_byte();
|
||||
if (byte & bit)
|
||||
*ptr = 0;
|
||||
else
|
||||
*ptr = 255;
|
||||
if (bit > 1)
|
||||
bit >>= 1;
|
||||
else
|
||||
bit = 128;
|
||||
}
|
||||
// Read remaining bytes to align to 32 bits...
|
||||
for (temp = (w() + 7) / 8; temp & 3; temp ++)
|
||||
getc(fp);
|
||||
rdr.read_byte();
|
||||
}
|
||||
}
|
||||
|
||||
// Close the file and return...
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'read_word()' - Read a 16-bit unsigned integer.
|
||||
//
|
||||
|
||||
static unsigned short // O - 16-bit unsigned integer
|
||||
read_word(FILE *fp) { // I - File to read from
|
||||
unsigned char b0, b1; // Bytes from file
|
||||
|
||||
b0 = (uchar)getc(fp);
|
||||
b1 = (uchar)getc(fp);
|
||||
|
||||
return ((b1 << 8) | b0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'read_dword()' - Read a 32-bit unsigned integer.
|
||||
//
|
||||
|
||||
static unsigned int // O - 32-bit unsigned integer
|
||||
read_dword(FILE *fp) { // I - File to read from
|
||||
unsigned char b0, b1, b2, b3; // Bytes from file
|
||||
|
||||
b0 = (uchar)getc(fp);
|
||||
b1 = (uchar)getc(fp);
|
||||
b2 = (uchar)getc(fp);
|
||||
b3 = (uchar)getc(fp);
|
||||
|
||||
return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 'read_long()' - Read a 32-bit signed integer.
|
||||
//
|
||||
|
||||
static int // O - 32-bit signed integer
|
||||
read_long(FILE *fp) { // I - File to read from
|
||||
unsigned char b0, b1, b2, b3; // Bytes from file
|
||||
|
||||
b0 = (uchar)getc(fp);
|
||||
b1 = (uchar)getc(fp);
|
||||
b2 = (uchar)getc(fp);
|
||||
b3 = (uchar)getc(fp);
|
||||
|
||||
return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
|
||||
// File is closed when returning...
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user