C++ 从cpp中的mysql blob解析BMP文件

C++ 从cpp中的mysql blob解析BMP文件,c++,mysql,c,linux,bitmap,C++,Mysql,C,Linux,Bitmap,我需要从bmp中获取宽度和高度值,以便在稍后从位图中的原始像素数据创建gdk pixmap时可以将其作为参数传递。 我对BMP格式做了一些研究,文件头应该是这样的: struct Fileheader { unsigned short Type; // signature - 'BM' unsigned long Size; // file size in bytes unsigned short Reserved1; //

我需要从bmp中获取宽度和高度值,以便在稍后从位图中的原始像素数据创建gdk pixmap时可以将其作为参数传递。 我对BMP格式做了一些研究,文件头应该是这样的:

struct Fileheader
{
    unsigned short Type;          // signature - 'BM'
    unsigned  long Size;          // file size in bytes
    unsigned short Reserved1;     // 0
    unsigned short Reserved2;     // 0
    unsigned long  OffBits;       // offset to bitmap
    unsigned long  StructSize;    // size of this struct (40)
    unsigned long  Width;         // bmap width in pixels
    unsigned long  Height;        // bmap height in pixels
    unsigned short Planes;        // num planes - always 1
    unsigned short BitCount;      // bits per pixel
    unsigned long  Compression;   // compression flag
    unsigned long  SizeImage;     // image size in bytes
    long           XPelsPerMeter; // horz resolution
    long           YPelsPerMeter; // vert resolution
    unsigned long  ClrUsed;       // 0 -> color table size
    unsigned long  ClrImportant;  // important color count
    Fileheader()
    {
        Size=Width=Height=Planes=BitCount=Compression=SizeImage=XPelsPerMeter= YPelsPerMeter=ClrUsed=ClrImportant=Type=StructSize=Reserved1=Reserved2=OffBits=0;}
    };
}
以标准方式将blob提取到第[0]行后

Fileheader fh;
memcpy(&fh, row[0], sizeof(Fileheader));

cout << "width: " << fh.Width << ", height: " << fh.Height << endl;

cout此结构中的
无符号长
值应仅为32位。给定显示的
高度值
,您读取的数据远不止此。

如果您要以这种方式解析数据(不鼓励这样做),至少:

  • 使用正确的、与平台无关的类型
    uint16\u t
    代替
    unsigned short
    uint32\u t
    代替
    unsigned long
  • 制作你的结构
它不会在任何地方都工作,但至少应该在
x86
x86\u 64
上工作

不鼓励使用它,主要是因为它依赖于平台和编译器:

  • \uuuuuuuuuu属性((打包))
    是gcc扩展。其他编译器可能会以不同的方式处理它
  • 在某些平台上,不可能将结构紧密打包。在其他情况下,它们的工作速度会慢一点
  • 它只能在小端机器上工作

gcc 64位上的long类型为64位长,但原始结构使用long,在Windows上定义为32位整数:

#pragma pack(push,1)
typedef struct tagBITMAPINFOHEADER {
  DWORD biSize; // use uint32_t instead
  LONG  biWidth;  // use int32_t instead
  LONG  biHeight; // use int32_t instead
  WORD  biPlanes;  // use uint16_t instead
  WORD  biBitCount;  // use uint16_t instead
  DWORD biCompression;  // use uint32_t instead
  DWORD biSizeImage;  // use uint32_t instead
  LONG  biXPelsPerMeter;  // use int32_t instead
  LONG  biYPelsPerMeter;  // use int32_t instead
  DWORD biClrUsed;  // use uint32_t instead
  DWORD biClrImportant;  // use uint32_t instead
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
#pragma pack(pop)
另外,注意负高度值:这标识第一个扫描行位于图像顶部的图像(必须获得高度的labs() 正高度值标识第一个扫描行位于图像底部的图像