717 changes: 717 additions & 0 deletions darktable.glade

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions darktable.gtkrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
style "default"{

#fonts
fg[NORMAL] = "#F0F0F0"
fg[PRELIGHT] = "#000000"
fg[SELECTED] = "#000000"

#selected areas
base[SELECTED] = "#8a8aa0"
base[ACTIVE] = "#e3e3e3"
base[PRELIGHT] = "#E5E5F7"
base[INSENSITIVE]= "#ced0d7"
bg[SELECTED]= "#828aa4"

#app backgrouds
bg[NORMAL] = "#333333"
# bg_pixmap[NORMAL] = "lines_background.png"
# bg_pixmap[PRELIGHT] = "lines_background_blue.png"
}class "GtkWidget" style "default"
5 changes: 5 additions & 0 deletions src/LibRaw/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
AM_CFLAGS=-O4 -I$(srcdir) -Wall -fopenmp -pthread
LDADD=$(LCMS_LIBS)
noinst_LIBRARIES=libraw_r.a
libraw_r_a_SOURCES=internal/dcraw_common.cpp src/libraw_cxx.cpp internal/dcraw_fileio.cpp internal/foveon.cpp src/libraw_c_api.cpp
noinst_HEADERS=internal/defines.h internal/libraw_internal_funcs.h internal/var_defines.h libraw/libraw_internal.h libraw/libraw_alloc.h libraw/libraw_types.h libraw/libraw.h libraw/libraw_version.h libraw/libraw_const.h libraw/libraw_datastream.h
8,244 changes: 8,244 additions & 0 deletions src/LibRaw/internal/dcraw_common.cpp

Large diffs are not rendered by default.

215 changes: 215 additions & 0 deletions src/LibRaw/internal/dcraw_fileio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
GENERATED FILE, DO NOT EDIT
Generated from dcraw/dcraw.c at Sat Feb 7 20:23:45 2009
Look into original file (probably http://cybercom.net/~dcoffin/dcraw/dcraw.c)
for copyright information.
*/

#line 3971 "dcraw/dcraw.c"
#define CLASS LibRaw::
#include "libraw/libraw_types.h"
#define LIBRAW_LIBRARY_BUILD
#include "libraw/libraw.h"
#include "internal/defines.h"
#include "internal/var_defines.h"
#line 3981 "dcraw/dcraw.c"

/*
Seach from the current directory up to the root looking for
a ".badpixels" file, and fix those pixels now.
*/
void CLASS bad_pixels (char *fname)
{
FILE *fp=0;
char *cp, line[128];
int len, time, row, col, r, c, rad, tot, n, fixed=0;

if (!filters) return;
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,0,2);
#endif
if (fname)
fp = fopen (fname, "r");
#line 4024 "dcraw/dcraw.c"
if (!fp)
{
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_NO_BADPIXELMAP;
#endif
return;
}
while (fgets (line, 128, fp)) {
cp = strchr (line, '#');
if (cp) *cp = 0;
if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue;
if ((unsigned) col >= width || (unsigned) row >= height) continue;
if (time > timestamp) continue;
for (tot=n=0, rad=1; rad < 3 && n==0; rad++)
for (r = row-rad; r <= row+rad; r++)
for (c = col-rad; c <= col+rad; c++)
if ((unsigned) r < height && (unsigned) c < width &&
(r != row || c != col) && fc(r,c) == fc(row,col)) {
tot += BAYER2(r,c);
n++;
}
BAYER2(row,col) = tot/n;
#ifdef DCRAW_VERBOSE
if (verbose) {
if (!fixed++)
fprintf (stderr,_("Fixed dead pixels at:"));
fprintf (stderr, " %d,%d", col, row);
}
#endif
}
#ifdef DCRAW_VERBOSE
if (fixed) fputc ('\n', stderr);
#endif
fclose (fp);
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_BAD_PIXELS,1,2);
#endif
}

void CLASS subtract (char *fname)
{
FILE *fp;
int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col;
ushort *pixel;
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME,0,2);
#endif

if (!(fp = fopen (fname, "rb"))) {
#ifdef DCRAW_VERBOSE
perror (fname);
#endif
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_FILE;
#endif
return;
}
if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1;
while (!error && nd < 3 && (c = fgetc(fp)) != EOF) {
if (c == '#') comment = 1;
if (c == '\n') comment = 0;
if (comment) continue;
if (isdigit(c)) number = 1;
if (number) {
if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0';
else if (isspace(c)) {
number = 0; nd++;
} else error = 1;
}
}
if (error || nd < 3) {
fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
fclose (fp); return;
} else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
#ifdef DCRAW_VERBOSE
fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
#endif
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_BAD_DARKFRAME_DIM;
#endif
fclose (fp); return;
}
pixel = (ushort *) calloc (width, sizeof *pixel);
merror (pixel, "subtract()");
for (row=0; row < height; row++) {
fread (pixel, 2, width, fp);
for (col=0; col < width; col++)
BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0);
}
free (pixel);
black = 0;
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_DARK_FRAME,1,2);
#endif
}
#line 9088 "dcraw/dcraw.c"

#ifndef NO_LCMS
void CLASS apply_profile (char *input, char *output)
{
char *prof;
cmsHPROFILE hInProfile=0, hOutProfile=0;
cmsHTRANSFORM hTransform;
FILE *fp;
unsigned size;

cmsErrorAction (LCMS_ERROR_SHOW);
if (strcmp (input, "embed"))
hInProfile = cmsOpenProfileFromFile (input, "r");
else if (profile_length) {
#ifndef LIBRAW_LIBRARY_BUILD
prof = (char *) malloc (profile_length);
merror (prof, "apply_profile()");
fseek (ifp, profile_offset, SEEK_SET);
fread (prof, 1, profile_length, ifp);
hInProfile = cmsOpenProfileFromMem (prof, profile_length);
free (prof);
#else
hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length);
#endif
} else
{
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE;
#endif
#ifdef DCRAW_VERBOSE
fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
#endif
}
if (!hInProfile)
{
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE;
#endif
return;
}
if (!output)
hOutProfile = cmsCreate_sRGBProfile();
else if ((fp = fopen (output, "rb"))) {
fread (&size, 4, 1, fp);
fseek (fp, 0, SEEK_SET);
oprof = (unsigned *) malloc (size = ntohl(size));
merror (oprof, "apply_profile()");
fread (oprof, 1, size, fp);
fclose (fp);
if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) {
free (oprof);
oprof = 0;
}
#ifdef DCRAW_VERBOSE
} else
fprintf (stderr,_("Cannot open file %s!\n"), output);
#else
}
#endif
if (!hOutProfile)
{
#ifdef LIBRAW_LIBRARY_BUILD
imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE;
#endif
goto quit;
}
#ifdef DCRAW_VERBOSE
if (verbose)
fprintf (stderr,_("Applying color profile...\n"));
#endif
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2);
#endif
hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
cmsDoTransform (hTransform, image, image, width*height);
raw_color = 1; /* Don't use rgb_cam with a profile */
cmsDeleteTransform (hTransform);
cmsCloseProfile (hOutProfile);
quit:
cmsCloseProfile (hInProfile);
#ifdef LIBRAW_LIBRARY_BUILD
RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2);
#endif
}
#endif
134 changes: 134 additions & 0 deletions src/LibRaw/internal/defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
GENERATED FILE, DO NOT EDIT
Generated from dcraw/dcraw.c at Sat Feb 7 20:23:43 2009
Look into original file (probably http://cybercom.net/~dcoffin/dcraw/dcraw.c)
for copyright information.
*/

#line 27 "dcraw/dcraw.c"
#define NO_JPEG
#line 32 "dcraw/dcraw.c"
#define VERSION "8.91"

#define _GNU_SOURCE
#define _USE_MATH_DEFINES
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#ifdef _OPENMP
#include <omp.h>
#endif
/*
NO_JPEG disables decoding of compressed Kodak DC120 files.
NO_LCMS disables the "-p" option.
*/
#ifndef NO_JPEG
#include <jpeglib.h>
#endif
#ifndef NO_LCMS
#include <lcms.h>
#endif
#ifdef LOCALEDIR
#include <libintl.h>
#define _(String) gettext(String)
#else
#define _(String) (String)
#endif
#line 75 "dcraw/dcraw.c"
#ifdef __CYGWIN__
#include <io.h>
#endif
#ifdef WIN32
#include <sys/utime.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#define snprintf _snprintf
#define strcasecmp _stricmp
#define strncasecmp strnicmp
typedef __int64 INT64;
typedef unsigned __int64 UINT64;
#else
#include <unistd.h>
#include <utime.h>
#include <netinet/in.h>
typedef long long INT64;
typedef unsigned long long UINT64;
#endif

#ifdef LJPEG_DECODE
#error Please compile dcraw.c by itself.
#error Do not link it with ljpeg_decode.
#endif

#ifndef LONG_BIT
#define LONG_BIT (8 * sizeof (long))
#endif
#line 169 "dcraw/dcraw.c"
#define FORC(cnt) for (c=0; c < cnt; c++)
#define FORC3 FORC(3)
#define FORC4 FORC(4)
#define FORCC FORC(colors)

#define SQR(x) ((x)*(x))
#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define LIM(x,min,max) MAX(min,MIN(x,max))
#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
#define CLIP(x) LIM(x,0,65535)
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }

/*
In order to inline this calculation, I make the risky
assumption that all filter patterns can be described
by a repeating pattern of eight rows and two columns
Do not use the FC or BAYER macros with the Leaf CatchLight,
because its pattern is 16x16, not 2x8.
Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1
0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4:
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M
1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C
2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y
3 C Y C Y C Y 3 G M G M G M 3 G M G M G M
4 C Y C Y C Y 4 Y C Y C Y C
PowerShot A5 5 G M G M G M 5 G M G M G M
0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y
7 M G M G M G 7 M G M G M G
0 1 2 3 4 5
0 C Y C Y C Y
1 G M G M G M
2 C Y C Y C Y
3 M G M G M G
All RGB cameras use one of these Bayer grids:
0x16161616: 0x61616161: 0x49494949: 0x94949494:
0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5
0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G
1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B
2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G
3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B
*/

#line 227 "dcraw/dcraw.c"
#define BAYER(row,col) \
image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]

#define BAYER2(row,col) \
image[((row) >> shrink)*iwidth + ((col) >> shrink)][fc(row,col)]
817 changes: 817 additions & 0 deletions src/LibRaw/internal/foveon.cpp

Large diffs are not rendered by default.

