DCRAW For Delphi
Last Updated 01/03/2010


New since last update:
Changed for 01/03/2010 version

1. Updates for the latest cameras.
2. Changed the names of the following TRawSettings variables..
The reason for these changes is so that as you are using the variable in the OnImageDone EVent, you will KNOW by the name of the variable if it can be MODIFIED in the OnImageDone EVent.
3. Made the CSTDIO.PAS file a component. So now there is a TRawObject contained in there. That means that you can NOT simply call functions and set properties that were in the CSTDIO file. You now HAVE TO CREATE a TRawObject in your code and then reference the object to set properties and call mentods. This makes it so that it's easier to do MULTITHREADING and it encapsulates teh code better too for organizational purposes. There are also many EVENTS that are now available for use to do cool things. You now reference the methods like so....



     MULTITHREAD can be set to TRUE, if you plan to use the object in various threads
        NOTE: If you set it to TRUE, then you MUST have the $DEFINE DYNAMICDLL variable set in CSTDIO.INC
        If you set it to FALSE, then you can still have a bunch of them created as objects, BUT you can
        only use those TRawObjects from a SINGLE thread (typically your main thread).
        I M P O R T A N T:  M U S T   R E A D   T H I S.......
           NOTE: You NEEEEEED to call RAW_ThreadEnd in order to clean up the temp dll that is copied
                 into your temp folder

  EVENT Properties

  1. Create TRawObject TObject
  2. You create it and then assign MultiThread:=True if you wish
  3. You assign the Event Properties if you need to
  4. You prefix all your references to the raw functions with the name of the object, for example...
     ... some code....
     ... maybe assign some other events too
     ... some more code...

  5. Made some changes to the CallBack functions. They now all have an additional
     parameter called SENDER as the first parameter. For example.....
     Procedure TForm1.Event_HistogramMake_Custom(Sender:TObject;Var RawSettings:TRAWSettings;HistP:Pointer;HistSize:Integer;RAWWidth,RAWHeight,Width,Height,Colors,BrightMode:Integer;Image:PPUSHORT;ImageBlockSize:Integer);
     NOTE: The reason we pass this new paramter is so that your code can now access any properties or methods of the TRawObject that you are currently using.
  6. Added a bunch of simple USER variables.

       NOTE: Used properly, these can be very useful

  7. Better approach to TEMP DLL stuff. Instead of each process, creating a list
     of temp DLLs, I create ONE temp dll for each THREAD.
     NOTE: This is better, BECAUSE if a thread is creating and destroying the TRawObject
           over and over, then the new way is more efficient (less disk acces).
           PLUS: The old way left room for a 2nd and 3rd copy of your program to be
           running and the temp dll names COULD CONFLICT between each process!!! BUT SINCE
           each THREAD ID IS UNIQUE throughout the system, this new method will NEVER have
           a conflict between multiple copies of your program running at the same time.
  8. In order for this new way to work properly, YOU NEED MUST BETTER let the TRawObject
     KNOW when you shut down your thread. So when the thread shuts down, THEN and ONLY THEN
     do we remove the temp dll from the temp folder. You do this by calling tthe function
     called  RAW_ThreadEnd.
     NOTE: If you do NOT call RAW_ThreadEnd, then the temp dlls will stick aroud and start
           to waste space
     HINT: Actually, you don't NEEEED to call the RAW_ThreadEnd explicitly because the temp
           files ARE REMOVED AUTOMATICALLY. It's just that they are NOT REMOVED PRECISELY when
           you terminate the thread. There is a TTIMER gTimerCleanup that checks every 5 seconds
           to see if it needs to cleanup any temp files that RAW_EndThread would otherwise clean up.
           So, by default ti's easier to just let the background timer automatically clean up your
           temp files, unless you are maticulous about cleaning things up EXACTLY when they are no
           longer needed ;)

  9. Added a property so that you know what THREAD created the TRAWObject

     Property  ThreadID:DWord read FThreadID;

  10. IF Your TRAWObject is used in a thread that is NOT your main thread, THEN if you
      FORGET to set the MultiThread to TRUE, then the moment you attempt to call one of the
      DLL functions, you will get an Exception that tells you to set MultiThread:=True;

