LibRaw 0.14.7

По традиции, анонсирую и тут.

Вышла LibRaw 0.14.7 в которой поддержаны камеры, вышедшие в последние полгода:

  • Canon: 5D Mark III, G1 X, 1D X и Powershot SX200
  • Nikon: D4,D800/D800E и D3200
  • FujiFilm: X-S1 и HS30EXR
  • Casio EX-Z8;
  • Olympus E-M5
  • Panasonic GF5
  • Sony: NEX-F3, SLT-A37 и SLT-A57
  • Samsung: NX20, NX210 и NX200 с новыми версиями firmware
Если вы пользуетесь каким-то варезом, использующим LibRaw (RawDigger :), Darktable, digiKam, Photoacute, что-то использующее FreeImage, да и вообще этого софта развелось в последнее время), требуйте обновления LibRaw у авторов соответствующего софта.

Остальные камеры и форматы, добавленные в dcraw 9.15 (Lossy DNG, Fuji X1-Pro, новые Сигмы), будут поддержаны в LibRaw 0.15. Поддержать их в 0.14 (т.е. с сохранением бинарной совместимости библиотек) нет никакой возможности.

P.S. RawDigger будет обновлен не очень скоро. Там уже используется LibRaw 0.15 (пре-альфа), вернуться к 0.14 малореально.

Comments

У X1-Pro же какой-то адский не-баер, там же надо совсем другую математику придумывать.
И разве libraw на Фовеон не забил? Это я про новые сигмы.

Залез в dcraw.c и не нашёл там X-1 Pro. Хотя, наверное, именно не нашёл -- там сложно что-то найти.

Гы!

На самом деле, оно очень клево написано в том смысле что компактность превыше всего.
RawSpeed, к примеру, в полтора раза больше кода, вдвое меньше список камер и только распаковка, без постпроцессинга.

Я не очень понимаю этой цели, если мы не на Хаос Констракшене.
Мне кажется, поддерживаемость кода -- первыше всего. Ну, если это не в ушерб уж совсем скорости. А сколько там кода -- какая разница?

Что-то я не видел, чтобы хоть кто-то это пытался поддерживать, пусть даже в очевидных местах. А сам Коффин - поддерживает. Ну и прекрасно.

Проблема в том, что Коффин завтра может под машину попасть. И вероятность, что кто-то разгребёт ЭТО, больше всего похожее на какую-то кодогенерацию из другого языка в стиле JavaScript, не так велика. Был бы нормально структурированный код -- была бы выше.

Нет, проблема не в этом.

Проблема в том, что когда очередной Canon в очередной раз поменяет способ распаковки sRAW - он никому об этом не скажет. И надо будет лезть отладчиком в DPP и смотреть как там и что.

На этом фоне странный код - он как раз в культурной традиции таких людей.

Не-байер там ацкий и именно по этой причине нужны немножко другие структуры данных, а следовательно сделать все в рамках одной major-версии (т.е. с сохранением бинарной совместимости) нельзя.
А с математикой, на удивление, проблем вроде нет.

С фовеоном же - внезапно в dcraw появилась поддержка DPx и SD15

А там будут работать те же алгоритмы демозаика? А будет ли при этом выигрыш от не-баера? Ведь оно там яко бы для более удобного и хорошего демозаика такое странное.

А в каком смысле "не байера"? Там паттерн размером 6x6, повторяющийся. А в других камерах бывает 8x2, а у Leaf CatchLight - 16x16. А в каждом пикселе одно значение, а еще 2(3) не хватает, надо интерполировать. Не вижу разницы.

А паттерн такой, на мой взгляд, не для "демозаика", а для борьбы с муаром.

И с ложными цветами, как я понял -- в любой горизонтали и вертикали есть все цвета.

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

Ну вот к примеру AHD: строится приблизительная homogenity map, и значение компонента берется (с бОльшим весом) с той стороны, которая более гомогенная. А где именно будет синий пиксел справа от текущего синего - через один или через полтора - какая хрен разница.

С ложными же цветами - шансов попасть в строго вертикальную/горизонтальную полосатость с шагом в пиксел - на практике немного.

Вскрытие показало, что для X1-Pro работают только линейная интерполяция и VNG