200 changes: 200 additions & 0 deletions src/LibRaw/internal/libraw_internal_funcs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/* -*- C++ -*-
* File: libraw_internal_funcs.h
* Copyright 2008 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 14, 2008
*
* LibRaw internal data structures (not visible outside)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef _LIBRAW_INTERNAL_FUNCS_H
#define _LIBRAW_INTERNAL_FUNCS_H

#ifndef LIBRAW_LIBRARY_BUILD
#error "This file should be used only for libraw library build"
#else
// inline functions
ushort sget2 (uchar *s);
ushort get2();
unsigned sget4 (uchar *s);
unsigned getint (int type);
float int_to_float (int i);
double getreal (int type);
void read_shorts (ushort *pixel, int count);

// Canon P&S cameras
void canon_600_fixed_wb (int temp);
int canon_600_color (int ratio[2], int mar);
void canon_600_auto_wb();
void canon_600_coeff();
void canon_600_load_raw();
int canon_s2is();
void canon_a5_load_raw();
void parse_ciff (int offset, int length);
void ciff_block_1030();

// LJPEG decoder
unsigned getbits (int nbits);
void init_decoder();
uchar * make_decoder (const uchar *source, int level);
int ljpeg_start (struct jhead *jh, int info_only);
int ljpeg_diff (struct decode *dindex);
ushort * ljpeg_row (int jrow, struct jhead *jh);

// Canon DSLRs
void crw_init_tables (unsigned table);
int canon_has_lowbits();
void canon_compressed_load_raw();
void lossless_jpeg_load_raw();
void canon_sraw_load_raw();
void canon_black(double *);
// Adobe DNG
void adobe_copy_pixel (int row, int col, ushort **rp);
void adobe_dng_load_raw_lj();
void adobe_dng_load_raw_nc();

// Pentax
void pentax_k10_load_raw();

// Nikon (and Minolta Z2)
void nikon_compressed_load_raw();
void nikon_load_raw();
int nikon_is_compressed();
int nikon_e995();
int nikon_e2100();
void nikon_3700();
int minolta_z2();
void nikon_e900_load_raw();
void nikon_e2100_load_raw();

// Fuji
void fuji_load_raw();
void parse_fuji (int offset);




// Rollei
void rollei_load_raw();
void parse_rollei();

// MF backs
int bayer (unsigned row, unsigned col);
void phase_one_flat_field (int is_float, int nc);
void phase_one_correct();
void phase_one_load_raw();
unsigned ph1_bits (int nbits);
void phase_one_load_raw_c();
void hasselblad_load_raw();
void leaf_hdr_load_raw();
void sinar_4shot_load_raw();
void imacon_full_load_raw();
void packed_12_load_raw();
void unpacked_load_raw();
void parse_sinar_ia();
void parse_phase_one (int base);

// Misc P&S cameras
void nokia_load_raw();
unsigned pana_bits (int nbits);
void panasonic_load_raw();
void olympus_e300_load_raw();
void olympus_e410_load_raw();
void olympus_cseries_load_raw();
void minolta_rd175_load_raw();
void casio_qv5700_load_raw();
void quicktake_100_load_raw();
const int* make_decoder_int (const int *source, int level);
int radc_token (int tree);
void kodak_radc_load_raw();
void kodak_jpeg_load_raw();
void kodak_dc120_load_raw();
void eight_bit_load_raw();
void smal_decode_segment (unsigned seg[2][2], int holes);
void smal_v6_load_raw();
int median4 (int *p);
void fill_holes (int holes);
void smal_v9_load_raw();
void parse_riff();
void parse_cine();
void parse_smal (int offset, int fsize);
int parse_jpeg (int offset);

// Kodak
void kodak_262_load_raw();
int kodak_65000_decode (short *out, int bsize);
void kodak_65000_load_raw();
void kodak_rgb_load_raw();
void kodak_yrgb_load_raw();

// It's a Sony (and K&M)
void sony_decrypt (unsigned *data, int len, int start, int key);
void sony_load_raw();
void sony_arw_load_raw();
void sony_arw2_load_raw();
void parse_minolta (int base);

#ifndef NO_FOVEON
// Foveon/Sigma
void foveon_load_camf();
void foveon_load_raw();
const char* foveon_camf_param (const char *block, const char *param);
void * foveon_camf_matrix (unsigned dim[3], const char *name);
int foveon_fixed (void *ptr, int size, const char *name);
float foveon_avg (short *pix, int range[2], float cfilt);
short * foveon_make_curve (double max, double mul, double filt);
void foveon_make_curves(short **curvep, float dq[3], float div[3], float filt);
int foveon_apply_curve (short *curve, int i);
void foveon_interpolate();
char * foveon_gets (int offset, char *str, int len);
void parse_foveon();
#endif


// CAM/RGB
void pseudoinverse (double (*in)[3], double (*out)[3], int size);
void cam_xyz_coeff (double cam_xyz[4][3]);
void adobe_coeff (const char *, const char *);
void simple_coeff (int index);


// Tiff/Exif parsers
void tiff_get (unsigned base,unsigned *tag, unsigned *type, unsigned *len, unsigned *save);
void parse_thumb_note (int base, unsigned toff, unsigned tlen);
void parse_makernote (int base, int uptag);
void parse_exif (int base);
void linear_table (unsigned len);
void parse_kodak_ifd (int base);
int parse_tiff_ifd (int base);
void parse_tiff (int base);
void parse_gps (int base);
void romm_coeff (float romm_cam[3][3]);
void parse_mos (int offset);
void get_timestamp (int reversed);

// External JPEGs, what cameras uses it ?
void parse_external_jpeg();

// The identify
short guess_byte_order (int words);

// Tiff writer
void tiff_set (ushort *ntag, ushort tag, ushort type, int count, int val);
void tiff_head (struct tiff_hdr *th, int full);
#endif

#endif
180 changes: 180 additions & 0 deletions src/LibRaw/internal/var_defines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/* -*- C++ -*-
* File: var_defines.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8, 2008
*
* LibRaw redefinitions of dcraw internal variables
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef VAR_DEFINES_H
#define VAR_DEFINES_H

// imgdata.idata
#define make (imgdata.idata.make)
#define model (imgdata.idata.model)
#define is_raw (imgdata.idata.raw_count)
#define dng_version (imgdata.idata.dng_version)
#define is_foveon (imgdata.idata.is_foveon)
#define colors (imgdata.idata.colors)
#define cdesc (imgdata.idata.cdesc)
#define filters (imgdata.idata.filters)

//imgdata image
#define image (imgdata.image)

// imgdata.sizes
#define raw_height (imgdata.sizes.raw_height)
#define raw_width (imgdata.sizes.raw_width)
#define height (imgdata.sizes.height)
#define width (imgdata.sizes.width)
#define top_margin (imgdata.sizes.top_margin)
#define left_margin (imgdata.sizes.left_margin)
#define bottom_margin (imgdata.sizes.bottom_margin)
#define right_margin (imgdata.sizes.right_margin)
#define iheight (imgdata.sizes.iheight)
#define iwidth (imgdata.sizes.iwidth)
#define pixel_aspect (imgdata.sizes.pixel_aspect)
#define flip (imgdata.sizes.flip)

//imgdata.color
#define white (imgdata.color.white)
#define cam_mul (imgdata.color.cam_mul)
#define pre_mul (imgdata.color.pre_mul)
#define cmatrix (imgdata.color.cmatrix)
#define rgb_cam (imgdata.color.rgb_cam)
#ifndef SRC_USES_CURVE
#define curve (imgdata.color.curve)
#endif
#ifndef SRC_USES_BLACK
#define black (imgdata.color.black)
#endif
#define maximum (imgdata.color.maximum)
#define profile_length (imgdata.color.profile_length)
#define color_flags (imgdata.color.color_flags)
#define ph1 (imgdata.color.phase_one_data)
#define flash_used (imgdata.color.flash_used)
#define canon_ev (imgdata.color.canon_ev)
#define model2 (imgdata.color.model2)

//imgdata.thumbnail

#define thumb_width (imgdata.thumbnail.twidth)
#define thumb_height (imgdata.thumbnail.theight)
#define thumb_length (imgdata.thumbnail.tlength)


//imgdata.others
#define iso_speed (imgdata.other.iso_speed)
#define shutter (imgdata.other.shutter)
#define aperture (imgdata.other.aperture)
#define focal_len (imgdata.other.focal_len)
#define timestamp (imgdata.other.timestamp)
#define shot_order (imgdata.other.shot_order)
#define gpsdata (imgdata.other.gpsdata)
#define desc (imgdata.other.desc)
#define artist (imgdata.other.artist)

//imgdata.output
#define greybox (imgdata.params.greybox)
#define aber (imgdata.params.aber)
#define user_mul (imgdata.params.user_mul)
#define shot_select (imgdata.params.shot_select)
#define bright (imgdata.params.bright)
#define threshold (imgdata.params.threshold)
#define half_size (imgdata.params.half_size)
#define four_color_rgb (imgdata.params.four_color_rgb)
#define document_mode (imgdata.params.document_mode)
#define highlight (imgdata.params.highlight)
//#define verbose (imgdata.params.verbose)
#define use_auto_wb (imgdata.params.use_auto_wb)
#define use_camera_wb (imgdata.params.use_camera_wb)
#define use_camera_matrix (imgdata.params.use_camera_matrix)
#define output_color (imgdata.params.output_color)
#define output_bps (imgdata.params.output_bps)
#define gamma_16bit (imgdata.params.gamma_16bit)
#define output_tiff (imgdata.params.output_tiff)
#define med_passes (imgdata.params.med_passes)
#define no_auto_bright (imgdata.params.no_auto_bright)
#define use_fuji_rotate (imgdata.params.use_fuji_rotate)
#define filtering_mode (imgdata.params.filtering_mode)

//rgb_constants
#define xyz_rgb (rgb_constants.xyz_rgb)
#define d65_white (rgb_constants.d65_white)

//libraw_internal_data.internal_data
#define meta_data (libraw_internal_data.internal_data.meta_data)
#define ifp libraw_internal_data.internal_data.input
#define ifname ((char*)libraw_internal_data.internal_data.input->fname())
#define profile_offset (libraw_internal_data.internal_data.profile_offset)
#define thumb_offset (libraw_internal_data.internal_data.toffset)

//libraw_internal_data.internal_output_params
#define mix_green (libraw_internal_data.internal_output_params.mix_green)
#define raw_color (libraw_internal_data.internal_output_params.raw_color)
#define use_gamma (libraw_internal_data.internal_output_params.use_gamma)
#define zero_is_bad (libraw_internal_data.internal_output_params.zero_is_bad)
#ifndef SRC_USES_SHRINK
#define shrink (libraw_internal_data.internal_output_params.shrink)
#endif
#define fuji_width (libraw_internal_data.internal_output_params.fuji_width)


//libraw_internal_data.output_data
#define histogram (libraw_internal_data.output_data.histogram)
#define oprof (libraw_internal_data.output_data.oprof)

//libraw_internal_data.identify_data
#define exif_cfa (libraw_internal_data.identify_data.olympus_exif_cfa)
#define unique_id (libraw_internal_data.identify_data.unique_id)
#define tiff_nifds (libraw_internal_data.identify_data.tiff_nifds)
#define tiff_flip (libraw_internal_data.identify_data.tiff_flip)

//libraw_internal_data.unpacker_data
#define order (libraw_internal_data.unpacker_data.order)
#define data_error (libraw_internal_data.unpacker_data.data_error)
#define cr2_slice (libraw_internal_data.unpacker_data.cr2_slice)
#define sraw_mul (libraw_internal_data.unpacker_data.sraw_mul)
#define kodak_cbpp (libraw_internal_data.unpacker_data.kodak_cbpp)
#define strip_offset (libraw_internal_data.unpacker_data.strip_offset)
#define data_offset (libraw_internal_data.unpacker_data.data_offset)
#define meta_offset (libraw_internal_data.unpacker_data.meta_offset)
#define meta_length (libraw_internal_data.unpacker_data.meta_length)
#define thumb_misc (libraw_internal_data.unpacker_data.thumb_misc)
#define fuji_layout (libraw_internal_data.unpacker_data.fuji_layout)
#define tiff_samples (libraw_internal_data.unpacker_data.tiff_samples)
#define tiff_bps (libraw_internal_data.unpacker_data.tiff_bps)
#define tiff_compress (libraw_internal_data.unpacker_data.tiff_compress)
#define zero_after_ff (libraw_internal_data.unpacker_data.zero_after_ff)
#define tile_width (libraw_internal_data.unpacker_data.tile_width)
#define tile_length (libraw_internal_data.unpacker_data.tile_length)
#define load_flags (libraw_internal_data.unpacker_data.load_flags)

#ifdef LIBRAW_IO_REDEFINED
#define fread(ptr,size,n,stream) stream->read(ptr,size,n)
#define fseek(stream,o,w) stream->seek(o,w)
#define fseeko(stream,o,w) stream->seek(o,w)
#define ftell(stream) stream->tell()
#define ftello(stream) stream->tell()
#define getc(stream) stream->get_char()
#define fgetc(stream) stream->get_char()
#define fgets(str,n,stream) stream->gets(str,n)
#define fscanf(stream,fmt,ptr) stream->scanf_one(fmt,ptr)
#endif

#endif
229 changes: 229 additions & 0 deletions src/LibRaw/libraw/libraw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/* -*- C++ -*-
* File: libraw.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8, 2008
*
* LibRaw C++ interface
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef _LIBRAW_CLASS_H
#define _LIBRAW_CLASS_H

#include <limits.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>


#include "libraw_datastream.h"
#include "libraw_types.h"
#include "libraw_const.h"
#include "libraw_internal.h"
#include "libraw_alloc.h"

//#define DCRAW_VERBOSE

#ifdef __cplusplus
extern "C"
{
#endif
DllDef const char *libraw_strerror(int errorcode);
DllDef const char *libraw_strprogress(enum LibRaw_progress);
// LibRaw C API
DllDef libraw_data_t *libraw_init(unsigned int flags);
DllDef int libraw_open_file(libraw_data_t*, const char *);
DllDef int libraw_open_buffer(libraw_data_t*, void * buffer, size_t size);
DllDef int libraw_unpack(libraw_data_t*);
DllDef int libraw_unpack_thumb(libraw_data_t*);
DllDef void libraw_recycle(libraw_data_t*);
DllDef void libraw_close(libraw_data_t*);
// version helpers
DllDef const char* libraw_version();
DllDef int libraw_versionNumber();
// Camera list
DllDef const char** libraw_cameraList();
DllDef int libraw_cameraCount();

DllDef void libraw_set_memerror_handler(libraw_data_t*, memory_callback cb, void *datap);
DllDef void libraw_set_dataerror_handler(libraw_data_t*,data_callback func,void *datap);
DllDef void libraw_set_progress_handler(libraw_data_t*,progress_callback cb,void *datap);
DllDef int libraw_add_masked_borders_to_bitmap(libraw_data_t* lr);
DllDef const char * libraw_unpack_function_name(libraw_data_t* lr);
DllDef int libraw_rotate_fuji_raw(libraw_data_t* lr);

// DCRAW compatibility
DllDef int libraw_adjust_sizes_info_only(libraw_data_t*);
DllDef int libraw_dcraw_document_mode_processing(libraw_data_t*);
DllDef int libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char *filename);
DllDef int libraw_dcraw_thumb_writer(libraw_data_t* lr,const char *fname);
DllDef int libraw_dcraw_process(libraw_data_t* lr);
DllDef libraw_processed_image_t* dcraw_make_mem_image(libraw_data_t* lr, int *errc);
DllDef libraw_processed_image_t* dcraw_make_mem_thumb(libraw_data_t* lr, int *errc);

#ifdef __cplusplus
}
#endif


#ifdef __cplusplus

class DllDef LibRaw
{
public:
libraw_data_t imgdata;
int verbose;

LibRaw(unsigned int flags = LIBRAW_OPTIONS_NONE);

libraw_output_params_t* output_params_ptr() { return &imgdata.params;}
int open_file(const char *fname);
int open_buffer(void *buffer, size_t size);
int open_datastream(LibRaw_abstract_datastream *);
int unpack(void);
int unpack_thumb(void);

int adjust_sizes_info_only(void);
void set_memerror_handler( memory_callback cb,void *data) {callbacks.memcb_data = data; callbacks.mem_cb = cb; }
void set_dataerror_handler(data_callback func, void *data) { callbacks.datacb_data = data; callbacks.data_cb = func;}
void set_progress_handler(progress_callback pcb, void *data) { callbacks.progresscb_data = data; callbacks.progress_cb = pcb;}

// helpers
static const char* version() { return LIBRAW_VERSION_STR;}
static int versionNumber() { return LIBRAW_VERSION; }
static const char** cameraList();
static int cameraCount();
static const char* strprogress(enum LibRaw_progress);
static const char* strerror(int p) { return libraw_strerror(p);}
// dcraw emulation
int dcraw_document_mode_processing();
int dcraw_ppm_tiff_writer(const char *filename);
int dcraw_thumb_writer(const char *fname);
int dcraw_process(void);
// memory writers
libraw_processed_image_t* dcraw_make_mem_image(int *errcode=NULL);
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode=NULL);

// free all internal data structures
void recycle();
~LibRaw(void) { recycle(); delete tls; }

int FC(int row,int col) { return (imgdata.idata.filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3);}
int fc (int row, int col);
int add_masked_borders_to_bitmap();

const char *unpack_function_name();
int rotate_fuji_raw();

private:
void* malloc(size_t t);
void* calloc(size_t n,size_t t);
void free(void *p);
void merror (void *ptr, const char *where);
void derror();

// data

LibRaw_TLS *tls;
libraw_internal_data_t libraw_internal_data;
decode first_decode[2048], *second_decode, *free_decode;
tiff_ifd_t tiff_ifd[10];
libraw_memmgr memmgr;
libraw_callbacks_t callbacks;

LibRaw_constants rgb_constants;
void (LibRaw:: *write_thumb)(FILE *),
(LibRaw:: *write_fun)(FILE *);
void (LibRaw:: *load_raw)(),
(LibRaw:: *thumb_load_raw)();

void kodak_thumb_loader();
void write_thumb_ppm_tiff(FILE *); // kodak
void foveon_thumb_loader (void); //Sigma


// moved from implementation level to private: visibility
void init_masked_ptrs();
ushort *get_masked_pointer(int row, int col);

int own_filtering_supported(){ return 0;}
void identify();
void write_ppm_tiff (FILE *ofp);
void convert_to_rgb();
void kodak_ycbcr_load_raw();
void remove_zeroes();
#ifndef NO_LCMS
void apply_profile(char*,char*);
#endif
// Iterpolators
void pre_interpolate();
void border_interpolate (int border);
void lin_interpolate();
void vng_interpolate();
void ppg_interpolate();
void ahd_interpolate();

// Image filters
void bad_pixels(char*);
void subtract(char*);
void hat_transform (float *temp, float *base, int st, int size, int sc);
void wavelet_denoise();
void scale_colors();
void median_filter ();
void blend_highlights();
void recover_highlights();

void fuji_rotate();
void stretch();

// Thmbnail functions
void foveon_thumb (FILE *tfp);
void jpeg_thumb_writer (FILE *tfp,char *thumb,int thumb_length);
void jpeg_thumb (FILE *tfp);
void ppm_thumb (FILE *tfp);
void layer_thumb (FILE *tfp);
void rollei_thumb (FILE *tfp);
void kodak_thumb_load_raw();

// utility for cut'n'pasted code
void foveon_decoder (unsigned size, unsigned code);
unsigned get4();

int flip_index (int row, int col);
void gamma_lut(ushort lut[0x10000]);


// == internal functions

#ifdef LIBRAW_LIBRARY_BUILD
#include "internal/libraw_internal_funcs.h"
#endif

};

#ifdef LIBRAW_LIBRARY_BUILD
#define RUN_CALLBACK(stage,iter,expect) if(callbacks.progress_cb) { \
int rr = (*callbacks.progress_cb)(callbacks.progresscb_data,stage,iter,expect); \
if(rr!=0) throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; \
}
#endif


#endif // __cplusplus


#endif // _LIBRAW_CLASS_H
98 changes: 98 additions & 0 deletions src/LibRaw/libraw/libraw_alloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* -*- C++ -*-
* File: libraw_alloc.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 22, 2008
*
* LibRaw C++ interface
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef __LIBRAW_ALLOC_H
#define __LIBRAW_ALLOC_H

#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#define bzero(p,sz) memset(p,0,sz)
#endif

#ifdef __cplusplus

#define MSIZE 32

class libraw_memmgr
{
public:
libraw_memmgr()
{
bzero(mems,sizeof(mems));
calloc_cnt=0;
}
void *malloc(size_t sz)
{
void *ptr = ::malloc(sz);
mem_ptr(ptr);
return ptr;
}
void *calloc(size_t n, size_t sz)
{
void *ptr = ::calloc(n,sz);
mem_ptr(ptr);
return ptr;
}
void free(void *ptr)
{
::free(ptr);
forget_ptr(ptr);
}
void cleanup(void)
{
for(int i = 0; i< MSIZE; i++)
if(mems[i])
{
// fprintf(stderr,"Found lost fragment at 0x%x\n",mems[i]);
free(mems[i]);
mems[i] = NULL;
}
}

private:
void *mems[MSIZE];
int calloc_cnt;
void mem_ptr(void *ptr)
{
if(ptr)
for(int i=0;i < MSIZE; i++)
if(!mems[i])
{
mems[i] = ptr;
break;
}
}
void forget_ptr(void *ptr)
{
if(ptr)
for(int i=0;i < MSIZE; i++)
if(mems[i] == ptr)
mems[i] = NULL;
}

};

#endif //C++

#endif
160 changes: 160 additions & 0 deletions src/LibRaw/libraw/libraw_const.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* -*- C++ -*-
* File: libraw_const.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8 , 2008
*
* LibRaw error codes
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef _LIBRAW_ERRORS_H
#define _LIBRAW_ERRORS_H

enum LibRaw_constructor_flags
{
LIBRAW_OPTIONS_NONE =0,
LIBRAW_OPIONS_NO_MEMERR_CALLBACK=1,
LIBRAW_OPIONS_NO_DATAERR_CALLBACK=1<<1
};

enum LibRaw_warnings
{
LIBRAW_WARN_NONE =0,
LIBRAW_WARN_FOVEON_NOMATRIX =1,
LIBRAW_WARN_FOVEON_INVALIDWB =1<<1,
LIBRAW_WARN_BAD_CAMERA_WB =1<<2,
LIBRAW_WARN_NO_METADATA =1<<3,
LIBRAW_WARN_NO_JPEGLIB = 1<<4,
LIBRAW_WARN_NO_EMBEDDED_PROFILE = 1<<5,
LIBRAW_WARN_NO_INPUT_PROFILE = 1<<6,
LIBRAW_WARN_BAD_OUTPUT_PROFILE= 1<<7,
LIBRAW_WARN_NO_BADPIXELMAP=1<<8,
LIBRAW_WARN_BAD_DARKFRAME_FILE=1<<9,
LIBRAW_WARN_BAD_DARKFRAME_DIM=1<<10
};

enum LibRaw_exceptions
{
LIBRAW_EXCEPTION_NONE =0,
LIBRAW_EXCEPTION_ALLOC =1,
LIBRAW_EXCEPTION_DECODE_RAW =2,
LIBRAW_EXCEPTION_DECODE_JPEG=3,
LIBRAW_EXCEPTION_IO_EOF =4,
LIBRAW_EXCEPTION_IO_CORRUPT =5,
LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK=6
};


enum LibRaw_colorstate
{
LIBRAW_COLORSTATE_UNKNOWN =0,
LIBRAW_COLORSTATE_INIT =1,
LIBRAW_COLORSTATE_CONST =2,
LIBRAW_COLORSTATE_LOADED =3,
LIBRAW_COLORSTATE_CALCULATED=4,
LIBRAW_COLORSTATE_RESERVED1 =5,
LIBRAW_COLORSTATE_RESERVED2 =6,
LIBRAW_COLORSTATE_RESERVED3 =7
};

enum LibRaw_filtering
{
LIBRAW_FILTERING_DEFAULT =0,
LIBRAW_FILTERING_NOZEROES =1, // no remove zeroes
LIBRAW_FILTERING_NOBLACKS =2, // no black subtraction
LIBRAW_FILTERING_NORAWCURVE =4, // no raw data postprocessing (e.g. PhaseOne corrections etc)
LIBRAW_FILTERING_NONE =7, // (_NOZEROES | _NOBLACKS | _NORAWCURVE)
LIBRAW_FILTERING_LIBRAWOWN =(8 | LIBRAW_FILTERING_NONE), // NONE + 8
LIBRAW_FILTERING_AUTOMATIC_BIT =16, // - restore automatic mode after processing
LIBRAW_FILTERING_AUTOMATIC = (LIBRAW_FILTERING_LIBRAWOWN | LIBRAW_FILTERING_AUTOMATIC_BIT)
};


enum LibRaw_progress
{
LIBRAW_PROGRESS_START = 0,
LIBRAW_PROGRESS_OPEN = 1,
LIBRAW_PROGRESS_IDENTIFY = 1<<1,
LIBRAW_PROGRESS_SIZE_ADJUST = 1<<2,
LIBRAW_PROGRESS_LOAD_RAW = 1<<3,
LIBRAW_PROGRESS_REMOVE_ZEROES = 1<<4,
LIBRAW_PROGRESS_BAD_PIXELS = 1<<5,
LIBRAW_PROGRESS_DARK_FRAME = 1<<6,
LIBRAW_PROGRESS_FOVEON_INTERPOLATE = 1<<7,
LIBRAW_PROGRESS_SCALE_COLORS = 1<<8,
LIBRAW_PROGRESS_PRE_INTERPOLATE = 1<<9,
LIBRAW_PROGRESS_INTERPOLATE = 1<<10,
LIBRAW_PROGRESS_MIX_GREEN = 1<<11,
LIBRAW_PROGRESS_MEDIAN_FILTER = 1<<12,
LIBRAW_PROGRESS_HIGHLIGHTS = 1<<13,
LIBRAW_PROGRESS_FUJI_ROTATE = 1<<14,
LIBRAW_PROGRESS_FLIP = 1<<15,
LIBRAW_PROGRESS_APPLY_PROFILE = 1<<16,
LIBRAW_PROGRESS_CONVERT_RGB = 1<<17,
LIBRAW_PROGRESS_STRETCH = 1<<18,
// reserved
LIBRAW_PROGRESS_STAGE19 = 1<<19,
LIBRAW_PROGRESS_STAGE20 = 1<<20,
LIBRAW_PROGRESS_STAGE21 = 1<<21,
LIBRAW_PROGRESS_STAGE22 = 1<<22,
LIBRAW_PROGRESS_STAGE23 = 1<<23,
LIBRAW_PROGRESS_STAGE24 = 1<<24,
LIBRAW_PROGRESS_STAGE25 = 1<<25,
LIBRAW_PROGRESS_STAGE26 = 1<<26,
LIBRAW_PROGRESS_STAGE27 = 1<<27,

LIBRAW_PROGRESS_THUMB_LOAD = 1<<28,
LIBRAW_PROGRESS_TRESERVED1 = 1<<29,
LIBRAW_PROGRESS_TRESERVED2 = 1<<30,
LIBRAW_PROGRESS_TRESERVED3 = 1<<31
};
#define LIBRAW_PROGRESS_THUMB_MASK 0x0fffffff

enum LibRaw_errors
{
LIBRAW_SUCCESS = 0,
LIBRAW_UNSPECIFIED_ERROR=-1,
LIBRAW_FILE_UNSUPPORTED = -2,
LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE=-3,
LIBRAW_OUT_OF_ORDER_CALL=-4,
LIBRAW_NO_THUMBNAIL=-5,
LIBRAW_UNSUPPORTED_THUMBNAIL=-6,
LIBRAW_CANNOT_ADDMASK=-7,
LIBRAW_UNSUFFICIENT_MEMORY=-100007,
LIBRAW_DATA_ERROR=-100008,
LIBRAW_IO_ERROR=-100009,
LIBRAW_CANCELLED_BY_CALLBACK=-100010
};

#define LIBRAW_FATAL_ERROR(ec) ((ec)<-100000)

enum LibRaw_thumbnail_formats
{
LIBRAW_THUMBNAIL_UNKNOWN=0,
LIBRAW_THUMBNAIL_JPEG=1,
LIBRAW_THUMBNAIL_BITMAP=2,
LIBRAW_THUMBNAIL_LAYER=4,
LIBRAW_THUMBNAIL_ROLLEI=5
};

enum LibRaw_image_formats
{
LIBRAW_IMAGE_BITMAP=1,
LIBRAW_IMAGE_JPEG=2
};

#endif
296 changes: 296 additions & 0 deletions src/LibRaw/libraw/libraw_datastream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
/* -*- C -*-
* File: libraw_datastream.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sun Jan 18 13:07:35 2009
*
* LibRaw Data stream interface
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef __LIBRAW_DATASTREAM_H
#define __LIBRAW_DATASTREAM_H

#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>

#ifndef __cplusplus

struct LibRaw_abstract_datastream;

#else // __cplusplus

#include "libraw_const.h"

class LibRaw_buffer_datastream;

class LibRaw_abstract_datastream
{
public:
LibRaw_abstract_datastream(){substream=0;};
virtual ~LibRaw_abstract_datastream(void){if(substream) delete substream;}
virtual int valid(){return 0;}
// file input emulation
virtual int read(void *,size_t, size_t ){ return -1;}
virtual int seek(off_t o, int whence){return -1;}
virtual int tell(){return -1;}
virtual int get_char(){return -1;}
virtual char* gets(char *, int){ return NULL;}
virtual int scanf_one(const char *, void *){return -1;}
virtual int eof(){return -1;}

virtual const char* fname(){ return NULL;};
virtual int subfile_open(const char*){ return EINVAL;}
virtual void subfile_close(){}
virtual int tempbuffer_open(void*, size_t);
virtual void tempbuffer_close()
{
if(substream) delete substream;
substream = NULL;
}

protected:
LibRaw_abstract_datastream *substream;
};


class LibRaw_file_datastream : public LibRaw_abstract_datastream
{
public:
LibRaw_file_datastream(const char *fname)
{
if(fname)
{filename = fname; f = fopen(fname,"rb");}
else
{filename=0;f=0;}
sav=0;
}

virtual ~LibRaw_file_datastream() {if(f)fclose(f); if(sav)fclose(sav);}

virtual int valid() { return f?1:0;}

#define CHK() do {if(!f) throw LIBRAW_EXCEPTION_IO_EOF;}while(0)
virtual int read(void * ptr,size_t size, size_t nmemb)
{
CHK();
return substream?substream->read(ptr,size,nmemb):fread(ptr,size,nmemb,f);
}
virtual int eof()
{
CHK();
return substream?substream->eof():feof(f);
}
virtual int seek(off_t o, int whence)
{
CHK();
return substream?substream->seek(o,whence):fseek(f,o,whence);
}
virtual int tell()
{
CHK();
return substream?substream->tell():ftell(f);
}
virtual int get_char()
{
CHK();
return substream?substream->get_char():fgetc(f);
}
virtual char* gets(char *str, int sz)
{
CHK();
return substream?substream->gets(str,sz):fgets(str,sz,f);
}
virtual int scanf_one(const char *fmt, void*val)
{
CHK();
return substream?substream->scanf_one(fmt,val):fscanf(f,fmt,val);
}

virtual const char *fname() { return filename; }

// secondary
virtual int subfile_open(const char *fn)
{
if(sav) return EBUSY;
sav = f;
f = fopen(fn,"rb");
if(!f)
{
f = sav;
sav = NULL;
return ENOENT;
}
else
return 0;
}
virtual void subfile_close()
{
if(!sav) return;
fclose(f);
f = sav;
sav = 0;
}

private:
FILE *f,*sav;
const char *filename;
};
#undef CHK

class LibRaw_buffer_datastream : public LibRaw_abstract_datastream
{
public:
LibRaw_buffer_datastream(void *buffer, size_t bsize)
{
buf = (unsigned char*)buffer; streampos = 0; streamsize = bsize;
}
virtual ~LibRaw_buffer_datastream(){}
virtual int valid() { return buf?1:0;}
virtual int read(void * ptr,size_t sz, size_t nmemb)
{
if(substream) return substream->read(ptr,sz,nmemb);
size_t to_read = sz*nmemb;
if(to_read > streamsize - streampos)
to_read = streamsize-streampos;
if(to_read<1)
return 0;
memmove(ptr,buf+streampos,to_read);
streampos+=to_read;
return (to_read+sz-1)/sz;
}

virtual int eof()
{
if(substream) return substream->eof();
return streampos >= streamsize;
}

virtual int seek(off_t o, int whence)
{
if(substream) return substream->seek(o,whence);
switch(whence)
{
case SEEK_SET:
streampos = o > streamsize ? streamsize: o;
return 0;
case SEEK_CUR:
if(o<0)
{
if (o < - streampos)
o = - streampos;
streampos += o;
}
else if (o>0)
{
if(o> streamsize-streampos)
o = streamsize - streampos;
streampos += o;
}
return 0;
case SEEK_END:
if(o>0)
streampos = streamsize;
else if ( -o > streamsize)
streampos = 0;
else
streampos = streamsize+o;
return 0;
default:
return 0;
}
}

virtual int tell()
{
if(substream) return substream->tell();
return streampos;
}

virtual int get_char()
{
if(substream) return substream->get_char();
if(streampos>=streamsize)
return -1;
return buf[streampos++];
}
virtual char* gets(char *s, int sz)
{
if (substream) return substream->gets(s,sz);
unsigned char *psrc,*pdest,*str;
str = (unsigned char *)s;
psrc = buf+streampos;
pdest = str;
while ( ((psrc - buf) < streamsize)
&&
((pdest-str)<sz)
)
{
*pdest = *psrc;
if(*psrc == '\n')
break;
psrc++;
pdest++;
}
if((psrc-buf) < streamsize)
psrc++;
if((pdest-str)<sz)
*(++pdest)=0;
streampos = psrc - buf;
return s;
}
virtual int scanf_one(const char *fmt, void* val)
{
if(substream) return substream->scanf_one(fmt,val);
int scanf_res;
if(streampos>streamsize) return 0;
scanf_res = sscanf((char*)(buf+streampos),fmt,val);
if(scanf_res>0)
{
int xcnt=0;
while(streampos<streamsize)
{
streampos++;
xcnt++;
if(buf[streampos] == 0
|| buf[streampos]==' '
|| buf[streampos]=='\t'
|| buf[streampos]=='\n'
|| xcnt>24)
break;
}
}
return scanf_res;
}
private:
unsigned char *buf;
size_t streampos,streamsize;
};

inline int LibRaw_abstract_datastream::tempbuffer_open(void *buf, size_t size)
{
if(substream) return EBUSY;
substream = new LibRaw_buffer_datastream(buf,size);
return substream?0:EINVAL;
}


#endif

#endif

241 changes: 241 additions & 0 deletions src/LibRaw/libraw/libraw_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/* -*- C++ -*-
* File: libraw_internal.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8 , 2008
*
* LibRaw internal data structures (not visible outside)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef _LIBRAW_INTERNAL_TYPES_H
#define _LIBRAW_INTERNAL_TYPES_H

#include <stdio.h>
#ifdef __cplusplus


#ifndef CLASS
#define CLASS LibRaw::
#endif

#else
// C build
#ifndef CLASS
#define CLASS
#endif
#endif


#ifdef __cplusplus

#include "libraw_datastream.h"

class LibRaw_TLS
{
public:
struct
{
unsigned bitbuf;
int vbits, reset;
}getbits;
struct
{
UINT64 bitbuf;
int vbits;

}ph1_bits;
int make_decoder_leaf;
struct
{
struct decode *dstart[18], *dindex;
const int *s;
}radc_token;
struct
{
unsigned pad[128], p;
}sony_decrypt;
unsigned foveon_decoder_huff[1024];
uchar jpeg_buffer[4096];
struct
{
uchar buf[0x4000];
int vbits, padding;
}pana_bits;

// init - should use in constructor/recycle
void init()
{
getbits.bitbuf = 0; getbits.vbits = getbits.reset = 0;
ph1_bits.bitbuf = 0; ph1_bits.vbits = 0;
pana_bits.vbits = 0;
}
};


class LibRaw_constants
{
public:
static const float d65_white[3];
static const double xyz_rgb[3][3];
};
#endif // __cplusplus

#ifdef WIN32
typedef long off_t;
#endif

typedef struct
{
#ifndef __cplusplus
struct
#endif
LibRaw_abstract_datastream *input;
int input_internal;
// char *ifname;
char *meta_data;
off_t profile_offset;
off_t toffset;

} internal_data_t;

typedef struct
{
unsigned mix_green;
unsigned raw_color;
unsigned use_gamma;
unsigned zero_is_bad;
ushort shrink;
ushort fuji_width;
ushort fwidth,fheight;
} internal_output_params_t;

#define LIBRAW_HISTOGRAM_SIZE 0x2000
typedef struct
{
int (*histogram)[LIBRAW_HISTOGRAM_SIZE];
unsigned *oprof;
} output_data_t;

typedef struct
{
unsigned olympus_exif_cfa;
unsigned unique_id;
unsigned tiff_nifds;
int tiff_flip;
}identify_data_t;

typedef struct
{
short order; // II* / MM* - file word byte order
ushort sraw_mul[4],cr2_slice[3];
unsigned kodak_cbpp;
off_t strip_offset, data_offset;
off_t meta_offset;
unsigned meta_length;
unsigned thumb_misc;
unsigned fuji_layout;
unsigned tiff_samples;
unsigned tiff_bps;
unsigned tiff_compress;
unsigned zero_after_ff;
unsigned tile_width, tile_length,load_flags;
unsigned data_error;
}unpacker_data_t;



typedef struct
{
internal_data_t internal_data;
internal_output_params_t internal_output_params;
output_data_t output_data;
identify_data_t identify_data;
unpacker_data_t unpacker_data;
// callbacks_t callbacks;
} libraw_internal_data_t;


struct decode
{
struct decode *branch[2];
int leaf;
};

struct tiff_ifd_t
{
int t_width, t_height, bps, comp, phint, offset, t_flip, samples, bytes;
};


struct jhead {
int bits, high, wide, clrs, sraw, psv, restart, vpred[6];
struct decode *huff[6];
ushort *row;
};
struct tiff_tag {
ushort tag, type;
int count;
union { char c[4]; short s[2]; int i; } val;
};

struct tiff_hdr {
ushort t_order, magic;
int ifd;
ushort pad, ntag;
struct tiff_tag tag[23];
int nextifd;
ushort pad2, nexif;
struct tiff_tag exif[4];
ushort pad3, ngps;
struct tiff_tag gpst[10];
short bps[4];
int rat[10];
unsigned gps[26];
char t_desc[512], t_make[64], t_model[64], soft[32], date[20], t_artist[64];
};



#ifdef DEBUG_STAGE_CHECKS
#define CHECK_ORDER_HIGH(expected_stage) \
do { if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= expected_stage) {fprintf(stderr,"CHECK_HIGH: check %d >= %d\n",imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK,expected_stage);return LIBRAW_OUT_OF_ORDER_CALL;} } while(0)

#define CHECK_ORDER_LOW(expected_stage) \
do { printf("Checking LOW %d/%d : %d\n",imgdata.progress_flags,expected_stage,imgdata.progress_flags<expected_stage); if( (imgdata.progress_flags&LIBRAW_PROGRESS_THUMB_MASK) < expected_stage ) { printf("failed!\n"); return LIBRAW_OUT_OF_ORDER_CALL;} } while(0)
#define CHECK_ORDER_BIT(expected_stage) \
do { if(imgdata.progress_flags & expected_stage) return LIBRAW_OUT_OF_ORDER_CALL; } while(0)

#define SET_PROC_FLAG(stage) do {imgdata.progress_flags |= stage; fprintf(stderr,"SET_FLAG: %d\n",stage); } while (0)

#else

#define CHECK_ORDER_HIGH(expected_stage) \
do { if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) >= expected_stage) \
{return LIBRAW_OUT_OF_ORDER_CALL;} } while(0)

#define CHECK_ORDER_LOW(expected_stage) \
do { if((imgdata.progress_flags&LIBRAW_PROGRESS_THUMB_MASK) < expected_stage) \
return LIBRAW_OUT_OF_ORDER_CALL; } while(0)

#define CHECK_ORDER_BIT(expected_stage) \
do { if(imgdata.progress_flags & expected_stage) return LIBRAW_OUT_OF_ORDER_CALL; } while(0)

#define SET_PROC_FLAG(stage) do {imgdata.progress_flags |= stage;} while (0)

#endif

#endif
291 changes: 291 additions & 0 deletions src/LibRaw/libraw/libraw_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
/* -*- C++ -*-
* File: libraw_types.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8 , 2008
*
* LibRaw C data structures
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef _LIBRAW_TYPES_H
#define _LIBRAW_TYPES_H

#ifndef WIN32
#include <sys/time.h>
#endif
#include <stdio.h>
#ifdef _OPENMP
#include <omp.h>
#endif


#ifdef __cplusplus
extern "C" {
#endif

#ifndef USE_LCMS
#define NO_LCMS
#endif

#include "libraw_const.h"
#include "libraw_version.h"

typedef long long INT64;
typedef unsigned long long UINT64;
//#define ushort UshORt
typedef unsigned char uchar;
typedef unsigned short ushort;

#ifdef WIN32
#ifdef LIBRAW_NODLL
# define DllDef
#else
# ifdef LIBRAW_BUILDLIB
# define DllDef __declspec( dllexport )
# else
# define DllDef __declspec( dllimport )
# endif
#endif
// NO Win32
#else
# define DllDef
#endif


//class LibRaw;

typedef void (* memory_callback)(void * data, const char *file, const char *where);

DllDef void default_memory_callback(void *data,const char *file, const char *where);

typedef void (*data_callback)(void *data,const char *file, const int offset);

DllDef void default_data_callback(void *data,const char *file, const int offset);

typedef int (* progress_callback) (void *data,enum LibRaw_progress stage, int iteration,int expected);

typedef struct
{
memory_callback mem_cb;
void* memcb_data;

data_callback data_cb;
void* datacb_data;

progress_callback progress_cb;
void *progresscb_data;
} libraw_callbacks_t;

// Output bitmap type

typedef struct
{
enum LibRaw_image_formats type;
ushort height,
width,
colors,
bits,
gamma_corrected;
#if 0//def _OPENMP
#pragma omp firstprivate(colors,height,width)
#endif
unsigned int data_size; // ðàçìåð ïîëÿ äàííûõ â áàéòàõ
unsigned char data[1]; // we'll allocate more!
}libraw_processed_image_t;


//Decoded from exif and used in calculations
typedef struct
{
char make[64];
char model[64];

unsigned raw_count;
unsigned dng_version;
unsigned is_foveon;
int colors;

unsigned filters; // camera CFA pattern mask
char cdesc[5];

}libraw_iparams_t;

typedef struct
{
ushort raw_height,
raw_width,
height,
width,
top_margin,
left_margin;
ushort iheight,
iwidth;
#if 0//def _OPENMP
#pragma omp firstprivate(iheight,iwidth)
#endif
double pixel_aspect;
int flip;

// masked border sizes
ushort right_margin,bottom_margin; // right masked width and bottom height, inited after idendify()

} libraw_image_sizes_t;

//Phase One data
struct ph1_t
{
int format, key_off, t_black, black_off, split_col, tag_21a;
float tag_210;
};


typedef struct
{
// 32 bits total
unsigned curve_state : 3;
unsigned rgb_cam_state : 3;
unsigned cmatrix_state : 3;
unsigned pre_mul_state : 3;
unsigned cam_mul_state : 3;
unsigned filler : 17;
} color_data_state_t;

typedef struct
{
color_data_state_t color_flags;
ushort white[8][8]; // white block extracted from ciff/CRW
float cam_mul[4]; // camera white balance (from RAW)
float pre_mul[4]; // either set in identify() or calculated. Used on output
float cmatrix[3][4]; // camera color matrix
float rgb_cam[3][4]; // another way to set color matrix
float cam_xyz[4][3]; // Camera to XYZ matrix (DNG coeffs)
ushort curve[0x4001]; // camera tone curve/ljpeg curve
unsigned black;
unsigned maximum;
struct ph1_t phase_one_data;
float flash_used; // canon/CRW only
float canon_ev; // canon/CRW only
char model2[64];
// profile
void *profile;
unsigned profile_length;
}libraw_colordata_t;

typedef struct
{
enum LibRaw_thumbnail_formats tformat;
ushort twidth,
theight;
unsigned tlength;
int tcolors;

// thumbnail buffer
char *thumb;
}libraw_thumbnail_t;

// Decoded from exif/raw, but not used in real calculations
typedef struct
{
float iso_speed;
float shutter;
float aperture;
float focal_len;
time_t timestamp;
unsigned shot_order;
unsigned gpsdata[32];
// string variables
char desc[512],
artist[64];
} libraw_imgother_t;

typedef struct
{
unsigned greybox[4]; /* -A x1 y1 x2 y2 */
double aber[4]; /* -C */
float user_mul[4]; /* -r mul0 mul1 mul2 mul3 */
unsigned shot_select; /* -s */
float bright; /* -b */
float threshold; /* -n */
#if 0//def _OPENMP
#pragma omp firstprivate(threshold)
#endif
int half_size; /* -h */
int four_color_rgb; /* -f */
int document_mode; /* -d/-D */
int highlight; /* -H */
// int verbose; /* -v */
int use_auto_wb; /* -a */
int use_camera_wb; /* -w */
int use_camera_matrix; /* +M/-M */
int output_color; /* -o */
char *output_profile; /* -o */
char *camera_profile; /* -p */
char *bad_pixels; /* -P */
char *dark_frame; /* -K */
int output_bps; /* -4 */
int gamma_16bit; /* -1 */
int output_tiff; /* -T */
int user_flip; /* -t */
int user_qual; /* -q */
int user_black; /* -k */
int user_sat; /* -S */

