【发布时间】:2014-07-03 01:48:32
【问题描述】:
自从最初发布后,某些事情发生了变化。我用 Edit 标头标记了它们。
我正在从不同格式的源写入图像文件。这是 1024x1024 的数据,每个像素有 2 个字节。
源图像格式和目标图像格式都包含可变字节数的标头(包含元数据,例如每个像素的字节数等),然后是图像数据。
不知道是否相关,但我们正在使用 40 多年前的软件(称为 Mcidas)来显示这些图像
以前,我将这两个字节读入unsigned short 数组。然后一些位操作将它们连接到一个新的unsigned short。然后我使用fwrite() 函数将它们写入目标文件。
编辑
我现在直接在data 上使用fread()。
读取操作运行良好(fputc() 和 fread() 都试过)
编辑
两个文件的 hexdumps 的图像数据部分完全匹配。但是,由于某种原因,图像似乎在某些字节中显示了位错误。源文件似乎也很干净。
这是图片(2MB 文件):
http://pdsimage.wr.usgs.gov/archive/mess-e_v_h-mdis-2-edr-rawdata-v1.0/MSGRMDS_1001/DATA/2007_156/EW0089565661F.IMG
您可以将其保存为“source.IMG”进行测试。
下面是源图像和最终图像的比较,第一行进行了行扫描。
注意某些像素的突然跳跃,这会产生轮廓。这些长度似乎约为 256,这使我们怀疑某处可能存在位翻转(可能是符号位?)。但是,相同的 hexdump 另有说明。
这是错误的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
unsigned char data_arr[2];
unsigned short data;
data=0;
int pixel_per_line=1024;
char path1[80]="source.IMG";
char path[80]="destination"
fp=fopen(path1,"rb");
bin=fopen(path,"wb");
//fp points to the input file, bin to the output file.
fseek(fp,8193,SEEK_SET);//sets the pointer to the relevant byte in the source file.
//A similar fseek() is used on bin in the original program
while(!feof(fp))
{
//fflush(fp); (Removed the fflush()s now)
int j;
for(j=0;j<pixels_per_line;j++)//iterate through all pixels in one line
{
for(int i=0;i<2;i++)
data_arr[i]=fgetc(fp);
//data=(data_arr[0] << 8) | data_arr[1];// bit manipulations done in the earlier version.
//This fails to give the right output.
data=data_arr[0]*256 + data_arr[1]; // This switches alternate bytes.
if(fwrite(&data,1,sizeof(data),bin)!=2)
printf("Write pains!");
}
//fflush(bin);
}
}
编辑:
-
添加
fopen()语句并在删除fflush()的情况下进行测试,错误仍然存在。 -
添加了
unsigned short data的声明 -
代码现在应该运行了。
编辑
解决了 2 字节图像的问题! 我所做的只是切换备用字节。查看更正后的代码。 我不确定它为什么会起作用。这是字节顺序问题吗?请注意,位移不起作用。
我现在对四字节图像也有类似的问题。数据存储为浮点数。我将fread() 字节转换为浮点数,对其进行缩放并将其转换为整数。结果同样粗糙。用位移位排列字节并不能解决问题。
任何人都可以对此有所了解吗?
【问题讨论】:
-
虽然
while(!feof(fp))也不会按照您的想法行事。在fgetc()已经失败一次之前它不会返回 true。 -
与 Paul Griffiths 提到的有关:stackoverflow.com/questions/5431941/…
-
位操作的期望结果是什么?我认为问题是由
fgetc()上的符号扩展引起的。 -
@humodz
fgetc()在unsigned char和EOF的范围内返回一个int。 (例如 0-255 和 -1)。只有将值保存在比int更长的位置时,才会出现任何符号扩展问题。 -
Mihir,为了获得更好的帮助,您需要发帖 MVCE