Что нового

Декодирование JPEG

lorents

Новичок
Сообщения
82
Репутация
1
Подскажите, пожалуйста, можно ли используя AutoIt получить следующую информацию:
1. метод кодирования
2. кол-во цветов.

Если стандартного решения нет, то как можно AutoIt использовать как Hex-редактор.
Вся нужная информация находится в маркере SOF, поэтому теоретически можно и Hex-редактор использовать для извлечения информации.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
lorents [?]
AutoIt использовать как Hex-редактор.
почему редактор? судя из вопроса, как просмотрщик. в любом случае, и то и другое возможно. но для чтения, достаточно открыть файл в шестнадцатеричном представлении и прочитать нужные байты.

Код:
$hFile = FileOpen('file.jpg', 16)
$xRed = FileRead($hFile, $nBytes)
 
Автор
L

lorents

Новичок
Сообщения
82
Репутация
1
Допустим вот изображение

dd85adf7.jpg


я использую для таких целей 010 Editor и JPGTemplate.bt

1. метод кодирования
SOF0 = $C0; //Baseline DCT
SOF1 = $C1; //Extended sequential DCT
SOF2 = $C2; //Progressive DCT
SOF3 = $C3; //Lossless (sequential)
SOF5 = $C5; //Differential sequential DCT
SOF6 = $C6; //Differential progressive DCT
SOF7 = $C7; //Differential lossless (sequential)
SOF9 = $C9; //Extended sequential DCT
SOF10= $CA; //Progressive DCT
SOF11= $CB; //Lossless (sequential)
SOF13= $CD; //Differential sequential DCT
SOF14= $CE; //Differential progressive DCT
SOF15= $CF; //Differential lossless (sequential)

2. кол-во цветов, это просто число

Как мне в этом случаи найти необходимую информацию?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
lorents
я не знаком с спецификацией JPG, и не могу сказать где там что. даже глядя на картинку. я лишь говорю, что все эти байты, что на картинке можно вытащить, хоть по одному, хоть скопом. сколько и где именно вытаскивать, тебе виднее, если ты хотя бы мельком знаком с форматом. я парсил в свое время bmp, но это совсем другая песня. поэтому, проблем быть не должно. попробуй поиграться взяв любую картинку и вытаскивая данные согласно спецификации
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
lorents,
Я не знаю структуру JPG-файла, но, ИМХО, можно как-то так попробовать.
Код:
#include <Array.au3>
;это данные для примера
Dim $aJPG[6][3] = [[5],['SOF0', 4, 2],['SOF1', 8, 4],['SOF2', 14, 2],['SOF3', 18, 4],['SOF4', 24, 4]]
#cs
	$aJPG[1-5][0] - название
	$aJPG[1-5][1] - стартовая позиция
	$aJPG[1-5][2] - кол-во байт
#ce
$sFile = @ScriptDir & '\Test.JPG'
;открываем файл для чтения в бинарном режиме
$h_File = FileOpen($sFile, 16)
;читаем первые 27 байт
$bRead = FileRead($h_File, 27)
FileClose($h_File)
ConsoleWrite($bRead & @LF)
For $i = 1 To $aJPG[0][0]
	;получаем заданные байты
	$aJPG[$i][1] = BinaryMid($bRead, $aJPG[$i][1], $aJPG[$i][2])
	;переводим их в Hex
	$aJPG[$i][2] = Hex($aJPG[$i][1])
Next
_ArrayDisplay($aJPG)
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
ок. структура понятна. читаем побайтно, если рядом с FF - известный байт, определяющий маркер, то можно в принципе вытащить все маркеры и их содержимое. в том числе и для FFC0-FFCF. а дальше уже совсем просто. перевести байты в нужные числа. вобщем, я уже засыпаю, если к завтрашнему никто ничего не сделает, то возьмусь. но мне кажется, что тут все просто уже


Добавлено:
Сообщение автоматически объединено:

madmasles [?]
Я не знаю структуру JPG-файла, но, ИМХО, можно как-то так попробовать
таких байтов в структуре нет. но такую функцию я раньше не встречал. с ней все может быть еще проще :smile:
 
Автор
L

lorents

Новичок
Сообщения
82
Репутация
1
Kaster я честно спецификацию, очень плохо знаю, просто привык смотреть информацию через 010 Editor

madmasles получил такой результат, но не понял что дает?

Для меня главное выйти на маркер SOF, а вот дальше я найду