Оба - подправлены мальца (шаг алгоритма) под эту камеру.

Ну вот, не всё так просто оказалось.

Кстати, а никто не пробовал алгоритм интерполяции, который строит двумерный сплайн по каждому цвету и вычитывает недостающее из этого сплайна? Ну, так, сеткой где-нибудь 32x32?

Типичный современный алгоритм интерполяции пытается как-то построить и проинтерпретировать кросс-корреляции между каналами.

Чтобы если у нас в канале 1 резкий пик (а каналов 0,2 и 4 в этом пикселе нет), то и в пропущенных каналах нарисовать похожий на правду пик/провал.

А сплайн с большой сеткой вряд-ли будет принципиально лучше банальной билинейной (ну, ладно, бикубической) интерполяции.

Можно ещё добавить edge detection... И края рисовать через кросс-кореляции а плавные области -- через сплайн. Хм. Жалко, я совсем плохо в этом понимаю и е могу быстро в Математике (Октаве) набросать код для эксперимента :(

Или в цитсире нашлась PhD по такому паттерну со всеми алгоритмами, на основе которой Фуджи это и придумала, взяв на работу автора? :)))

А вот вопрос дурацкий: "требуйте обновления LibRaw у авторов соответствующего софта" - то есть просто либу обновить для поддержки новых форматов не катит?

Если используется libraw.so.5 - то катит.
Если сложнее - то не катит :)

А что есть в 0.15 нового?

На текущий момент (до импорта свежей dcraw), из существенного:
- возможность поканального задания уровней черного
- Только в Win32: LibRaw::open_file (wchar_t *) т.е. возможность открывать файлы, имя которых задано в виндовой уникодной кодировке.
- 'Sony ARW2 hack' - возможность выключить деление на 4 для данных, раскодируемых из Sony ARW2.
- проковыряны дырки (сделаны вызовы), чтобы наиболее медленные фазы постпроцессинга можно было пере-имплементировать в производном классе более быстрым способом (SSE, многопоточность).

Все сделано для RawDigger, вестимо

а что там такое веселое у сони в их ARW2, и к каким камерам это относится?

Ко всем ARW2 это относится.

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

Смысла в таком делении нет, посему в LibRaw 0.15 проковыряна дырочка для его отключения, вдруг кому надо.

мдаааа. интересно, когда у сони вместо плейстейшна с функцией видеосъемки начнут нормальные фотоаппараты получаться...

Я не изучал - может в младших этих битах ничего хорошего нет, а режут их за дело. Не знаю.

В RawDigger текущем эта пимпа уже есть (Preferences - Data Processing - Sony ARW2 Hack), желающие могут изучить.

P.S. 0.15 переехала в github из 0.15-unstable в master.

А, вот сейчас писал Changelog и вспомнил.

Еще же ваш wf-debanding. Он был в 0.15-unstable и переехал, как и было обещано, в 0.15 (т.е. в master)

0.15-Alpha0 ожидается сегодня, ближе к вечеру.

src/libraw_cxx.cpp
пара вопросов :
1. LibRaw::get_decoder_info не часто вызывается?
2. смешаны exceptions и return codes - в итоге приходится заниматься и тем и тем. зачем? Ведь для C-api есть libraw_c_api.cpp, сюда и можно напихать try/catch

1) Первый вопрос не понял.

2) Да, смешаны. Но exceptions как интерфейс библиотеки - я в гробу видел. А кода написать мне не жалко.

1) в смысле как часто? если часто, то эту chain можно преобразовать
2) Почему? Возможные проблемы с ABI?
3) раз exceptions нежелательны, то например есть nothrow new: http://www.cplusplus.com/reference/std/new/nothrow/
char* p = new (nothrow) char [1048576];
имхо более эстетично, чем делать new прям в try/catch(std::bad_alloc)

1) Внутри библиотеки - два раза на изображение (в котором десятки миллионов пикселов). Если что и оптимизировать, то лучше ljpeg-декодер.

2-3) никто не гарантирует, что в своей имплементации datastream имплементирующий сделает nothrow. А new - скорее всего сделает.

И, аналогично, пользователь библиотеки не должен писать catch, если ему даются коды возврата. И не пишут, ловля std::bad_alloc появилась именно из за таких.

