简体   繁体   中英

Reading 4 bytes at a time from binary in C++

I'm trying to read 4 bytes at a time from a binary file. The file was converted to .bin from an image that is 512x512.

The structure of the file has the first 4 bytes the height and the second 4 bytes the width. Then the rest of the file is associated with values for the rest of the pixels.

This is the code I did for conversion in case someone needs it:

package main;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author FFA
 */
public class Main {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args){
        JFileChooser chooser = new JFileChooser();
        FileFilter filter = new FileNameExtensionFilter("Image File", ImageIO.getReaderFileSuffixes());
        chooser.setFileFilter(filter);
        chooser.showOpenDialog(null);
        File file = chooser.getSelectedFile();

        if(file == null) System.exit(0);
        File dest = new File(file.getParent(), file.getName().split("\\.")[0] + ".bin");
        dest.delete();
        try(FileOutputStream out = new FileOutputStream(dest, true)){
            BufferedImage image = ImageIO.read(file);
            int width = image.getWidth();
            int height = image.getHeight();
            byte[] data = new byte[width*height];
            int k = 0;

            byte[] widthData = ByteBuffer.allocate(4).putInt(width).array();
            byte[] heightData = ByteBuffer.allocate(4).putInt(height).array();
            out.write(widthData);
            out.write(heightData);

            for(int i=0; i<height;i++){
                for(int j=0; j<width; j++){
                    Color c = new Color(image.getRGB(j, i));

                    int grayValue = (int)Math.round(0.21*c.getRed() + 0.72*c.getGreen() + 0.07*c.getBlue());
                    data[k++] = (byte) grayValue;
                }
            }

            out.write(data);
            JOptionPane.showMessageDialog(null, "Conversion Done");
        }catch(IOException ex){
            JOptionPane.showMessageDialog(null, "Exception: "+ex);
        }
    }

}

The test image is grey Lena 512x512 so only grey-levels.

The whole plan was to convert from image to binary->read it in C++, do some operations, write it in binary and then convert it back to image.

How can I read the binary in C++ and then do operations like convolution in C++?

My plan goes something like this in pseudo-code:

read in 4 bytes
convert to local endian integer representation
assign to width
read in 4 bytes
convert to local endian integer representation
assign to height
for (row = 0; row < height; row++)
{
    add new row vector
    for (col = 0; col < width; col++)
    {
        read byte
        add to current row vector
    }
}

But I have some issues in translating it into C++. Can anyone give me a hand or some hints? Thanks!

Edit:

#include <iostream>
#include <fstream>

int main() {

    FILE *fileptr;
    char *buffer;
    long filelen;

    fileptr = fopen("file.bin", "rb");  
    fseek(fileptr, 0, SEEK_END);          
    filelen = ftell(fileptr);             
    rewind(fileptr);                      

    buffer = (char *)malloc((filelen + 1) * sizeof(char)); 
    fread(buffer, filelen, 1, fileptr); 
    fclose(fileptr);

    system("Pause");
}

I think this should be the code for reading every byte. For reading first 4 bytes I need to read from 1 to filelen/128?

you can use fopen with open flags "r+b" or _open on Windows, or Linux has the open function.

You will also need to use fread, fwrite and fclose with fopen, _read, _write and _close for Windows alternative, or read, write and close for Linux version.

You could also write your own interface class if you want to make it portable.

This can be detected using #ifdef _MSC_VER or #ifdef GNUC for Linux gcc, although this is a simplistic approach to making your solution portable.

You can also look at std::fstream if you wish to use the standard C++ file I/O library, which will give you portability for free.

They all have their pros and cons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM