├── LibRawNet.sln ├── LibRawNet ├── Internal │ ├── Action.cs │ └── GammaAlgorithm.cs ├── LibRawNet.csproj ├── Native │ ├── LibRawNativeException.cs │ ├── LibRaw_constructor_flags.cs │ ├── LibRaw_errors.cs │ ├── LibRaw_filtering.cs │ ├── LibRaw_image_formats.cs │ ├── LibRaw_progress.cs │ ├── LibRaw_thumbnail_formats.cs │ ├── LibRaw_warnings.cs │ ├── NativeMethods.cs │ ├── color_data_state_t.cs │ ├── libraw_colordata_t.cs │ ├── libraw_data_t.cs │ ├── libraw_image_sizes_t.cs │ ├── libraw_imgother_t.cs │ ├── libraw_iparams_t.cs │ ├── libraw_masked_t.cs │ ├── libraw_output_params_t.cs │ ├── libraw_processed_image_t.cs │ ├── libraw_thumbnail_t.cs │ └── ph1_t.cs ├── Properties │ └── AssemblyInfo.cs ├── RawImage.cs ├── Streams │ ├── AbstractBitmapDataStream.cs │ ├── BmpBitmapStream.cs │ ├── LibRawBitmapDataStream.cs │ └── UnmanagedBgrBitmapDataStream.cs ├── libraw.x64.dll └── libraw.x86.dll └── Raw2Any ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── Raw2Any.csproj └── app.config /LibRawNet.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibRawNet", "LibRawNet\LibRawNet.csproj", "{16A62E87-6A29-456B-AD1D-76C00D118576}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Raw2Any", "Raw2Any\Raw2Any.csproj", "{67EF1B86-A8E8-4270-9AE6-429BB242F035}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C3A027B1-3E72-4A9E-8099-7A4E7DC92C0B}" 9 | ProjectSection(SolutionItems) = preProject 10 | Performance1.psess = Performance1.psess 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Debug|Mixed Platforms = Debug|Mixed Platforms 17 | Release|Any CPU = Release|Any CPU 18 | Release|Mixed Platforms = Release|Mixed Platforms 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 24 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 25 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 28 | {16A62E87-6A29-456B-AD1D-76C00D118576}.Release|Mixed Platforms.Build.0 = Release|Any CPU 29 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Debug|Any CPU.ActiveCfg = Debug|x86 30 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 31 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Debug|Mixed Platforms.Build.0 = Debug|x86 32 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Release|Any CPU.ActiveCfg = Release|x86 33 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Release|Any CPU.Build.0 = Release|x86 34 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Release|Mixed Platforms.ActiveCfg = Release|x86 35 | {67EF1B86-A8E8-4270-9AE6-429BB242F035}.Release|Mixed Platforms.Build.0 = Release|x86 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /LibRawNet/Internal/Action.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LibRawNet.Internal { 5 | internal delegate void Action(); 6 | } 7 | -------------------------------------------------------------------------------- /LibRawNet/Internal/GammaAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using LibRawNet.Native; 5 | 6 | namespace LibRawNet.Internal { 7 | internal class GammaAlgorithm { 8 | public static void Histogram(libraw_data_t data) { 9 | var t_white = 0x995; // this was actually a 0x2000, 0x995 is just a temp value suitable for ARW 10 | int c; 11 | 12 | //var perc = (int)(data.sizes.width * data.sizes.height * 0.01); 13 | //if (?.fuji_width) perc /= 2; 14 | 15 | //if (!((data.@params.highlight & ~2) || data.@params.no_auto_bright)) 16 | // for (t_white = c = 0; c < P1.colors; c++) { 17 | // int val; 18 | // int total; 19 | // for (val = 0x2000, total = 0; --val > 32; ) 20 | // if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break; 21 | // if (t_white < val) t_white = val; 22 | // } 23 | 24 | GammaCurve( 25 | data.color.curve, 26 | data.@params.gamm[0], 27 | data.@params.gamm[1], 28 | (t_white << 3) / data.@params.bright 29 | ); 30 | } 31 | 32 | // directly from libraw/dcraw, needs rewrite/clarification 33 | private static void GammaCurve(ushort[] curve, double pwr, double ts, double imax) { 34 | int i; 35 | var g = new double[6]; 36 | var bnd = new[] {0.0, 0.0}; 37 | 38 | g[0] = pwr; 39 | g[1] = ts; 40 | g[2] = g[3] = g[4] = 0; 41 | bnd[g[1] >= 1 ? 1 : 0] = 1; 42 | if (g[1] > 0 && (g[1]-1)*(g[0]-1) <= 0) { 43 | for (i=0; i < 48; i++) { 44 | g[2] = (bnd[0] + bnd[1])/2; 45 | if (g[0] > 0) { 46 | bnd[(Math.Pow(g[2]/g[1], -g[0]) - 1)/g[0] - 1/g[2] > -1 ? 1 : 0] = g[2]; 47 | } 48 | else { 49 | bnd[g[2]/Math.Exp(1 - 1/g[2]) < g[1] ? 1 : 0] = g[2]; 50 | } 51 | } 52 | 53 | g[3] = g[2] / g[1]; 54 | if (g[0] > 0) 55 | g[4] = g[2] * (1/g[0] - 1); 56 | } 57 | if (g[0] > 0) { 58 | g[5] = 1/(g[1]*Square(g[3])/2 - g[4]*(1 - g[3]) + 59 | (1 - Math.Pow(g[3], 1 + g[0]))*(1 + g[4])/(1 + g[0])) - 1; 60 | } 61 | else { 62 | g[5] = 1 / (g[1]*Square(g[3])/2 + 1 - g[2] - g[3] - g[2]*g[3]*(Math.Log(g[3]) - 1)) - 1; 63 | } 64 | 65 | for (i=0; i < 0x10000; i++) { 66 | curve[i] = 0xffff; 67 | double r; 68 | if ((r = (double) i / imax) < 1) 69 | curve[i] = (ushort)(0x10000 * ( 70 | (r < g[3] ? r*g[1] : (g[0] > 0 ? Math.Pow( r,g[0])*(1+g[4])-g[4] : Math.Log(r)*g[2]+1)))); 71 | } 72 | } 73 | 74 | private static double Square(double p0) { 75 | return p0*p0; 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /LibRawNet/LibRawNet.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {16A62E87-6A29-456B-AD1D-76C00D118576} 9 | Library 10 | Properties 11 | LibRawNet 12 | LibRawNet 13 | v2.0 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | PreserveNewest 71 | 72 | 73 | PreserveNewest 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /LibRawNet/Native/LibRawNativeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | 5 | namespace LibRawNet.Native { 6 | [Serializable] 7 | public class LibRawNativeException : Exception { 8 | public LibRawNativeException() { 9 | } 10 | 11 | public LibRawNativeException(string message) : base(message) { 12 | } 13 | 14 | public LibRawNativeException(string message, Exception inner) : base(message, inner) { 15 | } 16 | 17 | protected LibRawNativeException( 18 | SerializationInfo info, 19 | StreamingContext context) : base(info, context) { 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_constructor_flags.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace LibRawNet.Native { 4 | [Flags] 5 | internal enum LibRaw_constructor_flags { 6 | LIBRAW_OPTIONS_NONE = 0, 7 | LIBRAW_OPIONS_NO_MEMERR_CALLBACK = 1, 8 | LIBRAW_OPIONS_NO_DATAERR_CALLBACK = 1 << 1 9 | } 10 | } -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_errors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LibRawNet.Native { 5 | internal enum LibRaw_errors { 6 | LIBRAW_SUCCESS = 0, 7 | LIBRAW_UNSPECIFIED_ERROR = -1, 8 | LIBRAW_FILE_UNSUPPORTED = -2, 9 | LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE = -3, 10 | LIBRAW_OUT_OF_ORDER_CALL = -4, 11 | LIBRAW_NO_THUMBNAIL = -5, 12 | LIBRAW_UNSUPPORTED_THUMBNAIL = -6, 13 | LIBRAW_CANNOT_ADDMASK = -7, 14 | LIBRAW_UNSUFFICIENT_MEMORY = -100007, 15 | LIBRAW_DATA_ERROR = -100008, 16 | LIBRAW_IO_ERROR = -100009, 17 | LIBRAW_CANCELLED_BY_CALLBACK = -100010, 18 | LIBRAW_BAD_CROP = -100011 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_filtering.cs: -------------------------------------------------------------------------------- 1 | namespace LibRawNet.Native { 2 | public enum LibRaw_filtering { 3 | LIBRAW_FILTERING_DEFAULT = 0, 4 | LIBRAW_FILTERING_NOZEROES = 1, 5 | LIBRAW_FILTERING_DEPRECATED1 = 2, 6 | LIBRAW_FILTERING_NORAWCURVE = 4, 7 | LIBRAW_FILTERING_NONE = 7, 8 | LIBRAW_FILTERING_LIBRAWOWN = 8 | LIBRAW_FILTERING_NONE, 9 | LIBRAW_FILTERING_AUTOMATIC_BIT = 16, 10 | LIBRAW_FILTERING_AUTOMATIC = LIBRAW_FILTERING_LIBRAWOWN | LIBRAW_FILTERING_AUTOMATIC_BIT, 11 | } 12 | } -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_image_formats.cs: -------------------------------------------------------------------------------- 1 | namespace LibRawNet.Native { 2 | public enum LibRaw_image_formats { 3 | LIBRAW_IMAGE_JPEG = 1, 4 | LIBRAW_IMAGE_BITMAP = 2, 5 | } 6 | } -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_progress.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LibRawNet.Native { 5 | [Flags] 6 | internal enum LibRaw_progress { 7 | LIBRAW_PROGRESS_START = 0, 8 | LIBRAW_PROGRESS_OPEN = 1, 9 | LIBRAW_PROGRESS_IDENTIFY = 1<<1, 10 | LIBRAW_PROGRESS_SIZE_ADJUST = 1<<2, 11 | LIBRAW_PROGRESS_LOAD_RAW = 1<<3, 12 | LIBRAW_PROGRESS_REMOVE_ZEROES = 1<<4, 13 | LIBRAW_PROGRESS_BAD_PIXELS = 1<<5, 14 | LIBRAW_PROGRESS_DARK_FRAME = 1<<6, 15 | LIBRAW_PROGRESS_FOVEON_INTERPOLATE = 1<<7, 16 | LIBRAW_PROGRESS_SCALE_COLORS = 1<<8, 17 | LIBRAW_PROGRESS_PRE_INTERPOLATE = 1<<9, 18 | LIBRAW_PROGRESS_INTERPOLATE = 1<<10, 19 | LIBRAW_PROGRESS_MIX_GREEN = 1<<11, 20 | LIBRAW_PROGRESS_MEDIAN_FILTER = 1<<12, 21 | LIBRAW_PROGRESS_HIGHLIGHTS = 1<<13, 22 | LIBRAW_PROGRESS_FUJI_ROTATE = 1<<14, 23 | LIBRAW_PROGRESS_FLIP = 1<<15, 24 | LIBRAW_PROGRESS_APPLY_PROFILE = 1<<16, 25 | LIBRAW_PROGRESS_CONVERT_RGB = 1<<17, 26 | LIBRAW_PROGRESS_STRETCH = 1<<18, 27 | /* reserved */ 28 | LIBRAW_PROGRESS_STAGE19 = 1<<19, 29 | LIBRAW_PROGRESS_STAGE20 = 1<<20, 30 | LIBRAW_PROGRESS_STAGE21 = 1<<21, 31 | LIBRAW_PROGRESS_STAGE22 = 1<<22, 32 | LIBRAW_PROGRESS_STAGE23 = 1<<23, 33 | LIBRAW_PROGRESS_STAGE24 = 1<<24, 34 | LIBRAW_PROGRESS_STAGE25 = 1<<25, 35 | LIBRAW_PROGRESS_STAGE26 = 1<<26, 36 | LIBRAW_PROGRESS_STAGE27 = 1<<27, 37 | 38 | LIBRAW_PROGRESS_THUMB_LOAD = 1<<28, 39 | LIBRAW_PROGRESS_TRESERVED1 = 1<<29, 40 | LIBRAW_PROGRESS_TRESERVED2 = 1<<30, 41 | LIBRAW_PROGRESS_TRESERVED3 = 1<<31 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_thumbnail_formats.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LibRawNet.Native { 5 | internal enum LibRaw_thumbnail_formats { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /LibRawNet/Native/LibRaw_warnings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace LibRawNet.Native { 5 | [Flags] 6 | internal enum LibRaw_warnings { 7 | LIBRAW_WARN_NONE = 0, 8 | LIBRAW_WARN_FOVEON_NOMATRIX = 1, 9 | LIBRAW_WARN_FOVEON_INVALIDWB = 1 << 1, 10 | LIBRAW_WARN_BAD_CAMERA_WB = 1 << 2, 11 | LIBRAW_WARN_NO_METADATA = 1 << 3, 12 | LIBRAW_WARN_NO_JPEGLIB = 1 << 4, 13 | LIBRAW_WARN_NO_EMBEDDED_PROFILE = 1 << 5, 14 | LIBRAW_WARN_NO_INPUT_PROFILE = 1 << 6, 15 | LIBRAW_WARN_BAD_OUTPUT_PROFILE = 1 << 7, 16 | LIBRAW_WARN_NO_BADPIXELMAP = 1 << 8, 17 | LIBRAW_WARN_BAD_DARKFRAME_FILE = 1 << 9, 18 | LIBRAW_WARN_BAD_DARKFRAME_DIM = 1 << 10 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /LibRawNet/Native/NativeMethods.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Security; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace LibRawNet.Native { 7 | [SuppressUnmanagedCodeSecurity] 8 | internal static class NativeMethods { 9 | [DllImport("libraw")] 10 | public static extern IntPtr libraw_init(LibRaw_constructor_flags flags); 11 | 12 | [DllImport("libraw")] 13 | public static extern int libraw_open_file(IntPtr data, string fileName); 14 | 15 | [DllImport("libraw")] 16 | public static extern int libraw_unpack(IntPtr data); 17 | 18 | [DllImport("libraw")] 19 | public static extern int libraw_close(IntPtr data); 20 | 21 | [DllImport("libraw")] 22 | public static extern int libraw_dcraw_process(IntPtr lr); 23 | 24 | [DllImport("libraw")] 25 | public static extern IntPtr libraw_dcraw_make_mem_image(IntPtr data, out int errc); 26 | 27 | [DllImport("libraw")] 28 | public static extern int libraw_dcraw_clear_mem(IntPtr processed); 29 | } 30 | } -------------------------------------------------------------------------------- /LibRawNet/Native/color_data_state_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | /// 7 | /// This structure (actually, a bit field) describes the source of color data 8 | /// for each field of structure , which may be obtained from 9 | /// different data sources. 10 | /// 11 | [StructLayout(LayoutKind.Sequential)] 12 | public struct color_data_state_t { 13 | public uint bitdata; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_colordata_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | [StructLayout(LayoutKind.Sequential)] 7 | internal struct libraw_colordata_t { 8 | /// Data structure describing the sources of color data. 9 | public color_data_state_t color_flags; 10 | 11 | /// 12 | /// Block of white pixels extracted from files CIFF/CRW. 13 | /// Not extracted for other formats. Used to calculate white balance coefficients. 14 | /// 15 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8 * 8)] 16 | public ushort[] white; //[8][8]; 17 | 18 | /// 19 | /// White balance coefficients (as shot). Either read from file or calculated. 20 | /// 21 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 22 | public float[] cam_mul; 23 | 24 | /// 25 | /// White balance coefficients for daylight (daylight balance). Either read from file, 26 | /// or calculated on the basis of file data, or taken from hardcoded constants. 27 | /// 28 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 29 | public float[] pre_mul; 30 | 31 | /// 32 | /// White balance matrix. Read from file for some cameras, calculated for others. 33 | /// 34 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 4)] 35 | public float[] cmatrix; //[3][4]; 36 | 37 | /// 38 | /// Another white balance matrix, read from file for Leaf and Kodak cameras. 39 | /// 40 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 4)] 41 | public float[] rgb_cam; //[3][4]; 42 | 43 | /// 44 | /// Camera RGB - XYZ conversion matrix. This matrix is constant (different for 45 | /// different models). Last row is zero for RGB cameras and non-zero for different 46 | /// color models (CMYG and so on). 47 | /// 48 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4 * 3)] 49 | public float[] cam_xyz; //[4][3]; 50 | 51 | /// 52 | /// Camera tone curve, read from file for Nikon, Sony and some other cameras. 53 | /// 54 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10000)] 55 | public ushort[] curve; //[0x4001]; 56 | 57 | /// 58 | /// Black level. Depending on the camera, it may be zero (this means that black 59 | /// has been subtracted at the unpacking stage or by the camera itself), 60 | /// calculated at the unpacking stage, read from the RAW file, or hardcoded. 61 | /// 62 | public uint black; 63 | 64 | /// 65 | /// Per-channel black level. Items 0-3 are black pixels values (averaged), items 4-7 are per-channel counts. 66 | /// 67 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] 68 | public uint[] cblack; 69 | 70 | /// 71 | /// Maximum pixel value. Calculated from the data for most cameras, hardcoded for others. This value may be 72 | /// changed on postprocessing stage (when black subtraction performed) and by automated maximum adjustment 73 | /// (this adjustment performed if params.adjust_maximum_thr is set to nonzero). 74 | /// 75 | public uint maximum; 76 | 77 | /// 78 | /// Per channel maximum pixel value. Calculated from RAW data on unpack stage. 79 | /// 80 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 81 | public uint[] channel_maximum; 82 | 83 | /// 84 | /// Color data block that is read for Phase One cameras. 85 | /// 86 | public ph1_t phase_one_data; 87 | 88 | /// Field used for white balance calculations (for some P&S Canon cameras). 89 | public float flash_used; 90 | 91 | /// Field used for white balance calculations (for some P&S Canon cameras). 92 | public float canon_ev; 93 | 94 | /// Firmware revision (for some cameras). 95 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 96 | public string model2; 97 | 98 | /// Pointer to the retrieved ICC profile (if it is present in the RAW file). 99 | public IntPtr profile; 100 | 101 | /// Length of ICC profile in bytes. 102 | public uint profile_length; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_data_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | /// Main Data Structure of LibRaw 7 | [StructLayout(LayoutKind.Sequential)] 8 | internal struct libraw_data_t { 9 | /// This field records the past phases of image processing. 10 | public LibRaw_progress progress_flags; 11 | 12 | /// This field records suspicious situations (warnings) that have emerged during image processing. 13 | public LibRaw_warnings progress_warnings; 14 | 15 | /// The structure describes the main image parameters retrieved from the RAW file. 16 | public libraw_iparams_t idata; 17 | 18 | /// The structure describes the geometrical parameters of the image. 19 | public libraw_image_sizes_t sizes; 20 | 21 | /// The structure contains color data retrieved from the file. 22 | public libraw_colordata_t color; 23 | 24 | /// Data structure for information purposes: it contains the image parameters that have been extracted from the file but are not needed in further file processing. 25 | public libraw_imgother_t other; 26 | 27 | /// Data structure containing information on the preview and the preview data themselves. All fields of this structure but thumbnail itself are filled when open_file() is called. Thumbnail readed by unpack_thumb() call. 28 | public libraw_thumbnail_t thumbnail; 29 | 30 | /// Structure containing pixel data for black (masked) border pixels. It is filled when unpack() is called. 31 | public libraw_masked_t masked_pixels; 32 | 33 | /// The memory area that contains the image pixels per se. It is filled when unpack() is called. 34 | public IntPtr image; 35 | 36 | /// Data structure intended for management of image postprocessing (using the dcraw emulator). 37 | public libraw_output_params_t @params; 38 | 39 | ///// ??? 40 | //public IntPtr parent_class; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_image_sizes_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | /// Image Dimensions 7 | [StructLayout(LayoutKind.Sequential)] 8 | internal struct libraw_image_sizes_t { 9 | /// Full height of RAW image (including the frame) in pixels. 10 | public ushort raw_height; 11 | 12 | /// Full width of RAW image (including the frame) in pixels. 13 | public ushort raw_width; 14 | 15 | /// Height of visible ("meaningful") part of the image (without the frame). 16 | public ushort height; 17 | 18 | /// Width of visible ("meaningful") part of the image (without the frame). 19 | public ushort width; 20 | 21 | /// 22 | /// Coordinate of the top left corner of the frame (the second corner is 23 | /// calculated from the full size of the image and size of its visible part). 24 | /// 25 | public ushort top_margin; 26 | 27 | /// 28 | /// Coordinate of the top left corner of the frame (the second corner is 29 | /// calculated from the full size of the image and size of its visible part). 30 | /// 31 | public ushort left_margin; 32 | 33 | /// 34 | /// Height of the output image (may differ from height for cameras that require 35 | /// image rotation or have non-square pixels). 36 | /// 37 | public ushort iheight; 38 | 39 | /// 40 | /// Width of the output image (may differ from width for cameras that require 41 | /// image rotation or have non-square pixels). 42 | /// 43 | public ushort iwidth; 44 | 45 | /// 46 | /// Pixel width/height ratio. If it is not unity, scaling of the image along 47 | /// one of the axes is required during output. 48 | /// 49 | public double pixel_aspect; 50 | 51 | /// 52 | /// Image orientation ( 53 | /// 0 if does not require rotation; 54 | /// 3 if requires 180-deg rotation; 55 | /// 5 if 90 deg counterclockwise, 56 | /// 6 if 90 deg clockwise 57 | /// ). 58 | /// 59 | public int flip; 60 | 61 | /// Width (in pixels) of right part of masked pixels area. 62 | public ushort right_margin; 63 | 64 | /// Width (in pixels) of bottom part of masked pixels area. 65 | public ushort bottom_margin; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_imgother_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | [StructLayout(LayoutKind.Sequential)] 7 | internal struct libraw_imgother_t { 8 | /// ISO sensitivity. 9 | public float iso_speed; 10 | 11 | /// Shutter speed. 12 | public float shutter; 13 | 14 | /// Aperture. 15 | public float aperture; 16 | 17 | /// Focal length. 18 | public float focal_len; 19 | 20 | /// Date of shooting. 21 | public long timestamp; 22 | 23 | /// Serial number of image. 24 | public uint shot_order; 25 | 26 | /// GPS data. 27 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] 28 | public uint[] gpsdata; 29 | 30 | /// Image description. 31 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] 32 | public string desc; 33 | 34 | /// Author of image. 35 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 36 | public string artist; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_iparams_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | /// Main Parameters of the Image 7 | [StructLayout(LayoutKind.Sequential)] 8 | internal struct libraw_iparams_t { 9 | /// Camera manufacturer. 10 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 11 | public string make; 12 | 13 | /// Camera model. 14 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 15 | public string model; 16 | 17 | /// Number of RAW images in file (0 means that the file has not been recognized). 18 | public uint raw_count; 19 | 20 | /// DNG version (for the DNG format). 21 | public uint dng_version; 22 | 23 | /// ? 24 | public uint is_foveon; 25 | 26 | /// Number of colors in the file. 27 | public int colors; 28 | 29 | /// 30 | /// Bit mask describing the order of color pixels in the matrix (0 for full-color images). 31 | /// 32 bits of this field describe 16 pixels (8 rows with two pixels in each, from left to right 32 | /// and from top to bottom). Each two bits have values 0 to 3, which correspond to four possible colors. 33 | /// Convenient work with this field is ensured by the COLOR(row,column) function, which returns 34 | /// the number of the active color for a given pixel. 35 | /// 36 | public uint filters; 37 | 38 | /// Description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG). 39 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)] 40 | public string cdesc; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_masked_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | [StructLayout(LayoutKind.Sequential)] 7 | public struct libraw_masked_t { 8 | public IntPtr buffer; 9 | public IntPtr tl; 10 | public IntPtr top; 11 | public IntPtr tr; 12 | public IntPtr left; 13 | public IntPtr right; 14 | public IntPtr bl; 15 | public IntPtr bottom; 16 | public IntPtr br; 17 | public IntPtr ph1_black; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_output_params_t.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace LibRawNet.Native { 4 | [StructLayout(LayoutKind.Sequential)] 5 | public struct libraw_output_params_t { 6 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 7 | public uint[] greybox; 8 | 9 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 10 | public uint[] cropbox; 11 | 12 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 13 | public double[] aber; 14 | 15 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 16 | public double[] gamm; 17 | 18 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] 19 | public float[] user_mul; 20 | 21 | public uint shot_select; 22 | public float bright; 23 | public float threshold; 24 | public int half_size; 25 | public int four_color_rgb; 26 | public int document_mode; 27 | public int highlight; 28 | public int use_auto_wb; 29 | public int use_camera_wb; 30 | public int use_camera_matrix; 31 | public int output_color; 32 | 33 | [MarshalAs(UnmanagedType.LPStr)] 34 | public string output_profile; 35 | 36 | [MarshalAs(UnmanagedType.LPStr)] 37 | public string camera_profile; 38 | 39 | [MarshalAs(UnmanagedType.LPStr)] 40 | public string bad_pixels; 41 | 42 | [MarshalAs(UnmanagedType.LPStr)] 43 | public string dark_frame; 44 | 45 | public int output_bps; 46 | public int output_tiff; 47 | public int user_flip; 48 | public int user_qual; 49 | public int user_black; 50 | public int user_sat; 51 | public int med_passes; 52 | public float auto_bright_thr; 53 | public float adjust_maximum_thr; 54 | public int no_auto_bright; 55 | public int use_fuji_rotate; 56 | public int green_matching; 57 | public LibRaw_filtering filtering_mode; 58 | public int dcb_iterations; 59 | public int dcb_enhance_fl; 60 | public int fbdd_noiserd; 61 | public int eeci_refine; 62 | public int es_med_passes; 63 | public int ca_correc; 64 | public float cared; 65 | public float cablue; 66 | public int cfaline; 67 | public float linenoise; 68 | public int cfa_clean; 69 | public float lclean; 70 | public float cclean; 71 | public int cfa_green; 72 | public float green_thresh; 73 | public int exp_correc; 74 | public float exp_shift; 75 | public float exp_preser; 76 | } 77 | } -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_processed_image_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace LibRawNet.Native { 5 | [StructLayout(LayoutKind.Sequential)] 6 | public struct libraw_processed_image_t { 7 | public LibRaw_image_formats type; 8 | public ushort height; 9 | public ushort width; 10 | public ushort colors; 11 | public ushort bits; 12 | public uint data_size; 13 | 14 | public IntPtr data(IntPtr structPtr) { 15 | return new IntPtr( 16 | structPtr.ToInt32() + Marshal.SizeOf(typeof(libraw_processed_image_t)) 17 | ); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /LibRawNet/Native/libraw_thumbnail_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | /// 7 | /// Structure describes all parameters associated with the preview saved in the RAW file. 8 | /// 9 | [StructLayout(LayoutKind.Sequential)] 10 | internal struct libraw_thumbnail_t { 11 | /// Thumbnail data format. One of the values among enum . 12 | public LibRaw_thumbnail_formats tformat; 13 | 14 | /// Width of the preview image in pixels. 15 | public ushort twidth; 16 | 17 | /// Height of the preview image in pixels. 18 | public ushort height; 19 | 20 | /// Thumbnail length in bytes. 21 | public uint tlength; 22 | 23 | /// Number of colors in the preview. 24 | public int tcolors; 25 | 26 | /// Pointer to thumbnail, extracted from the data file. 27 | public IntPtr thumb; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LibRawNet/Native/ph1_t.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace LibRawNet.Native { 6 | [StructLayout(LayoutKind.Sequential)] 7 | internal struct ph1_t { 8 | public int format; 9 | public int key_off; 10 | public int t_black; 11 | public int black_off; 12 | public int split_col; 13 | public int tag_21a; 14 | public float tag_210; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LibRawNet/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // Setting ComVisible to false makes the types in this assembly not visible 5 | // to COM components. If you need to access a type in this assembly from 6 | // COM, set the ComVisible attribute to true on that type. 7 | [assembly: ComVisible(false)] 8 | 9 | // The following GUID is for the ID of the typelib if this project is exposed to COM 10 | [assembly: Guid("17d4d2d0-547e-4b27-97b5-302c15eeaecf")] 11 | 12 | // Version information for an assembly consists of the following four values: 13 | // 14 | // Major Version 15 | // Minor Version 16 | // Build Number 17 | // Revision 18 | // 19 | // You can specify all the values or you can default the Build and Revision Numbers 20 | // by using the '*' as shown below: 21 | // [assembly: AssemblyVersion("1.0.*")] 22 | [assembly: AssemblyVersion("1.0.0.0")] 23 | [assembly: AssemblyFileVersion("1.0.0.0")] 24 | -------------------------------------------------------------------------------- /LibRawNet/RawImage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Drawing.Imaging; 5 | using System.IO; 6 | using System.Runtime.InteropServices; 7 | 8 | using LibRawNet.Internal; 9 | using LibRawNet.Native; 10 | using LibRawNet.Streams; 11 | 12 | namespace LibRawNet { 13 | internal delegate TResult Func(T arg1); 14 | 15 | public class RawImage : IDisposable { 16 | private static readonly IDictionary PixelFormats = new Dictionary { 17 | { 24, PixelFormat.Format24bppRgb }, 18 | { 48, PixelFormat.Format48bppRgb } 19 | }; 20 | 21 | private static readonly IDictionary> ErrorWrappers = new Dictionary> { 22 | { LibRaw_errors.LIBRAW_OUT_OF_ORDER_CALL, ex => new InvalidOperationException("This call was not expected at this point.", ex) } 23 | }; 24 | 25 | private bool processed; 26 | private readonly IntPtr dataPtr; 27 | 28 | private RawImage(IntPtr dataPtr) { 29 | this.dataPtr = dataPtr; 30 | } 31 | 32 | public static RawImage FromFile(string fileName) { 33 | var dataPtr = NativeMethods.libraw_init( 34 | LibRaw_constructor_flags.LIBRAW_OPIONS_NO_DATAERR_CALLBACK | LibRaw_constructor_flags.LIBRAW_OPIONS_NO_MEMERR_CALLBACK 35 | ); 36 | if (dataPtr == IntPtr.Zero) 37 | throw new LibRawNativeException("libraw_init returned NULL pointer."); 38 | 39 | ProcessResult( 40 | NativeMethods.libraw_open_file(dataPtr, fileName) 41 | ); 42 | return new RawImage(dataPtr); 43 | } 44 | 45 | private static void ProcessResult(int result) { 46 | if (result == 0) 47 | return; 48 | 49 | var error = (LibRaw_errors)result; 50 | var ex = (Exception)new LibRawNativeException("Operation failed with error code " + error + "."); 51 | if (ErrorWrappers.ContainsKey(error)) 52 | ex = ErrorWrappers[error].Invoke(ex); 53 | 54 | throw ex; 55 | } 56 | 57 | public Stream ToBitmapStream() { 58 | this.EnsureProcessed(); 59 | return new BmpBitmapStream(new LibRawBitmapDataStream(GetStructure(this.dataPtr))); 60 | } 61 | 62 | public Bitmap ToBitmap() { 63 | using (var stream = this.ToBitmapStream()) { 64 | return new Bitmap(stream); 65 | } 66 | } 67 | 68 | private void EnsureProcessed() { 69 | if (this.processed) 70 | return; 71 | 72 | ProcessResult(NativeMethods.libraw_unpack(this.dataPtr)); 73 | this.ChangeData(data => { 74 | data.@params.use_camera_wb = 1; 75 | return data; 76 | }); 77 | 78 | ProcessResult(NativeMethods.libraw_dcraw_process(this.dataPtr)); 79 | ChangeData(data => { 80 | GammaAlgorithm.Histogram(data); 81 | return data; 82 | }); 83 | 84 | this.processed = true; 85 | } 86 | 87 | private void ChangeData(Func change) { 88 | var data = GetData(); 89 | data = change(data); 90 | Marshal.StructureToPtr(data, this.dataPtr, true); 91 | } 92 | 93 | private libraw_data_t GetData() { 94 | return GetStructure(this.dataPtr); 95 | } 96 | 97 | private static T GetStructure(IntPtr ptr) 98 | where T : struct 99 | { 100 | return (T)Marshal.PtrToStructure(ptr, typeof (T)); 101 | } 102 | 103 | public void Dispose() { 104 | this.Dispose(true); 105 | } 106 | 107 | private void Dispose(bool disposing) { 108 | if (disposing) 109 | GC.SuppressFinalize(this); 110 | 111 | NativeMethods.libraw_close(this.dataPtr); 112 | } 113 | 114 | ~RawImage() { 115 | this.Dispose(false); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /LibRawNet/Streams/AbstractBitmapDataStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | 6 | namespace LibRawNet.Streams { 7 | internal abstract class AbstractBitmapDataStream : Stream { 8 | public abstract Size BitmapSize { get; } 9 | public abstract int BitsPerPixel { get; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /LibRawNet/Streams/BmpBitmapStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace LibRawNet.Streams { 6 | internal class BmpBitmapStream : Stream { 7 | private readonly AbstractBitmapDataStream dataStream; 8 | private readonly byte[] header; 9 | private int? positionInHeader; 10 | 11 | public BmpBitmapStream(AbstractBitmapDataStream dataStream) { 12 | this.dataStream = dataStream; 13 | this.header = GetHeader(); 14 | this.positionInHeader = 0; 15 | } 16 | 17 | private byte[] GetHeader() { 18 | const int HeaderSize = 0x36; 19 | 20 | var headerStream = new MemoryStream(); 21 | var binaryWriter = new BinaryWriter(headerStream); 22 | 23 | // "BM" Magic number (unsigned integer 66, 77) 24 | binaryWriter.Write((byte)0x42); 25 | binaryWriter.Write((byte)0x4D); 26 | 27 | // Size of the BMP file 28 | binaryWriter.Write(HeaderSize + (int)this.dataStream.Length); 29 | 30 | // Application specific 31 | binaryWriter.Write(0); 32 | 33 | // Offset where the Pixel Array (bitmap data) can be found 34 | binaryWriter.Write(HeaderSize); 35 | 36 | // Number of bytes in the DIB header (from this point) 37 | binaryWriter.Write(40); 38 | 39 | // Size of the bitmap in pixels 40 | binaryWriter.Write(this.dataStream.BitmapSize.Width); 41 | binaryWriter.Write(this.dataStream.BitmapSize.Height); 42 | 43 | // Number of color planes being used 44 | binaryWriter.Write((short)1); 45 | 46 | // Number of bits per pixel 47 | binaryWriter.Write((short)this.dataStream.BitsPerPixel); 48 | 49 | // BI_RGB, no Pixel Array compression used 50 | binaryWriter.Write(0); 51 | 52 | // Size of the raw data in the Pixel Array (including padding) 53 | binaryWriter.Write(0); 54 | 55 | // Resolution of the image 56 | binaryWriter.Write(3780); // no idea what does it mean for now 57 | binaryWriter.Write(3780); 58 | 59 | // Number of colors in the palette 60 | binaryWriter.Write(0); 61 | 62 | // 0 means all colors are important 63 | binaryWriter.Write(0); 64 | 65 | return headerStream.ToArray(); 66 | } 67 | 68 | public override bool CanRead { 69 | get { return true; } 70 | } 71 | 72 | public override bool CanSeek { 73 | get { return false; } 74 | } 75 | 76 | public override bool CanWrite { 77 | get { return false; } 78 | } 79 | 80 | public override void Flush() { 81 | throw new NotSupportedException(); 82 | } 83 | 84 | public override long Length { 85 | get { return this.header.Length + this.dataStream.Length; } 86 | } 87 | 88 | public override long Position { 89 | get { 90 | if (this.positionInHeader != null) 91 | return (int)this.positionInHeader; 92 | 93 | return this.header.Length + this.dataStream.Position; 94 | } 95 | set { throw new NotSupportedException(); } 96 | } 97 | 98 | public override int Read(byte[] buffer, int offset, int count) { 99 | var countWithinHeader = 0; 100 | if (this.positionInHeader != null) { 101 | countWithinHeader = count; 102 | if (Position + count > this.header.Length) 103 | countWithinHeader = this.header.Length - offset; 104 | 105 | Array.Copy(this.header, this.Position, buffer, offset, countWithinHeader); 106 | this.positionInHeader += countWithinHeader; 107 | if (this.positionInHeader >= this.header.Length) 108 | this.positionInHeader = null; 109 | 110 | if (countWithinHeader == count) 111 | return countWithinHeader; 112 | 113 | offset += countWithinHeader; 114 | count -= countWithinHeader; 115 | } 116 | 117 | return countWithinHeader + this.dataStream.Read(buffer, offset, count); 118 | } 119 | 120 | public override long Seek(long offset, SeekOrigin origin) { 121 | throw new NotSupportedException(); 122 | } 123 | 124 | public override void SetLength(long value) { 125 | throw new NotSupportedException(); 126 | } 127 | 128 | public override void Write(byte[] buffer, int offset, int count) { 129 | throw new NotSupportedException(); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /LibRawNet/Streams/LibRawBitmapDataStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | 7 | using LibRawNet.Native; 8 | 9 | namespace LibRawNet.Streams { 10 | internal class LibRawBitmapDataStream : AbstractBitmapDataStream { 11 | private readonly libraw_data_t data; 12 | private readonly int imageDataSize; 13 | private readonly int rowPadding; 14 | 15 | private int currentRow; 16 | private int currentColumn; 17 | private int currentColorIndex; 18 | private int currentRowPadding; 19 | private readonly Size bitmapSize; 20 | 21 | public LibRawBitmapDataStream(libraw_data_t data) { 22 | this.data = data; 23 | this.bitmapSize = (this.data.sizes.flip & 4) != 4 24 | ? new Size(data.sizes.width, data.sizes.height) 25 | : new Size(data.sizes.height, data.sizes.width); 26 | 27 | var unpaddedRowSize = (this.bitmapSize.Width * this.BitsPerPixel / 8); 28 | this.rowPadding = 4 - (unpaddedRowSize % 4); 29 | if (this.rowPadding == 4) 30 | this.rowPadding = 0; 31 | 32 | this.imageDataSize = data.sizes.height * this.RowSize; 33 | } 34 | 35 | public override int BitsPerPixel { 36 | get { return data.@params.output_bps * data.idata.colors; } 37 | } 38 | 39 | public override Size BitmapSize { 40 | get { return this.bitmapSize; } 41 | } 42 | 43 | public override bool CanRead { 44 | get { return true; } 45 | } 46 | 47 | public override bool CanSeek { 48 | get { return false; } 49 | } 50 | 51 | public override bool CanWrite { 52 | get { return false; } 53 | } 54 | 55 | public override void Flush() { 56 | throw new NotSupportedException(); 57 | } 58 | 59 | public override long Length { 60 | get { return this.imageDataSize; } 61 | } 62 | 63 | public override long Position { 64 | get { throw new NotImplementedException(); } 65 | set { throw new NotSupportedException(); } 66 | } 67 | 68 | private int RowSize { 69 | get { return (this.bitmapSize.Width * this.BitsPerPixel / 8) + this.rowPadding; } 70 | } 71 | 72 | public override int Read(byte[] buffer, int offset, int count) { 73 | var colorCount = this.data.idata.colors; 74 | var width = this.bitmapSize.Width; 75 | 76 | var bits = data.@params.output_bps; 77 | if (bits != 8 || colorCount != 3) 78 | throw new NotImplementedException(); 79 | 80 | var image = this.data.image; 81 | var bufferSubOffset = 0; 82 | for (; this.currentRow < this.bitmapSize.Height; this.currentRow += 1) { 83 | var bmpBitmapRow = this.bitmapSize.Height - this.currentRow - 1; // BMPs are upside down 84 | 85 | for (; this.currentColumn < width; this.currentColumn += 1) { 86 | for (; this.currentColorIndex < colorCount; this.currentColorIndex += 1) { 87 | var bgrColorIndex = colorCount - 1 - this.currentColorIndex; 88 | var bitmapOffset = this.GetSourceOffset(bmpBitmapRow, this.currentColumn); 89 | 90 | var @color = (ushort)Marshal.ReadInt16(image, (bitmapOffset * 4 + bgrColorIndex) * sizeof(short)); 91 | buffer[offset + bufferSubOffset] = (byte)(this.data.color.curve[@color] >> 8); 92 | 93 | bufferSubOffset += 1; 94 | if (bufferSubOffset == count) { 95 | this.currentColorIndex += 1; // loop will not increase it because we return 96 | return count; 97 | } 98 | } 99 | 100 | this.currentColorIndex = 0; 101 | } 102 | 103 | for (; this.currentRowPadding < this.rowPadding; this.currentRowPadding += 1) { 104 | bufferSubOffset += 1; 105 | if (bufferSubOffset == count) { 106 | this.currentRowPadding += 1; // loop will not increase it because we return 107 | return count; 108 | } 109 | } 110 | 111 | this.currentColumn = 0; 112 | this.currentRowPadding = 0; 113 | } 114 | 115 | return bufferSubOffset; 116 | } 117 | 118 | private int GetSourceOffset(int row, int column) { 119 | var size = this.data.sizes; 120 | var flip = this.data.sizes.flip; 121 | 122 | if ((flip & 4) == 4) { 123 | var swap = row; 124 | row = column; 125 | column = swap; 126 | } 127 | 128 | if ((flip & 2) == 2) 129 | row = size.height - 1 - row; 130 | 131 | if ((flip & 1) == 1) 132 | column = size.width - 1 - column; 133 | 134 | return row * size.width + column; 135 | } 136 | 137 | public override long Seek(long offset, SeekOrigin origin) { 138 | throw new NotSupportedException(); 139 | } 140 | 141 | public override void SetLength(long value) { 142 | throw new NotSupportedException(); 143 | } 144 | 145 | public override void Write(byte[] buffer, int offset, int count) { 146 | throw new NotSupportedException(); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /LibRawNet/Streams/UnmanagedBgrBitmapDataStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Runtime.InteropServices; 5 | 6 | using LibRawNet.Internal; 7 | 8 | namespace LibRawNet.Streams { 9 | internal class UnmanagedBgrBitmapDataStream : AbstractBitmapDataStream { 10 | private enum ColorPart { 11 | Blue, 12 | Green, 13 | Red 14 | } 15 | 16 | private readonly IntPtr dataPtr; 17 | private readonly Size bitmapSize; 18 | private readonly int bitsPerPixel; 19 | private readonly Action dispose; 20 | 21 | private int row; 22 | private int column; 23 | 24 | private bool flushSaved; 25 | private byte? savedBlue; 26 | private byte? savedGreen; 27 | 28 | public UnmanagedBgrBitmapDataStream(IntPtr dataPtr, Size bitmapSize, int bitsPerPixel, Action dispose) { 29 | this.dataPtr = dataPtr; 30 | this.bitmapSize = bitmapSize; 31 | this.bitsPerPixel = bitsPerPixel; 32 | this.dispose = dispose; 33 | } 34 | 35 | public override Size BitmapSize { 36 | get { return this.bitmapSize; } 37 | } 38 | 39 | public override int BitsPerPixel { 40 | get { return this.bitsPerPixel; } 41 | } 42 | 43 | public override bool CanRead { 44 | get { return true; } 45 | } 46 | 47 | public override long Length { 48 | get { return this.BitmapSize.Width * this.BitmapSize.Height * (this.BitsPerPixel / 8); } 49 | } 50 | 51 | public override long Position { 52 | get { return (this.row * this.RowSize) + this.column; } 53 | set { throw new NotSupportedException(); } 54 | } 55 | 56 | private int RowSize { 57 | get { return this.BitmapSize.Width * 3; } 58 | } 59 | 60 | private int DataOffset { 61 | get { return ((this.BitmapSize.Height - this.row - 1) * this.RowSize) + this.column; } 62 | } 63 | 64 | public override int Read(byte[] buffer, int offset, int count) { 65 | if (this.BitsPerPixel / 3 != 8) 66 | throw new NotImplementedException("Support for " + this.BitsPerPixel + " bits per pixel is not yet implemented."); 67 | 68 | var availableCount = (int)Math.Min(count, this.Length - this.Position); 69 | var index = 0; 70 | while (index < availableCount) { 71 | if (this.flushSaved) { 72 | if (this.savedGreen != null) { 73 | buffer[offset + index] = this.savedGreen.Value; 74 | index += 1; 75 | this.savedGreen = null; 76 | continue; 77 | } 78 | 79 | if (this.savedBlue != null) { 80 | buffer[offset + index] = this.savedBlue.Value; 81 | index += 1; 82 | this.savedBlue = null; 83 | } 84 | 85 | this.flushSaved = false; 86 | continue; 87 | } 88 | 89 | var colorPartValue = Marshal.ReadByte(this.dataPtr, this.DataOffset); 90 | var colorPartKind = (ColorPart)(this.Position % 3); 91 | 92 | if (colorPartKind == ColorPart.Red) { 93 | buffer[offset + index] = colorPartValue; 94 | index += 1; 95 | this.flushSaved = true; 96 | } 97 | else if (colorPartKind == ColorPart.Green) { 98 | this.savedGreen = colorPartValue; 99 | } 100 | else { 101 | this.savedBlue = colorPartValue; 102 | } 103 | this.column += 1; 104 | if (this.column == this.RowSize) { 105 | this.column = 0; 106 | this.row += 1; 107 | } 108 | } 109 | 110 | return availableCount; 111 | } 112 | 113 | protected override void Dispose(bool disposing) { 114 | try { 115 | this.dispose(); 116 | } 117 | finally { 118 | base.Dispose(disposing); 119 | } 120 | } 121 | 122 | #region Unsupported 123 | 124 | public override bool CanSeek { 125 | get { return false; } 126 | } 127 | 128 | public override bool CanWrite { 129 | get { return false; } 130 | } 131 | 132 | public override void Flush() { 133 | throw new NotSupportedException(); 134 | } 135 | 136 | public override long Seek(long offset, System.IO.SeekOrigin origin) { 137 | throw new NotSupportedException(); 138 | } 139 | 140 | public override void SetLength(long value) { 141 | throw new NotSupportedException(); 142 | } 143 | 144 | public override void Write(byte[] buffer, int offset, int count) { 145 | throw new NotSupportedException(); 146 | } 147 | 148 | #endregion 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /LibRawNet/libraw.x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashmind/librawnet/8d51f443f2d05b193e936c29e6396777fe35d89b/LibRawNet/libraw.x64.dll -------------------------------------------------------------------------------- /LibRawNet/libraw.x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashmind/librawnet/8d51f443f2d05b193e936c29e6396777fe35d89b/LibRawNet/libraw.x86.dll -------------------------------------------------------------------------------- /Raw2Any/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing.Imaging; 4 | using System.IO; 5 | 6 | using LibRawNet; 7 | 8 | namespace Raw2Any { 9 | public class Program { 10 | public static void Main(string[] args) { 11 | try { 12 | var rawFileName = args[0]; 13 | var pngFileName = Path.ChangeExtension(rawFileName, "png"); 14 | 15 | //using (var raw = RawImage.FromFile(rawFileName)) 16 | //using (var bitmap = raw.ToBitmap()) { 17 | // bitmap.Save(pngFileName, ImageFormat.Png); 18 | //} 19 | var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(rawFileName); 20 | 21 | using (var raw = RawImage.FromFile(rawFileName)) { 22 | using (var bitmapStream = raw.ToBitmapStream()) 23 | using (var target = File.Create(fileNameWithoutExtension + "_stream.bmp")) { 24 | bitmapStream.CopyTo(target); 25 | } 26 | 27 | //using (var bitmap = raw.ToBitmap()) { 28 | // bitmap.Save(fileNameWithoutExtension + ".bmp", ImageFormat.Bmp); 29 | //} 30 | } 31 | } 32 | catch (Exception ex) { 33 | Console.ForegroundColor = ConsoleColor.Red; 34 | Console.Error.Write(ex); 35 | Console.ResetColor(); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Raw2Any/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // Setting ComVisible to false makes the types in this assembly not visible 5 | // to COM components. If you need to access a type in this assembly from 6 | // COM, set the ComVisible attribute to true on that type. 7 | [assembly: ComVisible(false)] 8 | 9 | // The following GUID is for the ID of the typelib if this project is exposed to COM 10 | [assembly: Guid("7a0936a1-6188-485f-ad52-4115273c2815")] 11 | 12 | // Version information for an assembly consists of the following four values: 13 | // 14 | // Major Version 15 | // Minor Version 16 | // Build Number 17 | // Revision 18 | // 19 | // You can specify all the values or you can default the Build and Revision Numbers 20 | // by using the '*' as shown below: 21 | // [assembly: AssemblyVersion("1.0.*")] 22 | [assembly: AssemblyVersion("1.0.0.0")] 23 | [assembly: AssemblyFileVersion("1.0.0.0")] 24 | -------------------------------------------------------------------------------- /Raw2Any/Raw2Any.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {67EF1B86-A8E8-4270-9AE6-429BB242F035} 9 | Exe 10 | Properties 11 | Raw2Any 12 | raw2any 13 | v4.0 14 | 15 | 16 | 512 17 | 18 | 19 | x86 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | x86 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | {16A62E87-6A29-456B-AD1D-76C00D118576} 48 | LibRawNet 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Raw2Any/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | --------------------------------------------------------------------------------