Skip to Content

LibRaw

Об исключениях (C++)

Я не люблю C++-ные exceptions (за второй поток управления), как следствие - стараюсь их не использовать, а если использую, то перехватываю только те, которые порождает мой код. Как следствие, правил хорошего тона в этой области не знаю.

Возник вопрос, как правильно поступать. Вот есть такой примерно код:

  1. int some_class::some_function(std::filebuf& buf)
  2.  
  3.   try {
  4.       ....
  5.       buf.sgetn(....);
  6.       .....
  7.       return 0; // OK
  8.   }
  9.   catch (my_own_exception_type t) {
  10.         аккуратно_склеить_ласты();
  11.         return errorcode;
  12.    }
  13. }
Вопрос: должен ли я в подобном коде ловить исключения, порожденные std::filebuf? Ну там не смог он ничего прочесть? А вообще все исключения? Как требуют понятия хорошего тона?

Должны ли быть эти правила хорошего тона разными в таких двух случаях

  • Этот самый std::filebuf - на самом деле хранится внутри класса, где-то раньше был создан/открыт и все такое. То есть это наш сукин сын.
  • Этот самый IO-хэндл (std::filebuf) передан нам снаружи т.е. это чужой сукин сын.
?

P.S. Нашелся йузер у которого для файлов с SD-читалки не работает std::filebuf IO. Linux, холст, масло....

О языке ++C

Нашелся тут чудесный баг в KDE-шном DNG-конвертере. Вдруг, внезапно, перестал конвертировать, получаются совершенно ЧОРНЫЕ DNG.

Понятно, пишут в багрепорты digiKam-у, а дальше стрелки переводятся по кругу, ко мне (но LibRaw не менялась, в KDE все еще 0.13), к автору DNG Converter, все отпираются т.к. test cases работают.

И наконец виновник найден

Было:

  1.   *output = ...some value...;
  2.   *output++;
стало
  1.   *output = ... some value...;
  2.   ++(*output);
И комментарий к коммиту: use prefix operator

А я подозреваю, что исходно там было и вовсе:

  1.   *output++ = ... some value...;
Проверять не стал, но предсказываю это.

Потом один доброжелатель разбил операцию на две, как умел, а второй, из ненависти к суффиксным инкрементам (или из желания подавить compiler warning), поменял на префиксный. Тоже, как умел.

Всех люблю: опенсорс, коллаборативную разработку по схеме "у семи нянек....", язык C/C++ тоже люблю.

О legacy и форматах данных

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

А я вот тут читаю ассемблер, порожденный компилятором из C-шного кода обработки изображения. Много думаю.

Имею сказать, что распространенный в настоящее время формат "16-битное целое на компонент" - это максимально неудачный способ с точки зрения эффективности обработки:

  • от малейшего чиха переполняется или превращается в тыкву обнуляется, нужно постоянно следить за диапазоном;
  • векторные (SSE,AVX) операции с этим типом - очень ограничены, да и не векторные - тоже.
В результате, сплошные мучения компилятору, а результат - медленно работает. Скажем, вот такой вот код (из dcraw), который делает преобразование по матричному профилю для 3-4 входных каналов (цветов) и трех выходных:
  1. out[0] = out[1] = out[2] = 0;
  2. for (сc=0;сc<colors;сc++) {
  3.   out[0] += out_cam[0][сc] * img[сc];
  4.   out[1] += out_cam[1][сc] * img[сc];
  5.   out[2] += out_cam[2][сc] * img[сc];
  6. }
  7. for(=0;сc<3;сc++) img[сc] = CLIP((int) out[]);
img[] - unsigned short, out[] - int, out_cam[] - float.

Смотрю на код, который порождает интеловский компилятор. Ну код, да. (три-)четыре load по 2 байта (количество loads зависит от colors /количества цветов/), дальше "вручную" выписанный dot product (нормальный, насколько это возможно), ну и обрезание до диапазона 0-65к и store.

