LibRaw is a library for reading RAW files from digital photo cameras (CRW/CR2, NEF, RAF, DNG, MOS, KDC, DCR, etc.; virtually all RAW formats are supported). It pays special attention to correct retrieval of data required for subsequent RAW conversion.
The library is intended for embedding in RAW converters, data analyzers, and other programs using RAW files as the initial data.
LibRaw library, Copyright (C) 2008-2009 LibRaw LLC (info@libraw.org)
The library includes source code from
dcraw.c, Dave Coffin's raw photo decoder
Copyright 1997-2008 by Dave Coffin, dcoffin a cybercom o net
LibRaw is distributed for free under three different licenses:
The example below contains no error processing for the sake of brevity.
#include "libraw/libraw.h"
int process_image(char *file)
{
// Let us create an image processor
LibRaw iProcessor;
// Open the file and read the metadata
iProcessor.open_file(file);
// The metadata are accessible through data fields of the class
printf("Image size: %d x %d\n",iProcessor.imgdata.sizes.width,iProcessor.imgdata.sizes.height);
// Let us unpack the image
iProcessor.unpack();
// And let us print its dump; the data are accessible through data fields of the class
for(i = 0;
i < iProcessor.imgdata.sizes.iwidth * iProcessor.imgdata.sizes.iheight;
i++)
printf("i=%d R=%d G=%d B=%d G2=%d\n",
i,
iProcessor.imgdata.image[i][0],
iProcessor.imgdata.image[i][1],
iProcessor.imgdata.image[i][2],
iProcessor.imgdata.image[i][3]
);
// Finally, let us free the image processor for work with the next image
iProcessor.recycle();
}
LibRaw is distributed in the form of source codes and/or precompiled binaries. For further use, they should be compiled (and, if desired, placed into system folders with libraries and include-files).
To build the library, you will need a working C++ compiler (gcc ver. 3.x or 4.x will be OK; other compilers have not been tested) and the make utility. No other libraries or utilities are required.
LibRaw has been tested on 32- and 64-bit Unix systems working on x86- (and AMD64-) compatible processors. Building and work on other architectures have not been tested.
Unpack the downloaded distribution package, go to the resultant folder and run make:
tar xzvf LibRaw-X.YY.tar.gz
cd LibRaw-X.YY
make
As a result, you will compile
In the current version, only static libraries are built:
For LCMS support one should uncomment two lines of Makefile after the line
# LCMS supportIt is assumed, that LCMS library is installed in /usr/local/lib or /usr/lib, and lcms.h installed in /usr/local/include or /usr/include. If you have different LCMS installation path, you should edit Makefile settings.
For compilation with OpenMP support uncomennt line of Makefile next after the line
# OpenMP support
To install the library, run
make install
It will place the libraries in /usr/local/lib and the include-files in /usr/local/include (subfolder of libraw).
To use LibRaw, add the following parameters to the compiler call (when building your own projects):
To install examples, run make install-binaries. This command will copy all compiled examples to /usr/local/bin.
Building and installation are completely similar to building and installation under Unix systems.
Building under Windows has three steps:
If all paths are set correctly and the include-files/libraries have been found, then the following will be compiled:
Only the thread-safe library is built under Win32, but it can be used with non-threaded applications as well. All examples are linked with the dynamic library (DLL); if static linking is necessary, one should link applications with library libraw_static.lib and set the preprocessor option /DLIBRAW_NODLL during compilation.
Windows-version compiles without LCMS support for now.
During building of DLL, all public functions are exported; further, the exported subset may be reduced.
Unfortunately, paths to include/ libraries depend on the way Visual C (or other compiler) is installed; therefore, it is impossible to specify some standard paths in Makefile.msvc.
No installation under Windows is supported. It is assumed that all DLLs will be supplied together with the software using them (and this software will perform the installation). Accordingly, in building of programs using LibRaw, the paths to libraries, DLLs, and include-files should be specified manually.
LibRaw data structures are defined in header file libraw/libraw_types.h
Constants used in its work are defined in file libraw/libraw_const.h
Structure libraw_data_t is a "wrapping" for data structures accessible to the user of the library.
When one uses C++ API, it is accessible as LibRaw::imgdata (class_instance.imgdata). The data in this structure appear after
a file is opened through open_file (and other open_ calls), except for the image itself (filled by unpack()) and data containing
the preview information (filled by calling unpack_thumb()).
Data fields:
Structure libraw_image_sizes_t is a collection of all file data that describe the size of the image.
Data fields:
Structure libraw_colordata_t unites all color data, both retrieved from the RAW file and calculated on the basis of the
image itself. For different cameras, there are different ways of color handling.
Data fields:
This structure (actually, a bit field) describes the source of color data for each field of structure libraw_colordata_t, which may be obtained from different data sources.
Data fields:
unsigned curve_state : 3;
unsigned rgb_cam_state : 3;
unsigned cmatrix_state : 3;
unsigned pre_mul_state : 3;
unsigned cam_mul_state : 3;
Each field assumes one of the values that are possible for enum LibRaw_colorstate.
Structure libraw_imgother_t is a collection of data that have been read from the RAW file but are not needed for image postprocessing.
Data fields:
Structure libraw_thumbnail_t describes all parameters associated with the preview saved in the RAW file.
Data fields:
Structure libraw_output_params_t is used for management of dcraw-compatible calls dcraw_process(),
dcraw_ppm_tiff_writer(), dcraw_thumb_writer(), and dcraw_document_mode_processing(). Fields of this structure
correspond to command line keys of dcraw.
Data fields:
By default settings for rec. BT.709 are used: power 2.222 (i.e. gamm[0]=1/2.222) and slope 4.5. For sRGB curve use gamm[0]=1/2.4 and gamm[1]=12.92, for linear curve set gamm[0]/gamm[1] to 1.0.
Structure libraw_masked_t designed for storing pixel data for dark frame (black or masked pixels, not included
in active image sensor area). These pixel values can be used for black level subtraction, noise and banding
removal and so on.
Unlike imgdata.image bitmap which has 4-component pixels, masked pixel data stored in 1-component 16-bit values.
Different parts of border are stored in different buffers within libraw_masked_t structure, see picture:

