TGA图像头文件拾取的字节对齐及#pragma pack的使用
来源:互联网 发布:网络理财哪里做得好 编辑:程序博客网 时间:2024/06/07 12:19
在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。
在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储(成员之间可能有插入的空字节),第一个成员的地址和整个结构的地址相同。
例1:
struct Test{ char x1; // 成员x1为char型(其起始地址必须1字节对界),其偏移地址为0 char x2; // 成员x2为char型(其起始地址必须1字节对界,其偏移地址为1 float x3; // 成员x3为float型(其起始地址必须4字节对界),编译器在x2和x3之间填充了两个空字节,其偏移地址为4 char x4; // 成员x4为char型(其起始地址必须1字节对界),其偏移地址为8 };
在学习OpenGL蓝宝书的例子中,由于漏掉了gltLoadTGA函数头文件中#pragma pack的定义,导致图像数据头参数错误,OpenGL不能正常显示。
改变缺省的对界条件(指定对界)
· 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
· 使用伪指令#pragma pack (),取消自定义字节对齐方式。
#pragma pack(1)typedef struct{GLbyteidentsize; // Size of ID field that follows header (0)GLbytecolorMapType; // 0 = None, 1 = palettedGLbyteimageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rleunsigned shortcolorMapStart; // First colour map entryunsigned shortcolorMapLength; // Number of colorsunsigned char colorMapBits; // bits per palette entryunsigned shortxstart; // image x originunsigned shortystart; // image y originunsigned shortwidth; // width in pixelsunsigned shortheight; // height in pixelsGLbytebits; // bits per pixel (8 16, 24, 32)GLbytedescriptor; // image descriptor} TGAHEADER;#pragma pack()
GLubyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat){FILE *pFile;// File pointerTGAHEADER tgaHeader;// TGA file headerunsigned long lImageSize;// Size in bytes of imageshort sDepth;// Pixel depth;GLubyte*pBits = NULL; // Pointer to bits// Default/Failed values*iWidth = 0;*iHeight = 0;*eFormat = GL_BGR_EXT;*iComponents = GL_RGB8;// Attempt to open the filfopen_s(&pFile,szFileName, "rb");if (pFile == NULL)return NULL;// Read in header (binary)fread(&tgaHeader, sizeof(TGAHEADER), 1, pFile);// Do byte swap for big vs little endian#ifdef __APPLE__LITTLE_ENDIAN_WORD(&tgaHeader.colorMapStart);LITTLE_ENDIAN_WORD(&tgaHeader.colorMapLength);LITTLE_ENDIAN_WORD(&tgaHeader.xstart);LITTLE_ENDIAN_WORD(&tgaHeader.ystart);LITTLE_ENDIAN_WORD(&tgaHeader.width);LITTLE_ENDIAN_WORD(&tgaHeader.height);#endif// Get width, height, and depth of texture*iWidth = tgaHeader.width;*iHeight = tgaHeader.height;sDepth = tgaHeader.bits / 8;// Put some validity checks here. Very simply, I only understand// or care about 8, 24, or 32 bit targa's.if (tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32)return NULL;// Calculate size of image bufferlImageSize = tgaHeader.width * tgaHeader.height * sDepth;// Allocate memory and check for successpBits = (GLubyte*)malloc(lImageSize * sizeof(GLubyte));if (pBits == NULL)return NULL;// Read in the bits// Check for read error. This should catch RLE or other // weird formats that I don't want to recognizeif (fread(pBits, lImageSize, 1, pFile) != 1){free(pBits);return NULL;}// Set OpenGL format expectedswitch (sDepth){case 3: // Most likely case*eFormat = GL_BGR_EXT;*iComponents = GL_RGB8;break;case 4:*eFormat = GL_BGRA_EXT;*iComponents = GL_RGBA8;break;case 1:*eFormat = GL_LUMINANCE;*iComponents = GL_LUMINANCE8;break;};// Done with Filefclose(pFile);// Return pointer to image datareturn pBits;}
#pragma pack未定义导致TGAHEADER的读数错误
-tgaHeader{identsize=0 '\0' colorMapType=0 '\0' imageType=2 '\x2' ...}TGAHEADERidentsize0 '\0'charcolorMapType0 '\0'charimageType2 '\x2'charcolorMapStart0unsigned short //双字节对齐边界. 其偏移地址为4。第四个字节被舍弃colorMapLength0unsigned shortcolorMapBits0 '\0'unsigned charxstart0unsigned shortystart1024unsigned shortwidth1024unsigned shortheight24unsigned shortbits-116 '?'chardescriptor117 'u'char
body.tga中18个字节的文件头
00 00 02 00 00 00 00 00 00 00 00 00 00 04 00 04 18 00
0 0
- TGA图像头文件拾取的字节对齐及#pragma pack的使用
- C语言的字节对齐及#pragma pack的使用
- C语言的字节对齐及#pragma pack的使用
- C语言的字节对齐及#pragma pack的使用
- C语言的字节对齐及#pragma pack的使用
- C语言的字节对齐及#pragma pack的使用
- 内存对齐及#pragma pack的使用
- C语言的字节对齐以及#pragma pack的使用
- 关于pragma pack的用法 字节对齐
- #pragma pack(4) 对齐的使用
- 字节对齐 #pragma pack
- #pragma pack字节对齐
- pragma pack,字节对齐
- 字节对齐#pragma pack
- 字节对齐 pragma pack
- pragma pack(非常有用的字节对齐用法说明)
- pragma pack(非常有用的字节对齐用法说明)
- pragma pack(非常有用的字节对齐用法说明)
- matlab的eigs函数使用小tips
- scala List集合的用法
- 苹果MAC系统更换新硬盘 联网重装 地球一直转 速度过慢 apple.com/support -2002F问题解决办法
- 时间管理-总结
- BZOJ 1415: [Noi2005]聪聪和可可 概率DP,记忆化搜索,BFS
- TGA图像头文件拾取的字节对齐及#pragma pack的使用
- JS中匀速运动的基本框架
- 思维题-POJ1852-挑战程序设计2
- JSP内置对象
- strlen
- mysql导入文件报错,failed to open file 'file_name'
- 谈一谈软件开发过程中的优化心得
- 字符串面试指南
- 并查集