Вот статья на хабре, может поможет.
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
lorents
Шестнадцатеричный редактор
Код:
GUICreate('Шестнадцатеричный редактор', 610, 610)
$Edit=GUICtrlCreateEdit('', 5, 5, 600, 600)
$file = FileOpen(@ScriptDir&'\Test.jpg', 16)
$bin = FileRead($file)
FileClose($file)
GUICtrlSetData($Edit, $bin)
GUISetState()
Do
Until GUIGetMsg()=-3
 
Автор
L

lorents

Новичок
Сообщения
82
Репутация
1
На счет JPEG разобрался.
Все маркеры начинаются с FF

нам надо найти маркер который начинается с FF C0 или FF C1 или FF C2
Меня интересую файлы с этим кодированием

и так найдя маркер SOF, можно найти и цвет, обратите внимание на картинку

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
lorents,
Если я правильно понял эту статью , то вытащить данные SOF0 у меня получилось так, проверял на нескольких файлах, вроде, работает.
Код:
#include <Array.au3>
#include <Binary.au3>;http://www.autoitscript.com/forum/topic/131037-binary-udf/   ;эту библиотеку надо скачать и положить в папку ...\AutoIt3\Include

$bChecJPG = Binary('0xFFD8')
$bSearchSOF0 = Binary('0xFFC0')

Dim $aJPG[5][2] = [[4],['Bit', 1],['Height', 2],['Width', 2],['All Comp', 1]]
Dim $aComp[7] = ['', 'Num Comp', 'H', 'V', 'Num Table Quant', 'H_max', 'V_max']
$iStart = 1
$iH_max = 0
$iV_max = 0
$sFile = @ScriptDir & '\1_Test.jpg'
;$sFile = @ScriptDir & '\msn.jpg'

$h_File = FileOpen($sFile, 16)
If FileRead($h_File, 2) <> $bChecJPG Then
	ConsoleWrite('No JPG' & @LF)
	FileClose($h_File)
	Exit
EndIf
$bRead = FileRead($h_File);если файл большой, можно блоками читать
FileClose($h_File)

$iPos = _BinaryInBin($bRead, $bSearchSOF0, 1)
If $iPos Then
	$aJPG[0][1] = Dec(Hex(BinaryMid($bRead, $iPos + 2, 2)))
	$bSOF0 = BinaryMid($bRead, $iPos + 4, $aJPG[0][1] - 2)
	$bRead = 0
	For $i = 1 To $aJPG[0][0]
		$aJPG[0][1] = $aJPG[$i][1]
		$aJPG[$i][1] = Dec(Hex(BinaryMid($bSOF0, $iStart, $aJPG[$i][1])))
		$iStart += $aJPG[0][1]
	Next
	$aJPG[0][1] = $aJPG[$aJPG[0][0]][1]
	ReDim $aJPG[$aJPG[0][0] + $aJPG[0][1] * 4 + 3][2]
	For $j = 1 To $aJPG[0][1]
		For $i = 1 To 3
			$aJPG[0][0] += 1
			Switch $i
				Case 1
					$aJPG[$aJPG[0][0]][0] = $aComp[$i]
					$aJPG[$aJPG[0][0]][1] = Dec(Hex(BinaryMid($bSOF0, $iStart, 1)))
				Case 2
					$iPos = Hex(BinaryMid($bSOF0, $iStart, 1))
					$aJPG[$aJPG[0][0]][0] = $aComp[$i] & $j
					$aJPG[$aJPG[0][0]][1] = Number(StringLeft($iPos, 1))
					If $iH_max < $aJPG[$aJPG[0][0]][1] Then $iH_max = $aJPG[$aJPG[0][0]][1]
					$aJPG[0][0] += 1
					$aJPG[$aJPG[0][0]][0] = $aComp[$i + 1] & $j
					$aJPG[$aJPG[0][0]][1] = Number(StringRight($iPos, 1))
					If $iV_max < $aJPG[$aJPG[0][0]][1] Then $iV_max = $aJPG[$aJPG[0][0]][1]
				Case 3
					$aJPG[$aJPG[0][0]][0] = $aComp[$i + 1]
					$aJPG[$aJPG[0][0]][1] = Dec(Hex(BinaryMid($bSOF0, $iStart, 1)))
			EndSwitch
			$iStart += 1
		Next
	Next
EndIf
$aJPG[0][0] += 2
$aJPG[$aJPG[0][0] - 1][0] = $aComp[5]
$aJPG[$aJPG[0][0] - 1][1] = $iH_max
$aJPG[$aJPG[0][0]][0] = $aComp[6]
$aJPG[$aJPG[0][0]][1] = $iV_max
$iH_max = 0
$iV_max = 0
$aJPG[0][1] = ''
_ArrayDisplay($aJPG, 'SOF0')
 
Верх