Скорость работы этого кода - 100 мегапикселей в секунду на Sandy Bridge 4.5Ghz (в один поток, понятно что параллелится это на ура). Как-то не очень....

Да, считаем в мегапикселях т.к. в unsigned short у нас 8 байт на (4-компонентный) пиксель, а для float/int - 16 байт.

Visual Studio .sln/.vcproj generator?

По многочисленным просьбам трудящихся, я поставляю вместе с LibRaw еще и .sln/.vcproj файлы для MS Visual Studio.

Генерирую я их с помощью Qmake и все более-менее работает, но:

  • Иногда (когда Юпитер в Рыбах?) в sln-файле вместо относительных путей оказываются полные, приходится ручками чистить.
  • Проекты содержат AdditionalIncludeDirectories указывающие (абсолютным путем) на mkspecs от моего Qmake.
  • Можно сгенерировать проект для 32-бит, вроде бы можно (хотя не пробовал) для 64 бит, а вот под две платформы сразу - не умеет.
  • Была еще проблема с зависимостями (exe - dll), ибо зависимости ловятся искуственным интеллектом, но вроде я научился добиваться от него счастья.
  • Достали win32:/unix: конструкции в .pro-файлах, блин.
Короче, неаккуратненько, неровно висят.

Попробовал CMake и счастья еще меньше, проекты ALL_BUILD и ZERO_CHECK раздражают мое эстетическое чувство. При этом проблема абсолютных путей не решена, а дальше я копать не стал и CMake снес.

Что я упустил? Какой еще есть варез, который нагенерирует мне sln/vcproj из простых текстовых файлов?

LibRaw 0.14 Alpha

По сложившейся традиции, анонсирую тут новую major версию LibRaw, которая пока существует в альфа-варианте.

Скачать ее можно в обычном месте, почитать формальный Changelog там же, а тут хочется рассказать об изменениях человеческим языком.

До сего момента жизнь в LibRaw была устроена просто: открыл файл (LibRaw::open()), распаковал (LibRaw::unpack()), если своего постпроцессинга нет, то попользовался нашим (LibRaw::dcraw_process()). Если какие-то параметры поменялись, то все сначала, open, unpack и так далее.

Плюс этого подхода в том, что все варится в одном буфере, и распаковывается сразу куда надо и демозаика сразу in-place и все остальное - тоже.

Минус - тоже понятно какой: поменял ББ, даже в интерактивной программе и .... опять надо распаковывать RAW, а скажем в кэноновских CR2 тамошний Хаффман (lossless JPEG) устроен так, что хрен распараллелишь его распаковку. И секунда-две только на 30-мегабайтный CR2 - просто в природе вещей.

Что делаем? Правильно, меняем память на скорость.

Начиная с 0.14 байеровские данные распаковываются в один буфер, а весь постпроцессинг идет в другом. Для байеровских камер это penalty по памяти в 25% (40Mb для 20-мегапиксельной камеры), зато счастье велико есть. Для не-байеровских камер потери больше (вдвое), но там и кадры, как правило, небольшие (sRaw - 3-10 мегапикселов, фовеоны - 4Mpix), а владельцы Sigma SD1 или multi-shot задников могут и пару гигабайт памяти докупить.

О консистентности

Чтобы на времени компиляции убедиться в том, что у нас MS Visual C++ 2008 SP1+, нужно забабахать вот такое вот:
  1. #if defined(_MSC_VER) && _MSC_VER == 1500 && _MSC_FULL_VER >= 150030729

Ну ладно, ну вот лично я бы две старших цифры в _MSC_VER занял бы под major версию, а две младших - под minor (сервис-паки, то-се), ну ладно, пусть будет два макроса.

Опять-таки, ладно, что MS Visual C++ 2008 это на самом деле Visual C++ 9.0, а _MSC_VER у него 1500. Ну логично же, да?