int med_passes; /* -m */
int no_auto_bright; /* -W */
int use_fuji_rotate;/* -j */
enum LibRaw_filtering filtering_mode;
}libraw_output_params_t;

typedef struct
{
ushort *buffer; // actual pixel buffer size=(raw_width*raw_height - width*height)
ushort *tl; // top left size=(top_margin*left_margin)
ushort *top; // top size=(top_margin*width)
ushort *tr; // top right size=((raw_width-width-left_margin)*top_margin)
ushort *left; // left size=(left_margin*height)
ushort *right; // right size=(raw_width-width-left_margin)*height;
ushort *bl; // bottom left size=(raw_height-height-top_margin)*left_margin
ushort *bottom; // bottom size=(raw_height-height-top_margin)*width
ushort *br; // bottom right size=(raw_height-height-top_margin)*
ushort (*ph1_black)[2]; // Phase One black
}libraw_masked_t;

typedef struct
{
unsigned int progress_flags;
unsigned int process_warnings;
libraw_iparams_t idata;
libraw_image_sizes_t sizes;
libraw_colordata_t color;
libraw_imgother_t other;
libraw_thumbnail_t thumbnail;
libraw_masked_t masked_pixels;
ushort (*image)[4] ;
#if 0//def _OPENMP
#pragma omp shared(image)
#endif
libraw_output_params_t params;
// pointer to LibRaw class for use in C calls
void *parent_class;
} libraw_data_t;