Data fields:
Some cameras does not provide dark frame data. In this case buffer for frame data is not allocated and
all pointers are initialized to zero.
Also, structure data is not allocated if image is extracted into half-sized bitmap (i.e. if half_size,
wavelet threshold or aber[] fields is set in processing options).
Some cameras provides not full masked frame, but only several sides of it (only left and top for Canons, only
left and right for some Nikons and so on). In this case all structure fields are initialized, but allocated
size for this part of frame is equal to zero and corresponding size parameter (top_/left_/bottom_/right_margin)
is set too zero too.
Structure libraw_processed_image_t is produced by call of dcraw_make_mem_image()/dcraw_make_mem_thumb() and contains
in-memory image of interpolated data or thumbnail.
Data fields:
RAW data input (read) in LibRaw implemented by calling methods of object derived from LibRaw_abstract_datastream abstract class. Full list of methods is described in href="API-CXX-eng.html#datastream">C++ API reference.
There is two ready to use implementations of datastream objects:
LibRaw user can create own datastream object derived from LibRaw_abstract_datastream. For example, such object may implement reading RAW data directly from camera (by remote interface). LibRaw can use these objects via LibRaw::open_datastream() interface.
Datastreams can be used either via LibRaw::open_datastream() call (in this case datastream object should be created an maintained by user) or via LibRaw::open_file() and LibRaw::open_buffer() shortcuts.
Only C++ API users may use object-oriented interface and implement own input interfaces. For C API users only built-on libraw_open_file()/libraw_open_buffer() shortcuts are avaliable.
Definition:
class LibRaw_abstract_datastream {
...
protected:
LibRaw_abstract_datastream *substream;
}
Description: Ojects derived from LibRaw_abstract_datastream always contains pointer to secondary data stream (substream). This substream initialized internally when needed (really used only for Sony RAW data) and used for temporary switch input stream to temporary memory buffer allocated internally in LibRaw.
Substream usage details described more precisely in own datastream objects creation guide.
All functions returning integer numbers must return either errno or one of the following error codes (see also error code conventions).
Fatal errors (return of such an error code implies that file processing has to be terminated, since the state of data structures is unknown).
Non-Fatal Errors
LibRaw::imgdata.progress_flags contains a bit mask describing all stages of file processing that have already been performed.
File opening and RAW data extraction phase.
The following flags are set during usage of image processing that has been taken from dcraw.
The following flags are set during loading of thumbnails.
Thumbnail data format is written in the imgdata.thumbnail.tformat data field.
Presently LibRaw knows about four thumbnail formats, among which two are unpacked:
Some suspicious situations emerging during image processing are not fatal but may affect the result of data retrieval or postprocessing. Such states are indicated by setting a bit in the imgdata.process_warnings field.
This enum describes possible RAW data filtration modes during data unpacking and postprocessing. Usage recommendations are described in API comments. Filtering mode should be set by altering filtering_mode option before unpack() is called.
Best possible setting for common RAW-processing software is LIBRAW_FILTERING_AUTOMATIC. For RAW analyzers we recommend use LIBRAW_FILTERING_NONE or LIBRAW_FILTERING_NOBLACK.
For each type of retrieved color information (see above for description of structure imgdata.color.color_flags), the data source is recorded. The possible values are listed below.
type field of libraw_processed_image_t structure may have one of these values:
Contents
The main LibRaw object (class) is created either without parameters or with flags determining the object behavior.
#include "libraw/libraw.h"
...
LibRaw ImageProcessor(unsigned int flags=0);
...
Flags (several flags are combined via operator |, i.e., bitwise OR):
Three groups of methods are used for image processing
The results of processing are placed in the imgdata field of type libraw_data_t; the same data set contains fields that control the postprocessing and output.
All LibRaw API functions return an integer number in accordance with the return code convention. Please read the descriptions of this convention and LibRaw behavior in cases of fatal errors.
Opens a datastream with RAW data, reads metadata (EXIF) from it, and fills the following structures:
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Before file opening, recycle() is always called; hence, if several images are processed in the batch mode, there is no need to call recycle() at the end of each processing cycle.
Input data: pointer to object, derived from LibRaw_abstract_datastream class. This object should be initialized and ready to read. This object should be destroyed in calling application after use.
Creates an LibRaw_file_datastream object, calls open_datastream(). If succeed, sets internal flag which signals to destroy internal datastream object on recycle(). On failure, just created file_datastream destroyed immediately.
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Created an LibRaw_buffer_datastream object, calls open_datastream(). If succeed, sets internal flag which signals to destroy internal datastream object on recycle(). On failure, just created file_datastream destroyed immediately.
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Unpacks the RAW files of the image, calculates the black level (not for all formats), subtracts black (not for all formats). The results are placed in imgdata.image.
Data reading is sometimes (not frequently) affected by settings made in imgdata.params (libraw_output_params_t); see API notes for details.
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Reads (or unpacks) the image preview (thumbnail), placing the result into the imgdata.thumbnail.thumb buffer.
JPEG previews are placed into this buffer without any changes (with the header etc.). Other preview
formats are placed into the buffer in the form of the unpacked bitmap image (three components, 8 bits per component).
The thumbnail format is written to the imgdata.thumbnail.tformat field; for the possible values, see
description of constants and data structures.
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Returns string representation of LibRaw version in MAJOR.MINOR.PATCH-Status format (i.e. 0.6.0-Alpha2 or 0.6.1-Release).
Returns integer representation of LibRaw version. During LibRaw development, the version number is always increase .
Macro for version check in caller applications. Returns 'true' if current library version is greater or equal to set in macro parameters. This macro executes at runtime (not at compile time) and may be used for checking version of dynamically loaded LibRaw (from DLL/shared library).
Returns count of cameras supported.
Returns list of supported cameras. Latest item of list is set to NULL (for easy printing).
Returns function name of file unpacking function. Intended only for LibRaw test suite designers to use in test coverage evaluation.
This call rebuilds imgdata.image bitmap and makes full bitmap, contains both image data (active
pixels) and 'black border' (masked pixels). If no masked pixels data present, then this call does nothing.
Function call changes data fields sizes.width,sizes.height,sizes.iwidth,sizes.iheight to full image
size (i.e. raw_width/raw_height).
This call does nothing:
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
This function rotates non-interpolated RAW bitmap from FujiCCD sensors into 45-degree-rotated position, compatible with old LibRaw versions (prior to LibRaw 0.7). This call is intended for applications, which works with non-interpolated/non-demosaiced RAW data itself. If dcraw_process/dcraw_document_mode_processing calls are used, these call make the rotation internally.
The function returns an integer number in accordance with the return code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Frees the allocated data of LibRaw instance, enabling one to process the next file using the same processor. Repeated calls of recycle() are quite possible and do not conflict with anything.
Destructor, which consists in calling recycle().
Converts progress stage code to description string (in English).
Analog of strerror(3) function: outputs the text descriptions of LibRaw error codes (in English).
In process of RAW conversion LibRaw can call user-setted callback. This callback can be used for:
Also, work of the library may cause two types of exceptional situations that require notification of the calling application:
An application may set its own callbacks that will be called in the cases mentioned above to notify the user (or the calling program).
typedef int (*progress_callback)(void *callback_data,enum LibRaw_progress stage, int iteration, int expected);
void LibRaw::set_progress_handler(progress_callback func,void *callback_data);
LibRaw user can set own callback which will be called 10-50 times during RAW postprocessing by dcraw_process()/dcraw_document_mode_processing();
This callback may terminate current image processing by returning of non-zero value. In such case all processing will be cancelled immediately and all resources will be returned to system by recycle() call. Current call of dcraw_process()/dcraw_document_mode_processing() will return error code LIBRAW_CANCELLED_BY_CALLBACK.
Callback parameters:
If LibRaw compiled with OpenMP support, iteration parameter may not always increase within one stage. Out of order callback calls are possible.
Callback code sample:
int my_progress_callback(void *data,enum LibRaw_progress p,int iteration, int expected)
{
char *passed_string = (char *data);
printf("Callback: %s pass %d of %d, data passed: %s\n",libraw_strprogress(p),iteration,expected,passed_string);
if(timeout || key_pressed )
return 1; // cancel processing immediately
else
return 0; // can continue
}
typedef void (* memory_callback)(void *callback_data,const char *file, const char *where);
void LibRaw::set_memerror_handler(memory_callback func,void *callback_data);
The user may set his or her own function called in the case of memory shortage. It is a void function receiving two string parameters:
The callback function is intended for information purposes: it notifies the user or the program code that processing is impossible.
If the user does not set his or her own handler, the standard one (output of error message in stderr) will be used.
One can set the null handler by passing NULL to set_memerror_handler; then no notifier function will be called. The same effect can be achieved by creating a LibRaw object with the LIBRAW_OPTIONS_NO_MEMERR_CALLBACK flag in the contructor.
In the case of memory shortage, processing of the current file is terminated and a notifier is called; all
allocated resources are freed, and recycle() is performed. The current call will return
LIBRAW_UNSUFFICIENT_MEMORY.
At an attempt to continue data processing, all subsequent calls will return LIBRAW_OUT_OF_ORDER_CALL.
Processing of a new file may be started in the usual way, by calling LibRaw::open_file().
typedef void (*data_callback)(void *callback_data,const char *file, const int offset);
void LibRaw::set_dataerror_handler(data_callback func, void *callback_data);
The user can define his or her own function to be called in the case of error in the input data. It is a void function receiving two parameters:
The callback function is intended for information purposes: it notifies the user or the program code that processing is impossible.
If the user does not set his or her own handler, the standard one (output of error message in stderr) will be used.
One can set the null handler by passing NULL to set_memerror_handler; then no notifier function will be called. The same effect can be achieved by creating a LibRaw object with the LIBRAW_OPTIONS_NO_DATAERR_CALLBACK flag in the contructor.
In the case of error in the input data, processing of the current file is terminated and a notifier is called; all
allocated resources are freed, and recycle() is performed. The current call will return
LIBRAW_IO_ERROR.
At an attempt to continue data processing, all subsequent calls will return LIBRAW_OUT_OF_ORDER_CALL.
Processing of a new file may be started in the usual way, by calling LibRaw::open_file().
Instead of writing one's own Bayer pattern postprocessing, one can use the dcraw functions, which are called after the calls of open_file() + unpack() /+ unpack_thumb()/
Virtually all parameters that can be set through the dcraw command line are specified by assigning values to fields of the LibRaw::imgdata.params structure. The type of this structure is libraw_output_params_t; all fields are listed and described in sufficient detail in the description of data structures.
The function calculates the correct size of the output image (imgdata.sizes.iwidth and imgdata.sizes.iheight) for the following cases:
In the aforementioned cases, the function changes the fields of the image output size; note that this change cannot be repeated again.
The function should be used for information purposes; it is incompatible with dcraw_document_mode_processing() and dcraw_process() calls.
The function emulates dcraw -D: no interpolation, white balance, and color conversion.
It is called after calling LibRaw::unpack();
The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
The function emulates the postprocessing capabilities available in dcraw.
Called after calling LibRaw::unpack();
The entire functionality of dcraw (set via the field values in imgdata.params) is supported, except for
The function is intended solely for demonstration and testing purposes; it is assumed that its source code will be used in most real applications as the reference material concerning the order of RAW data processing.
The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
In spite of the abundance of libraries for file output in any formats, LibRaw includes calls that emulate the file output provided by dcraw. This is done primarily for easier verification of library work: the resultant files must be binary identical.
The function outputs the postprocessing results to a file in the PPM/PGM or TIFF format (the format is set via imgdata.params.output_tiff). The results are binary identical to those provided by dcraw.
The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
Writes the thumbnail to a file in the PPM format for bitmap thumbnails and in the JPEG format for JPEG thumbnails, i.e., in the format completely identical to the results provided by dcraw.
The function returns an integer number in accordance with the error code convention: positive if any system call has returned an error, negative (from the LibRaw error list) if there has been an error situation within LibRaw.
There is two function calls for store unpacked data into memory buffer (after using dcraw_process() and so on):
This function allocates memory buffer and stores unpacked-preprocessed image into this buffer. Function returns allocated structure libraw_processed_image_t with filled fields. Always returns data as RGB bitmap (i.e. type field is equal to LIBRAW_IMAGE_BITMAP).
dcraw_process() or dcraw_document_mode_processing() should be called before dcraw_make_mem_image();
Returns NULL in case of an error. If caller has passed not-NULL value as errorcode parameter, than *errorcode will be set to error code according to error code convention.
NOTE! Memory, allocated for return value will not be fried at destructor or LibRaw::recycle calls. Caller of dcraw_make_mem_image should free this memory by call to free().
This function allocates memory buffer and stores thumbnail data in it. Function returns allocated structure libraw_processed_image_t with filled fields. For most RAW images allocated structure will contains JPEG image (i.e. type field is equal to LIBRAW_IMAGE_JPEG). For some cameras with RGB-bitmap thumbnail (Kodak SLRs) returned structure contains RGB bitmap (type field is equal to LIBRAW_IMAGE_JPEG, see structure description for details).
unpack_thumb() should be called before dcraw_make_mem_thumb();
Returns NULL in case of an error. If caller has passed not-NULL value as errorcode parameter, than *errorcode will be set to error code according to с error code convention.
NOTE! Memory, allocated for return value will not be fried at destructor or LibRaw::recycle calls. Caller of dcraw_make_mem_image should free this memory by call to free().
LibRaw reads RAW-data by calling (virtual) methods of C++ object derived from LibRaw_abstract_datastream. This C++ class does not implement any read, but defines interface to be called. Call to base class methods always results in error.
This group of methods implements file object (FILE*) semantics.
This group of methods includes several supplementary calls. These calls are used to temporary switch to another data stream (file and/or memory buffer).
This call implemented in base class (LibRaw_abstract_datastream), there is no need to
reimplement in in derived classes.
Possible activity of temporary datastream requires very accurate programming when implementing
datastreams derived from base LibRaw_abstract_datastream. See below
for more details.
There is two "standard" input classes in LibRaw distribution:
LibRaw C++ interface users can implement their own input classes and use them via LibRaw::open_datastream call. Requirements and implementation specifics are described below.
This class implements input from file.
Class methods:
All other class methods are described above.
This class implements all possble methods, including fname() and subfile_open().
This class implements input from memory buffer.
Class methods:
All other class methods are described above.
This class does not implement fname() and subfile_open() calls, so external JPEG metadata parsing
is not possible.
To create own read interface LibRaw user should implement C++ class derived from
LibRaw_abstract_datastream with all read methods.
LibRaw standard implementations may be used as reference. See libraw/libraw_datastream.h file for details
(all standard LibRaw input classes are implemented using inline functions only).
substream field, defined in base LibRaw_abstract_datastream class requires some additional notes.
This field is used when input switched to temporary buffer (used for Sony metadata processing). Unfortunately,
there is now ideal C++ way to hide this functionality into base class internals. So, any read call in
derived class should include 1-line statement like this:
int method(...args...){ if(substream) return substream->method(...args...). For example:
virtual int eof()
{
if(substream) return substream->eof();
....
virtual int scanf_one(const char *fmt, void* val)
{
if(substream) return substream->scanf_one(fmt,val);
LibRaw C API is a wrapper around C++ API; therefore, virtually all documentation to C API functions is represented by a set of hyperlinks to the corresponding places in the description of C++ API.
Contents
The function returns the pointer to the instance of
libraw_data_t structure.
The resultant pointer should be passed as the first argument to all C API functions (except for libraw_strerror).
Returns NULL in case of error, pointer to the structure in all other cases.
Functions of C API return EINVAL (see errno.h) if the null pointer was passed to them as the first argument. In all other cases, the C++ API return code is returned.
The postprocessing parameters for the calls described below are set, just as for C++ API, via setting of fields in the libraw_output_params_t structure:
libraw_data_t *ptr = libraw_init(0);
ptr->params.output_tiff = 1; // output to TIFF
Fields of this structure are described in the documentation to libraw_output_params_t. For notes on their use, see API notes.
Since version 0.9, there is only one LibRaw variants. Older versions have three separate editions (normal, -Lite and -Commercial versions).
The following conventions concern the returned errors:
If the program has encountered a nonstandard situation that does not prevent retrieval of some data from a file, it sends a signal by setting the corresponding bit in imgdata.process_warnings. The possible types of warnings are listed and deciphered here.
LibRaw uses objects derived from LibRaw_abstract_datastream for data input. Semantics of these objects is similar to 'file with arbitrary seek' object: both read and seek operations are used.
Some RAW formats requires temporary switch to another data stream created on top on memory buffer for metadata
read. Methods for doing so are implemented in base class
LibRaw_abstract_datastream by internal data field substream.
Look into source code of LibRaw_file_datastream class
in libraw/libraw_datastream.h file for more details.
When implementing own datastream classes, you need to take substream into account and pass control to
methods of this field if it is active (not NULL).
If datastream implementaton knows name of input file, it should provide fname() call. This name will be used in error callbacks and in guessing name of JPEG file with metadata (for RAW files with external metadata).
For external metadata support input class should implement
subfile_open()/subfile_close() methods.
Sample of these methods implementation may be found in
LibRaw_file_datastream class (look into
libraw/libraw_datastream.h file for details).
Thread safety is ensured if a LibRaw object is created and used within one thread. At the same time, the number of threads (each with its own LibRaw object) is not limited in any way (except by memory requirements).
If a LibRaw object is created in one execution thread and used in another, external synchronization is necessary.
There is two libraries under Unix enviroment (Linux/FreeBSD/MacOS): libraw_r.a (thread-safe) and libraw.a (single-threaded, slightly faster).
Thread-safe library version stores intermediate unpacker data into LibRaw class data. So, several copies of LibRaw, working in parallel, is possible.
Not thread-safe library uses global variable for intermediate data store which is faster but not reenterant. This library may be used in multi-threaded apps, but only if exactly one LibRaw class copy exists in program.
Windows version is similar to multi-threaded Unix one.
Exception situations within LibRaw are handled using the C++ exception mechanism. All exceptions are caught inside the library functions and should not penetrate outside.
Memory is allocated/freed using functions malloc(calloc)/free rather than new/delete.
No specific libraries (STL, Boost, smart pointers) are used.
If C API is used, references to C++ calls new/delete still remain, and so linking with libstdc++(Unix)/....(Windows) is necessary.
Most data fields of structure LibRaw::imgdata.params affect only data postprocessing, but there are some exceptions, which have been inherited by the current version of LibRaw from/ dcraw source texts (these dependences will be gradually removed).
imgdata.sizes.flip = imgdata.params.user_flip is
performed at the open_file() stage.
During RAW unpacking and post-process stages LibRaw can filter RAW data:
Current LibRaw version allows tuning of filtration process by setting imgdata.params.filtering_mode option to one of enum LibRaw_filtering vales:
Some of RAW images contains data for not-active ("black","masked") pixels. For some of these formats LibRaw can extract these pixels values and store it in imgdata.masked_pixels data structure. These values can be explored for:
Masked pixel data avaliable only for bayer-pattern data (one component per pixel) and only for cameras with masked frame. Masked pixels extraction for other color models (Canon sRAW, Kodak YRGB, Sinar 4-shot files) will possibly be added in future LibRaw versions.
LibRaw provides interface for merging active pixel data and masked pixels into one bitmap: add_masked_borders_to_bitmap(). This call is useful for RAW analyzers.
An instance of the LibRaw class has its own size about 100 Kb; if constructions like LibRaw
imageProcessor; are used, this memory is stack-allocated.
Methods of class LibRaw (and C API calls) may allocate up to 130-140 Kb of data on the stack (to place auto variables) during their work.
Thus, the work of one LibRaw instance may require about 250 Kb of stack memory. This is not a problem for most contemporary architectures. However, when working in a multithreaded environment, one should not forget to allocate a sufficient amount of memory for the thread stack.
In the case of dynamic allocation (LibRaw *iProcessor = new LibRaw;), the requirements to stack
memory will decrease by 100 Kb, which is the size of a class instance). If C API is
used, the LibRaw instance is allocated dynamically.
LibRaw keeps record of all allocated dynamic memory blocks; in the case of an exceptional situation (fatal error), they are all freed. The code for keeping this record is fairly primitive and not designed to consider allocation of many blocks (in the normal situation, allocation takes place from 2 to 6 times during file processing); this fact should be taken into account by developers trying to add new methods to LibRaw.
LibRaw uses dynamic memory
To simplify further processing, memory for the extracted RAW data is allocated with a fourfold (for Bayer sensor
cameras) excess: for each pixel, four 16-bit components are available (three of them will be zero after
RAW unpacking). Thus, one can perform debayer and other postprocessing actions directly in the same buffer as
the one used for data extraction, but the required amount of memory becomes four times higher.
Hence, the size of memory for the image buffer is 6-10 times greater than the size of the source RAW
file.
It is quite likely that allocation of this buffer in next versions of LibRaw will be more
economical, under the condition that postprocessing calls inherited from dcraw will not be used..
The buffer for the decoded image is allocated upon calling unpack() and freed upon calling recycle().
Memory for the thumbmail is allocated upon calling unpack_thumb() and freed upon calling recycle(). The size of the allocated buffer is precisely adjusted to the thumbnail size, i.e., up to several Mb.
Memory for the ICC profile is allocated upon calling unpack_profile() and freed upon calling recycle(). The size of the allocated buffer is precisely adjusted to the ICC profile size, i.e., up to several hundred Kb.
Memory for temporary buffer needed during RAW data unpacking may be allocated during the work of unpack() and freed before completion of this function. The sizes of the allocated buffers are small, up to tens of Kb.
During image postprocessing (inherited from dcraw), memory for the histogram (128 Kb) is allocated. This memory is allocated upon calling dcraw_document_mode_processing() and dcraw_process() and freed upon calling recycle().
In addition, during the work of dcraw_process() and during the usage of some available possibilities, like
a temporary buffer with the size equal to the size of the resultant image (6-8 bytes per pixel for various processing stages)
will be allocated. As soon as the intermediate substage of processing is completed, the buffer with the previous copy
of the image will be freed.
If postprocessing is not used, then temporary buffers are not allocated.
Upon calling dcraw_ppm_tiff_writer(), memory for a single row of the output image is allocated. The allocated memory is freed before the end of this call.
Functons dcraw_make_mem_image() Х dcraw_make_mem_thumb() (and complementary calls in C-API) allocates memory for entire output datasets (full RGB bitmap and thumbnail, respectively). Calling function should free() this memory themself.
In some Kodak cameras, the preview (thumbnail) is stored in the form of uncorrected image. During its extraction using
dcraw -e, the white balance, color conversion, and other settings are the same as those used for extraction of the main RAW data
(including defect removal and dark frame subtraction, which is erroneous, since the image size is different).
In LibRaw::unpack_thumb() calls, the white balance taken from the camera ("as shot") is used and no settings from
imgdata.params are considered.
For all other cameras, thumbnails are extracted "as is," without any color conversions, both in dcraw and in LibRaw.
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:
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;
}