Validation of byte through array of bits of an image

3

I'm trying to validate an incoming image in an FTP folder. The images begin with the "FFD8" bytes and end with the "FFD9" sequence so that you can perform the scan.

I'm getting the image in a BufferedImage and converting it to an array of bytes, however, when accessing the initial positions of this array never match the value of FFD8, I get values like 001F 0019. I performed the verification of these same files in editors as sublimetext and some hexdumps and in them the start and end bytes correspond with the correct value "FFD8" (Initial) and "FFD9" (Final). In this small snippet of code I'm concatenating everything in StringBuilder . What could I be doing wrong?

void startProcessBloco(){
    int qtdBloco = 0;
    File fList[] = diretorio.listFiles();
     for ( int i = 0; i < fList.length; i++ ){
         //Validação verificando se o vetor não é nulo
         if(fList.length > i + 3){
             if(fList[i].getName().contains("_1") && fList[i+3].getName().contains("_4")){

                 try {
                        File imagemFisica = new File(dir+fList[i].getName());
                        BufferedImage imagemEmBuffer = ImageIO.read(imagemFisica);
                        byte[] imagemEmBytes = bloco.extractBytes(imagemEmBuffer);
                        bloco.getImagens().add(imagemEmBuffer);

                        StringBuilder sb = new StringBuilder();
                        for (byte b : imagemEmBytes) {
                            sb.append(String.format("%04X ", b));
                        }
                        System.out.println(sb.toString());

                        ImageIO.write(imagemEmBuffer, "jpg",
                                new File("D:\testesBlocoFtp\recebeImg\" + fList[i].getName()));

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
             }
         }
     }
     System.out.println(qtdBloco);
}
    
asked by anonymous 29.06.2015 / 22:17

2 answers

0

I solved my problem by using the following libraries:

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;

With commons.io.IOUtils the InputStream transformation, which was received in the previous code through an object of the File class, has become much easier:

byte[] imagemEmBytes = IOUtils.toByteArray(imagemFisica);

And with commons.codec.binary.Hex, the transformation of the byte array into a string in Hex returned the correct value in a string with the hex code of the image. Then you just perform the validation:

if (Hex.encodeHexString(imagemEmBytes).startsWith("ffd8") &&
    Hex.encodeHexString(imagemEmBytes).endsWith("ffd9")) {
    //Minha imagem foi validada, faço oque quiser com ela aqui.
}
    
01.07.2015 / 14:10
2

In your code there is this:

if(fList[i].getName().contains("_1") && fList[i+3].getName().contains("_4")){

This fList[i] and this fList[i+3] tell me that you expect the elements in the array to be in a certain order. However in the Javadocs of the listFiles () method is written :

  

There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

That translating into Portuguese is:

  

There is no guarantee that strings with names in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

In addition, bytes in Java range from -128 to 127, unlike most would expect from 0 to 255. And you're using this:

String.format("%04X ", b)

Let's see what this prints with a few bytes:

System.out.println(String.format("%04X ", (byte) -128));
System.out.println(String.format("%04X ", (byte) -127));
System.out.println(String.format("%04X ", (byte) -40));
System.out.println(String.format("%04X ", (byte) -39));
System.out.println(String.format("%04X ", (byte) -2));
System.out.println(String.format("%04X ", (byte) -1));
System.out.println(String.format("%04X ", (byte) 0));
System.out.println(String.format("%04X ", (byte) 1));
System.out.println(String.format("%04X ", (byte) 31));
System.out.println(String.format("%04X ", (byte) 25));
System.out.println(String.format("%04X ", (byte) 126));
System.out.println(String.format("%04X ", (byte) 127));
System.out.println(String.format("%04X ", (byte) 128));
System.out.println(String.format("%04X ", (byte) 129));
System.out.println(String.format("%04X ", (byte) 216));
System.out.println(String.format("%04X ", (byte) 217));
System.out.println(String.format("%04X ", (byte) 254));
System.out.println(String.format("%04X ", (byte) 255));

Here's the output:

0080 
0081 
00D8 
00D9 
00FE 
00FF 
0000 
0001 
001F 
0019 
007E 
007F 
0080 
0081 
00D8 
00D9 
00FE 
00FF 

Well, using "%04X " , you ALWAYS see the first two digits being zeros. Maybe "%02 " makes more sense. The% with% corresponds to 31,% with% corresponds to 25.% with% corresponds to -40 (or 216) and% with% corresponds to -39 (or 217). Note the following:

System.out.println(String.format("%04X ", (short) -40));
System.out.println(String.format("%04X ", (short) -39));

Here's the output:

FFD8
FFD9

The same values are -40 and -39, but represented as 001F instead of 0019 .

I know this does not solve your problem yet, but it should help you.

    
29.06.2015 / 22:55