[вернуться к оглавлению]

# LibRaw: примеры использования

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

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

- raw-identify Из вызовов LibRaw используется только open_file(), далее идет код, печатающий значения полей структуры imgdata. Выдача raw-identify/raw-identify -v практически полностью копирует выдачу dcraw -i/dcraw -i -v (в выдаче примера дополнительно печатаются источники цветовых данных и легенда к ним).
- 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 с теми же ключами командной строки.
  Этот пример поддерживает дополнительный ключ командной строки -1, означающий "выводить 16-битные данные (tiff/ppm/pgm) с гамма-коррекцией".
  Ключ -B включает использование интерфейса open_buffer() куда передается mmap()-ed файл (Unix only).
- 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-данные.

  В состав LibRaw-Lite данный пример не входит.

- 4channnels - сохраняет RAW-файл в виде 4 отдельных 16-битных grayscale TIFF-файлов (поканально).
  Ключи командной строки:
  - -s N выбрать N-е изображение (для файлов с несколькими изображениями)
  - -g выводить гамма-корректированное (2.2) изображение
  - -A автомасштабирование значений в целое число раз
  - -B отключить вычитание уровня черного
  - -N отключить тоновую кривую для RAW

  В примере для LibRaw-Lite ключи -B и -N не поддерживаются.

## Пример 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;
            }
        }
       // Распаковка данных
       if(OUT.document_mode)
               ret = RawProcessor.dcraw_document_mode_processing();
       else
               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;
    }

[вернуться к оглавлению]

Last modified: Mon May 4 22:11:59 MSD 2009