Но покажите мне пожалуйста табличку в официальной документации (на MSDN, например), где были бы перечислены версии компиляторов и против каждой версии было бы написано значение _MSC_VER и прочих макросов, важных для определения версии компилятора. blogs.msdn и social.msdn не принимаются, я хочу именно что документацию

А если эта табличка там есть (я не нашел), то какой осмысленный запрос надо вфигачить в поиск по MSDN, чтобы искомый документ оказался в первой тройке.

P.S. Нет, я не привередничаю. OpenMP в нужном мне виде правильно работает в VC++ 2010 и в 2008SP1, я и хочу чтобы оно собиралось бы с OpenMP на вышеуказанных версиях, а на более старых - и не думало бы. Аналогичный случай имеется с C++ TR1, который, вроде бы, человеческим тоже стал в 2008SP1.

P.P.S. В blogs.msdn.com, в каментах, сотрудник MS пишет что надо делать вот так:

  1. #if defined(_MSC_VER) && (_MSC_FULL_VER > 150021022 || _MSC_FULL_VER == 150021022 && _MSC_BUILD >= 8)
  2.        cout << "This is VC9 RTM or above." << endl;
  3. #endif
  4.  
  5. #if defined(_MSC_VER) && (_MSC_FULL_VER > 150030729 || _MSC_FULL_VER == 150030729 && _MSC_BUILD >= 1)
  6. cout << "This is VC9 SP1 or above." << endl;
  7. #endif
У меня нет слов. Еще и _MSC_BUILD (которого нету в VC8/2005 и более старых).

LibRaw 0.13

По традиции, анонсируем LibRaw 0.13-Release.

В сравнении с бетой-1 (анонсированной ранее), случились некоторые изменения к лучшему:

  • Обновились распаковщики данных (на dcraw 9.06), отчего добавилась поддержка шести новых камер, включая Панасоники GH2 и GF2 и Sony A-580. Еще для девяти камер обновились цветовые данные.
  • Экспокоррекция со сжатием светов теперь работает просто по такой тоновой кривой, линейной внизу и корнекубичной вверху. Без всяких заумных контекстных расчетов яркости (изначально заимствованных из RawTherapee), которые подглюкивают на изображениях, сильно окрашенных в синие тона (и красные тоже, но в меньшей степени).
  • Ну и много всяких правок по мелочи.
Прошу любить и жаловаться.

LibRaw 0.13-Beta1

Отметим завершение каникул анонсом LibRaw 0.13-Beta1.

Сегодня на экране:

  • Ускорение распаковки хаффмана за счет более правильной буферизации (а для файлов .CR2 - еще и за счет правильного пред-расчета смещений). В результате LibRaw::unpack() работает раза в полтора быстрее для .CR2 и на 20-30% быстрее для других подобных форматов (NEF, packed DNG).
  • Масса новых плюшек в demosaic packs (похоже, пора их переименовывать в feature packs):
    • Шумопонижение разных видов (подавление banding, подавление импульсного шума, выравнивание зеленых каналов).
    • Новый, более правильный, алгоритм автоподавления хроматических аберраций.
    • Правильная экспокоррекция с возможностью сохранять детали в светах (аналог compressed exposure в RPP).
    • Ускорение медианных фильтров при помощи OpenMP
  • Ну и, естественно, все фиксы из ветки 0.12
Все это благолепие - скоро в digiKam (собственно, кроме экспокоррекции - оно уже там).

О степенной функции, OpenMP и прочих граблях

Есть вот такое вот известное выражение, переложеное из википедии:

  1. #define To_sRGB(q) (((q)<=0.0031308f)? 12.92f*(q) : (1+0.055f)*powf(q,1/2.4f)-0.055f)
В том смысле, что у sRGB внизу - линейный участок, а дальше степенная функция.

