2010-02-12 2 views
21

Я хотел бы проверить некоторые jpegs на достоверность, прежде чем отправлять их по сети для более тщательного осмотра. Достаточно просто проверить допустимый верхний и нижний колонтитулы, но каков минимальный размер (в байтах) допустимого jpeg?Каков максимальный допустимый размер файла jpeg (в байтах)

+3

libjpeg может делать быстрые тесты, рекомендуется использовать его, а не гадать. – Tronic

+4

Я не хочу добавлять какие-либо дополнительные библиотеки в свое приложение. Кроме того, он не догадывается, если кто-то подскажет мне правильный ответ :) – twk

+1

Вероятно, вы должны изменить свой вопрос на «проверить, действительно ли допустимы некоторые jpegs», если вы не собираетесь выполнять кучу других тестов, если проверка размера файла проходит. В противном случае довольно просто создать недопустимый JPEG любого размера по сравнению с минимальным размером допустимого JPEG. – jball

ответ

16

1x1 серого пикселя в 125 байт с использованием арифметического кодирования, по-прежнему в стандарте JPEG, даже если большинство декодеров не может декодировать его:

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 

Я не думаю, упомянутый 134 байт примером является стандартным, поскольку отсутствует EOI. Все декодеры справятся с этим, но стандарт говорит, что он должен заканчиваться одним.

+4

Какой из этих байтов безопасен для увеличения, чтобы создать серию небольших, но разных JPEG-файлов? –

+0

@Quolonel Questions - квадрат байтов 8x8 в сегменте DQT - это, по сути, масштабные коэффициенты, любые из которых могут быть значениями 1-255. Я думаю, что единственное значение, которое используется в сегменте ЦАП этого примера, является первым в верхнем левом углу блока 8x8. – matja

2

Вот рутина C++ я написал, чтобы сделать это:

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 указывает на буфер, содержащий данные в формате JPEG.

Я уверен, что вам нужно больше байтов, чтобы иметь JPEG, который будет декодироваться на полезный образ, но справедливая ставка заключается в том, что если первые 10 байтов проходят этот тест, буфер, вероятно, содержит JPEG.

EDIT: Вы можете, конечно же, заменить 10 выше на более высокое значение, как только вы решите его. 134, как предложено в другом ответе, например.

0

Это не требование, чтобы JPEG содержал маркер JFIF или Exif. Но они должны начинаться с FF D8, и у них должен быть маркер, поэтому вы можете проверить FF D8 FF.

+0

Это замечательный комментарий, но он не отвечает на вопрос OP. Подумайте о том, чтобы разместить его под другим ответом. –

0

Хотя я понимаю, что это далеко от наименьшего допустимого jpeg и мало или ничего общего с вашим фактическим вопросом, я чувствовал, что должен делиться этим, поскольку я искал очень маленький JPEG, который на самом деле выглядел чем-то вроде сделайте некоторое тестирование, когда я нашел ваш вопрос. Я делюсь этим здесь, потому что он действителен, его маленький, и это делает меня ROFL.

Вот 384-байтовый JPEG-образ, который я сделал в фотошопе. Это буквы ROFL, нарисованные мной, а затем сохраненные с максимальными настройками сжатия, хотя они все еще являются читаемыми.

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 уцелевшие данные двоичного изображения (можно вставить прямо в 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

Это код perl, если кто-то задается вопросом. – kristianp

7

Я понимаю, что это старый вопрос, но это происходит со мной, вы могли бы сделать прогрессивный jpeg с только коэффициентами DC, что один серый пиксель может быть закодирован в 119 байтах. Это очень хорошо читается в нескольких программах, которые я пробовал в этом (Photoshop и другие).

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 

Основная экономия пространства заключается в том, чтобы иметь только один стол Хаффмана. Хотя это немного меньше, чем 125-байтовая арифметическая кодировка, указанная в другом ответе, арифметическое кодирование без заголовка JFIF будет еще меньше (107 байт), поэтому его все равно следует считать наименьшим из известных.

+0

Для любопытных при попытке прочитать это с помощью iOS '[UIImage imageWithData:] 'он выводит:' ImageIO: JPEG Коррумпированные данные JPEG: 2 посторонних байта перед маркером 0xda'. –

4

Попробуйте следующие (134 байт):

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 

Источник: Worlds Smallest, Valid JPEG? по Jesse_hz

-1

Найдено "the tiniest GIF ever" только 26 байт.

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 буквальным:

b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;' 
Смежные вопросы