#ifdef __cplusplus
}
#endif

#endif
47 changes: 47 additions & 0 deletions src/LibRaw/libraw/libraw_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* -*- C++ -*-
* File: version.h
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Mon Sept 8, 2008
*
* LibRaw C++ interface
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/

#ifndef __VERSION_H
#define __VERSION_H

#define LIBRAW_MAJOR_VERSION 0
#define LIBRAW_MINOR_VERSION 7
#define LIBRAW_PATCH_VERSION 0
#define LIBRAW_VERSION_TAIL Beta1

#define _LIBRAW_VERSION_MAKE(a,b,c,d) #a"."#b"."#c"-"#d
#define LIBRAW_VERSION_MAKE(a,b,c,d) _LIBRAW_VERSION_MAKE(a,b,c,d)

#define LIBRAW_VERSION_STR LIBRAW_VERSION_MAKE(LIBRAW_MAJOR_VERSION,LIBRAW_MINOR_VERSION,LIBRAW_PATCH_VERSION,LIBRAW_VERSION_TAIL)

#define LIBRAW_MAKE_VERSION(major,minor,patch) \
(((major) << 16) | ((minor) << 8) | (patch))

#define LIBRAW_VERSION \
LIBRAW_MAKE_VERSION(LIBRAW_MAJOR_VERSION,LIBRAW_MINOR_VERSION,LIBRAW_PATCH_VERSION)