Если его напрямую запрограммировать (вот прямо с powf()), то в зависимости от компилятора получается от 7 Mpix/sec (Visual C++ 2010, один поток) до 100Mpix/sec (Intel Parallel Studio XE, включен OpenMP). Пиксель - это 3 компонента по 4 байта (float), то бишь гигабайт с небольшим в секунду - это максимум.

Как-то медленно.

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

Полна чудес могучая природа

А в SSE4.1 оказывается есть минимум-максимум для 16-битных целых. 8 штук зараз.

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

И dot-product есть, правда только для float/double.

Чешутся руки забить на владельцев AMD и всего младше Penryn, держите меня...

Rawspeed: записки на манжетах

Есть такая библиотека RawSpeed, которая натурально написана с душой и склонностью к правильным оптимизациям. Например, файлы .CR2 распаковываются раз в пять быстрее чем это делает LibRaw.

В стремлении эту несуразность поправить, фтыкаю в ее исходники одним глазом, вторым и третьим - в результаты прогона профайлера на LibRaw и RawSpeed на одном и том же файле.

И вижу интересное (в исходниках, не в профайле): Canon 1D Mark III обрабатывается у Коффина в dcraw (и у нас) специфическим способом. Там, как обычно, грубый хак, но работающий. Касается этот хак буквально двух пикселов по ширине на рамке, видимой части изображения - не касается. Ага, сказали мужики и достали лом побольше пошаговый отладчик и grep.

Зная, что меня читают некоторые пользователи RawSpeed, имею сказать, исключительно в информационных целях:

  • RawSpeed извлекает уровень черного только из DNG и NEF, в остальных случаях берется predefined-значение из базы данных по камерам.
  • Уровень черного - это одно число. Даже не два, как в LibRaw/dcraw и не сложная структура, как оно бывает в некоторых камерах вроде PhaseOne (да и DNG - тоже. DNG-шные теги усредняются).
В результате будет два интересных эффекта:

Обилие демозаик

Тем временем, вышла LibRaw 0.12 (beta).

Усилиями контрибьюторов (как их писать на нашем, "вкладчики"?) была добавлена большая пачка разнообразных методов демозаики.

К несчастью, лицензионные ограничения не позволяют распространять все это богатство на тех же условиях, что и LibRaw (LGPL/CDDL), поэтому часть этих методов раздается отдельно, под соответствующими лицензиями:

  • Демозаика DCB и шумопонижение FBDD (автор: Jacek Gozdz) добавлена в основную LibRaw, ибо лицензия позволяет.
  • LibRaw-demosaic-pack-GPL2 включает в себя:
    • Алгоритмы, реализованные в Modified DCRAW by Paul Lee: VCD, modified AHD, AHD+VCD и модифицированные медианные фильтры.
    • Алгоритмы из Perfect Raw by Manuel Llorens (удивительно, но не нашел куда нормально дать ссылку): AFD и LMMSE
  • LibRaw-demosaic-pack-GPL3: AMaZE из RawTherapee 3 и подавление хроматических аберраций оттуда же.

Удивительное дело, но на тех снимках, на которых я тестировался (попались детские портреты) разница между алгоритмами - минимальна. Да, она есть, она видна на мелких деталях (а где же еще), но стоит ли овчинка того или нет - мне сложно сказать.

Beware: git(hub)+git+subversion= many epic fails...

Вынужден с огорчением признать, что такая вот схема:

GitHub <--> локальный git <--> SVN-репозиторий
оказалась нежизнеспособной, хотя изначально не казалась таковой.

У меня это, правда, осложнялось тем, что в SVN-е запомнена долгая и трудная жизнь, а на GitHub я поэкспортил только /trunk/, только одного проекта, да и то не весь, а только начиная с публичных версий.

LibRaw 0.11.2

По традиции, поспамлю тут немножко.

