2010-02-12 7 views
21

Vorrei visualizzare alcuni valori JPEG prima di inviarli attraverso la rete per un'ispezione più ampia. È abbastanza semplice controllare un'intestazione e un piè di pagina validi, ma qual è la dimensione più piccola (in byte) potrebbe essere un jpeg valido?Qual è la più piccola dimensione del file jpeg valida (in byte)

+3

libjpeg può fare test rapidi, considerare l'utilizzo di esso, piuttosto che indovinare. – Tronic

+4

Non voglio aggiungere alcuna libreria aggiuntiva alla mia app. Inoltre, non indovinare se qualcuno mi dice la risposta giusta :) – twk

+1

Probabilmente dovresti cambiare la tua domanda in "testare se alcuni jpeg sono probabilmente validi" a meno che tu non abbia intenzione di fare un sacco di altri test se il test della dimensione del file passa. Altrimenti è abbastanza facile produrre un JPEG non valido di qualsiasi dimensione oltre la dimensione minima di un JPEG valido. – jball

risposta

16

Un pixel 1x1 grigio in 125 byte con codifica aritmetica, ancora nello standard JPEG anche se molti decodificatori non può 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 

non ritengo il 134 byte esempio citato è standard, come manca un EOI. Tutti i decodificatori gestiranno questo, ma lo standard dice che dovrebbe finire con uno.

+4

Quale di questi byte è sicuro da incrementare per produrre una serie di JPEG piccoli ma diversi? –

+0

@Quolonel Domande - I 8x8 "quadrati" di byte nel segmento DQT sono essenzialmente fattori di ridimensionamento, ognuno dei quali può essere valori 1-255. Penso che l'unico valore utilizzato nel segmento DAC di questo esempio sia il primo nell'angolo in alto a sinistra del blocco 8x8. – matja

2

Ecco la routine C++ che ho scritto per fare questo:

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 punta a un buffer contenente i dati JPEG.

Sono sicuro che sono necessari più byte per avere un JPEG che decodifichi un'immagine utile, ma è una buona scommessa che se i primi 10 byte superano questo test, il buffer probabilmente contiene un JPEG.

MODIFICA: È possibile, naturalmente, sostituire il 10 sopra con un valore più alto una volta deciso uno. 134, come suggerito in un'altra risposta, per esempio.

0

Non è necessario che i JPEG contengano o un marcatore JFIF o Exif. Ma devono iniziare con FF D8, e devono avere un marker che lo segue, quindi puoi controllare FF D8 FF.

+0

Questo è un grande commento, ma non risponde alla domanda dell'OP. Potresti metterlo sotto un'altra risposta. –

0

Mentre mi rendo conto che questo è lontano dal più piccolo jpeg valido e ha poco o nulla a che fare con la tua domanda, ho sentito che dovrei condividere questo come stavo cercando un JPEG molto piccolo che in realtà sembrava qualcosa di fai qualche prova con quando ho trovato la tua domanda. Lo sto condividendo qui perché è valido, è piccolo e mi rende ROFL.

Ecco un'immagine JPEG da 384 byte creata in Photoshop. Sono le lettere ROFL disegnate da me da me e poi salvate con le impostazioni di compressione massime pur rimanendo leggibili.

sequenze 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 sfuggito dati di immagine binaria (può incollare a destra in un 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

Questo è il codice perl nel caso in cui qualcuno si stia chiedendo. – kristianp

7

Mi rendo conto che è una vecchia questione, ma mi viene in mente che si potrebbe fare un jpeg progressivo con solo i coefficienti DC, che un singolo pixel grigio potrebbe essere codificato in 119 byte. Questo si legge bene in alcuni programmi in cui l'ho provato (Photoshop e altri).

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 

Il risparmio di spazio principale è avere solo una tabella di Huffman. Sebbene questo sia leggermente più piccolo della codifica aritmetica a 125 byte fornita in un'altra risposta, la codifica aritmetica senza l'intestazione JFIF sarebbe ancora più piccola (107 byte), quindi dovrebbe essere considerata la più piccola nota.

+0

Per i curiosi, quando si tenta di leggere questo con iOS ''[UIImage imageWithData:]' emette: 'ImageIO: JPEG Corrotto dati JPEG: 2 byte estranei prima dell'indicatore 0xda'. –

4

provare quanto segue (134 byte):

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 

Fonte: Worlds Smallest, Valid JPEG? da Jesse_hz

-1

Trovato "the tiniest GIF ever" con solo 26 byte.

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 letterale:

b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;' 
Problemi correlati