New since last update:
Changed for 05/25/2009 version
1. Updates for the latest cameras.
2. Changed the way the following function is setup....
Procedure HistogramLutCalc(Var Ptrs:TRAWEvents;Var LUT:TLUT;
It now looks like this.....
Procedure HistogramLutCalc(Var Ptrs:TRAWEvents;Var GammaCurve:TGammaCurve;

Also in the UNIT1.PAS file, then cooresponding function called....
Procedure TForm1.Event_HistogramLutCalc_Custom(Var RawSettings:TRAWSettings;LUTP:Pointer;

now looks like this....
Procedure TForm1.Event_HistogramLutCalc_Custom(Var RawSettings:TRAWSettings;GammaCurveP:Pointer;

TIP: You will notice that I changed WHITE from single to integer; I also removed the brightmode variable. ALSO, the LUT table has been changed to a CURVE table. It performs the same basic function, BUT instead of being an array of 8 bit numbers, it's now an array of 16bit numbers. So, now this table can be used to produce nice 8 bit images, BUT ALSO NICE 16 bit images. So, the values in each slot in the table now range from 0-65535 instead of 0-255.

3. When you checkmark the Use 16bit dataa only, it NOW allows you to use the Real-Time-Enhancements. And when you are done, the Demo program asks if you want the image to be strtched to look good. Click YES, and then the 16 bit image will look great instead of the typical super dark image.

Changed for 03/11/2009 version
        1. CSTDIO is now a UNIT instead of an $Included file.
        2. The following procedures in CSTDIO.PAS have been renamed for better organizational purposes....
                adj_defaults is now RAW_Adj_Defaults
                MyProgress is now RAW_MyProgress
                RawInfo is now RAW_Info
                FromRAWToPSD is now RAW_LoadRAW
                Extract_Thumbnail is now RAW_Extract_Thumbnail
                GetGammaVariables is now RAW_GetGammaVariables
        3. Since it's a unit now, you can see all of the procedure/functions names near the top of the unit. If you want to double check their spelling.
           procedure Raw_CheckDLL_RaiseError this checks to make sure the dll is found and if NOT it raises an error if the DLL is found BUT it's not of the correct version, then it raises a different error message. With the dynamic loading of the DLL, you can have many different names for the DLL. TYPICALLY, you will have MSDCRAW.DLL and just leave it alone. BUT, if for some reason, you will create programs that use DIFFERENT versions of this dll, then you can name them    MSDCRAW5.DLL and MSDCRAW6.DLL and thus you will be able to keep both of them in the same folder. AND the program that needs version 5 will find version 5 and the program that needs version 6 will find version 6. No muss-, no-fuss.
        4. Several callback functions are now passed an EXTRA parameter of TRAWSettings.
                TRAWCallBack_AfterLoadRetry = Function(
                                Var EventLoopData:TEventLoopData;
                                Var RawSettings:TRAWSettings;

Changed for 09/09/2008 version
        1. Some images when loaded in FULL SIZE mode could get a MAZE pattern in the image.
            This is caused by an inbalance in the G1 and G2 sensors. This fix, averages the two
            together and removesthe maze effect. It would have been UNNOTICED in the half size
            mode because of the way interpolation is performed.
        2. Several callback functions are now passed an EXTRA parameter of TRAWSettings.
            Several people wanted to know certain input values into the FromRAWtoPSD function
            and didn't want to keep global variables hanging around. So, now these callback functions
            have a way of knowing what the settings were when then main decoding function was called.
                TRAWCallBack_AfterLoadRetry = Function(
                                Var EventLoopData:TEventLoopData;
                                Var RawSettings:TRAWSettings;
                                Var BrightAdded,Contrast,Gamma:Single) :Integer Of Object;
                TRAWCallBack_HistMake = Procedure(
                                Var RawSettings:TRAWSettings;
                                ImageBlockSize:Integer) Of Object;
                TRAWCallBack_HistSearch = Function(
                                Var RawSettings:TRAWSettings;
                                ImageBlockSize:Integer):Integer Of Object;
                TRAWCallBack_HistLUTCalc = Procedure(
                                Var RawSettings:TRAWSettings;
                                ImageBlockSize:Integer) Of Object;
                TRAWCallBack_ImageDone = Procedure(
                                Var RawSettings:TRAWSettings;
                                Width,Height:Integer) Of Object;
        3. Added NEW event.
                TRAWCallBack_ImageDoneQUERY = Procedure(
                                Var RawSettings:TRAWSettings;
                                Var FixMazeEffect:Boolean) Of Object;
                You can see that this event can OVERRIDE the default operation of fixing the MAZE effect.
                By default the logic is to fix the maze effect only for images that is of RGBG type and is 3 colors.
                So, the value of FIXMAZEEFFECT will be true or false depending on RGBG type and colors=3.
                The Query event allows you to OVERRIDE the FixMazeEffect to true or false.
                This effectively allows YOU to decide if you want that logic performed. If you do nothing to change the variable, then
                the default logic will be taken.
                HINT: The MazeFixup logic basically balances the G1 and G2 color scales. For cameras that don't have a misbalanced
                G1/G2 channels, the fixup will not affect the output visually.  So, no need to worry about fixing up an image that doesn't need fixing up.
                The reason we check for RGBG in the CDesc field is that if you have a RGBE or GMCY value, then there IS NOT G1/G2.
                The RGBE has a G1 and an EMERALD channel. So, balancing will screw it up. The GMCY is an odd ball and of course doesn't
                have 2 green channels. So, balancing will screw it up.
                NOTE: Unless you know what you are doing, DO NOT USE THIS EVENT.
        4. Also the TRAWSettings structure has a few new items.
                The user can use this for ANYTHING he wants to in order for the callback functions to be able to know certain things

                oFilters:Integer;        //Filter value reported from dcraw (tech stuff)
                oColors:Integer;       //Colors reported from dcraw  (3 or 4)
                oCDesc:TChar5;     //contains  RGBG, or GMCY, or RBTG or RGBE or maybe others
                oMake:TChar50;      //Make of camera
                oModel:TChar50;     //Model of camera

    Changed for 09/01/2008 version

1. Added support for the -n Noise reduction command from dcraw into MSDCRAW.
    In the TRawSettings there is a new variable called iNoiseReduction:Integer;
    You can supply a value of ZERO <default> that means NO noise reduction NR.
    Or you can pass a value of 500 which is a pretty strong NR value, and 1000
    which is very very strong smoothing.
2. The AfterLoadRetry event that gets TEventLoopData passed into it, now has 2 new variables defined in the teventloopdata...
This means that in the AfterLoadRetry callback, you can set the NoiseReduction value to a new value and you can change the Quality setting too. And great care was taken to make sure that all of this functions as fast as possible using temp copies of the loaded image. For exampe: If you load an image with a NR value of 1000, then it takes about 5 seconds to smooth the image before any color correction is done. Well, if you then want to change the color space to Adobe or XYZ or RAW, then we swap the IMAGE data with the temp data that was saved away. Thus eliminating the need for the 5 seconds of NR logic ;) It's all very efficient now. It uses RAM to keep these extra copies of the image to swap around, and if there is not enough RAM then we use your temp drive. ALL done automatically.
NOTE: See, the AfterLoadRetry is cool because before the image is completely done loading, you can SEE the image on your screen and change some parameters and tell it to RE-SHOW you the image. And it does it fast because it doesn't have to reload/decode the image etc..... And you can keep playing with the parameters (Scale colors, gamma, contrast, brightness, noise reduction level, etc...) until they are the way you want them. Then you tell the AfterLoadRetry to stop looping and to finish the load. MUCH FASTER than loading the image and then changing a value, then reloading the image etc....
3. Changed the way the Make, Model and TimeStamp are passed to the two main functions of RawInfo and FromPSDtoRaw
    The old way was
  Status:= RawInfo (@FilePtrs, @ExifRecordB, @ExifEssentials, IFileName, FShrinkFactor, IWidth, IHeight, IFovWidth, IFovHeight, @PMake, @PModel, @PTimeStamp);
            The NEW way is
  Status:= RawInfo (@FilePtrs, @ExifRecordB, @ExifEssentials, IFileName, FShrinkFactor, IWidth, IHeight, IFovWidth, IFovHeight, PMake, PModel, PTimeStamp);

You can see that the @ is no longer required, and instead of defining them as Array[0..xxx] of char, they are NOW declaed as TChar50. And you do NOT need to fillchar them to initialize them. All that is handledf for you now.
NOTE: Since they are now 50 bytes, and YOU MAY HAVE some fillchar functions to initialize your arrays of let's pretend 100 bytes, THEN when you switch to TChar50, your program will blow up or should, because you are zeroing out 100 bytes instead of 50 ;) So, remove your fillchar stuff on those variables.

4. Fixed a date time stamp problem. It seemed that some images returned the wrong TIME (jhour) it had to do with time zones. Very strange stuff, but that is fixed now.

    Changed for 08/06/2008 version
    1. Added additional camera support
    2. Added new features to the MSDCRAW package.

A. 5 New EVENTS that can be used for custom things.
         HistogramMake_CallBack:TRAWCallBack_HistMake;       //Event to MAKE your own histogram
         HistogramSearch_CallBack:TRAWCallBack_HistSearch;   //Event to SEARC your own histogram
         HistogramLutCalc_CallBack:TRAWCallBack_HistLutCalc; //Event to CREATE your own LUT table
         AfterLoadRetry_CallBack:TRAWCallBack_AfterLoadRetry;   //Event to Re-make image with new parameters (brightness/contrast/gamma/etc..)
         ImageDone_CallBack:TRAWCallBack_ImageDone;          //Event to gain access to the just loaded IMAGE data
2 Histogram building and searching for white point for auto brightening.
D. Added 3 additional methods of calculating the Auto-Brightness. The dcraw code prodoces decent auto-bright for  most images, but for tough ones like pics of the moon where most of the sky is black etc... the dcraw doesn't quite do a good job. Sooooo, I added 3 more methods of exposure sensing.

The MIKE'S way is the best and should be the one you use for all your images unless you can show me a reason why. That is why it is now the DEFAULT mode of auto exposure.

E. Added ability to control the contrast, brightness, and gamma of the developed image. Here are the variables for that
  adj_Gamma_Def=0.45;    {0.01=brightened way up, 1.0=darkened way down with GAMMA curve}
  adj_Contrast_Def=1.0;  {1=default  0 = ZERO contrast, 1=decent, 4=way too contrasty}
  adj_Brightness_Def=0;  {0=default  0 = no additional brightness, -1=total darkness, +1=total brightness}
So, by changing these values, you can effectively control the brightness and contrast and gamma of the image. NOW you may be wondering, why have "adj_brightness" when there is ALREADY a value being passed to dcraw called "RawSettings.iBright"  Well, this is true. We now have TWO brightness controls. The BRIGHT variable used by dcraw is used as a MULTIPLIER for the incoming data. The "adj_brightness" is not a multiplier, instead it's an ADDITIVE. So, all pixels are brightened the same amount. This is the traditional method of brightness operation.

F. You need to add CSTDIO_TYPES to your USES clause, because I have separated out all the types of record structures and event method types into a new files.

G. YThe variable GammaVal has been renamed to Gamma.

    Changed for 06/29/2008 version
    1. Added additional camera codecs
    2. Added ability to just get the RAW image <RGGB> data before any processing is done.
    3. Added a SATuration option which is the -S option in the DCRAW.C code

    Changed for 04/23/2008 version
    1. Added code to control AUTO ROTATE of RAW images. You now have 5 options
        Auto Rotate
        No Rotate
        90 Degree rotate
        180 Degree rotate
        270 Degree rotate

    Changed for 04/04/2008 version
    5. Added source code for MSDCRAW.C in case you feel the need ;)
    4. Added support for MEMORY thumbnails instead of thumbnails saved to file.
    3. Much more camera support
    2. A couple of new options (you can see the new checkboxs etc...)
    1. Improved CSTDIO.PAS file (mostly in MyProgress funtion)

========= E N D   O F   H I S T O R Y =================================
========= S T A R T   O F   D A V I D   C O F F I N   S E C T I O N =================================

David Coffin: Please click here for your test files.

The DCRAW c++ files allow you to read RAW images from higher end digital cameras. If you don't know c++, then you are at a disadvantage to use them. That is why I've written a wrapper for Delphi that can make use of the DCRAW c++ code.

The first thing I had to do was to compile the DCRAW.C code along with additional c++ files I created in order to produce a viable DLL that could be used with Delphi. This compiled code is MSDCRAW.DLL. You need this DLL to be included with your application and keep the DLL in the same folder as your application program.

DCRAW c++ code was generously written by David Coffin and you can view his website by clicking here.

The purpose of the DCRAW functionality is so that programmers can have the ability to load RAW digital images. For example: The Canon G2, G3, G5 Digital EOS Rebel all have the ability to save photos in either RAW or JPG format. The JPG format is best for 95% of what you photograph. However, if you are taking an award winning photo and you want the very best results, some people choose to save in the RAW format. For Canon, these files are *.crw, for Nikon, they are *.nef and other manufacturers have there own extensions as well. Please refer to David Coffin's web site for a complete list of extensions.
========= E N D   O F   D A V I D   C O F F I N   S E C T I O N =================================

3 Delphi Functions I've Provided

There are 3 functions that you can use to work with RAW images:

NOTE: Not all RAW files have thumbnails built into them
NOTE: Although MOST thumbails are in JPG format, there are quite a few that are in PPM format and some in TIFF format.

These 3 functions are located in the CstdIO.pas file. In order to show you how to use them, I've provided a sample project that utilizes them. The sample project allows you to browse for a file and then either get INFO on it, or LOAD the raw file, or Extract the thumbnail.

Source Files And What They Do
When you download the Delphi sample project files, you get a ZIP file that contains the following files:

** NOTE: The TFastFile class is basically a BUFFERED file I/O system that uses a 4K buffer. This produces MUCH faster processing of reading single byte at a time. It's about 20 times faster than using the standard TFileStream class. Have fun with it.

**** NOTE: The CSTDIO not only contains the 3 Raw function calls, but it also contains all of the FILE I/O faking needed. See, the C++ library has it's own TStream which is DIFFERENT from Delphi's TStream :(  So, I had to create all of the C++ stream functions like fseek, feof, fread, fwrite, fopen, fclose etc...

Files To Download

Please DONATE to keep my efforts worth it. As long as the donations are fair, I will keep this web site up.

Click on the "Make A Donation" button to donate an amount that you think is fair.

Download Sample Delphi Project files.
Download Sample Raw Photo
Download Latest MSDCRAW.DLL file (dated 01/03/2010).

OLDER Previous Versions
     OLDER Download Sample Delphi Project files. (dated May  2009)
     OLDER Download Sample Delphi Project files. (dated Mar  2009)
     OLDER Download Sample Delphi Project files. (dated Sept  2008)
     OLDER Download Sample Delphi Project files. (dated Aug  2008)
     OLDER Download Sample Delphi Project files. (dated June 2008)
     OLDER Download Sample Delphi Project files. (dated April 2008)
     OLDER Download Sample Delphi Project files. (dated June 2007)

NOTE: You NEED to make sure you have the latest version of the MSDCRAW.DLL on an ongoing basis. This is because it's periodically updated to add new camera models to the list of what RAW files it can deal with.


If you wish to leave us mail just click on the name below:
Mail Box E-Mail to: Davie Lee Reed



David, here are the files in question:

SIGMA Problem dated 01/24/2006
Sigma photo of a bird IMG00203.X3F
Same photo converted to jpg with the sigma software IMG00203_sRGB.JPG

Files below are older problem files that have been resolved.

2 Sample NEF Files:
File to produce a JPG thumbnail: nef_jpg.nef
File to produce a PPM thumbnail: nef_ppm.nef

Canon 350D file that decodes as black :(: Download CANON.350D CR2 raw file.

PHASE_ONE doesn't parse a viable thumbnail : Download phaseone raw file.
CANON_CR2 doesn't dcraw a viable image: Download CANON.CR2 raw file.
RT16.TIF file that dcraw decodes black and parse extracts white thumbnail: Download RT16.TIF.