2010-02-12 8 views
21

Me gustaría seleccionar algunos jpegs para ver su validez antes de enviarlos a través de la red para una inspección más exhaustiva. Es bastante fácil verificar si hay un encabezado y pie de página válidos, pero ¿cuál es el tamaño más pequeño (en bytes) que puede tener un jpeg válido?Cuál es el tamaño de archivo jpeg válido más pequeño (en bytes)

+3

libjpeg puede hacer pruebas rápidas, considerar el uso de ella en lugar de adivinar. – Tronic

+4

No quiero agregar ninguna biblioteca adicional a mi aplicación. Además, no es adivinar si alguien me dice la respuesta correcta :) – twk

+1

Probablemente deberías cambiar tu pregunta para "probar si algunos jpegs son probablemente válidos" a menos que vayas a hacer un montón de otras pruebas si la prueba del tamaño del archivo pasa. De lo contrario, es bastante fácil producir un archivo JPEG no válido de cualquier tamaño sobre el tamaño mínimo de un archivo JPEG válido. – jball

Respuesta

16

Un píxel 1x1 gris en 125 bytes utilizando la codificación aritmética, todavía en el estándar JPEG, aunque la mayoría de los decodificadores no puede decodificarlo:

ff d8 : SOI 
ff e0 ; APP0 
00 10 
4a 46 49 46 00 01 01 01 00 48 00 48 00 00 
ff db ; DQT 
00 43 
00 
03 02 02 02 02 02 03 02 
02 02 03 03 03 03 04 06 
04 04 04 04 04 08 06 06 
05 06 09 08 0a 0a 09 08 
09 09 0a 0c 0f 0c 0a 0b 
0e 0b 09 09 0d 11 0d 0e 
0f 10 10 11 10 0a 0c 12 
13 12 10 13 0f 10 10 10 
ff c9 ; SOF 
00 0b 
08 00 01 00 01 01 01 11 00 
ff cc ; DAC 
00 06 00 10 10 05 
ff da ; SOS 
00 08 
01 01 00 00 3f 00 d2 cf 20 
ff d9 ; EOI 

no creo que el mencionado ejemplo 134 bytes es estándar, ya que falta un EOI. Todos los decodificadores manejarán esto, pero el estándar dice que debería terminar con uno.

+4

¿Cuál de estos bytes es seguro de incrementar para producir una serie de archivos JPEG pequeños pero diferentes? –

+0

@Quolonel Preguntas - El 8x8 'cuadrado' de bytes en el segmento DQT son esencialmente factores de escala, cualquiera de los cuales puede ser valores de 1-255. Creo que el único valor que se usa en el segmento DAC de este ejemplo es el primero en la esquina superior izquierda del bloque 8x8. – matja

2

Aquí está la rutina de C++ que escribí para hacer esto:

bool is_jpeg(const unsigned char* img_data, size_t size) 
{   
    return img_data && 
      (size >= 10) && 
      (img_data[0] == 0xFF) && 
      (img_data[1] == 0xD8) && 
      ((memcmp(img_data + 6, "JFIF", 4) == 0) || 
      (memcmp(img_data + 6, "Exif", 4) == 0)); 
} 

img_data apunta a un tampón que contiene los datos JPEG.

Estoy seguro de que necesitas más bytes para tener un JPEG que decodificará una imagen útil, pero es una apuesta justa que si los primeros 10 bytes superan esta prueba, el buffer probablemente contenga un JPEG.

EDIT: Por supuesto, puede reemplazar los 10 anteriores con un valor más alto una vez que decida uno. 134, como se sugiere en otra respuesta, por ejemplo.

0

No es un requisito que los archivos JPEG contengan un marcador JFIF o Exif. Pero deben comenzar con FF D8, y deben tener un marcador después de eso, para que pueda verificar si hay FF ​​D8 FF.

+0

Este es un gran comentario, pero no responde la pregunta del OP. Considera colocarlo bajo otra respuesta. –

0

Aunque me doy cuenta de que esto está lejos de ser el jpeg válido más pequeño y tiene poco o nada que ver con su pregunta real, sentí que debería compartir esto ya que estaba buscando un JPEG muy pequeño que realmente parecía algo hacer algunas pruebas con cuando encontré tu pregunta. Lo estoy compartiendo aquí porque es válido, es pequeño, y me hace ROFL.

Aquí hay una imagen JPEG de 384 bytes que hice en photoshop. Son las letras ROFL dibujadas a mano por mí y luego se guardan con la configuración máxima de compresión mientras aún se puede leer.

secuencias HEX:

my @image_hex = qw{ 
FF D8 FF E0 00 10 4A 46 49 46 00 01 02 00 00 64 
00 64 00 00 FF EC 00 11 44 75 63 6B 79 00 01 00 
04 00 00 00 00 00 00 FF EE 00 0E 41 64 6F 62 65 
00 64 C0 00 00 00 01 FF DB 00 84 00 1B 1A 1A 29 
1D 29 41 26 26 41 42 2F 2F 2F 42 47 3F 3E 3E 3F 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 01 1D 29 29 
34 26 34 3F 28 28 3F 47 3F 35 3F 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 
47 47 47 47 47 47 47 47 47 47 47 47 47 FF C0 00 
11 08 00 08 00 19 03 01 22 00 02 11 01 03 11 01 
FF C4 00 61 00 01 01 01 01 00 00 00 00 00 00 00 
00 00 00 00 00 00 04 02 05 01 01 01 01 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 02 04 10 00 02 
02 02 02 03 01 00 00 00 00 00 00 00 00 00 01 02 
11 03 00 41 21 12 F0 13 04 31 11 00 01 04 03 00 
00 00 00 00 00 00 00 00 00 00 00 00 21 31 61 71 
B1 12 22 FF DA 00 0C 03 01 00 02 11 03 11 00 3F 
00 A1 7E 6B AD 4E B6 4B 30 EA E0 19 82 39 91 3A 
6E 63 5F 99 8A 68 B6 E3 EA 70 08 A8 00 55 98 EE 
48 22 37 1C 63 19 AF A5 68 B8 05 24 9A 7E 99 F5 
B3 22 20 55 EA 27 CD 8C EB 4E 31 91 9D 41 FF D9 
}; #this is a very tiny jpeg. it is a image representaion of the letters "ROFL" hand drawn by me in photoshop and then saved at the lowest possible quality settings where the letters could still be made out :) 

my $image_data = pack('H2' x scalar(@image_hex), @image_hex); 
my $url_escaped_image = uri_escape($image_data); 

URL escaparon datos de imagen binaria (puede pegar a la derecha en una URL)

%FF%D8%FF%E0%00%10JFIF%00%01%02%00%00d%00d%00%00%FF%EC%00%11Ducky%00%01%00%04%00%00%00%00%00%00%FF%EE%00%0EAdobe%00d%C0%00%00%00%01%FF%DB%00%84%00%1B%1A%1A)%1D)A%26%26AB%2F%2F%2FBG%3F%3E%3E%3FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG%01%1D))4%264%3F((%3FG%3F5%3FGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG%FF%C0%00%11%08%00%08%00%19%03%01%22%00%02%11%01%03%11%01%FF%C4%00a%00%01%01%01%01%00%00%00%00%00%00%00%00%00%00%00%00%00%04%02%05%01%01%01%01%00%00%00%00%00%00%00%00%00%00%00%00%00%00%02%04%10%00%02%02%02%02%03%01%00%00%00%00%00%00%00%00%00%01%02%11%03%00A!%12%F0%13%041%11%00%01%04%03%00%00%00%00%00%00%00%00%00%00%00%00%00!1aq%B1%12%22%FF%DA%00%0C%03%01%00%02%11%03%11%00%3F%00%A1~k%ADN%B6K0%EA%E0%19%829%91%3Anc_%99%8Ah%B6%E3%EAp%08%A8%00U%98%EEH%227%1Cc%19%AF%A5h%B8%05%24%9A~%99%F5%B3%22%20U%EA'%CD%8C%EBN1%91%9DA%FF%D9 
+0

Ese es el código perl en caso de que alguien se lo esté preguntando. – kristianp

7

Comprendo que esto es una cuestión de edad, pero se me ocurre que podría hacer un jpeg progresivo con solo los coeficientes DC, que un solo pixel gris podría codificarse en 119 bytes. Esto parece estar bien en algunos programas en los que lo probé (Photoshop y otros).

ff d8 : SOI 
ff db ; DQT 
00 43 
00 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
01 01 01 01 01 01 01 01 
ff c2 ; SOF 
00 0b 
08 00 01 00 01 01 01 11 00 
ff c4 ; DHT 
00 14 
00 
01 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
03 
ff da ; SOS 
00 08 
01 01 00 00 00 01 3F 
ff d9 ; EOI 

El principal ahorro de espacio es tener solo una mesa Huffman. Aunque esto es ligeramente más pequeño que la codificación aritmética de 125 bytes dada en otra respuesta, la codificación aritmética sin el encabezado JFIF sería aún más pequeña (107 bytes), por lo que todavía se debe considerar la más pequeña conocida.

+0

Para los curiosos, al tratar de leer esto con iOS ''[UIImage imageWithData:]' da como resultado: 'ImageIO: JPEG Datos JPEG corruptos: 2 bytes extraños antes del marcador 0xda'. –

4

pruebe los siguientes (134 bytes):

FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 48 00 48 00 00 
FF DB 00 43 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
FF FF FF FF FF FF FF FF FF FF C2 00 0B 08 00 01 00 01 01 01 
11 00 FF C4 00 14 10 01 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 FF DA 00 08 01 01 00 01 3F 10 

Fuente: Worlds Smallest, Valid JPEG? por Jesse_hz

-1

Encontrado "the tiniest GIF ever" con sólo 26 bytes.

47 49 46 38 39 61 01 00 01 00 
00 ff 00 2c 00 00 00 00 01 00 
01 00 00 02 00 3b 

Python literal:

b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;' 
Cuestiones relacionadas