Примеры использования

Обзор примеров в дистрибутиве (samples/*)

В поставку LibRaw включено несколько примеров использования библиотеки, их исходные тексты расположены в каталоге samples/, после сборки они оказываются в каталоге bin/:

  • raw-identify Из вызовов LibRaw используется только open_file(), далее идет код, печатающий значения полей структуры imgdata. Выдача raw-identify/raw-identify -v практически полностью копирует выдачу dcraw -i/dcraw -i -v (в выдаче примера дополнительно печатаются источники цветовых данных и легенда к ним).

    Дополнительные параметры, отсутствующие у dcraw: -u - печатать имя функции - распаковщика данных; -u -f - печатать имя распаковщика и размер черной (маскированной) рамки.

  • simple_dcraw Простой "эмулятор" dcraw, воспроизводящий поведение dcraw [-D] [-e] [-v] [-T]. Результат работы должен бинарно совпадать с результатами работы dcraw запущенной с нужными ключами. Упрощенный вариант этого примера рассмотрен ниже.
    Ключ -B включает использование интерфейса open_buffer() куда передается mmap()-ed файл (Unix only).
  • dcraw_half Демонстрация использования C API. Пример эмулирует поведение dcraw -h (какие-то еще управляющие параметры этому примеру задать нельзя). Результат работы должен бинарно совпадать с результатами работы dcraw -h.
  • dcraw_emu Полный эмулятор dcraw (за исключением ключей -D -d -P -K -i -e, которые обрабатываются в других примерах использования). Основной интерес представляет обработка ключей командной строки (скопированная из dcraw). Результат работы должен бинарно совпадать с результатом работы dcraw с теми же ключами командной строки.

    Этот пример поддерживает дополнительные ключи, отсутствующие в оригинальной dcraw:

    -mmap
    Включает использование интерфейса open_buffer() куда передается mmap()-ed файл (Unix only).
    -mem
    Входной файл читается в буфер в памяти и раскодируется оттуда.
    -c значение в диапазоне 0-1
    Ключ меняет значение параметра params.adjust_maximum_thr. Для отключения автоматического вычисления максимума, поставьте этот параметр в 0.0.
    Умолчание: 0.75
    -timing
    Включает тайминг отдельных этапов обработки.
    -G
    Включает green_matching: выравнивание каналов зеленого для тех камер, где эти каналы различаются.
    -B x y w h
    Включает обрезание (cropping) выходного изображения до прямоугольника с верхним левым углом в x,y шириной w и высотой h. Координаты и размеры - до поворотов изображения (если применяются повороты).
    -dcbi N
    Устанавливает количество дополнительных итераций алгоритма DCB (только для -q 4). Умолчание - 0 (нет дополнительных итераций)
    -dcbe
    Включает режим DCB color enhance (только для -q 4).
    -eeci
    Включает режим EECI refine (только для mixed VCD/AHD -q 8)
    -esmed N
    Количество проходов edge-sensitive median filter для интерполяции VCD+AHD
    -acae r b
    Включает режим подавления хроматической аберрации. Параметры r и b означают величину коррекции по красной и синей осям. Эти параметры обязательны, для автоматической коррекции следует использовать -acae 0 0
    -aline l
    Включает режим подавления полосатости (banding). l - степень подавления шума, диапазон значений 0.001-0.02, типичное значение 0.005
    -aclean l c
    Включает режим подавления импульсного шума. l - степень подавления яркостного (luminocity) шума, c - цветового (chrominance) шума. Разумный диапазон значений обоих параметров 0.005-0.05, типовое - 0.01.
    -agreen g
    Включает режим выравнивания зеленых каналов на равномерных поверхностях. g - степень чувствительности алгоритма, диапазон значений 0.01-0.1, типичное значение 0.03.
    -aexpo e p
    Включает экспокоррекцию (до демозаики). e - величина экспокоррекции (в линейной шкале), диапазон от 0.25 (-2 стопа) до 8 (+3 стопа). p - степень предохранения светов при положительной экспокоррекции, диапазон от 0.0 (просто линейный сдвиг данных с клиппингом) до 1.0 (полное отсутствие дополнительного клиппинга от экспокоррекции).
  • half_mt Эмулятор dcraw -h, понимает ключи -a (автоматический баланс белого по всему изображению), -w (баланс белого камеры), -T (выводить в tiff) и -J n - количество параллельных threads, запускаемых для обработки изображений.
    На мультипроцессорных/multicore машинах дает существенный выигрыш в скорости при массовой обработке.
    На Win32-машине пример собирается из исходного файла half_mt_win32.c, причина в том, что работа с threads на Windows принципиально другая и проще размножить простые исходники, чем написать один сложный.
  • mem_image Пример использования функций dcraw_make_mem_image и dcraw_make_mem_thumb: распаковка изображений и preview() в память с последующей простой записью в форматах PPM (и JPEG для thumbnail). Результат работы должен быть идентичен результатам работы dcraw с теми же ключами (поддерживаются ключи -4, -1, -e, -h).
  • unprocessed_raw - извлечение максимально неизмененных RAW-данных, без вычитания уровня черного и маскирования черных пикселов (на тех камерах, где возможно маскирование). Для тех камер, которые выдают в RAW-данные черную рамку (маскированные пикселы) - рамка включается в выдаваемые данные. Ключи командной строки: -q - не выдавать текстовую справку о размерах файла, -A - автомасштабирование данных в целое число раз, -g выдавать гамма-корректированные (2.2) данные, а не линейные, -N - выключает наложение тоновой кривой на RAW-данные, -B включает вычитание уровня черного из данных, -M добавляет маскированную рамку к результирующему изображению.
  • 4channnels - сохраняет RAW-файл в виде 4 отдельных 16-битных grayscale TIFF-файлов (поканально).
    Ключи командной строки:
    • -s N выбрать N-е изображение (для файлов с несколькими изображениями)
    • -g выводить гамма-корректированное (2.2) изображение
    • -A автомасштабирование значений в целое число раз
    • -B отключить вычитание уровня черного
    • -N отключить тоновую кривую для RAW
  • multirender_test - простой пример, показывающий возможность множественной постобработки с разными параметрами без переоткрытия файла.

Пример simple_dcraw

Ниже рассмотрен пример samples/simple_dcraw.cpp - эмулирующий поведение dcraw [-D] [-e][-v][-t]. Для экономии места представим, что всегда заданы ключи -t -v (чтобы не комментировать разбор командной строки) и что параметр (имя файла) всегда один и всегда передается.

int main(int ac, char *av[])
{
    int  i, ret, verbose=0, output_thumbs=0;
    char outfn[1024],thumbfn[1024]; 

    // Создадим объект - обработчик изображений.
    LibRaw RawProcessor;
    
    // В TIFF пишется дата в локальном формате, для совместимости с dcraw поставим таймзону
    putenv ((char*)"TZ=UTC"); 

// Определим переменные для удобного доступа к полям RawProcessor
#define P1  RawProcessor.imgdata.idata
#define S   RawProcessor.imgdata.sizes
#define C   RawProcessor.imgdata.color
#define T   RawProcessor.imgdata.thumbnail
#define P2  RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params

    OUT.output_tiff = 1; // Выводить будем TIFF

   // Откроем файл
   if( (ret = RawProcessor.open_file(av[1])) != LIBRAW_SUCCESS)
      {
          fprintf(stderr,"Cannot open %s: %s\n",av[i],libraw_strerror(ret));

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

          RawProcessor.recycle(); 
          goto end;
      }

   // Распакуем изображение
   if( (ret = RawProcessor.unpack() ) != LIBRAW_SUCCESS)
      {
          fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));

          if(LIBRAW_FATAL_ERROR(ret))
                    goto end;
          // для нефатальной ошибки - пробуем продолжить
      }
  // Распакуем thumbnail
  if( (ret = RawProcessor.unpack_thumb() ) != LIBRAW_SUCCESS)
     {
          // обработка ошибки полностью аналогична предыдущему случаю
           fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
           if(LIBRAW_FATAL_ERROR(ret))
                   goto end; 
    }
  else // Успешно распаковали thumbnail, запишем его в файл
    {
      snprintf(thumbfn,sizeof(thumbfn),"%s.%s",av[i],T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg" : "thumb.ppm");
      if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_thumb_writer(thumbfn)))
        {
                fprintf(stderr,"Cannot write %s: %s\n",thumbfn,libraw_strerror(ret));

                // в случае фатальной ошибки мы должны заканчивать обработку текущего файла
                if(LIBRAW_FATAL_ERROR(ret))
                          goto end; 
        }
    }
   // Распаковка данных
   ret = RawProcessor.dcraw_process();

    if(LIBRAW_SUCCESS != ret ) // ошибка на предыдущем шаге
          {
               fprintf(stderr,"Cannot do postprocessing on %s: %s\n",av[i],libraw_strerror(ret));
               if(LIBRAW_FATAL_ERROR(ret))
                        goto end;
          }
   else  // Успешная обработка документа
     {
        snprintf(outfn,sizeof(outfn),"%s.%s", av[i], "tiff");
        if( LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
                fprintf(stderr,"Cannot write %s: error %d\n",outfn,ret);
     }

  // Не делаем recycle, не зовем деструктор, C++ все делает за нас.
  return 0;
end:
  // сюда попали после ошибки
  return 1;
}