Вышла LibRaw 0.11.2 в которой:

  • Вычитание уровня черного производится всегда на стадии постпроцессинга (про что я тут уже писал), что сильно упрощает жизнь, особенно если у вас постпроцессинг свой: не надо разные камеры обрабатывать разными способами, черный или всегда сами вычитаете или всегда зовете LibRaw::subtract_black().
    Для пользователей постпроцессинга LibRaw в этом месте ничего вообще не изменилось, API старый, вычитание делается прозрачно для вас.
  • Сильно порефакторена AHD-интерполяция, если используется OpenMP, то на 4-процессорной машине оно теперь раза в полтора быстрее чем раньше (тоже с OpenMP) на полной обработке, т.е. AHD-стадия быстрее разика в 2-2.5
  • Новый I/O-layer, сделанный на iostreams, что для мультипоточных программ на Win32 и Linux сильно быстрее (на этих системах в FILE* I/O явно переборщили с блокировками). На FreeBSD/MacOS разницы никакой нет, что мне говорит об отсутствии там лишних блокировок (а кому-то еще - об убогости тамошней реализации iostreams :).
  • Поддержан мешочек новых камер (импортирована свежая dcraw 9.05):
    • Canon: G12, SX120, 60D,
    • Hasselblad H4D, Nokia X2, Olympus E-5,
    • Nikon: D3100, D7000, P7000,
    • Panasonic: FZ40, FZ100, LX5,
    • Pentax: K-r, K-5, 645D,
    • Samsung GX20, WB2000
  • Ну и по мелочи много поправлено, читайте Changelog.

Ну и на закуску: основная ветка разработки теперь дублируется на GitHub: github.com/LibRaw/LibRaw, отчего участие в наших развлечениях для сторонних желающих сильно облегчилось. Увы, но сил на дублирование всего репозитория не хватило, поэтому релизные боковые ветки - бэкпортятся в master, но вот самих боковых веток на github нету.

LibRaw 0.10 и 0.11

Некоторые пользователи LibRaw тусуются здесь, поэтому я тут и поспамлю немножко.

LibRaw 0.10 Release
Это формальный выпуск, признание того факта, что версия 0.10 - стабильна, каких-то значимых нареканий на нее за лето не было. Значимых отличий от 0.10-Beta3 нет.
LibRaw 0.11 Beta1
А это, наоборот, дивный новый мир с дополнениями и изменениями:
  • Выходное изображение (результат) можно кропать. Кроппинг делается до постпроцессинга, поэтому для маленького выходного размера постпроцессинг будет очень быстрым*.
  • Сильно изменена обработка вычитания уровня черного: теперь для всех камер (за единственным, но никому не интересным исключением, которое я просто протестировать не могу**) на этапе распаковки RAW-данных вычитание черного не производится. Дальше можно вычитать одним из трех способов: постпроцессинг (dcraw_process()) сделает все сам, если вы делаете демозаику и т.п. сами - вам подойдет новый вызов LibRaw::subtract_black(), ну и полностью самостоятельно все можно делать, данные черной рамки доступны и все такое.
  • Ну и всякие изменения по мелочи, скажем аллоцированное dcraw_make_mem_image()(_mem_thumb()) теперь надо освобождать через dcraw_clear_mem(), обсуждению этого парадокса посвящен предыдущий пост.

Ну кто так строит.....

С лета у меня висела плавающая бага, все руки не доходили.

Суть в том, что в LibRaw внутри аллоцируется кусок памяти, отдается вызвавшему приложению, а оно, когда с ним наиграется, должно освободить его путем банального free()

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

Беда, коль сапоги начнет печи...

Вот, казалось бы, хорошая идея - давить пиковые выбросы прямо в RAW-данных. Hot pixels так можно задавить. Вот мне для LibRaw такой патч и прислали, причем, как я понимаю, он уже вовсю работает в одном опенсорсном RAW-процессоре.

На картике слева (кликабельна, по клику увидите как оно на экране при 150%) показан результат применения этого веселого подхода к снимку resolution target. Сверху - результат фильтрации, снизу - без фильтрации. Холст, масло, Canon 500D, снимок взят с imaging-resource.

