使用fwrite()写入某些字节时出错

时间:2014-07-03 01:48:33

标签: c file-io io

自最初发布以来,某些事情已发生变化。我已使用修改标题对其进行了标记。

我正在使用不同格式的来源编写图像文件。这是1024x1024的数据,每像素有2个字节。

源图像格式和目标图像格式都包含可变字节数的标头(包含元数据,例如每像素的字节数等),然后是图像数据。

不知道是否相关,但我们使用40岁以上的软件(称为Mcidas)来显示这些图像 以前,我将两个字节都读入unsigned short数组。然后一些操作将它们连接到一个新的unsigned short。然后我使用fwrite()函数将它们写入目标文件。

修改
我现在直接在fread()上使用data

读取操作运行良好(同时尝试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"测试它。

下面是源图像和最终图像的比较,并在第一行进行了线扫描。

Source file and Image http://i60.tinypic.com/11j24cy.png

请注意某些像素的突然跳跃,这会产生轮廓。这些似乎长度约为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);
}
}

编辑

  1. 添加了fopen()语句并在fflush()删除时进行了测试,错误仍然存​​在。

  2. 添加了unsigned short data

  3. 的声明
  4. 代码现在应该运行。

  5. 修改

    2字节图像的问题解决了! 我所做的就是切换备用字节。查看更正后的代码。 我不知道为什么它有效。这是一个字节序问题吗?请注意,位移不起作用。

    我现在遇到类似的四字节图像问题。数据存储为浮点数。我将fread()个字节放入浮点数,对其进行缩放并将其转换为整数。结果同样是颗粒状的。使用位移来置换字节并不能解决问题。

    有人可以对此有所了解吗?

1 个答案:

答案 0 :(得分:0)

小问题:

请勿使用feof(fp),而是使用:

while (1) {
  ...
  int ch = fgetc(fp);
  if (ch == EOF) break;
  data_arr[0] = ch;
  ch = fgetc(fp);
  if (ch == EOF) break;
  data_arr[1] = ch; 

更大的问题: 我怀疑您的输入文件,但打开时“rb”在您阅读时会发生变化。也许你没有独家锁定。