Usage Examples

Overview of Examples in the Distribution Package (samples/*)

The LibRaw package contains several examples illustrating the use of this library. Their source codes are located in the samples/ folder, and after library build they will be in the bin/ folder:

  • raw-identify The only LibRaw call it uses is open_file(); further code prints the values of the fields of the imgdata structure. The output of raw-identify/raw-identify -v is virtually identical to the output of dcraw -i/dcraw -i -v (in the output of this example, the sources of color data in the numeric form are additionally printed). Command line key -u shows unpacking function name, while -u -f prints function name and masked are sizes.
  • simple_dcraw A simple "emulation" of dcraw reproducing the behavior of dcraw [-D] [-e] [-v] [-T]. The result of its work must be binary identical to the result produced by a dcraw run with relevant keys. A simplified version of this example is considered below.
    -B command-line switch turns on use of open_buffer() API call used via mmap() of input file (Unix only).
  • dcraw_half Demonstrates the use of C API. The example emulates the behavior of dcraw -h (no other control parameters can be specified in this example). The result of its work must be binary identical to the results produced by dcraw -h.
  • dcraw_emu Complete emulation of dcraw (except for keys -D -d -P -K -i -e, which are considered in other usage examples). Of most interest is processing of command line keys (copied from dcraw). The result of its work must be binary identical to the results produced by dcraw with the same command line keys.

    This sample supports additional command-line parameters absent in original dcraw:

    -mmap
    Use open_buffer() interface. Buffer prepared by mmap() call. This option not supported under Win32.
    -meme
    Use open_buffer() interface. Buffer prepared by malloc()+read() calls.
    -c float-value
    This key sets params.adjust_maximum_thr parameter.
    Use -c 0 to completely disable automatic maximum calculation.
    Default value: 0.75
    -timing
    Turns on detailed timing print.
    -G
    Turns on "green_matching" mode to suppress color mazes on cameras with different green channels.
    -B x y w h
    Crops output to rectangle with width w, height h and x,y coordinates of left upper corner. All coordinates applied before any image rotation.
    -dcbi N
    Sets number of additional DCB-demosaic iterations (option valid only for -q 4, i.e. for DCB demosaic).
    -dcbe
    Turns on DCB color enhance mode (only for DCB demosaic, -q 4).
    -eeci
    Turns on EECI refine (only for mixed VCD/AHD -q 8)
    -esmed N
    Number of passes of edge-sensitive median filter for VCD+AHD demosaic.
    -acae r b
    Turns on chromatic aberration suppression. r and b parameters are amount of red and blue axis correction respectively. For automatic correction use -acae 0 0.
    -aline l
    Turns on banding suppression. l is the correction amount, useable range is from 0.001 to 0.02, typical value is 0.005.
    -aclean l c
    Turns on impulse noise suppression. l and c are luminocity and chrominance suppression values, respectively. Useable range for both is 0.005-0.05 and typical value is 0.01.
    -agreen g
    Turns on green channels equalization on uniform surfaces. g is the algorithm sensitivity with useable range 0.01-0.1 and typical value 0.03.
    -aexpo e p
    Turns on exposure correction. e is exposure shift in linear scale from 0.25 (darken 2 stops) to 8.0 (lighten 3 stops). p is highlights preservation amount from 0.0 (no preservation, full clipping) to 1.0 (full preservation, S-like curve in highlights).
  • half_mt Emulation of dcraw -h. It "understands" the following keys: -a (automatic white balance over the entire image), -w (white balance of the camera), -T (output in the tiff format), and -J n (number of parallel threads launched for image processing).
    On multiprocessor/multicore computers, the speed gain is notable in the case of mass processing. On a Win32 machine, the example is assembled from the initial file half_mt_win32.c, since work with threads under Windows is fundamentally different and it it easier to copy simple source codes than write one complex code.
  • mem_image This sample uses dcraw_make_mem_image and dcraw_make_mem_thumb calls, than writes data in PPM format. Results should be identical with dcraw with same command-line options (options supported: -4, -1, -e, -h).
  • unprocessed_raw This sample extracts (mostly) unaltered RAW data including masked pixels data (on supported cameras). If black frame exists and black frame extraction is supported for given format, masked pixels data is added to resulting .TIFF file. Command line options: -q - be quiet, -A - autoscale data (integer multiplier), -g gamma-correction (gamma 2.2) for data (instead of precise linear one), -B turns on black level subtraction
  • 4channnels - splits RAW-file into four separate 16-bit grayscale TIFFs (per RAW channel).
    Command line switches:
    • -s N selects N-th image from RAW with multiple images
    • -g gamma correction (gamma 2.2)
    • -A values autoscale by auto-calculated integer factor
    • -B turn off black subtraction
    • -N no RAW curve
  • multirender_test - very simple example of multiple rendering on one file without reopen.

Example of docmode

Below we consider the samples/simple_dcraw.cpp example, which emulates the behavior of dcraw [-D] [-e][-v][-t]. To save space, let us assume that keys -t -v are always specified (to avoid comments on command line parsing) and there is always one parameter (name of file), which is the only one and always passed to the program.

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

    // Creation of image processing object
    LibRaw RawProcessor;
    
    // The date in TIFF is written in the local format; let us specify the timezone for compatibility with dcraw 
    putenv ((char*)"TZ=UTC"); 

// Let us define variables for convenient access to fields of 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; // Let us output TIFF

   // Let us open the file
   if( (ret = RawProcessor.open_file(av[1])) != LIBRAW_SUCCESS)
      {
          fprintf(stderr,"Cannot open %s: %s\n",av[i],libraw_strerror(ret));

          // recycle() is needed only if we want to free the resources right now. 
          // If we process files in a cycle, the next open_file() 
          // will also call recycle(). If a fatal error has happened, it means that recycle()
          // has already been called (repeated call will not cause any harm either).

          RawProcessor.recycle(); 
          goto end;
      }

   // Let us unpack the image
   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;
          // if there has been a non-fatal error, we will try to continue
      }
  // Let us unpack the thumbnail
  if( (ret = RawProcessor.unpack_thumb() ) != LIBRAW_SUCCESS)
     {
          // error processing is completely similar to the previous case
           fprintf(stderr,"Cannot unpack_thumb %s: %s\n",av[i],libraw_strerror(ret));
           if(LIBRAW_FATAL_ERROR(ret))
                   goto end; 
    }
  else // We have successfully unpacked the thumbnail, now let us write it to a file
    {
      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));

                // in the case of fatal error, we should terminate processing of the current file
                if(LIBRAW_FATAL_ERROR(ret))
                          goto end; 
        }
    }
   // Data unpacking
   if(OUT.document_mode)
           ret = RawProcessor.dcraw_document_mode_processing();
   else
           ret = RawProcessor.dcraw_process();

    if(LIBRAW_SUCCESS != ret ) // error at the previous step
          {
               fprintf(stderr,"Cannot do postprocessing on %s: %s\n",av[i],libraw_strerror(ret));
               if(LIBRAW_FATAL_ERROR(ret))
                        goto end;
          }
   else  // Successful document processing
     {
        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);
     }

  // we don't evoke recycle() or call the desctructor; C++ will do everything for us
  return 0;
end:
  // got here after an error
  return 1;
}

Comments

Hi,
According to the sample code, the option "unprocessed_raw" extracts (mostly) unaltered RAW data including masked pixels data.

Is it possible to extract ALL unprocessed raw data, without the metadata and the thumbnail in order to save it into a new binary file?, can you please point me in the right direction to do this using LibRaw?.

Thanks in advance for your kindly answer.

For many (but not all) RAW formats, you can use this trick:
1) Call LibRaw::open_file()
2) Position to libraw_internal_data.unpacker_data.data_offset
3) Read libraw_internal_data.unpacker_data.data_size bytes

This method will work with Canon CR2, Nikon NEFs and many others.
This method will not work for tiled DNGs

I took the unprocessed_raw.cpp, clean it a little bit the code and processed a 11MB image raw file, but the resultant have 55MB, so i assume that there is a post-processing when saving the file in .tiff format.

I basically want to extract the raw image data, without metadata, read it, make a little processing and then save it in a new file.

In order to do that, your suggestion looks what i need to do, but can you please give a reference code about how to implement it?. I'm not asking for an elaborate coding, only a few lines in order to follow the idea.

I'm not c++ expert, so if the question is basic or simple, i'm sorry.

If you use unchanged unprocessed_raw sample, what size has the result?

Thanks for your answer.

Obviously my cleaning wasn't good, i ran the unprocessed_raw with a raw image file of 11.2MB and the result was a .tiff file with 18.4MB, so i have check my code. Here is the small routine (without validations) that i did:
---

int main(int i, char *rawimg[])
  {
// Initialization
  LibRaw RawProcessor;
  RawProcessor.imgdata.params.document_mode = 2;
  RawProcessor.imgdata.params.output_bps = 16;
  RawProcessor.imgdata.params.output_tiff = 1;
  RawProcessor.imgdata.params.user_flip = 0;
  RawProcessor.imgdata.params.no_auto_bright = 1;
  RawProcessor.imgdata.params.filtering_mode = (LibRaw_filtering)(LIBRAW_FILTERING_DEFAULT);
 
// Opening file and unpack
  int tmpimg;
  i = 1;
  tmpimg = RawProcessor.open_file(rawimg[i]);
  tmpimg = RawProcessor.unpack();
 
// extracting raw image data
  int row, col;
  char rawfn[1024];
  for(row=0;row<RawProcessor.imgdata.sizes.iheight;row++)
    for(col=0;col<RawProcessor.imgdata.sizes.iwidth;col++)
      RawProcessor.imgdata.image[row*RawProcessor.imgdata.sizes.iwidth+col][0]= 
      RawProcessor.imgdata.image[row*RawProcessor.imgdata.sizes.iwidth+col]
      [RawProcessor.COLOR(row,col)];
 
// formating and saving image data
  snprintf(rawfn,sizeof(rawfn),"%s.tiff",rawimg[i]);
  tmpimg = RawProcessor.dcraw_ppm_tiff_writer(rawfn);
 
// cleaning image processor
  RawProcessor.recycle();
 
  return 0;
}

---

If the unprocessed_raw extract only the raw data, without process anything, why the resultant file is bigger that the original?.

According with your suggestion, how can i do the step two (position to libraw_internal_data.unpacker_data.data_offset), and the step three (Read libraw_internal_data.unpacker_data.data_size bytes)?

For the step three, i assume can be done using a "for" structure, but if you can show a basic example code for your suggestion it will be really helpful for me, because i'm not an expert.

Thank you for your time and help.

To turn on pretty printing of code use
<code>
.... your code here
</code>

Also, to pass through antispam filter and captcha, it is better to register on this site once...

Sorry for bad formatting, I'll install plugin for right code display, but not today.

The 'dirty trick' in unprocessed_raw.cpp is P1.colors=1; This is instruction to dump only first component for the internal tiff writer.

The result is larger than source RAW because:

  • The source RAW is compressed, while resulting .tiff is uncompressed
  • The source RAW has 12 or 14 (or, may be, 10) bits per pixel, while resulting .tiff is stored in 16-bit per pixel format.

Thanks for the "dirty trick" info.
I will add the P1.colors=1 to my code and try again.

About your first suggestion, you mention three steps:
1) Call LibRaw::open_file()
2) Position to libraw_internal_data.unpacker_data.data_offset
3) Read libraw_internal_data.unpacker_data.data_size bytes

So i try to code you suggestion:

int main(int i, char *img[])
{
  i=1;
  int tempimg, row, col;
 
// step one: Open file
  LibRaw RawProcessor;
  tempimg = RawProcessor.open_file(img[i]);
#define RAW RawProcessor.libraw_internal_data.unpacker_data
 
// step two: positioning libraw_internal_data.unpacker_data.data_offset
  tmpimg = RawProcessor.unpack();
 
/* how to position it in data.offset?... */
 
// step three: Read libraw_internal_data.unpacker_data.data_size
  for(row=0;row<RAW.data_size.iheight;row++)
    for(col=0;col<RAW.data_size.iwidth;col++)
      RAW[row*RAW.data_size.iwidth+col][0] = RAW[row*RAW.data_size.iwidth+col][RawProcessor.COLOR(row,col)];
 
// mode coding, not finished yet...
 
  RawProcessor.recycle();
  return 0;
}