И результат совпадает с ожиданиями, если на исходно ч-б картинке обработать каналы независимо, до интерполяции, а потом интерполировать, то появления цветных каемок сложно будет избежать.

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

Такое впечатление, что тестировать результаты собственного программирования - просто не принято в последние годы. Я эту красивую картинку получил в первом же (!) тесте (то, что туда попалась resolution target - случайность, но артефакты полезут на любых контрастных границах).

Похоже, что я излишне суров к Adobe, дивный новый мир опенсорца - гораздо хуже.

P.S. Второй содержательный патч из того же источника - не тестировал пока, хотя он мне идеологически тоже не нравится. Он давит maze artefacts, но должен и малоконтрастные детали тоже сгрызать.

Linux и Large Files

А вот представим, что у меня есть библиотека, собранная с -D_FILE_OFFSET_BITS=64
Все fopen/fseek/fread/fclose там делаются внутри, снаружи только имена файлов прилетают.

А потом я к ней линкую приложение, компилированное без этого флага, просто gcc -c

Вопрос: оно будет работать? Или возможны моментики?

Нет, я не ленивый и конечно попробую, но у меня этих линуксов под рукой штуки две и с новыми ядрами, а что будет со старыми ядрами/glibc/whatever?

P.S. Назначение LARGEFILE_SOURCE/LARGEFILE64_SOURCE так и не понял, вроде бы для позиционирования за 2 гигабайта и чтения мелкими кусками достаточно _FILE_OFFSET_BITS

P.P.S. Единственная система, где вообще не надо париться - FreeBSD :) Какой, оказывается, кусок жизни с этой LFS прошел мимо меня...

LibRaw Lite

почти копия анонса с сайта

По многочисленным заявкам нелюбителей GPL выпущена LibRaw-Lite

Как следует из названия, это облегченная версия LibRaw, основные отличия которой от полной версии таковы:

  • Лицензия LGPL, что позволяет использовать (немодифицированную) библиотеку в не-опенсорсных приложениях.
  • (увы) нет поддержки Foveon в силу лицензионных ограничений на этот кусок dcraw (откуда растут ноги у LibRaw). Мы работаем над этим и возможно предложим какую-то замену.
  • Нет целого ряда улучшений (сделанных нами относительно функциональности dcraw):
    • черная рамка (маскированные пикселы) не извлекается, эти пикселы приложению не доступны;
    • вычитание точки черного и прочая пред-интерполяционная обработка RAW-данных не отключается;
    • способ, которым получены цветовые данные (матрицы RGB-XYZ и т.п.) не запоминается;
    • нет поддержки OpenMP.

Другими словами, все то хорошее что мы сделали в расчете на разработчиков RAW-конверторов, анализаторов RAW и прочие программы, которым нужен доступ к исходным RAW-данным - в Lite-версии отсутствует.

LibRaw 0.7 Release

Вышла LibRaw 0.7. В том смысле, что "не бета".

Поскольку эта версия полностью совместима (на уровне исходных текстов) с версиями 0.5 и 0.6, поддержка старых версий прекращается вот прямо сегодня.

Что нового

По отношению к 0.7-BETA5:
RAW-данные с сенсоров Fuji SuperCCD раскладываются по правильным цветовым каналам на этапе распаковки RAW, а не на фазе постпроцесинга, как оно было ранее.

Это важно для тех приложений, которые самостоятельно делают дебайеризацию и вообще постпроцессинг. Кроме того, пример 4channels стал правильно работать с файлами с вышеупомянутых камер.