#define LIBRAW_CHECK_VERSION(major,minor,patch) \
( LibRaw::versionNumber() >= LIBRAW_MAKE_VERSION(major,minor,patch) )


#endif
149 changes: 149 additions & 0 deletions src/LibRaw/src/libraw_c_api.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* -*- C++ -*-
* File: libraw_c_api.cpp
* Copyright 2008-2009 Alex Tutubalin <lexa@lexa.ru>
* Created: Sat Mar 8 , 2008
*
* LibRaw C++ interface (implementation)
*/
#include <errno.h>
#include "libraw/libraw.h"

#ifdef __cplusplus
extern "C"
{
#endif

libraw_data_t *libraw_init(unsigned int flags)
{
LibRaw *ret = new LibRaw(flags);
return &(ret->imgdata);
}

const char* libraw_version() { return LibRaw::version();}
const char* libraw_strprogress(enum LibRaw_progress p) { return LibRaw::strprogress(p);}
int libraw_versionNumber() { return LibRaw::versionNumber();}
const char** libraw_cameraList() { return LibRaw::cameraList();}
int libraw_cameraCount() { return LibRaw::cameraCount(); }
const char* libraw_unpack_function_name(libraw_data_t* lr)
{
if(!lr) return "NULL parameter passed";
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->unpack_function_name();
}
int libraw_rotate_fuji_raw(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->rotate_fuji_raw();
}

int libraw_add_masked_borders_to_bitmap(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->add_masked_borders_to_bitmap();
}

int libraw_open_file(libraw_data_t* lr, const char *file)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->open_file(file);
}
int libraw_open_buffer(libraw_data_t* lr, void *buffer, size_t size)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->open_buffer(buffer,size);
}
int libraw_unpack(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->unpack();
}
int libraw_unpack_thumb(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->unpack_thumb();
}
void libraw_recycle(libraw_data_t* lr)
{
if(!lr) return;
LibRaw *ip = (LibRaw*) lr->parent_class;
ip->recycle();
}
void libraw_close(libraw_data_t* lr)
{
if(!lr) return;
LibRaw *ip = (LibRaw*) lr->parent_class;
delete ip;
}