Am i in the right direction or i'm completely lost?...

Really appreciate any comments you can give me.

Please describe, what kind of data do you want:

- compressed (as in file)
- or unpacked ?

If you wand 'file' data (compressed by lossless jpeg or so), you need to position to data offset and read the data manually (and unpack them)

If you want unpacked data (huffman decoded or so), just use unprocessed_raw sample as your base.

Thanks for the answer.

I didn't know that the raw data can come compressed from the camera, thanks for the tip. Just curious, can you tell me which kind of compression can be found usually? deflate?, other?...

I want the data unpacked, so i will reuse the unprocessed_raw sample as you suggest, using the P1.colors=1.

I'm sorry for all the questions, i really value your help.

Thanks for your answer and suggestion.
I'm trying to compile a .cpp file using g++ and linking libraw, but i'm getting "undefined reference" error. This is the instruction that i'm using:

g++ ext-raw-dat.cpp -o extract -I/usr/local/include/libraw -L/usr/local/lib -lraw

can you tell me please what i am doing wrong?, at least please point me in the right direction, i know the solution must be plain simple, but i'm not really an expert and i don't see it.

Thanks in advance.

What references are undefined?

Usually, you need math library added to linker command line (-lm switch)

Hi!
Thanks for the answer.

This is what i get from g++ (a little bit long, sorry about that):
-----
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `_ZN6LibRaw15ahd_interpolateEv.omp_fn.0':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4178: undefined reference to `GOMP_loop_dynamic_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4166: undefined reference to `omp_get_thread_num'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4178: undefined reference to `GOMP_loop_dynamic_next'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4192: undefined reference to `GOMP_loop_end'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `LibRaw::ahd_interpolate()':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4166: undefined reference to `GOMP_parallel_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:4166: undefined reference to `GOMP_parallel_end'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `_ZN6LibRaw15ppg_interpolateEv.omp_fn.1':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3861: undefined reference to `omp_get_num_threads'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3861: undefined reference to `omp_get_thread_num'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `_ZN6LibRaw15ppg_interpolateEv.omp_fn.2':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3883: undefined reference to `omp_get_num_threads'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3883: undefined reference to `omp_get_thread_num'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `_ZN6LibRaw15ppg_interpolateEv.omp_fn.3':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3897: undefined reference to `omp_get_num_threads'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3897: undefined reference to `omp_get_thread_num'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `LibRaw::ppg_interpolate()':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3858: undefined reference to `GOMP_parallel_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3858: undefined reference to `GOMP_parallel_end'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3880: undefined reference to `GOMP_parallel_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3880: undefined reference to `GOMP_parallel_end'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3894: undefined reference to `GOMP_parallel_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3894: undefined reference to `GOMP_parallel_end'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `_ZN6LibRaw15wavelet_denoiseEv.omp_fn.4':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3313: undefined reference to `omp_get_num_threads'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3313: undefined reference to `omp_get_thread_num'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3319: undefined reference to `GOMP_barrier'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3326: undefined reference to `GOMP_barrier'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3334: undefined reference to `GOMP_barrier'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3343: undefined reference to `GOMP_barrier'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3355: undefined reference to `GOMP_barrier'
/usr/local/lib/libraw.a(lib_libraw_a-dcraw_common.o): In function `LibRaw::wavelet_denoise()':
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3313: undefined reference to `GOMP_parallel_start'
.../Software/Libraries/LibRaw-0.12.1/internal/dcraw_common.cpp:3313: undefined reference to `GOMP_parallel_end'
collect2: ld returned 1 exit status
-----

I don't really know why the compiler looks for this file, because is not even in the /usr/local/lib or /usr/local/include directories.

I hope this could give you relevant information in order to point me in the right direction.

Thanks in advance!.

You have compiled LibRaw with OpenMP support, but build your application without OpenMP.

You should add -fopenmp to gcc command line when building your app or rebuild LibRaw with ./configure --disable-openmp

Thanks for your answer.
i used the -fopenmp and compiled flawlessly.

I really appreciate your help.

Maybe you could rename the identify sample program. Anybody who installs it will have a conflict with ImageMagick's command of the same name.

Thank you for your suggestion.

We'll rename identify sample to libraw_identify

If one of the threads in half_mt encounters an error processing a file it quits but never restarts. Remaining threads, however, continue to function.

half_mt is just a simple(!) sample.

Anyway, to be fixed in next release

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.