[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libcvd-members] libcvd cvd/internal/io/bmp.h pnm_src/bmp.cxx
From: |
Edward Rosten |
Subject: |
[libcvd-members] libcvd cvd/internal/io/bmp.h pnm_src/bmp.cxx |
Date: |
Thu, 15 May 2008 22:54:13 +0000 |
CVSROOT: /cvsroot/libcvd
Module name: libcvd
Changes by: Edward Rosten <edrosten> 08/05/15 22:54:13
Modified files:
cvd/internal/io: bmp.h
pnm_src : bmp.cxx
Log message:
Fix .bmp loading and saving on 64 bit platforms
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/internal/io/bmp.h?cvsroot=libcvd&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/libcvd/pnm_src/bmp.cxx?cvsroot=libcvd&r1=1.1&r2=1.2
Patches:
Index: cvd/internal/io/bmp.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/internal/io/bmp.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- cvd/internal/io/bmp.h 29 Sep 2006 21:59:45 -0000 1.5
+++ cvd/internal/io/bmp.h 15 May 2008 22:54:11 -0000 1.6
@@ -96,7 +96,10 @@
unsigned int w,h,ch, comp;
readBMPHeader(w,h,ch,comp,in);
if (comp || (ch != 3 && ch != 1))
+ {
+ std::cerr << comp << " " << ch << "\n";
throw CVD::Exceptions::Image_IO::UnsupportedImageType();
+ }
im.resize(ImageRef(w,h));
if (ch == 1)
BMPReader<T,1>::read(im, in);
Index: pnm_src/bmp.cxx
===================================================================
RCS file: /cvsroot/libcvd/libcvd/pnm_src/bmp.cxx,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- pnm_src/bmp.cxx 28 Nov 2005 19:07:40 -0000 1.1
+++ pnm_src/bmp.cxx 15 May 2008 22:54:12 -0000 1.2
@@ -22,6 +22,7 @@
using namespace std;
#include <iostream>
+#include <sstream>
#include <iomanip>
#include <setjmp.h>
@@ -30,16 +31,16 @@
namespace BMP
{
-#pragma pack(4)
struct BMPHeader
{
unsigned long size; //!< header size
- unsigned long reserved; //!< reserved
+ unsigned short reserved[2]; //!< reserved
unsigned long dataOffset; //!< offset to beginning of data
unsigned long infoSize; //!< size of info
unsigned long width; //!< width of image
unsigned long height; //!< height of image
- unsigned short planes_bpp[2]; //!< planes and color depth
+ unsigned short planes; //!< planes
+ unsigned short bpp; //!< colour depth
unsigned long compression; //!< compression type
unsigned long dataSize; //!< size of data
unsigned long xPelsPerMeter; //!< x resolution in pixels/meter
@@ -47,69 +48,145 @@
unsigned long colors; //!< number of specified colors in the map
unsigned long importantColors; //!< number of important colors
};
-#pragma pack()
- inline bool isBigEndian()
+
+ void write_u4(ostream& o, unsigned long l)
+ {
+ o << (unsigned char)(0xff & (l))
+ << (unsigned char)(0xff & (l >> 8))
+ << (unsigned char)(0xff & (l >> 16))
+ << (unsigned char)(0xff & (l >> 24));
+ }
+
+ void write_u1(ostream& o, unsigned long l)
{
- char buf[4]={'a','b','c','d'};
- return (*(unsigned long*)buf & 0xFF) == 'd';
+ o << (unsigned char)(0xff & (l));
}
- //! Returns the byte reversal of a short.
- inline unsigned short rev(unsigned short s)
+ void write_u2(ostream& o, unsigned long l)
{
- return ((s&0xFF)<<8)|(s>>8);
+ o << (unsigned char)(0xff & (l))
+ << (unsigned char)(0xff & (l >> 8));
}
- //! Returns the byte reversal of a long.
- inline unsigned long rev(unsigned long w)
+ inline unsigned long read_u4(istream& i)
{
- return
((w&0xFF000000)>>24)|((w&0xFF0000)>>8)|((w&0xFF00)<<8)|((w&0xFF)<<24);
+ //Data is little endian:
+ unsigned long r = i.get() | (i.get() << 8) | (i.get() << 16) |
(i.get() << 12);
+ if(i.eof())
+ throw(Exceptions::Image_IO::MalformedImage("EOF in
header."));
+
+ return r;
}
- void correctByteOrder(BMPHeader& header)
+ inline unsigned long read_u2(istream& i)
+ {
+ //Data is little endian:
+ unsigned long r = i.get() | (i.get() << 8);
+ if(i.eof())
+ throw(Exceptions::Image_IO::MalformedImage("EOF in
header."));
+
+ return r;
+ }
+
+ BMPHeader read_header(istream& i)
+ {
+ //Read the header
+ BMPHeader h;
+ h.size = read_u4(i);
+ h.reserved[0] = read_u2(i);
+ h.reserved[1] = read_u2(i);
+ h.dataOffset = read_u4(i);
+
+ //Read the info block
+ h.infoSize = read_u4(i);
+
+ if(h.infoSize != 40)
+ {
+
+ string type;
+
+ switch(h.infoSize)
{
- if (!isBigEndian())
- return;
- header.size = rev(header.size);
- header.dataOffset = rev(header.dataOffset);
- header.infoSize = rev(header.infoSize);
- header.width = rev(header.width);
- header.height = rev(header.height);
- header.planes_bpp[0] = rev(header.planes_bpp[0]);
- header.planes_bpp[1] = rev(header.planes_bpp[1]);
- header.compression = rev(header.compression);
- header.dataSize = rev(header.dataSize);
- header.xPelsPerMeter = rev(header.xPelsPerMeter);
- header.yPelsPerMeter = rev(header.yPelsPerMeter);
- header.colors = rev(header.colors);
- header.importantColors = rev(header.importantColors);
+ case 40:
+ type = "Windows 3.x style bitmap
unsupported.";
+ break;
+ case 12:
+ type = "OS/2 1.x style bitmap
unsupported.";
+ break;
+ case 64:
+ type = "OS/2 2.x style bitmap
unsupported.";
+ break;
+ case 108:
+ type = "Windows V4 (95/NT) style bitmap
unsupported.";
+ break;
+ case 124:
+ type = "Windows V5 (98/2000) style
bitmap unsupported.";
+ break;
+ default:
+ {
+ ostringstream ts;
+ ts << "unknown bitmap type (info size =
" << h.infoSize << ")";
+ type = ts.str();
+ }
+ }
+
+
throw(Exceptions::Image_IO::UnsupportedImageSubType("Windows BMP/DIB", type));
}
+ h.width = read_u4(i);
+ h.height = read_u4(i);
+ h.planes = read_u2(i);
+ h.bpp = read_u2(i);
+ h.compression = read_u4(i);
+ h.dataSize = read_u4(i);
+ h.xPelsPerMeter = read_u4(i);
+ h.yPelsPerMeter = read_u4(i);
+ h.colors = read_u4(i);
+ h.importantColors = read_u4(i);
+
+ return h;
+ }
+
void writeBMPHeader(unsigned int width, unsigned int height, unsigned int
channels, ostream& out)
{
unsigned int rowSize = channels*width;
if (rowSize%4)
rowSize += 4-(rowSize%4);
- out.write("BM",2);
- struct BMPHeader header;
- memset(&header,0,sizeof(header));
- header.dataOffset=2+sizeof(header) + (channels == 1 ? 1024 : 0);
- header.dataSize=rowSize*height;
- header.size=header.dataOffset+header.dataSize;
- header.width = width;
- header.height = height;
- header.compression = 0;
- header.planes_bpp[0] = 1;
- header.planes_bpp[1] = channels*8;
- header.infoSize=40;
- correctByteOrder(header);
- out.write((const char*)&header,sizeof(header));
- if (channels == 1) {
- unsigned long val = 0;
- unsigned long step = 0x01010101;
- for (unsigned int i=0; i<256;i++, val+=step)
- out.write((const char*)&val, 4);
+
+ unsigned long dataSize = rowSize * height;
+ unsigned long offset = 14 + 40 + (channels == 1 ? 1024 : 0);
+
+ //Output header
+ /* 0 */ out << "BM";
+ /* 2 */ write_u4(out, offset + dataSize); //File size
+ /* 6 */ write_u2(out, 0); //Reserved
+ /* 8 */ write_u2(out, 0); //Reserved
+ /* 10 */ write_u4(out, offset); //Data offset
+
+ //Output info
+ /* 14 */ write_u4(out, 40); //3.x style header size
+ /* 18 */ write_u4(out, width);
+ /* 22 */ write_u4(out, height);
+ /* 26 */ write_u2(out, 1); //Planes (always 1);
+ /* 28 */ write_u2(out, channels*8); //Bpp
+ /* 30 */ write_u4(out, 0); //Compression method
+ /* 34 */ write_u4(out, dataSize);
+ /* 38 */ write_u4(out, 0); //Pixels per meter (x)
+ /* 42 */ write_u4(out, 0); //Pixels per meter (y)
+ /* 46 */ write_u4(out, 0); //Number of colours (0 == 2^N)
+ /* 50 */ write_u4(out, 0); //Number of important colora
+
+ //Write the palette
+ if (channels == 1)
+ {
+ for (unsigned int i=0; i<256;i++)
+ {
+ write_u1(out, i); //Blue
+ write_u1(out, i); //Green
+ write_u1(out, i); //Red
+ write_u1(out, 0); //Reserved
+ }
}
}
@@ -119,15 +196,21 @@
in.read(tag,2);
if (strcmp(tag, "BM") != 0)
throw CVD::Exceptions::Image_IO::MalformedImage("BMP files must start
with 'BM'");
- struct BMPHeader header;
- in.read((char*)&header, sizeof(header));
- correctByteOrder(header);
- channels = (unsigned int)header.planes_bpp[1]/8;
+ struct BMPHeader header = read_header(in);
+
+ if(header.bpp == 8)
+ channels = 1;
+ else if(header.bpp == 24)
+ channels = 3;
+ else
+
throw(Exceptions::Image_IO::UnsupportedImageSubType("Windows BMP/DIB", "image
is not 8 or 24 bits per pixel."));
+
compression = header.compression;
+ if(compression != 0)
+
throw(Exceptions::Image_IO::UnsupportedImageSubType("Windows BMP/DIB",
"compressed images not supported."));
+
width = header.width;
height = header.height;
}
-
-
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libcvd-members] libcvd cvd/internal/io/bmp.h pnm_src/bmp.cxx,
Edward Rosten <=