void libraw_set_memerror_handler(libraw_data_t* lr, memory_callback cb,void *data)
{
if(!lr) return;
LibRaw *ip = (LibRaw*) lr->parent_class;
ip->set_memerror_handler(cb,data);

}
void libraw_set_dataerror_handler(libraw_data_t* lr,data_callback func,void *data)
{
if(!lr) return;
LibRaw *ip = (LibRaw*) lr->parent_class;
ip->set_dataerror_handler(func,data);

}
void libraw_set_progress_handler(libraw_data_t* lr, progress_callback cb,void *data)
{
if(!lr) return;
LibRaw *ip = (LibRaw*) lr->parent_class;
ip->set_progress_handler(cb,data);

}

// DCRAW
int libraw_adjust_sizes_info_only(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->adjust_sizes_info_only();
}

int libraw_dcraw_document_mode_processing(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->dcraw_document_mode_processing();

}
int libraw_dcraw_ppm_tiff_writer(libraw_data_t* lr,const char *filename)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->dcraw_ppm_tiff_writer(filename);
}
int libraw_dcraw_thumb_writer(libraw_data_t* lr,const char *fname)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->dcraw_thumb_writer(fname);

}
int libraw_dcraw_process(libraw_data_t* lr)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->dcraw_process();
}
libraw_processed_image_t *dcraw_make_mem_image(libraw_data_t* lr, int *errorcode)
{
if(!lr) return NULL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->dcraw_make_mem_image(errorcode);
}

#ifdef __cplusplus
}
#endif
1,935 changes: 1,935 additions & 0 deletions src/LibRaw/src/libraw_cxx.cpp

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
SUBDIRS=LibRaw
include shared.am
noinst_LIBRARIES=libdarktable.a
libdarktable_a_SOURCES=control/jobs.c library/film.c library/library.c gui/gtk.c gui/navigation.c gui/histogram.c gui/curveeditor.c develop/develop.c develop/imageop.c common/imageio.c common/darktable.c common/nikon_curve.c control/control.c develop/iop_hsb.c gui/develop_view.c common/image.c common/image_cache.c common/image_compression.c
bin_PROGRAMS=darktable
darktable_SOURCES=main.c
darktable_LDADD=-lgomp $(MAGICK_LIBS) $(CAIRO_LIBS) $(GLADE_LIBS) $(GTK_LIBS) $(GTHREAD_LIBS) $(SQLITE_LIBS) libdarktable.a LibRaw/libraw_r.a -lstdc++
noinst_HEADERS=library/library.h gui/curveeditor.h gui/gtk.h gui/histogram.h gui/navigation.h develop/develop.h develop/imageop.h common/nikon_curve.h common/darktable.h common/imageio.h control/settings.h control/control.h control/jobs.h develop/iop_hsb.h common/image.h common/image_cache.h common/image_compression.h
131 changes: 131 additions & 0 deletions src/common/darktable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "common/darktable.h"
#include "common/image.h"
#include "common/image_cache.h"
#include "library/library.h"
#include "develop/develop.h"
#include "control/control.h"
#include "gui/gtk.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_MAGICK
#include <magick/MagickCore.h>
#endif
#include <string.h>
#ifdef _OPENMP
# include <omp.h>
#endif

darktable_t darktable;

