Open jpg image under Ubuntu prompt Error interpreting JPEG image file (Not a JPEG file: starts with 0x89 0x50)

created at 11-12-2021 views: 68

problem

The java background received a picture in jpg format and found that it can be opened and displayed normally under windows, but it prompts Error interpreting JPEG image file (Not a JPEG file: starts with 0x89 0x50) when it is opened under Ubuntu. As shown below:

error

It is suggested that the file is not a JPEG image file, and the first two bytes of the file are 0x89 and 0x50 respectively.

Solution
According to Wikipedia List_of_file_signatures, the file signature at the beginning of these two bytes should be in the png file format. Modify the file suffix name to png, and then open the file to display it normally.

List_of_file_signatures

For this reason, the logic of judging the file signature is added to the back-end interface to prevent the suffix submitted by the front-end from not being the real format of the file (not limited to pictures).

For malicious files that deliberately forge the file header information, the following logic cannot play a role in screening.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class filetools
{
    public final static Map<String, String> FILE_TYPE_MAP = new HashMap<String, String>();

    static
    {
        getAllFileType();
    }

    private static void getAllFileType()
    {
        FILE_TYPE_MAP.put("jpg(JFIF)", "^FFD8FFE000104A4649460001"); // jpg JFIF file format
        FILE_TYPE_MAP.put("jpg(Exif)", "^FFD8FFE1.{4}457869660000"); // jpg Exif file format
        FILE_TYPE_MAP.put("jpeg", "^FFD8FFEE"); // jpeg
        FILE_TYPE_MAP.put("png", "^89504E470D0A1A0A"); // PNG (png)
        FILE_TYPE_MAP.put("bmp", "^424D"); // Windows Bitmap (bmp)
        FILE_TYPE_MAP.put("mp4", "^000000206674797069736F6D"); // ISO Base Media file (MPEG-4)
    }

    public final static String getFileByFile(File file)
    {
        String filetyp = null;
        byte[] fileheader = new byte[15]; // Only read the first 15 bytes, and judge according to the actual need to read certain bytes
        try
        {
            InputStream is = new FileInputStream(file);
            is.read(fileheader);
            filetyp = getFileTypeByStream(fileheader);
            is.close();
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return filetyp;
    }

    public final static String getFileTypeByStream(byte[] b)
    {
        String filetypeHex = String.valueOf(getFileHexString(b));
        Iterator<Entry<String, String>> entryiterator = FILE_TYPE_MAP.entrySet().iterator();
        while (entryiterator.hasNext())
        {
            Entry<String, String> entry = entryiterator.next();
            String fileTypeHexValue = entry.getValue();
            Pattern p = Pattern.compile(fileTypeHexValue);
            Matcher m = p.matcher(filetypeHex.toUpperCase());

            if (m.find()) // Only judge whether the match is successful
    {
    if (0 == m.start()) // Determine whether the beginning of the match
    return entry.getKey();
    }
        }
        return "unknow type";
    }

    public final static String getFileHexString(byte[] b)
    {
        StringBuilder stringBuilder = new StringBuilder();
        if (b == null || b.length <= 0)
        {
            return null;
        }
        for (int i = 0; i < b.length; i++)
        {
            int v = b[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2)
            {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args)
    {
        File f = new File("/home/alderaan/111.jpg");
        if (f.exists())
        {
            String filetype = getFileByFile(f);
            System.out.println(filetype);
        } else
        {
            System.out.println(f.getPath() + " not found!");
        }
    }
}
created at:11-12-2021
edited at: 11-12-2021: