我在从yuv文件读取一些字节时遇到问题(如果重要的话,它是1280x720),并且希望有人可以指出我做错了什么。我使用read命令和使用istream迭代器得到不同的结果。这是我正在尝试做的一些示例代码:
void readBlock(std::ifstream& yuvFile, YUVBlock& destBlock, YUVConfig& config, const unsigned int x, const unsigned int y, const bool useAligned = false)
{
//Calculate luma offset
unsigned int YOffset = (useAligned ? config.m_alignedYFileOffset : config.m_YFileOffset) +
(destBlock.yY * (useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth) + destBlock.yX);// *config.m_bitDepth;
//Copy Luma data
//yuvFile.seekg(YOffset, std::istream::beg);
for (unsigned int lumaY = 0; lumaY < destBlock.m_YHeight && ((lumaY + destBlock.yY) < config.m_YUVHeight); ++lumaY)
{
yuvFile.seekg(YOffset + ((useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth)/* * config.m_bitDepth*/) * (lumaY), std::istream::beg);
int copySize = destBlock.m_YWidth;
if (destBlock.yX + copySize > config.m_YUVWidth)
{
copySize = config.m_YUVWidth - destBlock.yX;
}
if (destBlock.yX >= 1088 && destBlock.yY >= 704)
{
char* test = new char[9];
yuvFile.read(test, 9);
delete[] test;
yuvFile.seekg(YOffset + ((useAligned ? config.m_alignedYUVWidth : config.m_YUVWidth)/* * config.m_bitDepth*/) * (lumaY));
}
std::istream_iterator<uint8_t> start = std::istream_iterator<uint8_t>(yuvFile);
std::copy_n(start, copySize, std::back_inserter(destBlock.m_yData));
}
}
struct YUVBlock
{
std::vector<uint8_t> m_yData;
std::vector<uint8_t> m_uData;
std::vector<uint8_t> m_vData;
unsigned int m_YWidth;
unsigned int m_YHeight;
unsigned int m_UWidth;
unsigned int m_UHeight;
unsigned int m_VWidth;
unsigned int m_VHeight;
unsigned int yX;
unsigned int yY;
unsigned int uX;
unsigned int uY;
unsigned int vX;
unsigned int vY;
};
此错误似乎仅在图像中的X = 1088和Y = 704处发生。我希望看到字节值为10作为我读回的第一个字节。当我使用
yuvFile.read(test, 9);
我的第一个字节是10。当我使用istream迭代器:
std::istream_iterator<uint8_t> start = std::istream_iterator<uint8_t>(yuvFile);
std::copy_n(start, copySize, std::back_inserter(destBlock.m_yData));
我读取的第一个字节是17. 17是10之后的字节,所以似乎istream迭代器跳过第一个字节。
任何帮助将不胜感激
答案 0 :(得分:2)
istream::read
和std::istream_iterator
之间存在重大差异。
std::istream::read
执行未格式化的阅读
std::istream_iterator
执行格式化读取。
来自http://en.cppreference.com/w/cpp/iterator/istream_iterator
std::istream_iterator
是一个单行输入迭代器,它通过调用相应的T
从构造它的std::basic_istream
对象中读取类型为operator>>
的连续对象。
如果您的文件是使用std::ostream::write
或fwrite
创建的,则必须使用std::istream::read
或fread
来读取数据。
如果您的文件是使用创建格式化输出的任何方法创建的,例如std::ostream::operato<<()
,fprintf
,则您有机会使用std::istream_iterator
读取数据。