По отношению к ветке 0.6.x:
  • Извлекаются (и доступны в приложении) данные черной рамки
  • Приложению доступны "совсем необработанные" RAW-данные: без вычитания точки черного, замазывания нулевых пикселов и наложенной тоновой кривой.
  • Новая input framework. На ее основе поддержано чтение из файла и из буфера в памяти, реализовать собственное чтение совсем несложно.
  • Для камер Fuji доступны исходные (неповернутые) позиции пикселов.
  • Новые тестовые приложения unprocessed_raw и 4channels, позволяющие посмотреть на непроцессированные данные.

LibRaw 0.6.15 и 0.7-BETA5

Если вы используете LibRaw 0.6.14, то вам полезно было бы обновиться до 0.6.15. В предыдущей версии - обидная ошибка (переполнение) в генерации гамма-кривой.

Кроме того, в 0.6.15 и в 0.7-BETA5 инкорпорирована новая dcraw. Из существенного: улучшена и генерализована поддержка PEF-файлов Pentax.

качать отсюда

свежие версии LibRaw

Для читающих анонсы тут, а не на libraw.su/org

Вышли новые версии LibRaw. Все изменения довольно существенные:

  • Поддержан Pentax K2000/K-m
  • Поддержана правильная распаковка sRAW от Canon 5D Mark II с последней версией firmware
  • При использовании встроенного постпроцессинга можно задать свою gamma-curve (с опциональным линейным участком в начале)

Кратко о чувствительности цифровых камер

Я несколько опережаю события и фактически презентую незаконченное микро-исследование, но мне кажется полезным немножко обсудить методику с сообществом, прежде чем доделывать работу до конца.

Текущие стандарты (ISO 12232) на чувствительность цифровых камер довольно креативны: специфицируется значение, которое должен иметь средний тон (18%-й серый) в sRGB-файле, а про RAW ничего не говорится. Неявно предполагается, что RAW обрабатывается каким-то проявителем конвертором и, соответственно, чувствительность оценивается у всего комплекса камера-конвертор. Собственно, оно так и было в пленочном мире, пока не проявишь - ничего не понятно.

Вместе с тем, линейная передаточная характеристика современных цифровиков и доступность RAW-данных в цифровом виде позволяют подойти к проблеме и с другой стороны.

Расщепи своих каналов

Выпустил LibRaw 0.7-BETA1.

Каких-либо изменений собственно библиотеки в сравнении с предыдущей Alpha6 нет, но зато добавлено новое тестовое приложение, которое мне кажется очень полезным в хозяйстве:

4channels - сохраняет RAW-файл в виде четырех отдельных TIFF-файлов, по одному на канал.

DNG, уровень черного и dcraw

В стандарте DNG 1.2 правильной поддержке уровня черного уделена масса внимания: можно задать базовый паттерн произвольного размера с разными уровнями (скажем, поканальными) и коррекцию этого паттерна для каждой конкретной строки и столбца. Для большинства практических применений этого достаточно, нормально описать таким способом нельзя, пожалуй, только неповернутый паттерн Fuji SuperCCD.

Надо сказать, что Adobe DNG Converter креативно пользуется этими возможностями. Скажем, для новых камер Canon (смотрел 50D и 5DmkII) считается только базовое значение, тогда как для старых (смотрел 400D) считается уровень черного для каждой строки. И это правильно, товарищи!

Но вот dcraw, а за ней и все приложения, использующие её код, начиная с LightZone и ACDSee, а заканчивая LibRaw, поступают с этими данными тупо и глупо: все что есть в DNG-файле усредняется и это среднее вычитается из всех значений.

Естественно, это все касается только тех форматов данных, где вычитание базового черного не делает сама камера. Из распространенных - это камеры Canon (все), ряд моделей Sony и многие P&S камеры.

Как следствие, если в DNG-файле и были данные для подавления бандинга и прочих подобных безобразий, на этапе обработки ими не пользуются и бандинг не подавляется.

Пользователи LibRaw будут со временем осчастливлены кодом получше, а вот пользователям других производных от dcraw я бы посоветовал форматом DNG без нужды не увлекаться.

Syndicate content


.