int dt_init(int argc, char *argv[])
{
#ifdef _OPENMP
omp_set_num_threads(omp_get_num_procs());
#endif
darktable.unmuted = 0;
for(int k=0;k<argc;k++)
{
if(argv[k][0] == '-' && argv[k][1] == 'd' && argc > k+1)
{
if(!strcmp(argv[k+1], "cache")) darktable.unmuted |= DT_DEBUG_CACHE; // enable debugging for lib/film/cache module
if(!strcmp(argv[k+1], "control")) darktable.unmuted |= DT_DEBUG_CONTROL; // enable debugging for scheduler module
if(!strcmp(argv[k+1], "dev")) darktable.unmuted |= DT_DEBUG_DEV; // develop module
}
}

#ifdef HAVE_MAGICK
MagickCoreGenesis(*argv, MagickTrue);
#endif
char *homedir = getenv("HOME");
char filename[512], *c = NULL;
snprintf(filename, 512, "%s/.darktablerc", homedir);
FILE *f = fopen(filename, "rb");
if(f)
{
c = fgets(filename, 512, f);
fclose(f);
}
if(!c) snprintf(filename, 512, "%s/.darktabledb", homedir);
if(sqlite3_open(filename, &(darktable.db)))
{
fprintf(stderr, "[init] could not open database %s!\n", filename);
sqlite3_close(darktable.db);
exit(1);
}
pthread_mutex_init(&(darktable.db_insert), NULL);

// has to go first for settings needed by all the others.
darktable.control = (dt_control_t *)malloc(sizeof(dt_control_t));
dt_control_init(darktable.control);

darktable.mipmap_cache = (dt_mipmap_cache_t *)malloc(sizeof(dt_mipmap_cache_t));
dt_mipmap_cache_init(darktable.mipmap_cache, 500);

darktable.image_cache = (dt_image_cache_t *)malloc(sizeof(dt_image_cache_t));
dt_image_cache_init(darktable.image_cache, 500);

darktable.library = (dt_library_t *)malloc(sizeof(dt_library_t));
dt_library_init(darktable.library);

darktable.develop = (dt_develop_t *)malloc(sizeof(dt_develop_t));
dt_dev_init(darktable.develop, 1);

darktable.gui = (dt_gui_gtk_t *)malloc(sizeof(dt_gui_gtk_t));
dt_gui_gtk_init(darktable.gui, argc, argv);

dt_control_load_config(darktable.control);

return 0;
}

void dt_cleanup()
{
dt_ctl_gui_mode_t gui;
DT_CTL_GET_GLOBAL(gui, gui);
if(gui == DT_DEVELOP) dt_dev_leave();
char *homedir = getenv("HOME");
char filename[512];
snprintf(filename, 512, "%s/.darktablerc", homedir);
FILE *f = fopen(filename, "wb");
if(f)
{
if(fputs(darktable.control->global_settings.dbname, f) == EOF) fprintf(stderr, "[cleanup] could not write to %s!\n", filename);
fclose(f);
}
else fprintf(stderr, "[cleanup] could not write to %s!\n", filename);
dt_control_write_config(darktable.control);

dt_control_cleanup(darktable.control);
free(darktable.control);
dt_dev_cleanup(darktable.develop);
free(darktable.develop);
dt_library_cleanup(darktable.library);
free(darktable.library);
dt_gui_gtk_cleanup(darktable.gui);
free(darktable.gui);
dt_image_cache_cleanup(darktable.image_cache);
free(darktable.image_cache);
dt_mipmap_cache_cleanup(darktable.mipmap_cache);
free(darktable.mipmap_cache);

sqlite3_close(darktable.db);
pthread_mutex_destroy(&(darktable.db_insert));

#ifdef HAVE_MAGICK
MagickCoreTerminus();
#endif
}

void dt_print(dt_debug_thread_t thread, const char *msg, ...)
{
if(darktable.unmuted & thread)
{
va_list ap;
va_start(ap, msg);
vprintf(msg, ap);
va_end(ap);
}
}
53 changes: 53 additions & 0 deletions src/common/darktable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef DARKROOM_H
#define DARKROOM_H

#include <inttypes.h>
#include <sqlite3.h>
#include <pthread.h>

#define DT_VERSION 9

#define HANDLE_SQLITE_ERR(rc) \
if(rc != SQLITE_OK) \
{ \
fprintf(stderr, "sqlite3 error: %s\n", sqlite3_errmsg(darktable.db)); \
return 1; \
} \


struct dt_library_t;
struct dt_gui_gtk_t;
struct dt_control_t;
struct dt_develop_t;
struct dt_mipmap_cache_t;
struct dt_image_cache_t;

typedef enum dt_debug_thread_t
{
DT_DEBUG_CACHE = 1,
DT_DEBUG_CONTROL = 2,
DT_DEBUG_DEV = 4 // powers of two, masking
}
dt_debug_thread_t;

typedef struct darktable_t
{
int32_t unmuted;
struct dt_library_t *library;
struct dt_develop_t *develop;
struct dt_control_t *control;
struct dt_gui_gtk_t *gui;
struct dt_mipmap_cache_t *mipmap_cache;
struct dt_image_cache_t *image_cache;
sqlite3 *db;
pthread_mutex_t db_insert;
}
darktable_t;

extern darktable_t darktable;

int dt_init(int argc, char *argv[]);
void dt_cleanup();
void dt_print(dt_debug_thread_t thread, const char *msg, ...);

#endif
517 changes: 517 additions & 0 deletions src/common/image.c

Large diffs are not rendered by default.

112 changes: 112 additions & 0 deletions src/common/image.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#ifndef DT_IMAGE_H
#define DT_IMAGE_H

#include <inttypes.h>
#include <pthread.h>

typedef enum
{
DT_IMAGE_PORTRAIT = 1,
DT_IMAGE_GOOD = 2,
DT_IMAGE_BAD = 4,
DT_IMAGE_SELECTED = 8
}
dt_image_flags_t;

typedef enum
{
DT_IMAGE_MIP0 = 0,
DT_IMAGE_MIP1 = 1,
DT_IMAGE_MIP2 = 2,
DT_IMAGE_MIP3 = 3,
DT_IMAGE_MIP4 = 4,
DT_IMAGE_MIPF = 5,
DT_IMAGE_FULL = 6,
DT_IMAGE_NONE = 7
}
dt_image_buffer_t;

typedef struct dt_image_lock_t
{
unsigned write : 1;
unsigned users : 7;
}
dt_image_lock_t;

typedef struct dt_image_t
{
// common stuff
int32_t width, height;
char filename[512];
// used by library
int32_t num, flags, film_id, id;
// cache
int32_t cacheline; // for image_cache
#ifdef _DEBUG
int32_t mip_buf_size[DT_IMAGE_NONE];
#endif
uint8_t *mip[DT_IMAGE_MIPF]; // for mipmap_cache
float *mipf;
dt_image_lock_t lock[DT_IMAGE_NONE];
// raw image
int32_t shrink, wb_auto, wb_cam, orientation;
float exposure;
float *pixels;
// libexif data
// ExifContent *exif;
// minimal exif data here:
char exif_maker[20], exif_model[20], exif_datetime_taken[20];
float exif_exposure;
float exif_aperture;
float exif_iso;
float exif_focal_length;
}
dt_image_t;

// image buffer operations:
/** inits basic values to sensible defaults. */
void dt_image_init(dt_image_t *img);
/** opens an image with minimal storage from the data base and stores it in image cache. */
int dt_image_open(const int32_t id);
int dt_image_open2(dt_image_t *img, const int32_t id);
/** imports a new image from raw/etc file and adds it to the data base and image cache. */
int dt_image_import(const int32_t film_id, const char *filename);
/** cleanup. */
void dt_image_cleanup(dt_image_t *img);
/** loads the requested buffer to cache, with read lock set. */
int dt_image_load(dt_image_t *img, dt_image_buffer_t mip);
/** prefetches given image buffer (mip map level/float preview/full raw), without marking it as used. */
void dt_image_prefetch(dt_image_t *img, dt_image_buffer_t mip);
/** returns appropriate mip map size for given area to paint on (width, height). */
dt_image_buffer_t dt_image_get_matching_mip_size(const dt_image_t *img, const int32_t width, const int32_t height, int32_t *w, int32_t *h);
/** returns appropriate mip map size for given mip level. */
void dt_image_get_mip_size(const dt_image_t *img, dt_image_buffer_t mip, int32_t *w, int32_t *h);
/** returns real image extends within mip map buffer size, in floating point. */
void dt_image_get_exact_mip_size(const dt_image_t *img, dt_image_buffer_t mip, float *w, float *h);
/** writes mip4 through to all smaller levels. */
int dt_image_update_mipmaps(dt_image_t *img);

// memory management interface
typedef struct dt_mipmap_cache_t
{
pthread_mutex_t mutex;
int32_t num_entries[DT_IMAGE_NONE];
dt_image_t **mip_lru[DT_IMAGE_NONE];
}
dt_mipmap_cache_t;

void dt_mipmap_cache_init(dt_mipmap_cache_t *cache, int32_t entries);
void dt_mipmap_cache_cleanup(dt_mipmap_cache_t *cache);

/** if in debug mode, asserts image buffer size for mip is alloc'ed this large. */
void dt_image_check_buffer(dt_image_t *image, dt_image_buffer_t mip, int32_t size);
/** alloc new buffer for this mip map and image. also lock for writing. */
int dt_image_alloc(dt_image_t *img, dt_image_buffer_t mip);
/** destroy buffer. */
void dt_image_free(dt_image_t *img, dt_image_buffer_t mip);
/** gets the requested image buffer or a smaller preview if it is not available (w lock || =NULL), marking this with the read lock. returns found mip level. */
dt_image_buffer_t dt_image_get(dt_image_t *img, const dt_image_buffer_t mip, const char mode);
/** unflags the used flag of given mip map level. these remove r and w locks, respectively. dropping the w lock will leave the r lock in place. */
void dt_image_release(dt_image_t *img, dt_image_buffer_t mip, const char mode);

#endif
136 changes: 136 additions & 0 deletions src/common/image_cache.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@

#include "common/darktable.h"
#include "common/image_cache.h"

#include <stdlib.h>
#include <stdio.h>

void dt_image_cache_init(dt_image_cache_t *cache, int32_t entries)
{
pthread_mutex_init(&(cache->mutex), NULL);
cache->num_lines = entries;
cache->line = (dt_image_cache_line_t *)malloc(sizeof(dt_image_cache_line_t)*cache->num_lines);
cache->by_id = (int16_t *)malloc(sizeof(int16_t)*cache->num_lines);
for(int k=0;k<cache->num_lines;k++)
{
cache->by_id[k] = k;
dt_image_init(&(cache->line[k].image));
cache->line[k].lock.users = cache->line[k].lock.write = 0;
cache->line[k].image.cacheline = k;
cache->line[k].lru = k-1;
cache->line[k].mru = k+1;
}
cache->lru = 0;
cache->mru = cache->num_lines-1;
}

void dt_image_cache_cleanup(dt_image_cache_t *cache)
{
// free mipmap cache lines
for(int k=0;k<cache->num_lines;k++)
{
// TODO: update images set !!
dt_image_cleanup(&(cache->line[k].image));
}
free(cache->line);
free(cache->by_id);
pthread_mutex_destroy(&(cache->mutex));
}

