使用字节数组C ++时出错

时间:2013-03-31 09:52:12

标签: c++ file-io byte

我正在尝试将标准的24位BMP文件读入字节数组,以便我可以将该字节数组发送到libpng以保存为png。我的代码编译:

#include <string>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <Windows.h>
#include "png.h"

using namespace std;

namespace BMP2PNG {
long getFileSize(FILE *file)
    {
        long lCurPos, lEndPos;
        lCurPos = ftell(file);
        fseek(file, 0, 2);
        lEndPos = ftell(file);
        fseek(file, lCurPos, 0);
        return lEndPos;
    }


private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
         {
             std::string filenamePNG = "D:\\TEST.png";
             FILE *fp = fopen(filenamePNG.c_str(), "wb");

             png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);

             png_info *info_ptr = png_create_info_struct(png_ptr);

             png_init_io(png_ptr, fp);

             png_set_IHDR(png_ptr,info_ptr,1920,1080,16,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);

             png_write_info(png_ptr,info_ptr);
             png_set_swap(png_ptr);

             const char *inputImage = "G:\\R-000.bmp";
             BYTE *fileBuf;
             BYTE *noHeaderBuf;
             FILE *inFile = NULL;

             inFile = fopen(inputImage, "rb");

             long fileSize = getFileSize(inFile);

             fileBuf = new BYTE[fileSize];
             noHeaderBuf = new BYTE[fileSize - 54];

             fread(fileBuf,fileSize,1,inFile);

             for(int i = 54; i < fileSize; i++) //gets rid of 54-byte bmp header
             {
                noHeaderBuf[i-54] = fileBuf[i];
             }

             fclose(inFile);

             png_write_rows(png_ptr, (png_bytep*)&noHeaderBuf, 1);

             png_write_end(png_ptr, NULL);

             fclose(fp);
         }
};

不幸的是,当我单击运行代码的按钮时,我收到错误“尝试读取或写入受保护的内存......”。我对C ++很新,但我以为我正在正确阅读文件。为什么会发生这种情况?如何解决?

另外,我的最终目标是一次读取一个BMP像素行,所以我不会占用太多内存。如果BMP是1920x1080,我只需要读取每行1920 x 3字节。我如何一次将文件读入n个字节的字节数组?

3 个答案:

答案 0 :(得分:0)

您的getFileSize()方法实际上并未返回文件大小。您基本上移动到BMP标头中的正确位置,但实际上没有读取表示大小的下4个字节,而是返回文件中的位置(始终为2)。 然后在调用函数中,您没有任何错误检查,并且您有代码假定文件大小始终大于54(例如,读取缓冲区的分配)。

另请注意,BMP标题中的文件大小字段可能并不总是正确的,您还应该考虑实际的文件大小。

答案 1 :(得分:0)

您正在读取* .bmp文件的文件大小,但“真实”数据可能更大。 BMP可以进行压缩(RLE)。之后,当您将解压缩的PNG写入该数组时,您可以获得图像的溢出大小,因为您预先获得了压缩BMP文件的大小。

答案 2 :(得分:0)

在功能中

png_set_IHDR(png_ptr,info_ptr,1920,1080,16,PNG_COLOR_TYPE_RGB,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);

为什么位深度设置为16?不应该是8,因为BMP的每个RGB通道都是8位。

对于PNG处理,我正在使用此库:http://lodev.org/lodepng/。它工作正常。