图像写入功能未执行

Image writing function not executing

本文关键字:执行 功能 图像      更新时间:2023-10-16

我有一个在我的驱动程序中调用时不执行的函数。我通过printf语句逐行调试它,但是无论我将它们放在函数中的哪个位置,都无法使它们出现。该函数没有产生预期的结果——写入映像文件。

void WriteImage(char *filename, Image &img)
{
    printf("writingn");
    FILE *f = fopen(filename, "wb");
    if (f == NULL)
    {
        fprintf(stderr, "Can't open file %s to write.n", filename);
        return;
    }
    fprintf(f, "P6n");
    fprintf(f, "%d %dn", img.GetX(), img.GetY());
    fprintf(f, "%dn", 255);
    fwrite(img.GetData(), sizeof(PixelStruct), img.GetX() * img.GetY(), f);
    fclose(f);
}

这是从一个有效的C函数中提取的代码,我知道它是有效的,所以我不知道发生了什么。什么好主意吗?

编辑:

值得注意的是,当它被自身调用且仅被自身调用时,它确实会执行。当我事先调用前面的ReadImage时,WriteImage不会执行。ReadImage:

void ReadImage(char *filename, Image &output)
{
    FILE *f = fopen(filename, "rb");
    char magicNum[128];
    int  width, height, maxval;
    if (f == 0)
    {
        fprintf(stderr, "Unable to open file %sn", filename);
        exit(0);
    }
    fscanf(f, "%sn%d %dn%dn", magicNum, &width, &height, &maxval);
    printf("Magic num = %s width = %d, height = %d, maxval = %dn",
            magicNum, width, height, maxval); 

    if (strcmp(magicNum, "P6") != 0)
    {
        fprintf(stderr, "Unable to read from file %s, because it is not a PNM file of type P6n", filename);
        exit(1);
    }
    output.ResetSize(width, height);
    PixelStruct *data = output.GetData();
    output = Image(width, height, data);
    fread(output.GetData(), sizeof(PixelStruct), width*height, f);
    fclose(f);
}

EDIT 2: Main function.

int main(int argc, char *argv[])
{
    Image img;
    ReadImage(argv[1], img);
    printf("ReadImage called.n");
    WriteImage(argv[2], img);
}

编辑3:参数化构造函数。

Image::Image(int width, int height, PixelStruct* data)
{
    this->x = width;
    this->y = height;
    this->data = data;
}

编辑4:Image.

struct PixelStruct
{
    unsigned char red;
    unsigned char green;
    unsigned char blue;
};
class Image
{
        private:
            int x;
            int y;
            PixelStruct *data;
        public:
            Image(void); /* Default constructor */
            Image(int width, int height, PixelStruct* data); /* Parameterized constructor */
            Image(Image &); /* Copy constructor */
            void ResetSize(int width, int height);
            int GetX();
            int GetY();
            PixelStruct* GetData();
            void SetData(PixelStruct *data);
};
Image::Image(void)
{
    x = 0;
    y = 0;
    data = 0;
}
Image::Image(int width, int height, PixelStruct* data)
{
    this->x = width;
    this->y = height;
    this->data = data;
}
Image::Image(Image &img)
{
    this->x = img.x;
    this->y = img.y;
    this->data = img.data;
}
void Image::ResetSize(int width, int height)
{
    this->x = width;
    this->y = height;
}
int Image::GetX()
{
    return x;
}
int Image::GetY()
{
    return y;
}
PixelStruct* Image::GetData()
{
    return data;
}

您的类在数据成员方面有许多内存管理问题。让我从你的具体问题开始吧

Image img;
ReadImage(argv[1], img);

此时img的缓冲区为0。

output.ResetSize(width, height);      // Buffer is still 0
PixelStruct *data = output.GetData(); // data is 0
output = Image(width, height, data);  // data is still zero

这里你有一个记忆问题。你没有赋值运算符。在这种特殊情况下,它没有真正的影响,但从长远来看可能会杀死你。你可能应该有一个工作

 ouput.ResetSize (width, height) ;

(如下所述),而不包含其他语句

fread(output.GetData(), sizeof(PixelStruct), width*height, f); // data is still 0

我很惊讶你没有被释放。

修复:

这些函数应该为数据分配一个缓冲区。

        Image(int width, int height, PixelStruct* data); 
        void ResetSize(int width, int height);
这个函数

        Image(Image &); /* Copy constructor */

应该复制数据(而不仅仅是赋值指针)。你需要一个赋值操作符来做同样的事情,但应该删除所有现有的数据。

你应该有一个析构函数来释放数据

这只是部分答案,因为有更好的方法来设计你的类(也取决于你是否可以使用c++11结构),但我能想到的修复程序的最短方法如下:

1。在构造函数中分配内存,并在析构函数中释放内存:

Image::Image(int width, int height)
{
    this->x = width;
    this->y = height;
    this->data = new PixelStruct[width*height];
}
Image::~Image()
{
    delete[] data;
}

2。删除默认构造函数、复制构造函数和resize方法

3。修改你的Read Image函数

Image* ReadImage(char *filename)
{
    .
            .
            .
            //read image size

    Image *output = new Image(width, height);
    fread(output->GetData(), sizeof(PixelStruct), width*height, f);
    fclose(f);
    return output;
}

4。修改main为:

int main(int argc, char *argv[])
{
    Image* img= ReadImage(argv[1]);
    printf("ReadImage called.n");
    WriteImage(argv[2], *img);
}

同样,这不是推荐的方法,但它应该使您的代码在没有太多修改和引入新概念的情况下工作。