Точнее, bad_alloc вообще до кучи появилась.
А избежать (возможных) ексепшенов в IO-layer (который может быть подменен пользователем) - через nothrow все едино нельзя.

ну тогда ловить нужно вообще всё catch(...) - прийти от пользователя ведь что-угодно может, а выпускать наружу, как я понял нельзя

Я на эту тему долго думал и решил так

1) std::exception я ловлю, потому что оно и от LibRaw_datastream (моей) может прилететь (точнее от стримового IO, который там внизу) ну и пользователь, который сам что-то имплементировал (поверх Libraw_abstract_datastream) на стандартной библиотеке - может быть не в курсе исключений.

2) А если у пользователя в его реализации I/O что-то свое, личное - то пусть сам и ловит. Все одно, нормально обработать его исключения я не могу, а значит не моя это проблема.

да, я догадывался, что задумка такая.

Но, на первый взгляд, у вас ведь код не рассчитан на такие метеориты: например, в LibRaw::open_file если что-то вылетит из
int ret = open_datastream(stream);
то stream потерян. в общем нужно RAII

А почему он потерян? Туда передается datastream, уже созданный пользователем библиотеки. Путь он его и убивает если вдруг че.
Это если кто open_datastream позвал.

А в случае open_file - создаются свои (из состава LibRaw) потоки.
Все что может вылететь из своих датастримов, созданных в open_file - в open_datastream и поймается: там ловятся LibRaw_exceptions (свои) и std::exception (от стандартных потоков).

Если тут покопаться в блоге - мне где-то объясняют, что ловить *все* под виндой - очень плохая практика т.к. какие-то еще механизмы рантайма винды работают на exceptions.

в https://github.com/LibRaw/LibRaw/blob/master/src/libraw_cxx.cpp
на 652 строчке

int ret = open_datastream(stream);

а там внутри на 706:

if(!stream->valid())

что нибудь вылетает.
кто сделает delete stream; ?

Свои имплементации в этом месте исключений не генерируют.

А чужая - не пройдет через open_file(), а исключение пусть ловит тот, кто датастрим создал и засунул в open_datastream().

да, не увидел что свои датастримы


А в случае open_file - создаются свои (из состава LibRaw) потоки.
Все что может вылететь из своих датастримов, созданных в open_file - в open_datastream и поймается: там ловятся LibRaw_exceptions (свои) и std::exception (от стандартных потоков).

понял, не увидел что датастримы свои.


Если тут покопаться в блоге - мне где-то объясняют, что ловить *все* под виндой - очень плохая практика т.к. какие-то еще механизмы рантайма винды работают на exceptions.

если не ловить - тогда RAII, иначе очень легко что-то где-то забыть

Во, вот тут в комментариях обсуждение: http://blog.lexa.ru/2011/12/28/ob_isklyucheniyakh_c.html

Так как смысла ловить ... чтобы его потом rethrow - никакого нет вообще (что делать с чужим неизвестно каким исключением?) то, собственно, и было принято решение ловить только std::exception (ну и до кучи bad_alloc вокруг new)

А ресурсы подчистит LibRaw::recycle(), включая и созданные в open_file() потоки.

можно ещё и goto cleanup :) тогда точно будет C

Да какая разница, какой язык используется.

Постановка простая: есть объект LibRaw, которым могут быть обработаны много файлов.
Следовательно, нужен учет ресурсов (втч. и в коде, который не я писал, но откуда может прилететь исключение) и их освобождение по свистку.

В деструкторе - тоже recycle()

Но goto cleanup не спасет. Только longjmp, только хардкор

разница в том, что в C++ есть более православные решения чем копипаста. но и то, и то работает

Ну если учесть, что изрядная доля кода LibRaw - по жизни копипаста из dcraw.c (правда скриптом и C preprocessor, а не вручную), то остальное уже мелочи.

То есть цель - чтобы изменения в dcraw импортировались по git merge. В данном случае - не получилось, слишком глобальные изменения, но вообще - работает.

2-3) ясно, то есть ловятся не только свои, но и чужие bad-alloc, но в этом случае ловить нужно абсолютно всё catch(...)


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

естественно - либо то, либо то. я не говорю что нужны и коды возврата и исключения