Para saber si es una imagen o lo que, o miras el mime type (primeros bytes binarios del archivo) que siempre debería ser los mismos o intentas visualizar el formato dando por echo de antemano que es una imagen.
https://github.com/StringManolo/JEX/blob/master/jexLastVersion.html#L194Aquí hice un listado de los bytes binarios. Está en hexadecimal porque ocupa menos y se reconocen mejor.
El código que te pasé es un string de cabeceras separadas por coma. Al final del string le aplico el método toUpperCase() para pasarlo a mayúsculas
Más alante hago split por las comas de tal forma que obtengo un array con 156 elementos que contienen 156 cadenas hexadecimales.
En la línea 216
https://github.com/StringManolo/JEX/blob/master/jexLastVersion.html#L216 tienes lo mismo pero esta vez son las extensiones/nombre de formatos de los archivos.
En la línea 235
https://github.com/StringManolo/JEX/blob/master/jexLastVersion.html#L235hay una llamada a
CompareMagicN(header, magicN[k])
donde se compara en un bucle cada elemento del array de números mágicos con la cabecera del archivo.
Si CompareMagicN encuentra una coincidencia de numeros mágicos se obtiene la extensión equivalente con var tipoDelArchivo = typeN[k];
Tienes la función definida en la línea 185
https://github.com/StringManolo/JEX/blob/master/jexLastVersion.html#L185 Solo es comparar los caracteres de la header con los caracteres de cada elemento de typeN
Por último, definí la función para leer el archivo en la línea 98
https://github.com/StringManolo/JEX/blob/master/jexLastVersion.html#L98IMPORTANTE: Tu deberías leer solo los 32 primeros caracteres en hexadecimal, no tiene sentido leer todo el archivo para determinar el tipo a menos que programes un binwalk o algo por el estilo.
Si solo vas a trabajar con imágenes, puedes usar el canvas para leer los magic number, va a ser más eficiente.
CONSIDERACIONES:
Si esta comprobación es parte de una aplicación que enviará datos al backend recuerda que nunca se debe creer lo que mande el cliente.
La eficiencia del navegador es nula si trabajas con archivos muy grandes como puedan ser imágenes RAW de una cámara. En este caso tendrás que implementar lógica en el back-end ya sea para adecuar el tamaño en bytes del archivo o procesarla en el back-end. Una solución 100% navegador es programarlo en C/C++ y cross compilarlo a WebAssembler, cargar el módulo y llamar la función.
Si tu aplicación no va a ser stateless, incluir javascript inline impide que puedas utilizar normas restrictivas como CSP para hacer tu aplicación más segura. Deberías entonces mover todo el javascript y css a otros archivos.