c++ tga解析某些分辨率的incorrect_color/distortion
c++ tga parsing incorrect_color/distortion with some resolutions
我想得到一些帮助我的问题与。tga文件格式解析。我有代码,我用了很长时间:
int fileLength = Input.tellg();
vector<char> tempData;
tempData.resize(fileLength);
Input.seekg(0);
Input.read(&tempData[0], fileLength);
Input.close();
// Load information about the tga, aka the header.
// Seek to the width.
w = byteToUnsignedShort(tempData[12], tempData[13]);
// Seek to the height.
h = byteToUnsignedShort(tempData[14], tempData[15]);
// Seek to the depth.
depth = unsigned(tempData[16]);
// Mode = components per pixel.
md = depth / 8;
// Total bytes = h * w * md.
t = h * w * md;
//Delete allocated data, if need to
clear();
//Allocate new storage
data.resize(t);
// Copy image data.
for(unsigned i = 0, s = 18; s < t + 18; s++, i++)
data[i] = unsigned char(tempData[s]);
// Mode 3 = RGB, Mode 4 = RGBA
// TGA stores RGB(A) as BGR(A) so
// we need to swap red and blue.
if(md > 2)
{
char aux;
for(unsigned i = 0; i < t; i+= md)
{
aux = data[i];
data[i] = data[i + 2];
data[i + 2] = aux;
}
}
但是对于某些图像分辨率(主要是奇数和非pot分辨率),它偶尔会失败。它导致扭曲的图像(与对角线图案)或错误的颜色。上次我遇到它-它是9x924bpp的图像显示奇怪的颜色。
我在windows上(所以它意味着小端),用opengl渲染(我考虑到alpha通道存在,当用glTexImage2D传递图像数据时)。我用photoshop保存我的图像,而不是设置RLE标志。此代码总是读取正确的图像分辨率和颜色深度。
图片引起麻烦的例子:http://pastie.org/private/p81wbh5sb6coldspln6mw
加载有问题的图像后,此代码:
for(unsigned f = 0; f < imageData.w * imageData.h * imageData.depth; f += imageData.depth)
{
if(f % (imageData.w * imageData.depth) == 0)
writeLog << endl;
writeLog << "[" << unsigned(imageData.data[f]) << "," << unsigned(imageData.data[f + 1]) << "," << unsigned(imageData.data[f + 2]) << "]" << flush;
}
输出:
[37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40]
[37,40,40][173,166,164][93,90,88][93,90,88][93,90,88][93,90,88][93,90,88][88,85,83][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][237,232,230][235,229,228][235,229,228][235,229,228][235,229,228][235,229,228][223,214,212][37,40,40]
[37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40]
所以我猜它确实读取正确的数据。这就引出了opengl;
glGenTextures(1, &textureObject);
glBindTexture(GL_TEXTURE_2D, textureObject);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GLenum in_comp_mode, comp_mode;
if(linear) //false for that image
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//i don't use 1 or 2 - channel textures, so it's always 24 or 32bpp
if(imageData.depth == 24)
{
in_tex_mode = GL_RGB8;
tex_mode = GL_RGB;
}
else
{
in_tex_mode = GL_RGBA8;
tex_mode = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, in_tex_mode, imageData.w, imageData.h, 0, tex_mode, GL_UNSIGNED_BYTE, &imageData.data[0]);
glBindTexture(GL_TEXTURE_2D, NULL);
纹理压缩代码被省略了,因为它对那个纹理来说不是活动的。
这可能是一个填充/对齐问题。
你正在加载一个TGA,它没有行填充,但将它传递给GL,它默认情况下期望像素行填充为4字节的倍数。
可能的修复:
- 告诉GL你的纹理是如何打包的,使用(例如)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- 改变纹理的尺寸,这样就不会有填充。
- 改变纹理的加载,使填充与GL期望的一致
大多数图像格式保存图像数据对齐(一般为4字节)。例如,分辨率:1行1列每行有一个像素,所以如果使用RGB,每行有3个字节。并将扩展到4字节,因为CPU喜欢这样。
英语不是我的母语,所以我糟糕的语法会要了你的命。试着去理解它相关文章:
- 在 Cocos2dx 中初始化粒子效果后的警告 - "libpng warning: iCCP: known incorrect sRGB profile"
- 给一个图 G 找到此图中的所有节点 blob,以便 node.color 属性 = 特定颜色
- 不存在从"Magick::Color"到"MagickCore::Quantum"的合适转换功能
- vim使用户定义类型的COLOR与C++中的基本类型相同
- "Color Game" - 从数组 C++ 调用随机
- 为什么"cout << Color::green"不编译?
- VSCode 错误: "incorrect use of va_start"
- 系统调用失败"Incorrect Section Name -e" C++
- :void setData(const Color * & data_ptr)中的 *& 是什么意思;
- 为什么系统("color 3")"global"?
- GetTimeZoneInformation 函数返回具有"incorrect"值的结构
- MsiViewFetch "SELECT * FROM `Property`"成功,但返回"Incorrect function." C++
- C# DLL 导入失败:"The application has failed to start because its side-by-side configuration is incorrect
- DirectX Color:为什么它不能是浮点数?
- 是否有可以在控制台中设置颜色的 WinAPI 调用,如'color xx'命令?
- Color Blind是一个c++程序
- C++ 从二进制文件中读回"incorrect"值?
- Is fmod incorrect?
- C++输出到Windows终端使用cout<<term_cc<color,default,attrib>在Windows上正确输出颜色和属性,但在Linux上不能
- create an RBG Color QImage from a GDALDataSet