Понимаю, что тема слабо относится к Фотошопу, но...
Суть проблемы: мне нужно получить полные пути линкованных файлов прямо из внутренностей PSD (прочитать бинарный файл).
Я ищу originalPathTEXT, успешно нахожу, получаю строку. С латиницей всё просто - что записано, то и прочитано. С кириллицей (и скорее всего с другими локалями) начинаются заморочки - Adobe, судя по всему, сокращает байты, заменяя для некоторых символов (пробел, слэш, точку и скорее всего что-то еще) на сокращенную запись, например:
Я вроде бы глазами и головой принцип понимаю, но не могу сформулировать в коде.
Возможно у кого-то есть идеи, как это расшифровать чтобы символы не повреждались.
Скрипт для Фотошопа ниже, файл чтобы поиграться здесь: PSD с линкованными файлами
Суть проблемы: мне нужно получить полные пути линкованных файлов прямо из внутренностей PSD (прочитать бинарный файл).
Я ищу originalPathTEXT, успешно нахожу, получаю строку. С латиницей всё просто - что записано, то и прочитано. С кириллицей (и скорее всего с другими локалями) начинаются заморочки - Adobe, судя по всему, сокращает байты, заменяя для некоторых символов (пробел, слэш, точку и скорее всего что-то еще) на сокращенную запись, например:
читается какE:\_Output\22\ИмяФайла.psd
из-за того что байты записаны следующим образом:E:\_Output\22ќИмяФайл0.psd
* видно что как только появляется кириллица начинаются сокращения для определенных символов: слэш 5c 00 получает 04 от кириллицы и становится 5c 04 == ќ, буква а перед точкой наоборот теряет свою 04 и превращается в 30 00 == 0 и т.п.45 00 == E
3a 00 == :
5c 00 == \
5f 00 == _
4f 00 == O
75 00 == u
74 00 == t
70 00 == p
75 00 == u
74 00 == t
5c 00 == \
32 00 == 2
32 00 == 2
5c 04 == ќ
18 04 == И
3c 04 == м
4f 04 == я
24 04 == Ф
30 04 == а
39 04 == й
3b 04 == л
30 00 == 0
2e 00 == .
70 00 == p
73 00 == s
64 00 == d
Я вроде бы глазами и головой принцип понимаю, но не могу сформулировать в коде.
Возможно у кого-то есть идеи, как это расшифровать чтобы символы не повреждались.
Скрипт для Фотошопа ниже, файл чтобы поиграться здесь: PSD с линкованными файлами
JavaScript:
#target photoshop
var BLOCK_START = 'originalPathTEXT\0\0\0',
BLOCK_END = String.fromCharCode('00', '07'),
CHUNK_SIZE = 64 * 1024,
OVERLAP = 512;
var file = File.openDialog("Выберите PSD-файл");
if (file && file.exists) {
file.encoding = 'BINARY';
if (!file.open("r")) {
alert("Не удалось открыть файл.");
} else {
var size = file.length,
position = size,
buffer = '',
strings = [],
symbols = [];
while (position > 0) {
var readSize = Math.min(CHUNK_SIZE, position);
position -= readSize;
file.seek(position);
var chunk = file.read(readSize);
buffer = chunk + buffer.slice(0, OVERLAP);
var searchPos = 0;
while (true) {
var startIndex = buffer.indexOf(BLOCK_START, searchPos);
if (startIndex === -1) break;
var endIndex = buffer.indexOf(BLOCK_END, startIndex + BLOCK_START.length);
if (endIndex === -1) break;
endIndex += BLOCK_END.length;
strings.push(decodeBytes(buffer.slice(startIndex, endIndex)));
symbols.push(decodeBytesToCharCodes(buffer.slice(startIndex, endIndex)))
searchPos = endIndex;
}
buffer = chunk;
}
file.close();
if (strings.length > 0) {
var log = new File("~/Desktop/output.txt");
log.open("w");
for (var i = 0; i < strings.length; i++) {
log.writeln(strings[i]);
log.writeln(symbols[i]);
}
log.close();
alert("Найдено строк: " + strings.length + "\nСохранено в output.txt на рабочем столе.");
} else {
alert("Строки не найдены.");
}
}
}
function decodeBytes(bytes) {
var pathBytes = bytes.slice(21),
decoded = '';
for (var i = 0; i < pathBytes.length - 1; i += 2) {
var lo = pathBytes.charCodeAt(i),
hi = pathBytes.charCodeAt(i + 1),
code = lo + (hi << 8);
if (code === 0) continue;
if (lo === 0 && hi === 7) break;
decoded += String.fromCharCode(code);
}
return decoded;
}
function decodeBytesToCharCodes(bytes) {
var pathBytes = bytes.slice(21),
decoded = '';
for (var i = 0; i < pathBytes.length - 1; i += 2) {
var lo = pathBytes.charCodeAt(i),
hi = pathBytes.charCodeAt(i + 1),
code = lo + (hi << 8);
if (code === 0) continue;
if (lo === 0 && hi === 7) break;
decoded += toHex([lo, hi]) + ' == ' + String.fromCharCode(code) + '\n';
}
return decoded;
}
function toHex(charCodes) {
var hexString = '';
for (var i = 0; i < charCodes.length; i++) {
var hex = charCodes[i].toString(16);
if (hex.length < 2) {
hex = '0' + hex;
}
hexString += hex + ' ';
}
return hexString;
}