LINUX.ORG.RU

Можно ли определить (хотя бы примерно) искажённый байт в JPEG?

 , ,


0

3

Привет, ЛОР.

Возникла нетривиальная задачка уровня «шлакоблокунь». :) Есть кучка JPEG-файлов, вытащенных из MJPEG-потока с довольно большим количеством битых участков. Оригинальный поток тоже имеется и связать позиции файлов с позицией потока я могу. Нужно определить закономерность, с которой возникают сбои.

Со сбоями в растровых изображениях я сталкиваюсь не в первый раз, даже написал простенький алгоритм, который на раскодированном битмапе считает разности цветовых компонентов и определяет строку, с которой начался искажённый фрагмент. Немножко усложнив алгоритм, можно и пиксель определить (хотя там уже есть нюансы). Так вот, а получится ли, зная X и Y, определить, какой байт в JPEG-е виновен в его подтверждении?

На самом деле да, я понимаю, что этих байт может быть несколько, поскольку JPEG собирается из нескольких таблиц. Но если на выходе у меня будут несколько «подозреваемых», это тоже поможет сложить пазл.

Битые байты, разумеется, могут попадать не только на «количественные» поля. Но если в сигнатуре «JFIF» или «AVI1» вместо I будет Q или что-то вообще нечитаемое – тут сразу понятно, кто виноват. Если в таблице смещений попадётся смещение, выкидывающее за пределы файла – тоже. К сожалению, не все искажения такие легко определяемые.

Уже вижу, как мне пишут про проблему XY. Да, методически я занимаюсь не совсем правильными вещами, надо искать сам источник искажений. Но доступ к нему у меня не слишком регулярный, а вот анализ потока помог бы понять, периодические эти искажения или нет? И если да, то с каким периодом? Байты только искажаются или добавляются/пропадают? В зависимости от этого уже можно определиться, кого пинать – канал связи, сервисы, через которые этот поток проходил до меня и др.

★★★★★

Последнее исправление: hobbit (всего исправлений: 3)

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

и сравни два файла исходный, и сжатый обратно. вот где есть расхождения - туда попала красная тревожная точка.

если там уже стоит красная тревожная точка - поставь синюю тревожную точку!!! и жми картинку назад.

логично?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от alysnix

а жыпеге не записано с какими потерями его жали?

А вот это – хороший вопрос, на который у меня нет хорошего ответа. Знаю только, что при сжатии задаётся качество в процентах. А вот можно ли его определить на основании самого файла…

hobbit ★★★★★
() автор топика
Ответ на: комментарий от hobbit

Кстати, да, jpeg сжимает каждый канал отдельно. И там 2 цветовых канала еще уменьшаются в 4 раза (2х2). То есть квадратить неправильным цветом может блоками 16х16.

В общем, придется повторить декодер и маркировать-индекировать блоки.

anonymous
()

Пробуй менять случайный байт в исходном изображении и смотреть на результат. Методом деления пополам ты быстро должен найти того самого говнюка. И так с каждым кадром 😭

cobold ★★★★★
()
Ответ на: комментарий от hobbit

а жыпеге не записано с какими потерями его жали?

А вот можно ли его определить на основании самого файла…

Качество записано не прямо, но косвенно. В виде матриц квантизации коэффициентов ДКТ. И в разных библиотеках и в разном софте они вычисляются по-разному, а в некоторых просто идут предрасчитаными наборами. Своего рода сигнатура. Где-то встречал огромную коллекцию для обратного определения исходного параметра «качество».

По исходному вопросу: ответ – иногда можно, если повезёт.

В JPEG (JFIF) есть разные режимы кодирования макроблоков. Самый лёгкий и достоверный для определения повреждений – это когда они кодируются последовательно (Y, Cb, Cr – яркость, цветность) и представляют собой RLE-кодированные последовательности коэффициентов ДКТ. И повреждение произвольного байта с большой вероятностью приведёт к явному несоответствию стандарту и можно будет точно сказать его координаты в декодированном изображении.

Но если не повезёт, то RLE последовательность вполне может оказаться валидной и для этого блока и даже для нескольких следующих, а накопится ошибка позже, так что в декодированном изображении будет много визуально поломанных блоков, которые не нарушают стандарт/протокол.

Ещё есть прогрессивные режимы, там ещё меньше шансов определить, так как в проходах уточнения коэффициентов они просто кодируются наборами младших бит. И если повредить байт в таком участке, то визуально это будет выглядеть подозрительно или даже поломанным, но весь файл будет валидным.

anonymous
()

Удваивай все байты. Какие байты пришли неверно удвоенные, те искажены. Короче, перенеси на уровень транспорта.

Или контрольную сумму в группы байт добавь. Хотя бы банально на каждые 8 байт один дополнительный байт, где каждый бит задаёт четность соответствующего байта полезной нагрузки.

KivApple ★★★★★
()

а почему ты решил, что виновен какой-то байт в jpeg? если бьются отдельные пикселы, то, скорее всего, это происходит ещё до кодирования в jpeg.

anonymous
()