int32_t dt_image_cache_bsearch(const int32_t id)
{
dt_image_cache_t *cache = darktable.image_cache;
unsigned int min = 0, max = cache->num_lines;
unsigned int t = max/2;
while (t != min)
{
if(cache->line[cache->by_id[t-1]].image.id < id) min = t;
else max = t;
t = (min + max)/2;
}
if(cache->line[cache->by_id[t]].image.id != id) return -1;
return cache->by_id[t];
}

int dt_image_cache_compare_id(const int16_t *l1, const int16_t *l2)
{
return darktable.image_cache->line[*l1].image.id - darktable.image_cache->line[*l2].image.id;
}

dt_image_t *dt_image_cache_get(int32_t id, const char mode)
{
dt_image_t *img = dt_image_cache_use(id, mode);
if(img == NULL) return NULL;
if(img->film_id == -1) if(dt_image_open2(img, id))
{
dt_image_cache_release(img, mode);
return NULL;
}
return img;
}

dt_image_t *dt_image_cache_use(int32_t id, const char mode)
{
dt_image_cache_t *cache = darktable.image_cache;
pthread_mutex_lock(&(cache->mutex));
// int16_t *res = bsearch(&id, cache->by_id, cache->num_lines, sizeof(int16_t), (int(*)(const void *, const void *))&dt_image_cache_compare_id);
int32_t res = dt_image_cache_bsearch(id);
dt_image_t *ret = NULL;
int16_t k = cache->lru;
if(res < 0)
{
// get least recently used image without lock and replace it:
for(int i=0;i<cache->num_lines;i++)
{
if(cache->line[k].image.id == -1) break;
if(cache->line[k].lock.write == 0 && cache->line[k].lock.users == 0) break;
k = cache->line[k].mru;
}
if(k == cache->num_lines)
{
fprintf(stderr, "[image_cache_use] all slots are in use!\n");
pthread_mutex_unlock(&(cache->mutex));
return NULL;
}
// TODO: update images set !!
dt_image_cleanup(&(cache->line[k].image));
dt_image_init(&(cache->line[k].image));
cache->line[k].image.id = id;
cache->line[k].image.cacheline = k;
cache->line[k].image.film_id = -1;
// TODO: insertion sort faster here?
qsort(cache->by_id, cache->num_lines, sizeof(int16_t), (int(*)(const void *, const void *))&dt_image_cache_compare_id);
res = k;
}
if(cache->line[res].lock.write)
{
ret = NULL;
}
else
{
// update lock
cache->line[res].lock.users++;
if(mode == 'w') cache->line[res].lock.write = 1;
ret = &(cache->line[res].image);
}
// update least recently used/most recently used linked list:
cache->line[cache->mru].mru = res;
if(cache->line[res].lru >= 0) cache->line[cache->line[res].lru].mru = cache->line[res].mru;
if(cache->line[res].mru < cache->num_lines) cache->line[cache->line[res].mru].lru = cache->line[res].lru;
if(cache->lru == res) cache->lru = cache->line[res].mru;
cache->line[res].mru = cache->num_lines+1;
cache->line[res].lru = cache->mru;
cache->mru = res;
pthread_mutex_unlock(&(cache->mutex));
return ret;
}

void dt_image_cache_release(dt_image_t *img, const char mode)
{
dt_image_cache_t *cache = darktable.image_cache;
pthread_mutex_lock(&(cache->mutex));
cache->line[img->cacheline].lock.users--;
if(mode == 'w') cache->line[img->cacheline].lock.write = 0;
pthread_mutex_unlock(&(cache->mutex));
}

48 changes: 48 additions & 0 deletions src/common/image_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef DT_IMAGE_CACHE_H
#define DT_IMAGE_CACHE_H

#include "common/image.h"

#include <inttypes.h>
#include <pthread.h>

/**
* image cache to hold temporary representations
* from sql queries.
* fast access by img->id via sorted index,
* which is updated each time a new image is alloc'ed or
* an old image is kicked.
* lru list maintained via linked list for fast updates.
*/

typedef struct dt_image_cache_line_t
{
dt_image_t image;
dt_image_lock_t lock;
int16_t mru, lru;
}
dt_image_cache_line_t;

typedef struct dt_image_cache_t
{
pthread_mutex_t mutex;
int32_t num_lines;
dt_image_cache_line_t *line;
int16_t *by_id;
int16_t lru, mru;
}
dt_image_cache_t;

void dt_image_cache_init(dt_image_cache_t *cache, int32_t entries);
void dt_image_cache_cleanup(dt_image_cache_t *cache);

/** returns alloc'ed image (newly or from cache) or NULL on failure.
* lru is freed instead. there is no explicit interface for free.
* result will have users lock incremented. */
dt_image_t *dt_image_cache_use(int32_t id, const char mode);
/** same as use, but init image from db if it was not already loaded. */
dt_image_t *dt_image_cache_get(int32_t id, const char mode);
/** decrements users lock. */
void dt_image_cache_release(dt_image_t *img, const char mode);

#endif
130 changes: 130 additions & 0 deletions src/common/image_compression.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#include "common/image_compression.h"

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void dt_image_uncompress(const uint8_t *in, float *out, const int32_t width, const int32_t height)
{
float L[16], chrom[4][3];
const float fac[3] = {4., 2., 4.};
uint32_t *L32 = (uint32_t*)L;
uint16_t L16[16];
int32_t n_zeroes, Lbias;
uint8_t r[4], b[4];
const uint8_t *block = in;
for(int j=0;j<height;j+=4)
{
for(int i=0;i<width;i+=4)
{
// luma
Lbias = (block[0] >> 3) << 10;
n_zeroes = block[0] & 0x7;
const int shift = 14-n_zeroes-4+1;

for(int k=0;k<8;k++)
{
L16[2*k ] = ((int)(block[1+k]>> 4) << shift) + Lbias;
L16[2*k+1] = ((int)(block[1+k]&0xf) << shift) + Lbias;
}
for(int k=0;k<16;k++)
{
L32[k] = (((int)(L16[k]) >> 10)-(15-127)) << (23);
L32[k] |= (L16[k] & 0x3ff)<<13;
}
// chroma
r[0] = block[ 9] >> 1;
b[0] = ((block[ 9] & 0x01) << 6) | (block[10] >> 2);
r[1] = ((block[10] & 0x03) << 5) | (block[11] >> 3);
b[1] = ((block[11] & 0x07) << 4) | (block[12] >> 4);
r[2] = ((block[12] & 0x0f) << 3) | (block[13] >> 5);
b[2] = ((block[13] & 0x1f) << 2) | (block[14] >> 6);
r[3] = ((block[14] & 0x3f) << 1) | (block[15] >> 7);
b[3] = block[15] & 0x7f;

for(int q=0;q<4;q++)
{
chrom[q][0] = r[q]*(1./127.);
chrom[q][2] = b[q]*(1./127.);
chrom[q][1] = 1. - chrom[q][0] - chrom[q][2];
}
for(int k=0;k<16;k++)
for(int c=0;c<3;c++)
out[3*(i + (k & 3) + width*(j + (k>>2))) + c] = L[k]*fac[c]*chrom[((k>>3)<<1)|((k&3)>>1)][c];
block += 16*sizeof(uint8_t);
}
}
}

void dt_image_compress(const float *in, uint8_t *out, const int32_t width, const int32_t height)
{
float L[16];
int16_t Lmin, Lmax, n_zeroes, L16[16];
int32_t L32;
uint8_t *block = out, r[4], b[4];
for(int j=0;j<height;j+=4)
{
for(int i=0;i<width;i+=4)
{
Lmin = 0x7fff;
for(int q=0;q<4;q++)
{
float chrom[3] = {0,0,0};
for(int pj=0;pj<2;pj++)
{
for(int pi=0;pi<2;pi++)
{
const int io = (pi+((q&1)<<1)), jo = (pj+(q&2));
const int ii = i + io, jj = j + jo;

L[io+4*jo] = (in[3*(ii+width*jj) + 0] + 2*in[3*(ii+width*jj) +1] + in[3*(ii+width*jj) +2])*.25;
for(int k=0;k<3;k++) chrom[k] += L[io+4*jo]*in[3*(ii+width*jj) + k];
L32 = *(uint32_t *)(L + io + 4*jo);
L16[io+4*jo] = (L32>>13)&0x3ff;
int e = ((L32 >> (23))-(127-15));
e = e > 0 ? e : 0;
e = e > 30 ? 30 : e;
L16[io+4*jo] |= e<<10;
Lmin = Lmin < L16[io+4*jo] ? Lmin : L16[io+4*jo];
}
}
const float norm = 1./(chrom[0] + 2*chrom[1] + chrom[2]);
r[q] = (int)(127.*(chrom[0]*norm));
b[q] = (int)(127.*(chrom[2]*norm));
}
// store luma
Lmin &= ~0x3ff;
block[0] = (Lmin>>10)<<3; // Lbias
Lmax = 0;
for(int k=0;k<16;k++)
{
L16[k] -= Lmin;
Lmax = Lmax > L16[k] ? Lmax : L16[k];
}
n_zeroes = 0;
for(int k=1<<14;(k&Lmax)==0&&n_zeroes<7;k>>=1) n_zeroes++;
block[0] |= n_zeroes;
const int shift = 14-n_zeroes-4+1;
const int off = (1<<shift)>>1;
for(int k=0;k<8;k++)
{
L16[2*k] = ((int)L16[2*k] + off)>>shift;
L16[2*k] = L16[2*k] > 0xf ? 0xf : L16[2*k];
L16[2*k+1] = ((int)L16[2*k+1] + off)>>shift;
L16[2*k+1] = L16[2*k+1] > 0xf ? 0xf : L16[2*k+1];
block[k+1] = L16[2*k+1] | (L16[2*k]<<4);
}
// store chroma
block[ 9] = (r[0] << 1) | (b[0] >> 6);
block[10] = (b[0] << 2) | (r[1] >> 5);
block[11] = (r[1] << 3) | (b[1] >> 4);
block[12] = (b[1] << 4) | (r[2] >> 3);
block[13] = (r[2] << 5) | (b[2] >> 2);
block[14] = (b[2] << 6) | (r[3] >> 1);
block[15] = (r[3] << 7) | (b[3] >> 0);
block += 16*sizeof(uint8_t);
}
}
}

8 changes: 8 additions & 0 deletions src/common/image_compression.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef DT_IMAGE_COMPRESSION
#include <inttypes.h>

/** K. Roimela, T. Aarnio and J. Itäranta. High Dynamic Range Texture Compression. Proceedings of SIGGRAPH 2006. */
void dt_image_compress(const float *in, uint8_t *out, const int32_t width, const int32_t height);
void dt_image_uncompress(const uint8_t *in, float *out, const int32_t width, const int32_t height);

#endif
Loading