Squashed 'rtengine/libraw/' content from commit cccb97647

git-subtree-dir: rtengine/libraw
git-subtree-split: cccb97647fcee56801fa68231fa8a38aa8b52ef7
This commit is contained in:
Lawrence Lee
2023-11-12 11:49:00 -08:00
commit 638ecc4cde
213 changed files with 77043 additions and 0 deletions

174
samples/4channels.cpp Normal file
View File

@@ -0,0 +1,174 @@
/* -*- C++ -*-
* File: 4channels.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Mon Feb 09, 2009
*
* LibRaw sample
* Generates 4 TIFF file from RAW data, one file per channel
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <netinet/in.h>
#else
#include <winsock2.h>
#endif
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif
int main(int ac, char *av[])
{
int i, ret;
int autoscale = 0, black_subtraction = 1, use_gamma = 0;
char outfn[1024];
LibRaw RawProcessor;
if (ac < 2)
{
usage:
printf("4channels - LibRaw %s sample. %d cameras supported\n"
"Usage: %s [-s N] [-g] [-A] [-B] [-N] raw-files....\n"
"\t-s N - select Nth image in file (default=0)\n"
"\t-g - use gamma correction with gamma 2.2 (not precise,use for "
"visual inspection only)\n"
"\t-A - autoscaling (by integer factor)\n"
"\t-B - no black subtraction\n",
LibRaw::version(), LibRaw::cameraCount(), av[0]);
return 0;
}
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
#define OUTR RawProcessor.imgdata.rawparams
OUT.output_bps = 16;
OUT.output_tiff = 1;
OUT.user_flip = 0;
OUT.no_auto_bright = 1;
OUT.half_size = 1;
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == 's' && av[i][2] == 0)
{
i++;
OUTR.shot_select = av[i] ? atoi(av[i]) : 0;
}
else if (av[i][1] == 'g' && av[i][2] == 0)
use_gamma = 1;
else if (av[i][1] == 'A' && av[i][2] == 0)
autoscale = 1;
else if (av[i][1] == 'B' && av[i][2] == 0)
{
black_subtraction = 0;
}
else
goto usage;
continue;
}
if (!use_gamma)
OUT.gamm[0] = OUT.gamm[1] = 1;
int c;
printf("Processing file %s\n", av[i]);
if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if (P1.is_foveon)
{
printf("Cannot process Foveon image %s\n", av[i]);
continue;
}
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
continue;
}
RawProcessor.raw2image();
if (black_subtraction)
{
RawProcessor.subtract_black();
}
if (autoscale)
{
unsigned max = 0, scale = 1;
for (int j = 0; j < S.iheight * S.iwidth; j++)
for (int c = 0; c < 4; c++)
if (max < RawProcessor.imgdata.image[j][c])
max = RawProcessor.imgdata.image[j][c];
if (max > 0 && max < 1 << 15)
{
scale = (1 << 16) / max;
printf("Scaling with multiplier=%d (max=%d)\n", scale, max);
for (int j = 0; j < S.iheight * S.iwidth; j++)
for (c = 0; c < 4; c++)
RawProcessor.imgdata.image[j][c] *= scale;
}
printf("Black level (scaled)=%d\n", C.black * scale);
}
else
printf("Black level (unscaled)=%d\n", C.black);
// hack to make dcraw tiff writer happy
int isrgb = (P1.colors == 4 ? 0 : 1);
P1.colors = 1;
S.width = S.iwidth;
S.height = S.iheight;
for (int layer = 0; layer < 4; layer++)
{
if (layer > 0)
{
for (int rc = 0; rc < S.iheight * S.iwidth; rc++)
RawProcessor.imgdata.image[rc][0] =
RawProcessor.imgdata.image[rc][layer];
}
char lname[8];
if (isrgb)
{
snprintf(lname, 7, "%c", ((char *)("RGBG"))[layer]);
if (layer == 3)
strcat(lname, "2");
}
else
snprintf(lname, 7, "%c", ((char *)("GCMY"))[layer]);
if (OUTR.shot_select)
snprintf(outfn, sizeof(outfn), "%s-%d.%s.tiff", av[i], OUTR.shot_select,
lname);
else
snprintf(outfn, sizeof(outfn), "%s.%s.tiff", av[i], lname);
printf("Writing file %s\n", outfn);
if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
}
}
return 0;
}

2
samples/Makefile Normal file
View File

@@ -0,0 +1,2 @@
all:
(cd ..; make all_samples)

670
samples/dcraw_emu.cpp Normal file
View File

@@ -0,0 +1,670 @@
/* -*- C++ -*-
* File: dcraw_emu.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sun Mar 23, 2008
*
* LibRaw simple C++ API sample: almost complete dcraw emulator
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#ifdef _MSC_VER
// suppress sprintf-related warning. sprintf() is permitted in sample code
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <sys/mman.h>
#include <sys/time.h>
#include <unistd.h>
#else
#include <io.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#include <windows.h>
#else
#define O_BINARY 0
#endif
#ifdef USE_DNGSDK
#include "dng_host.h"
#include "dng_negative.h"
#include "dng_simple_image.h"
#include "dng_info.h"
#endif
void usage(const char *prog)
{
printf("dcraw_emu: almost complete dcraw emulator\n");
printf("Usage: %s [OPTION]... [FILE]...\n", prog);
printf("-c float-num Set adjust maximum threshold (default 0.75)\n"
"-v Verbose: print progress messages (repeated -v will add "
"verbosity)\n"
"-w Use camera white balance, if possible\n"
"-a Average the whole image for white balance\n"
"-A <x y w h> Average a grey box for white balance\n"
"-r <r g b g> Set custom white balance\n"
"+M/-M Use/don't use an embedded color matrix\n"
"-C <r b> Correct chromatic aberration\n"
"-P <file> Fix the dead pixels listed in this file\n"
"-K <file> Subtract dark frame (16-bit raw PGM)\n"
"-k <num> Set the darkness level\n"
"-S <num> Set the saturation level\n"
"-R <num> Set raw processing options to num\n"
"-n <num> Set threshold for wavelet denoising\n"
"-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)\n"
"-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)\n"
"-o [0-8] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ,ACES,\n"
" DCI-P3,Rec2020)\n"
#ifndef NO_LCMS
"-o file Output ICC profile\n"
"-p file Camera input profile (use \'embed\' for embedded profile)\n"
#endif
"-j Don't stretch or rotate raw pixels\n"
"-W Don't automatically brighten the image\n"
"-b <num> Adjust brightness (default = 1.0)\n"
"-q N Set the interpolation quality:\n"
" 0 - linear, 1 - VNG, 2 - PPG, 3 - AHD, 4 - DCB\n"
" 11 - DHT, 12 - AAHD\n"
"-h Half-size color image (twice as fast as \"-q 0\")\n"
"-f Interpolate RGGB as four colors\n"
"-m <num> Apply a 3x3 median filter to R-G and B-G\n"
"-s [0..N-1] Select one raw image from input file\n"
"-4 Linear 16-bit, same as \"-6 -W -g 1 1\n"
"-6 Write 16-bit output\n"
"-g pow ts Set gamma curve to gamma pow and toe slope ts (default = "
"2.222 4.5)\n"
"-T Write TIFF instead of PPM\n"
"-G Use green_matching() filter\n"
"-B <x y w h> use cropbox\n"
"-F Use FILE I/O instead of streambuf API\n"
"-Z <suf> Output filename generation rules\n"
" .suf => append .suf to input name, keeping existing suffix "
"too\n"
" suf => replace input filename last extension\n"
" - => output to stdout\n"
" filename.suf => output to filename.suf\n"
"-timing Detailed timing report\n"
"-fbdd N 0 - disable FBDD noise reduction (default), 1 - light "
"FBDD, 2 - full\n"
"-dcbi N Number of extra DCD iterations (default - 0)\n"
"-dcbe DCB color enhance\n"
"-aexpo <e p> exposure correction\n"
"-apentax4shot enables merge of 4-shot pentax files\n"
"-apentax4shotorder 3102 sets pentax 4-shot alignment order\n"
#ifdef USE_RAWSPEED_BITS
"-arsbits V Set use_rawspeed to V\n"
#endif
"-mmap Use memory mmaped buffer instead of plain FILE I/O\n"
"-mem Use memory buffer instead of FILE I/O\n"
"-disars Do not use RawSpeed library\n"
"-disinterp Do not run interpolation step\n"
"-dsrawrgb1 Disable YCbCr to RGB conversion for sRAW (Cb/Cr "
"interpolation enabled)\n"
"-dsrawrgb2 Disable YCbCr to RGB conversion for sRAW (Cb/Cr "
"interpolation disabled)\n"
#ifdef USE_DNGSDK
"-dngsdk Use Adobe DNG SDK for DNG decode\n"
"-dngflags N set DNG decoding options to value N\n"
#endif
"-doutputflags N set params.output_flags to N\n"
);
exit(1);
}
static int verbosity = 0;
int cnt = 0;
int my_progress_callback(void *d, enum LibRaw_progress p, int iteration,
int expected)
{
char *passed = (char *)(d ? d : "default string"); // data passed to callback
// at set_callback stage
if (verbosity > 2) // verbosity set by repeat -v switches
{
printf("CB: %s pass %d of %d (data passed=%s)\n", libraw_strprogress(p),
iteration, expected, passed);
}
else if (iteration == 0) // 1st iteration of each step
printf("Starting %s (expecting %d iterations)\n", libraw_strprogress(p),
expected);
else if (iteration == expected - 1)
printf("%s finished\n", libraw_strprogress(p));
/// if(++cnt>10) return 1; // emulate user termination on 10-th callback
/// call
return 0; // always return 0 to continue processing
}
// timer
#ifndef LIBRAW_WIN32_CALLS
static struct timeval start, end;
void timerstart(void) { gettimeofday(&start, NULL); }
void timerprint(const char *msg, const char *filename)
{
gettimeofday(&end, NULL);
float msec = (end.tv_sec - start.tv_sec) * 1000.0f +
(end.tv_usec - start.tv_usec) / 1000.0f;
printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec);
}
#else
LARGE_INTEGER start;
void timerstart(void) { QueryPerformanceCounter(&start); }
void timerprint(const char *msg, const char *filename)
{
LARGE_INTEGER unit, end;
QueryPerformanceCounter(&end);
QueryPerformanceFrequency(&unit);
float msec = (float)(end.QuadPart - start.QuadPart);
msec /= (float)unit.QuadPart / 1000.0f;
printf("Timing: %s/%s: %6.3f msec\n", filename, msg, msec);
}
#endif
struct file_mapping
{
void *map;
INT64 fsize;
#ifdef LIBRAW_WIN32_CALLS
HANDLE fd, fd_map;
file_mapping() : map(0), fsize(0), fd(INVALID_HANDLE_VALUE), fd_map(INVALID_HANDLE_VALUE){}
#else
int fd;
file_mapping() : map(0), fsize(0), fd(-1){}
#endif
};
void create_mapping(struct file_mapping& data, const std::string& fn)
{
#ifdef LIBRAW_WIN32_CALLS
std::wstring fpath(fn.begin(), fn.end());
if ((data.fd = CreateFileW(fpath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) return;
LARGE_INTEGER fs;
if (!GetFileSizeEx(data.fd, &fs)) return;
data.fsize = fs.QuadPart;
if ((data.fd_map = ::CreateFileMapping(data.fd, 0, PAGE_READONLY, fs.HighPart, fs.LowPart, 0)) == INVALID_HANDLE_VALUE) return;
data.map = MapViewOfFile(data.fd_map, FILE_MAP_READ, 0, 0, data.fsize);
#else
struct stat stt;
if ((data.fd = open(fn.c_str(), O_RDONLY)) < 0) return;
if (fstat(data.fd, &stt) != 0) return;
data.fsize = stt.st_size;
data.map = mmap(0, data.fsize, PROT_READ | PROT_WRITE, MAP_PRIVATE, data.fd, 0);
return;
#endif
}
void close_mapping(struct file_mapping& data)
{
#ifdef LIBRAW_WIN32_CALLS
if (data.map) UnmapViewOfFile(data.map);
if (data.fd_map != INVALID_HANDLE_VALUE) CloseHandle(data.fd_map);
if (data.fd != INVALID_HANDLE_VALUE) CloseHandle(data.fd);
data.map = 0;
data.fsize = 0;
data.fd = data.fd_map = INVALID_HANDLE_VALUE;
#else
if (data.map)
munmap(data.map, data.fsize);
if (data.fd >= 0)
close(data.fd);
data.map = 0;
data.fsize = 0;
data.fd = -1;
#endif
}
int main(int argc, char *argv[])
{
if (argc == 1)
usage(argv[0]);
LibRaw RawProcessor;
int i, arg, c, ret;
char opm, opt, *cp, *sp;
int use_timing = 0, use_mem = 0, use_mmap = 0;
char *outext = NULL;
#ifdef USE_DNGSDK
dng_host *dnghost = NULL;
#endif
struct file_mapping mapping;
void *iobuffer = 0;
#ifdef OUT
#undef OUT
#endif
#define OUT RawProcessor.imgdata.params
#define OUTR RawProcessor.imgdata.rawparams
argv[argc] = (char *)"";
for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';)
{
char *optstr = argv[arg];
opt = argv[arg++][1];
if ((cp = strchr(sp = (char *)"cnbrkStqmHABCgU", opt)) != 0)
for (i = 0; i < "111411111144221"[cp - sp] - '0'; i++)
if (!isdigit(argv[arg + i][0]) && !optstr[2])
{
fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt);
return 1;
}
if (!strchr("ftdeam", opt) && argv[arg - 1][2]) {
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
continue;
}
switch (opt)
{
case 'v':
verbosity++;
break;
case 'G':
OUT.green_matching = 1;
break;
case 'c':
OUT.adjust_maximum_thr = (float)atof(argv[arg++]);
break;
case 'U':
OUT.auto_bright_thr = (float)atof(argv[arg++]);
break;
case 'n':
OUT.threshold = (float)atof(argv[arg++]);
break;
case 'b':
OUT.bright = (float)atof(argv[arg++]);
break;
case 'P':
OUT.bad_pixels = argv[arg++];
break;
case 'K':
OUT.dark_frame = argv[arg++];
break;
case 'r':
for (c = 0; c < 4; c++)
OUT.user_mul[c] = (float)atof(argv[arg++]);
break;
case 'C':
OUT.aber[0] = 1 / atof(argv[arg++]);
OUT.aber[2] = 1 / atof(argv[arg++]);
break;
case 'g':
OUT.gamm[0] = 1 / atof(argv[arg++]);
OUT.gamm[1] = atof(argv[arg++]);
break;
case 'k':
OUT.user_black = atoi(argv[arg++]);
break;
case 'S':
OUT.user_sat = atoi(argv[arg++]);
break;
case 'R':
OUTR.options = atoi(argv[arg++]);
break;
case 't':
if (!strcmp(optstr, "-timing"))
use_timing = 1;
else if (!argv[arg - 1][2])
OUT.user_flip = atoi(argv[arg++]);
else
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
break;
case 'q':
OUT.user_qual = atoi(argv[arg++]);
break;
case 'm':
if (!strcmp(optstr, "-mmap"))
use_mmap = 1;
else
if (!strcmp(optstr, "-mem"))
use_mem = 1;
else
{
if (!argv[arg - 1][2])
OUT.med_passes = atoi(argv[arg++]);
else
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
}
break;
case 'H':
OUT.highlight = atoi(argv[arg++]);
break;
case 's':
OUTR.shot_select = abs(atoi(argv[arg++]));
break;
case 'o':
if (isdigit(argv[arg][0]) && !isdigit(argv[arg][1]))
OUT.output_color = atoi(argv[arg++]);
#ifndef NO_LCMS
else
OUT.output_profile = argv[arg++];
break;
case 'p':
OUT.camera_profile = argv[arg++];
#endif
break;
case 'h':
OUT.half_size = 1;
break;
case 'f':
if (!strcmp(optstr, "-fbdd"))
OUT.fbdd_noiserd = atoi(argv[arg++]);
else
{
if (!argv[arg - 1][2])
OUT.four_color_rgb = 1;
else
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
}
break;
case 'A':
for (c = 0; c < 4; c++)
OUT.greybox[c] = atoi(argv[arg++]);
break;
case 'B':
for (c = 0; c < 4; c++)
OUT.cropbox[c] = atoi(argv[arg++]);
break;
case 'a':
if (!strcmp(optstr, "-aexpo"))
{
OUT.exp_correc = 1;
OUT.exp_shift = (float)atof(argv[arg++]);
OUT.exp_preser = (float)atof(argv[arg++]);
}
#ifdef USE_RAWSPEED_BITS
else if (!strcmp(optstr, "-arsbits"))
{
OUTR.use_rawspeed = atoi(argv[arg++]);
}
#endif
else if (!strcmp(optstr, "-apentax4shot"))
{
OUTR.options |= LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES;
}
else if (!strcmp(optstr, "-apentax4shotorder"))
{
strncpy(OUTR.p4shot_order, argv[arg++], 5);
}
else if (!argv[arg - 1][2])
OUT.use_auto_wb = 1;
else
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
break;
case 'w':
OUT.use_camera_wb = 1;
break;
case 'M':
OUT.use_camera_matrix = (opm == '+')?3:0;
break;
case 'j':
OUT.use_fuji_rotate = 0;
break;
case 'W':
OUT.no_auto_bright = 1;
break;
case 'T':
OUT.output_tiff = 1;
break;
case '4':
OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1; /* no break here! */
case '6':
OUT.output_bps = 16;
break;
case 'Z':
outext = strdup(argv[arg++]);
break;
case 'd':
if (!strcmp(optstr, "-dcbi"))
OUT.dcb_iterations = atoi(argv[arg++]);
else if (!strcmp(optstr, "-doutputflags"))
OUT.output_flags = atoi(argv[arg++]);
else if (!strcmp(optstr, "-disars"))
OUTR.use_rawspeed = 0;
else if (!strcmp(optstr, "-disinterp"))
OUT.no_interpolation = 1;
else if (!strcmp(optstr, "-dcbe"))
OUT.dcb_enhance_fl = 1;
else if (!strcmp(optstr, "-dsrawrgb1"))
{
OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_RGB;
OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE;
}
else if (!strcmp(optstr, "-dsrawrgb2"))
{
OUTR.specials &= ~LIBRAW_RAWSPECIAL_SRAW_NO_RGB;
OUTR.specials |= LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE;
}
#ifdef USE_DNGSDK
else if (!strcmp(optstr, "-dngsdk"))
{
dnghost = new dng_host;
RawProcessor.set_dng_host(dnghost);
}
else if (!strcmp(optstr, "-dngflags"))
{
OUTR.use_dngsdk = atoi(argv[arg++]);
}
#endif
else
fprintf(stderr, "Unknown option \"%s\".\n", argv[arg - 1]);
break;
default:
fprintf(stderr, "Unknown option \"-%c\".\n", opt);
break;
}
}
#ifndef LIBRAW_WIN32_CALLS
putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#else
_putenv(
(char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#endif
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
if (outext && !strcmp(outext, "-"))
use_timing = verbosity = 0;
if (verbosity > 1)
RawProcessor.set_progress_handler(my_progress_callback,
(void *)"Sample data passed");
#ifdef LIBRAW_USE_OPENMP
if (verbosity)
printf("Using %d threads\n", omp_get_max_threads());
#endif
int done = 0;
int total = argc - arg;
for (; arg < argc; arg++)
{
char outfn[1024];
if (verbosity)
printf("Processing file %s\n", argv[arg]);
timerstart();
if (use_mmap)
{
create_mapping(mapping, argv[arg]);
if (!mapping.map)
{
fprintf(stderr, "Cannot map %s\n", argv[arg]);
close_mapping(mapping);
continue;
}
if ((ret = RawProcessor.open_buffer(mapping.map,mapping.fsize) !=
LIBRAW_SUCCESS))
{
fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg], libraw_strerror(ret));
close_mapping(mapping);
continue; // no recycle b/c open file will recycle itself
}
}
else if (use_mem)
{
int file = open(argv[arg], O_RDONLY | O_BINARY);
struct stat st;
if (file < 0)
{
fprintf(stderr, "Cannot open %s: %s\n", argv[arg], strerror(errno));
continue;
}
if (fstat(file, &st))
{
fprintf(stderr, "Cannot stat %s: %s\n", argv[arg], strerror(errno));
close(file);
continue;
}
if (!(iobuffer = malloc(st.st_size)))
{
fprintf(stderr, "Cannot allocate %d kbytes for memory buffer\n",
(int)(st.st_size / 1024));
close(file);
continue;
}
int rd;
if (st.st_size != (rd = read(file, iobuffer, st.st_size)))
{
fprintf(stderr,
"Cannot read %d bytes instead of %d to memory buffer\n",
(int)rd, (int)st.st_size);
close(file);
free(iobuffer);
continue;
}
close(file);
if ((ret = RawProcessor.open_buffer(iobuffer, st.st_size)) !=
LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open_buffer %s: %s\n", argv[arg],
libraw_strerror(ret));
free(iobuffer);
continue; // no recycle b/c open file will recycle itself
}
}
else
{
ret = RawProcessor.open_file(argv[arg]);
if (ret != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open %s: %s\n", argv[arg],
libraw_strerror(ret));
continue; // no recycle b/c open_file will recycle itself
}
}
if (use_timing)
timerprint("LibRaw::open_file()", argv[arg]);
timerstart();
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg],
libraw_strerror(ret));
continue;
}
if (use_timing)
timerprint("LibRaw::unpack()", argv[arg]);
timerstart();
if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_process()))
{
fprintf(stderr, "Cannot do postprocessing on %s: %s\n", argv[arg],
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue;
}
if (use_timing)
timerprint("LibRaw::dcraw_process()", argv[arg]);
if (!outext)
snprintf(outfn, sizeof(outfn), "%s.%s", argv[arg],
OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm"));
else if (!strcmp(outext, "-"))
snprintf(outfn, sizeof(outfn), "-");
else
{
if (*outext == '.') // append
snprintf(outfn, sizeof(outfn), "%s%s", argv[arg], outext);
else if (strchr(outext, '.') && *outext != '.') // dot is not 1st char
strncpy(outfn, outext, sizeof(outfn));
else
{
strncpy(outfn, argv[arg], sizeof(outfn));
if (strlen(outfn) > 0)
{
char *lastchar = outfn + strlen(outfn); // points to term 0
while (--lastchar > outfn)
{
if (*lastchar == '/' || *lastchar == '\\')
break;
if (*lastchar == '.')
{
*lastchar = 0;
break;
};
}
}
strncat(outfn, ".", sizeof(outfn) - strlen(outfn) - 1);
strncat(outfn, outext, sizeof(outfn) - strlen(outfn) - 1);
}
}
if (verbosity)
{
printf("Writing file %s\n", outfn);
}
if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
else
done++;
RawProcessor.recycle(); // just for show this call
if (use_mmap && mapping.map)
close_mapping(mapping);
else if (use_mem && iobuffer)
{
free(iobuffer);
iobuffer = 0;
}
}
#ifdef USE_DNGSDK
if (dnghost)
delete dnghost;
#endif
if (total == 0)
return 1;
if (done < total)
return 2;
return 0;
}

78
samples/dcraw_half.c Normal file
View File

@@ -0,0 +1,78 @@
/* -*- C++ -*-
* File: dcraw_half.c
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sat Mar 8 , 2008
*
* LibRaw C API sample: emulates "dcraw -h"
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "libraw/libraw.h"
#define HANDLE_FATAL_ERROR(ret) \
if (ret) \
{ \
fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \
if (LIBRAW_FATAL_ERROR(ret)) \
exit(1); \
}
#define HANDLE_ALL_ERRORS(ret) \
if (ret) \
{ \
fprintf(stderr, "%s: libraw %s\n", av[i], libraw_strerror(ret)); \
continue; \
}
int main(int ac, char *av[])
{
int i;
libraw_data_t *iprc = libraw_init(0);
if (!iprc)
{
fprintf(stderr, "Cannot create libraw handle\n");
exit(1);
}
iprc->params.half_size = 1; /* dcraw -h */
for (i = 1; i < ac; i++)
{
char outfn[1024];
int ret = libraw_open_file(iprc, av[i]);
HANDLE_ALL_ERRORS(ret);
printf("Processing %s (%s %s)\n", av[i], iprc->idata.make,
iprc->idata.model);
ret = libraw_unpack(iprc);
HANDLE_ALL_ERRORS(ret);
ret = libraw_dcraw_process(iprc);
HANDLE_ALL_ERRORS(ret);
strcpy(outfn, av[i]);
strcat(outfn, ".ppm");
printf("Writing to %s\n", outfn);
ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn);
HANDLE_FATAL_ERROR(ret);
}
libraw_close(iprc);
return 0;
}

178
samples/half_mt.c Normal file
View File

@@ -0,0 +1,178 @@
/* -*- C++ -*-
* File: halt_mt.c
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sat Mar 8, 2008
*
* LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a]
[-v]"
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include "libraw/libraw.h"
#define HANDLE_ERRORS(ret) \
do \
{ \
if (ret) \
{ \
fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \
if (LIBRAW_FATAL_ERROR(ret)) \
{ \
libraw_close(iprc); \
return NULL; \
} \
} \
} while (0)
int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0;
pthread_mutex_t qm;
char **queue = NULL;
size_t qsize = 0, qptr = 0;
char *get_next_file()
{
char *ret;
if (!queue)
return NULL;
if (qptr >= qsize)
return NULL;
pthread_mutex_lock(&qm);
ret = queue[qptr++];
pthread_mutex_unlock(&qm);
return ret;
}
void *process_files(void *q)
{
int ret;
int count = 0;
char outfn[1024], *fn;
libraw_data_t *iprc = libraw_init(0);
if (!iprc)
{
fprintf(stderr, "Cannot create libraw handle\n");
return NULL;
}
while ((fn = get_next_file()))
{
iprc->params.half_size = 1; /* dcraw -h */
iprc->params.use_camera_wb = use_camera_wb;
iprc->params.use_auto_wb = use_auto_wb;
iprc->params.output_tiff = tiff_mode;
ret = libraw_open_file(iprc, fn);
if (verbose)
fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model);
HANDLE_ERRORS(ret);
ret = libraw_unpack(iprc);
HANDLE_ERRORS(ret);
ret = libraw_dcraw_process(iprc);
HANDLE_ERRORS(ret);
snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tiff" : "ppm");
if (verbose)
fprintf(stderr, "Writing file %s\n", outfn);
ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn);
HANDLE_ERRORS(ret);
count++;
}
libraw_close(iprc);
return NULL;
}
void usage(const char *p)
{
printf("%s: Multi-threaded LibRaw sample app. Emulates dcraw -h [-w] [-a]\n",
p);
printf("Options:\n"
"-J n - set parallel job count (default 2)\n"
"-v - verbose\n"
"-w - use camera white balance\n"
"-a - average image for white balance\n");
exit(1);
}
int show_files(void *q)
{
char *p;
int cnt = 0;
while ((p = get_next_file()))
{
printf("%s\n", p);
cnt++;
}
return cnt;
}
int main(int ac, char *av[])
{
int i, max_threads = 2;
pthread_t *threads;
if (ac < 2)
usage(av[0]);
queue = calloc(ac - 1, sizeof(queue[0]));
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == 'w')
use_camera_wb = 1;
if (av[i][1] == 'a')
use_auto_wb = 1;
if (av[i][1] == 'v')
verbose = 1;
if (av[i][1] == 'T')
tiff_mode = 1;
if (av[i][1] == 'J')
{
max_threads = atoi(av[++i]);
if (max_threads < 1)
{
fprintf(stderr, "Job count should be at least 1\n");
exit(1);
}
}
}
else
queue[qsize++] = av[i];
}
pthread_mutex_init(&qm, NULL);
threads = calloc(max_threads, sizeof(threads[0]));
for (i = 0; i < max_threads; i++)
pthread_create(&threads[i], NULL, process_files, NULL);
for (i = 0; i < max_threads; i++)
{
int *iptr;
if (threads[i])
{
pthread_join(threads[i], (void *)&iptr);
}
}
return 0;
}

212
samples/half_mt_win32.c Normal file
View File

@@ -0,0 +1,212 @@
/* -*- C++ -*-
* File: halt_mt_win32.c
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sat Mar 8, 2008
*
* LibRaw C API mutithreaded sample: emulates call to "dcraw -h [-w] [-a]
[-v]"
* Win32 version
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include "libraw/libraw.h"
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif
#define HANDLE_ERRORS(ret) \
do \
{ \
if (ret) \
{ \
fprintf(stderr, "%s: %s\n", fn, libraw_strerror(ret)); \
if (LIBRAW_FATAL_ERROR(ret)) \
{ \
libraw_close(iprc); \
return -1; \
} \
} \
} while (0)
// global settings
int verbose = 0, use_camera_wb = 0, use_auto_wb = 0, tiff_mode = 0;
// global file queue
HANDLE qmutex;
char **queue = NULL;
size_t qsize = 0, qptr = 0;
char *get_next_file()
{
char *ret;
DWORD dwWaitResult;
if (!queue)
return NULL;
if (qptr >= qsize)
return NULL;
dwWaitResult = WaitForSingleObject(qmutex, // handle to mutex
INFINITE); // no time-out interval
switch (dwWaitResult)
{
// The thread got ownership of the mutex
case WAIT_OBJECT_0:
ret = queue[qptr++];
ReleaseMutex(qmutex);
break;
case WAIT_ABANDONED:
return NULL; // cannot obtain the lock
};
return ret;
}
// thread routine
int process_files(void *q)
{
int ret;
int count = 0;
char outfn[1024], *fn;
libraw_data_t *iprc = libraw_init(0);
if (!iprc)
{
fprintf(stderr, "Cannot create libraw handle\n");
return -1;
}
while ((fn = get_next_file()))
{
iprc->params.half_size = 1; /* dcraw -h */
iprc->params.use_camera_wb = use_camera_wb;
iprc->params.use_auto_wb = use_auto_wb;
iprc->params.output_tiff = tiff_mode;
ret = libraw_open_file(iprc, fn);
if (verbose)
fprintf(stderr, "%s: %s/%s\n", fn, iprc->idata.make, iprc->idata.model);
HANDLE_ERRORS(ret);
ret = libraw_unpack(iprc);
HANDLE_ERRORS(ret);
ret = libraw_dcraw_process(iprc);
HANDLE_ERRORS(ret);
snprintf(outfn, 1023, "%s.%s", fn, tiff_mode ? "tif" : "ppm");
if (verbose)
fprintf(stderr, "Writing file %s\n", outfn);
ret = libraw_dcraw_ppm_tiff_writer(iprc, outfn);
HANDLE_ERRORS(ret);
count++;
}
libraw_close(iprc);
printf("Processed %d files\n", count);
return 0;
}
void usage(const char *p)
{
printf("Options:\n"
"-J n - set parallel job count (default 2)\n"
"-v - verbose\n"
"-w - use camera white balance\n"
"-T - output TIFF instead of PPM\n"
"-a - average image for white balance\n");
exit(1);
}
int show_files(void *q)
{
char *p;
int cnt = 0;
while (p = get_next_file())
{
printf("%s\n", p);
cnt++;
}
return cnt;
}
int main(int ac, char *av[])
{
int i, max_threads = 2;
HANDLE *threads;
DWORD ThreadID;
if (ac < 2)
usage(av[0]);
queue = calloc(ac - 1, sizeof(queue[0]));
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == 'w')
use_camera_wb = 1;
if (av[i][1] == 'a')
use_auto_wb = 1;
if (av[i][1] == 'v')
verbose = 1;
if (av[i][1] == 'T')
tiff_mode = 1;
if (av[i][1] == 'J')
{
max_threads = atoi(av[++i]);
if (max_threads < 1)
{
fprintf(stderr, "Job count should be at least 1\n");
exit(1);
}
}
}
else
queue[qsize++] = av[i];
}
qmutex = CreateMutex(NULL, FALSE, NULL);
threads = calloc(max_threads, sizeof(threads[0]));
for (i = 0; i < max_threads; i++)
{
if (NULL ==
(threads[i] = CreateThread(NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE)process_files,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID) // receive thread identifier
))
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
}
WaitForMultipleObjects(max_threads, threads, TRUE, INFINITE);
// Close thread and mutex handles
for (i = 0; i < max_threads; i++)
CloseHandle(threads[i]);
CloseHandle(qmutex);
return 0;
}

View File

@@ -0,0 +1,282 @@
/* -*- C++ -*-
* File: mem_image.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
*
* LibRaw mem_image/mem_thumb API test. Results should be same (bitwise) to
dcraw [-4] [-6] [-e]
* Testing note: for ppm-thumbnails you should use dcraw -w -e for thumbnail
extraction
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifdef USE_JPEG
#include "jpeglib.h"
#endif
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <netinet/in.h>
#endif
#ifdef USE_JPEG
void write_jpeg(libraw_processed_image_t *img, const char *basename, int quality)
{
char fn[1024];
if(img->colors != 1 && img->colors != 3)
{
printf("Only BW and 3-color images supported for JPEG output\n");
return;
}
snprintf(fn, 1024, "%s.jpg", basename);
FILE *f = fopen(fn, "wb");
if (!f)
return;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
int row_stride; /* physical row width in image buffer */
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, f);
cinfo.image_width = img->width; /* image width and height, in pixels */
cinfo.image_height = img->height;
cinfo.input_components = img->colors; /* # of color components per pixel */
cinfo.in_color_space = img->colors==3?JCS_RGB:JCS_GRAYSCALE; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
row_stride = img->width * img->colors; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &img->data[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(f);
jpeg_destroy_compress(&cinfo);
}
#endif
// no error reporting, only params check
void write_ppm(libraw_processed_image_t *img, const char *basename)
{
if (!img)
return;
// type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check
if (img->type != LIBRAW_IMAGE_BITMAP)
return;
if (img->colors != 3 && img->colors != 1)
{
printf("Only monochrome and 3-color images supported for PPM output\n");
return;
}
char fn[1024];
snprintf(fn, 1024, "%s.p%cm", basename, img->colors==1?'g':'p');
FILE *f = fopen(fn, "wb");
if (!f)
return;
fprintf(f, "P%d\n%d %d\n%d\n", img->colors/2 + 5, img->width, img->height, (1 << img->bits) - 1);
/*
NOTE:
data in img->data is not converted to network byte order.
So, we should swap values on some architectures for dcraw compatibility
(unfortunately, xv cannot display 16-bit PPMs with network byte order data
*/
#define SWAP(a, b) \
{ \
a ^= b; \
a ^= (b ^= a); \
}
if (img->bits == 16 && htons(0x55aa) != 0x55aa)
for (unsigned i = 0; i < img->data_size-1; i += 2)
SWAP(img->data[i], img->data[i + 1]);
#undef SWAP
fwrite(img->data, img->data_size, 1, f);
fclose(f);
}
void write_thumb(libraw_processed_image_t *img, const char *basename)
{
if (!img)
return;
if (img->type == LIBRAW_IMAGE_BITMAP)
{
char fnt[1024];
snprintf(fnt, 1024, "%s.thumb", basename);
write_ppm(img, fnt);
}
else if (img->type == LIBRAW_IMAGE_JPEG)
{
char fn[1024];
snprintf(fn, 1024, "%s.thumb.jpg", basename);
FILE *f = fopen(fn, "wb");
if (!f)
return;
fwrite(img->data, img->data_size, 1, f);
fclose(f);
}
}
int main(int ac, char *av[])
{
int i, ret, output_thumbs = 0;
#ifdef USE_JPEG
int output_jpeg = 0, jpgqual = 90;
#endif
// don't use fixed size buffers in real apps!
LibRaw RawProcessor;
if (ac < 2)
{
printf("mem_image - LibRaw sample, to illustrate work for memory buffers.\n"
"Emulates dcraw [-4] [-1] [-e] [-h]\n"
#ifdef USE_JPEG
"Usage: %s [-D] [-j[nn]] [-T] [-v] [-e] raw-files....\n"
#else
"Usage: %s [-D] [-T] [-v] [-e] raw-files....\n"
#endif
"\t-6 - output 16-bit PPM\n"
"\t-4 - linear 16-bit data\n"
"\t-e - extract thumbnails (same as dcraw -e in separate run)\n"
#ifdef USE_JPEG
"\t-j[qual] - output JPEG with qual quality (e.g. -j90)\n"
#endif
"\t-h - use half_size\n", av[0]);
return 0;
}
putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == '6' && av[i][2] == 0)
OUT.output_bps = 16;
if (av[i][1] == '4' && av[i][2] == 0)
{
OUT.output_bps = 16;
OUT.gamm[0] = OUT.gamm[1] = OUT.no_auto_bright = 1;
}
if (av[i][1] == 'e' && av[i][2] == 0)
output_thumbs++;
if (av[i][1] == 'h' && av[i][2] == 0)
OUT.half_size = 1;
#ifdef USE_JPEG
if (av[i][1] == 'j')
{
output_jpeg = 1;
if(av[i][2] != 0)
jpgqual = atoi(av[i]+2);
}
#endif
continue;
}
#ifdef USE_JPEG
if(output_jpeg && OUT.output_bps>8)
{
printf("JPEG is limited to 8 bit\n");
OUT.output_bps = 8;
}
#endif
printf("Processing %s\n", av[i]);
if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
continue;
}
// we should call dcraw_process before thumbnail extraction because for
// some cameras (i.e. Kodak ones) white balance for thumbnail should be set
// from main image settings
ret = RawProcessor.dcraw_process();
if (LIBRAW_SUCCESS != ret)
{
fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i],
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue;
}
libraw_processed_image_t *image = RawProcessor.dcraw_make_mem_image(&ret);
if (image)
{
#ifdef USE_JPEG
if(output_jpeg)
write_jpeg(image, av[i], jpgqual);
else
#endif
write_ppm(image, av[i]);
LibRaw::dcraw_clear_mem(image);
}
else
fprintf(stderr, "Cannot unpack %s to memory buffer: %s\n", av[i],
libraw_strerror(ret));
if (output_thumbs)
{
if ((ret = RawProcessor.unpack_thumb()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i],
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue; // skip to next file
}
else
{
libraw_processed_image_t *thumb =
RawProcessor.dcraw_make_mem_thumb(&ret);
if (thumb)
{
write_thumb(thumb, av[i]);
LibRaw::dcraw_clear_mem(thumb);
}
else
fprintf(stderr,
"Cannot unpack thumbnail of %s to memory buffer: %s\n", av[i],
libraw_strerror(ret));
}
}
RawProcessor.recycle(); // just for show this call
}
return 0;
}

View File

@@ -0,0 +1,107 @@
/* -*- C++ -*-
* File: multirender_test.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Jul 10, 2011
*
* LibRaw simple C++ API: creates 8 different renderings from 1 source file.
The 1st and 4th one should be identical
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#endif
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif
int process_once(LibRaw &RawProcessor, int half_mode, int camera_wb,
int auto_wb, int suffix, int user_flip, char *fname)
{
char outfn[1024];
RawProcessor.imgdata.params.half_size = half_mode;
RawProcessor.imgdata.params.use_camera_wb = camera_wb;
RawProcessor.imgdata.params.use_auto_wb = auto_wb;
RawProcessor.imgdata.params.user_flip = user_flip;
int ret = RawProcessor.dcraw_process();
if (LIBRAW_SUCCESS != ret)
{
fprintf(stderr, "Cannot do postprocessing on %s: %s\n", fname,
libraw_strerror(ret));
return ret;
}
snprintf(outfn, sizeof(outfn), "%s.%d.%s", fname, suffix,
(RawProcessor.imgdata.idata.colors > 1 ? "ppm" : "pgm"));
printf("Writing file %s\n", outfn);
if (LIBRAW_SUCCESS != (ret = RawProcessor.dcraw_ppm_tiff_writer(outfn)))
fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
return ret;
}
int main(int ac, char *av[])
{
int i, ret;
LibRaw RawProcessor;
if (ac < 2)
{
printf("multirender_test - LibRaw %s sample. Performs 4 different "
"renderings of one file\n"
" %d cameras supported\n"
"Usage: %s raw-files....\n",
LibRaw::version(), LibRaw::cameraCount(), av[0]);
return 0;
}
for (i = 1; i < ac; i++)
{
printf("Processing file %s\n", av[i]);
if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
continue;
}
process_once(RawProcessor, 0, 0, 0, 1, -1, av[i]); // default flip
process_once(RawProcessor, 1, 0, 1, 2, -1, av[i]);
process_once(RawProcessor, 1, 1, 0, 3, -1, av[i]); // default flip
process_once(RawProcessor, 1, 1, 0, 4, 1, av[i]); // flip 1
process_once(RawProcessor, 1, 1, 0, 5, 3, av[i]); // flip 3
process_once(RawProcessor, 1, 1, 0, 6, 1, av[i]); // 1 again same as 4
process_once(RawProcessor, 1, 1, 0, 7, -1,
av[i]); // default again, same as 3
process_once(RawProcessor, 0, 0, 0, 8, -1, av[i]); // same as 1
RawProcessor.recycle(); // just for show this call
}
return 0;
}

View File

@@ -0,0 +1,65 @@
/* -*- C++ -*-
* File: openvayer_sample.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Feb 11, 2020
*
* LibRaw simple C++ API: opens bayer data (Kodak KAI-0340 sensor) from buffer,
dump as 8-bit tiff
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#endif
int main(int ac, char *av[])
{
if (ac != 2)
return 1;
FILE *in = fopen(av[1], "rb");
fseek(in, 0, SEEK_END);
unsigned fsz = ftell(in);
unsigned char *buffer = (unsigned char *)malloc(fsz);
if (!buffer)
return 2;
fseek(in, 0, SEEK_SET);
unsigned readb = fread(buffer, 1, fsz, in);
if (readb != fsz)
return 3;
LibRaw rp;
rp.imgdata.params.output_tiff = 1;
int ret = rp.open_bayer(buffer, fsz, 640, 480, 0, 0, 0, 0, 0,
LIBRAW_OPENBAYER_RGGB, 0, 0, 1400);
if (ret != LIBRAW_SUCCESS)
return 4;
if ((ret = rp.unpack()) != LIBRAW_SUCCESS)
printf("Unpack error: %d\n", ret);
if ((ret = rp.dcraw_process()) != LIBRAW_SUCCESS)
printf("Processing error: %d\n", ret);
char outfn[256];
sprintf(outfn, "%s.tif", av[1]);
if (LIBRAW_SUCCESS != (ret = rp.dcraw_ppm_tiff_writer(outfn)))
printf("Cannot write %s: %s\n", outfn, libraw_strerror(ret));
else
printf("Created %s\n", outfn);
}

View File

@@ -0,0 +1,223 @@
/* -*- C++ -*-
* File: postprocessing_benchmark.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Jul 13, 2011
*
* LibRaw simple C++ API: creates 8 different renderings from 1 source file.
The 1st and 4th one should be identical
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#else
#include <winsock2.h>
#endif
#include "libraw/libraw.h"
void timerstart(void);
float timerend(void);
int main(int argc, char *argv[])
{
int i, ret, rep = 1;
LibRaw RawProcessor;
#ifdef OUT
#undef OUT
#endif
#define OUT RawProcessor.imgdata.params
#define OUTR RawProcessor.imgdata.rawparams
#define S RawProcessor.imgdata.sizes
if (argc < 2)
{
printf(
"postprocessing benchmark: LibRaw %s sample, %d cameras supported\n"
"Measures postprocessing speed with different options\n"
"Usage: %s [-a] [-H N] [-q N] [-h] [-m N] [-n N] [-s N] [-B x y w h] "
"[-R N]\n"
"-a average image for white balance\n"
"-H <num> Highlight mode (0=clip, 1=unclip, 2=blend, "
"3+=rebuild)\n"
"-q <num> Set the interpolation quality\n"
"-h Half-size color image\n"
"-m <num> Apply a num-passes 3x3 median filter to R-G and B-G\n"
"-n <num> Set threshold for wavelet denoising\n"
"-s <num> Select one raw image from input file\n"
"-B <x y w h> Crop output image\n"
"-R <num> Number of repetitions\n"
"-c Do not use rawspeed\n",
LibRaw::version(), LibRaw::cameraCount(), argv[0]);
return 0;
}
char opm, opt, *cp, *sp;
int arg, c;
int shrink = 0;
argv[argc] = (char *)"";
for (arg = 1; (((opm = argv[arg][0]) - 2) | 2) == '+';)
{
char *optstr = argv[arg];
opt = argv[arg++][1];
if ((cp = strchr(sp = (char *)"HqmnsBR", opt)) != 0)
for (i = 0; i < "1111141"[cp - sp] - '0'; i++)
if (!isdigit(argv[arg + i][0]) && !optstr[2])
{
fprintf(stderr, "Non-numeric argument to \"-%c\"\n", opt);
return 1;
}
switch (opt)
{
case 'a':
OUT.use_auto_wb = 1;
break;
case 'H':
OUT.highlight = atoi(argv[arg++]);
break;
case 'q':
OUT.user_qual = atoi(argv[arg++]);
break;
case 'h':
OUT.half_size = 1;
OUT.four_color_rgb = 1;
shrink = 1;
break;
case 'm':
OUT.med_passes = atoi(argv[arg++]);
break;
case 'n':
OUT.threshold = (float)atof(argv[arg++]);
break;
case 's':
OUTR.shot_select = abs(atoi(argv[arg++]));
break;
case 'B':
for (c = 0; c < 4; c++)
OUT.cropbox[c] = atoi(argv[arg++]);
break;
case 'R':
rep = abs(atoi(argv[arg++]));
if (rep < 1)
rep = 1;
break;
case 'c':
RawProcessor.imgdata.rawparams.use_rawspeed = 0;
break;
default:
fprintf(stderr, "Unknown option \"-%c\".\n", opt);
return 1;
}
}
for (; arg < argc; arg++)
{
printf("Processing file %s\n", argv[arg]);
timerstart();
if ((ret = RawProcessor.open_file(argv[arg])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open_file %s: %s\n", argv[arg],
libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", argv[arg],
libraw_strerror(ret));
continue;
}
float qsec = timerend();
printf("\n%.1f msec for unpack\n", qsec);
float mpix, rmpix;
timerstart();
for (c = 0; c < rep; c++)
{
if ((ret = RawProcessor.dcraw_process()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot postprocess %s: %s\n", argv[arg],
libraw_strerror(ret));
break;
}
libraw_processed_image_t *p = RawProcessor.dcraw_make_mem_image();
if (p)
RawProcessor.dcraw_clear_mem(p);
RawProcessor.free_image();
}
float msec = timerend() / (float)rep;
if ((ret = RawProcessor.adjust_sizes_info_only()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot adjust sizes for %s: %s\n", argv[arg],
libraw_strerror(ret));
break;
}
rmpix = (S.iwidth * S.iheight) / 1000000.0f;
if (c == rep) // no failure
{
unsigned int crop[4];
for (int i = 0; i < 4; i++)
crop[i] = (OUT.cropbox[i]) >> shrink;
if (crop[0] + crop[2] > S.iwidth)
crop[2] = S.iwidth - crop[0];
if (crop[1] + crop[3] > S.iheight)
crop[3] = S.iheight - crop[1];
mpix = float(crop[2] * crop[3]) / 1000000.0f;
float mpixsec = mpix * 1000.0f / msec;
printf("Performance: %.2f Mpix/sec\n"
"File: %s, Frame: %d %.1f total Mpix, %.1f msec\n"
"Params: WB=%s Highlight=%d Qual=%d HalfSize=%s Median=%d "
"Wavelet=%.0f\n"
"Crop: %u-%u:%ux%u, active Mpix: %.2f, %.1f frames/sec\n",
mpixsec, argv[arg], OUTR.shot_select, rmpix, msec,
OUT.use_auto_wb ? "auto" : "default", OUT.highlight, OUT.user_qual,
OUT.half_size ? "YES" : "No", OUT.med_passes, OUT.threshold,
crop[0], crop[1], crop[2], crop[3], mpix, 1000.0f / msec);
}
}
return 0;
}
#ifndef LIBRAW_WIN32_CALLS
static struct timeval start, end;
void timerstart(void) { gettimeofday(&start, NULL); }
float timerend(void)
{
gettimeofday(&end, NULL);
float msec = (end.tv_sec - start.tv_sec) * 1000.0f +
(end.tv_usec - start.tv_usec) / 1000.0f;
return msec;
}
#else
LARGE_INTEGER start;
void timerstart(void) { QueryPerformanceCounter(&start); }
float timerend()
{
LARGE_INTEGER unit, end;
QueryPerformanceCounter(&end);
QueryPerformanceFrequency(&unit);
float msec = (float)(end.QuadPart - start.QuadPart);
msec /= (float)unit.QuadPart / 1000.0f;
return msec;
}
#endif

739
samples/raw-identify.cpp Normal file
View File

@@ -0,0 +1,739 @@
/* -*- C++ -*-
* File: identify.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sat Mar 8, 2008
*
* LibRaw C++ demo: emulates dcraw -i [-v]
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <string>
#include <list>
#include "libraw/libraw.h"
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#ifndef LIBRAW_WIN32_CALLS
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#ifndef MAX_PATH
#define MAX_PATH PATH_MAX
#endif
#endif
#ifdef _MSC_VER
#if _MSC_VER < 1800 /* below MSVC 2013 */
float roundf(float f) { return floorf(f + 0.5); }
#endif
#endif
#define P1 MyCoolRawProcessor.imgdata.idata
#define P2 MyCoolRawProcessor.imgdata.other
#define P3 MyCoolRawProcessor.imgdata.makernotes.common
#define mnLens MyCoolRawProcessor.imgdata.lens.makernotes
#define exifLens MyCoolRawProcessor.imgdata.lens
#define ShootingInfo MyCoolRawProcessor.imgdata.shootinginfo
#define S MyCoolRawProcessor.imgdata.sizes
#define O MyCoolRawProcessor.imgdata.params
#define C MyCoolRawProcessor.imgdata.color
#define T MyCoolRawProcessor.imgdata.thumbnail
void print_verbose(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn);
void print_wbfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn);
void print_szfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn);
void print_unpackfun(FILE *, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn);
/*
table of fluorescents:
12 = FL-D; Daylight fluorescent (D 5700K 7100K) (F1,F5)
13 = FL-N; Day white fluorescent (N 4600K 5400K) (F7,F8)
14 = FL-W; Cool white fluorescent (W 3900K 4500K) (F2,F6, office,
store,warehouse) 15 = FL-WW; White fluorescent (WW 3200K 3700K) (F3,
residential) 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4,
kitchen, bath)
*/
static const struct
{
const int NumId;
const char *StrId;
const char *hrStrId; // human-readable
const int aux_setting;
} WBToStr[] = {
{LIBRAW_WBI_Unknown, "WBI_Unknown", "Unknown", 0},
{LIBRAW_WBI_Daylight, "WBI_Daylight", "Daylight", 0},
{LIBRAW_WBI_Fluorescent, "WBI_Fluorescent", "Fluorescent", 0},
{LIBRAW_WBI_Tungsten, "WBI_Tungsten", "Tungsten (Incandescent)", 0},
{LIBRAW_WBI_Flash, "WBI_Flash", "Flash", 0},
{LIBRAW_WBI_FineWeather, "WBI_FineWeather", "Fine Weather", 0},
{LIBRAW_WBI_Cloudy, "WBI_Cloudy", "Cloudy", 0},
{LIBRAW_WBI_Shade, "WBI_Shade", "Shade", 0},
{LIBRAW_WBI_FL_D, "WBI_FL_D", "Daylight Fluorescent", 0},
{LIBRAW_WBI_FL_N, "WBI_FL_N", "Day White Fluorescent", 0},
{LIBRAW_WBI_FL_W, "WBI_FL_W", "Cool White Fluorescent", 0},
{LIBRAW_WBI_FL_WW, "WBI_FL_WW", "White Fluorescent", 0},
{LIBRAW_WBI_FL_L, "WBI_FL_L", "Warm White Fluorescent", 0},
{LIBRAW_WBI_Ill_A, "WBI_Ill_A", "Illuminant A", 0},
{LIBRAW_WBI_Ill_B, "WBI_Ill_B", "Illuminant B", 0},
{LIBRAW_WBI_Ill_C, "WBI_Ill_C", "Illuminant C", 0},
{LIBRAW_WBI_D55, "WBI_D55", "D55", 0},
{LIBRAW_WBI_D65, "WBI_D65", "D65", 0},
{LIBRAW_WBI_D75, "WBI_D75", "D75", 0},
{LIBRAW_WBI_D50, "WBI_D50", "D50", 0},
{LIBRAW_WBI_StudioTungsten, "WBI_StudioTungsten", "ISO Studio Tungsten", 0},
{LIBRAW_WBI_BW, "WBI_BW", "BW", 0},
{LIBRAW_WBI_Other, "WBI_Other", "Other", 0},
{LIBRAW_WBI_Sunset, "WBI_Sunset", "Sunset", 1},
{LIBRAW_WBI_Underwater, "WBI_Underwater", "Underwater", 1},
{LIBRAW_WBI_FluorescentHigh, "WBI_FluorescentHigh", "Fluorescent High", 1},
{LIBRAW_WBI_HT_Mercury, "WBI_HT_Mercury", "HT Mercury", 1},
{LIBRAW_WBI_AsShot, "WBI_AsShot", "As Shot", 1},
{LIBRAW_WBI_Measured, "WBI_Measured", "Camera Measured", 1},
{LIBRAW_WBI_Auto, "WBI_Auto", "Camera Auto", 1},
{LIBRAW_WBI_Auto1, "WBI_Auto1", "Camera Auto 1", 1},
{LIBRAW_WBI_Auto2, "WBI_Auto2", "Camera Auto 2", 1},
{LIBRAW_WBI_Auto3, "WBI_Auto3", "Camera Auto 3", 1},
{LIBRAW_WBI_Auto4, "WBI_Auto4", "Camera Auto 4", 1},
{LIBRAW_WBI_Custom, "WBI_Custom", "Custom", 1},
{LIBRAW_WBI_Custom1, "WBI_Custom1", "Custom 1", 1},
{LIBRAW_WBI_Custom2, "WBI_Custom2", "Custom 2", 1},
{LIBRAW_WBI_Custom3, "WBI_Custom3", "Custom 3", 1},
{LIBRAW_WBI_Custom4, "WBI_Custom4", "Custom 4", 1},
{LIBRAW_WBI_Custom5, "WBI_Custom5", "Custom 5", 1},
{LIBRAW_WBI_Custom6, "WBI_Custom6", "Custom 6", 1},
{LIBRAW_WBI_PC_Set1, "WBI_PC_Set1", "PC Set 1", 1},
{LIBRAW_WBI_PC_Set2, "WBI_PC_Set2", "PC Set 2", 1},
{LIBRAW_WBI_PC_Set3, "WBI_PC_Set3", "PC Set 3", 1},
{LIBRAW_WBI_PC_Set4, "WBI_PC_Set4", "PC Set 4", 1},
{LIBRAW_WBI_PC_Set5, "WBI_PC_Set5", "PC Set 5", 1},
{LIBRAW_WBI_Kelvin, "WBI_Kelvin", "Kelvin", 1},
};
const char *WB_idx2str(unsigned WBi)
{
for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++)
if (WBToStr[i].NumId == (int)WBi)
return WBToStr[i].StrId;
return 0;
}
const char *WB_idx2hrstr(unsigned WBi)
{
for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++)
if (WBToStr[i].NumId == (int)WBi)
return WBToStr[i].hrStrId;
return 0;
}
double _log2(double a)
{
if(a > 0.00000000001) return log(a)/log(2.0);
return -1000;
}
void trimSpaces(char *s)
{
char *p = s;
if (!strncasecmp(p, "NO=", 3))
p = p + 3; /* fix for Nikon D70, D70s */
int l = strlen(p);
if (!l)
return;
while (isspace(p[l - 1]))
p[--l] = 0; /* trim trailing spaces */
while (*p && isspace(*p))
++p, --l; /* trim leading spaces */
memmove(s, p, l + 1);
}
void print_usage(const char *pname)
{
printf("Usage: %s [options] inputfiles\n", pname);
printf("Options:\n"
"\t-v\tverbose output\n"
"\t-w\tprint white balance\n"
"\t-u\tprint unpack function\n"
"\t-f\tprint frame size (only w/ -u)\n"
"\t-s\tprint output image size\n"
"\t-h\tforce half-size mode (only for -s)\n"
"\t-M\tdisable use of raw-embedded color data\n"
"\t+M\tforce use of raw-embedded color data\n"
"\t-L filename\tread input files list from filename\n"
"\t-o filename\toutput to filename\n");
}
int main(int ac, char *av[])
{
int ret;
int verbose = 0, print_sz = 0, print_unpack = 0, print_frame = 0, print_wb = 0;
LibRaw MyCoolRawProcessor;
char *filelistfile = NULL;
char *outputfilename = NULL;
FILE *outfile = stdout;
std::vector<std::string> filelist;
filelist.reserve(ac - 1);
for (int i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (!strcmp(av[i], "-v"))
verbose++;
if (!strcmp(av[i], "-w"))
print_wb++;
if (!strcmp(av[i], "-u"))
print_unpack++;
if (!strcmp(av[i], "-s"))
print_sz++;
if (!strcmp(av[i], "-h"))
O.half_size = 1;
if (!strcmp(av[i], "-f"))
print_frame++;
if (!strcmp(av[i], "-M"))
MyCoolRawProcessor.imgdata.params.use_camera_matrix = 0;
if (!strcmp(av[i], "-L") && i < ac - 1)
{
filelistfile = av[i + 1];
i++;
}
if (!strcmp(av[i], "-o") && i < ac - 1)
{
outputfilename = av[i + 1];
i++;
}
continue;
}
else if (!strcmp(av[i], "+M"))
{
MyCoolRawProcessor.imgdata.params.use_camera_matrix = 3;
continue;
}
filelist.push_back(av[i]);
}
if (filelistfile)
{
char *p;
char path[MAX_PATH + 1];
FILE *f = fopen(filelistfile, "r");
if (f)
{
while (fgets(path, MAX_PATH, f))
{
if ((p = strchr(path, '\n')))
*p = 0;
if ((p = strchr(path, '\r')))
*p = 0;
filelist.push_back(path);
}
fclose(f);
}
}
if (filelist.size() < 1)
{
print_usage(av[0]);
return 1;
}
if (outputfilename)
outfile = fopen(outputfilename, "wt");
for (int i = 0; i < (int)filelist.size(); i++)
{
if ((ret = MyCoolRawProcessor.open_file(filelist[i].c_str())) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot decode %s: %s\n", filelist[i].c_str(), libraw_strerror(ret));
continue; // no recycle, open_file will recycle
}
if (print_sz)
print_szfun(outfile, MyCoolRawProcessor, filelist[i]);
else if (verbose)
print_verbose(outfile, MyCoolRawProcessor, filelist[i]);
else if (print_unpack)
print_unpackfun(outfile, MyCoolRawProcessor, print_frame, filelist[i]);
else if (print_wb)
print_wbfun(outfile, MyCoolRawProcessor, filelist[i]);
else
fprintf(outfile, "%s is a %s %s image.\n", filelist[i].c_str(), P1.make, P1.model);
MyCoolRawProcessor.recycle();
} // endfor
return 0;
}
#define PRINTMATRIX3x4(of, mat, clrs) \
do \
{ \
for (int r = 0; r < 3; r++) \
if (clrs == 4) \
fprintf(of, "%6.4f\t%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2], mat[r][3]); \
else \
fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \
} while (0)
#define PRINTMATRIX4x3(of, mat, clrs) \
do \
{ \
for (int r = 0; r < clrs && r < 4; r++) \
fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \
} while (0)
void print_verbose(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn)
{
int WBi;
float denom;
int ret;
if ((ret = MyCoolRawProcessor.adjust_sizes_info_only()))
{
fprintf(outfile, "Cannot decode %s: %s\n", fn.c_str(), libraw_strerror(ret));
return; // no recycle, open_file will recycle
}
fprintf(outfile, "\nFilename: %s\n", fn.c_str());
if (C.OriginalRawFileName[0])
fprintf(outfile, "OriginalRawFileName: =%s=\n", C.OriginalRawFileName);
fprintf(outfile, "Timestamp: %s", ctime(&(P2.timestamp)));
fprintf(outfile, "Camera: %s %s ID: 0x%llx\n", P1.make, P1.model, mnLens.CamID);
fprintf(outfile, "Normalized Make/Model: =%s/%s= ", P1.normalized_make, P1.normalized_model);
fprintf(outfile, "CamMaker ID: %d\n", P1.maker_index);
{
int i = 0;
char sep[] = ", ";
if (C.UniqueCameraModel[0])
{
i++;
fprintf(outfile, "UniqueCameraModel: =%s=", C.UniqueCameraModel);
}
if (C.LocalizedCameraModel[0])
{
if (i)
{
fprintf(outfile, "%s", sep);
i++;
}
fprintf(outfile, "LocalizedCameraModel: =%s=", C.LocalizedCameraModel);
}
if (i)
{
fprintf(outfile, "\n");
i = 0;
}
if (C.ImageUniqueID[0])
{
if (i)
fprintf(outfile, "%s", sep);
i++;
fprintf(outfile, "ImageUniqueID: =%s=", C.ImageUniqueID);
}
if (C.RawDataUniqueID[0])
{
if (i)
fprintf(outfile, "%s", sep);
i++;
fprintf(outfile, "RawDataUniqueID: =%s=", C.RawDataUniqueID);
}
if (i)
fprintf(outfile, "\n");
}
if (ShootingInfo.BodySerial[0] && strcmp(ShootingInfo.BodySerial, "0"))
{
trimSpaces(ShootingInfo.BodySerial);
fprintf(outfile, "Body#: %s", ShootingInfo.BodySerial);
}
else if (C.model2[0] && (!strncasecmp(P1.normalized_make, "Kodak", 5)))
{
trimSpaces(C.model2);
fprintf(outfile, "Body#: %s", C.model2);
}
if (ShootingInfo.InternalBodySerial[0])
{
trimSpaces(ShootingInfo.InternalBodySerial);
fprintf(outfile, " BodyAssy#: %s", ShootingInfo.InternalBodySerial);
}
if (exifLens.LensSerial[0])
{
trimSpaces(exifLens.LensSerial);
fprintf(outfile, " Lens#: %s", exifLens.LensSerial);
}
if (exifLens.InternalLensSerial[0])
{
trimSpaces(exifLens.InternalLensSerial);
fprintf(outfile, " LensAssy#: %s", exifLens.InternalLensSerial);
}
if (P2.artist[0])
fprintf(outfile, " Owner: %s\n", P2.artist);
if (P1.dng_version)
{
fprintf(outfile, " DNG Version: ");
for (int i = 24; i >= 0; i -= 8)
fprintf(outfile, "%d%c", P1.dng_version >> i & 255, i ? '.' : '\n');
}
fprintf(outfile, "\nEXIF:\n");
fprintf(outfile, "\tMinFocal: %0.1f mm\n", exifLens.MinFocal);
fprintf(outfile, "\tMaxFocal: %0.1f mm\n", exifLens.MaxFocal);
fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", exifLens.MaxAp4MinFocal);
fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", exifLens.MaxAp4MaxFocal);
fprintf(outfile, "\tCurFocal: %0.1f mm\n", P2.focal_len);
fprintf(outfile, "\tMaxAperture @CurFocal: f/%0.1f\n", exifLens.EXIF_MaxAp);
fprintf(outfile, "\tFocalLengthIn35mmFormat: %d mm\n", exifLens.FocalLengthIn35mmFormat);
fprintf(outfile, "\tLensMake: %s\n", exifLens.LensMake);
fprintf(outfile, "\tLens: %s\n", exifLens.Lens);
fprintf(outfile, "\n");
fprintf(outfile, "\nMakernotes:\n");
fprintf(outfile, "\tDriveMode: %d\n", ShootingInfo.DriveMode);
fprintf(outfile, "\tFocusMode: %d\n", ShootingInfo.FocusMode);
fprintf(outfile, "\tMeteringMode: %d\n", ShootingInfo.MeteringMode);
fprintf(outfile, "\tAFPoint: %d\n", ShootingInfo.AFPoint);
fprintf(outfile, "\tExposureMode: %d\n", ShootingInfo.ExposureMode);
fprintf(outfile, "\tExposureProgram: %d\n", ShootingInfo.ExposureProgram);
fprintf(outfile, "\tImageStabilization: %d\n", ShootingInfo.ImageStabilization);
fprintf(outfile, "\tLens: %s\n", mnLens.Lens);
fprintf(outfile, "\tLensFormat: %d, ", mnLens.LensFormat);
fprintf(outfile, "\tLensMount: %d, ", mnLens.LensMount);
fprintf(outfile, "\tFocalType: %d, ", mnLens.FocalType);
switch (mnLens.FocalType)
{
case LIBRAW_FT_UNDEFINED:
fprintf(outfile, "Undefined\n");
break;
case LIBRAW_FT_PRIME_LENS:
fprintf(outfile, "Prime lens\n");
break;
case LIBRAW_FT_ZOOM_LENS:
fprintf(outfile, "Zoom lens\n");
break;
default:
fprintf(outfile, "Unknown\n");
break;
}
fprintf(outfile, "\tLensFeatures_pre: %s\n", mnLens.LensFeatures_pre);
fprintf(outfile, "\tLensFeatures_suf: %s\n", mnLens.LensFeatures_suf);
fprintf(outfile, "\tMinFocal: %0.1f mm\n", mnLens.MinFocal);
fprintf(outfile, "\tMaxFocal: %0.1f mm\n", mnLens.MaxFocal);
fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", mnLens.MaxAp4MinFocal);
fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", mnLens.MaxAp4MaxFocal);
fprintf(outfile, "\tMinAp @MinFocal: f/%0.1f\n", mnLens.MinAp4MinFocal);
fprintf(outfile, "\tMinAp @MaxFocal: f/%0.1f\n", mnLens.MinAp4MaxFocal);
fprintf(outfile, "\tMaxAp: f/%0.1f\n", mnLens.MaxAp);
fprintf(outfile, "\tMinAp: f/%0.1f\n", mnLens.MinAp);
fprintf(outfile, "\tCurFocal: %0.1f mm\n", mnLens.CurFocal);
fprintf(outfile, "\tCurAp: f/%0.1f\n", mnLens.CurAp);
fprintf(outfile, "\tMaxAp @CurFocal: f/%0.1f\n", mnLens.MaxAp4CurFocal);
fprintf(outfile, "\tMinAp @CurFocal: f/%0.1f\n", mnLens.MinAp4CurFocal);
if (exifLens.makernotes.FocalLengthIn35mmFormat > 1.0f)
fprintf(outfile, "\tFocalLengthIn35mmFormat: %0.1f mm\n", exifLens.makernotes.FocalLengthIn35mmFormat);
if (exifLens.nikon.EffectiveMaxAp > 0.1f)
fprintf(outfile, "\tEffectiveMaxAp: f/%0.1f\n", exifLens.nikon.EffectiveMaxAp);
if (exifLens.makernotes.LensFStops > 0.1f)
fprintf(outfile, "\tLensFStops @CurFocal: %0.2f\n", exifLens.makernotes.LensFStops);
fprintf(outfile, "\tTeleconverterID: %lld\n", mnLens.TeleconverterID);
fprintf(outfile, "\tTeleconverter: %s\n", mnLens.Teleconverter);
fprintf(outfile, "\tAdapterID: %lld\n", mnLens.AdapterID);
fprintf(outfile, "\tAdapter: %s\n", mnLens.Adapter);
fprintf(outfile, "\tAttachmentID: %lld\n", mnLens.AttachmentID);
fprintf(outfile, "\tAttachment: %s\n", mnLens.Attachment);
fprintf(outfile, "\n");
fprintf(outfile, "ISO speed: %d\n", (int)P2.iso_speed);
if (P3.real_ISO > 0.1f)
fprintf(outfile, "real ISO speed: %d\n", (int)P3.real_ISO);
fprintf(outfile, "Shutter: ");
if (P2.shutter > 0 && P2.shutter < 1)
P2.shutter = fprintf(outfile, "1/%0.1f\n", 1.0f / P2.shutter);
else if (P2.shutter >= 1)
fprintf(outfile, "%0.1f sec\n", P2.shutter);
else /* negative*/
fprintf(outfile, " negative value\n");
fprintf(outfile, "Aperture: f/%0.1f\n", P2.aperture);
fprintf(outfile, "Focal length: %0.1f mm\n", P2.focal_len);
if (P3.exifAmbientTemperature > -273.15f)
fprintf(outfile, "Ambient temperature (exif data): %6.2f° C\n", P3.exifAmbientTemperature);
if (P3.CameraTemperature > -273.15f)
fprintf(outfile, "Camera temperature: %6.2f° C\n", P3.CameraTemperature);
if (P3.SensorTemperature > -273.15f)
fprintf(outfile, "Sensor temperature: %6.2f° C\n", P3.SensorTemperature);
if (P3.SensorTemperature2 > -273.15f)
fprintf(outfile, "Sensor temperature2: %6.2f° C\n", P3.SensorTemperature2);
if (P3.LensTemperature > -273.15f)
fprintf(outfile, "Lens temperature: %6.2f° C\n", P3.LensTemperature);
if (P3.AmbientTemperature > -273.15f)
fprintf(outfile, "Ambient temperature: %6.2f° C\n", P3.AmbientTemperature);
if (P3.BatteryTemperature > -273.15f)
fprintf(outfile, "Battery temperature: %6.2f° C\n", P3.BatteryTemperature);
if (P3.FlashGN > 1.0f)
fprintf(outfile, "Flash Guide Number: %6.2f\n", P3.FlashGN);
fprintf(outfile, "Flash exposure compensation: %0.2f EV\n", P3.FlashEC);
if (C.profile)
fprintf(outfile, "Embedded ICC profile: yes, %d bytes\n", C.profile_length);
else
fprintf(outfile, "Embedded ICC profile: no\n");
if (C.dng_levels.baseline_exposure > -999.f)
fprintf(outfile, "Baseline exposure: %04.3f\n", C.dng_levels.baseline_exposure);
fprintf(outfile, "Number of raw images: %d\n", P1.raw_count);
if (S.pixel_aspect != 1)
fprintf(outfile, "Pixel Aspect Ratio: %0.6f\n", S.pixel_aspect);
if (T.tlength)
fprintf(outfile, "Thumb size: %4d x %d\n", T.twidth, T.theight);
fprintf(outfile, "Full size: %4d x %d\n", S.raw_width, S.raw_height);
if (S.raw_inset_crops[0].cwidth)
{
fprintf(outfile, "Raw inset, width x height: %4d x %d ", S.raw_inset_crops[0].cwidth, S.raw_inset_crops[0].cheight);
if (S.raw_inset_crops[0].cleft != 0xffff)
fprintf(outfile, "left: %d ", S.raw_inset_crops[0].cleft);
if (S.raw_inset_crops[0].ctop != 0xffff)
fprintf(outfile, "top: %d", S.raw_inset_crops[0].ctop);
fprintf(outfile, "\n");
}
fprintf(outfile, "Image size: %4d x %d\n", S.width, S.height);
fprintf(outfile, "Output size: %4d x %d\n", S.iwidth, S.iheight);
fprintf(outfile, "Image flip: %d\n", S.flip);
fprintf(outfile, "Raw colors: %d", P1.colors);
if (P1.filters)
{
fprintf(outfile, "\nFilter pattern: ");
if (!P1.cdesc[3])
P1.cdesc[3] = 'G';
for (int i = 0; i < 16; i++)
putchar(P1.cdesc[MyCoolRawProcessor.fcol(i >> 1, i & 1)]);
}
if (C.black)
{
fprintf(outfile, "\nblack: %d", C.black);
}
if (C.cblack[0] != 0)
{
fprintf(outfile, "\ncblack[0 .. 3]:");
for (int c = 0; c < 4; c++)
fprintf(outfile, " %d", C.cblack[c]);
}
if ((C.cblack[4] * C.cblack[5]) > 0)
{
fprintf(outfile, "\nBlackLevelRepeatDim: %d x %d\n", C.cblack[4], C.cblack[5]);
int n = C.cblack[4] * C.cblack[5];
fprintf(outfile, "cblack[6 .. %d]:", 6 + n - 1);
for (int c = 6; c < 6 + n; c++)
fprintf(outfile, " %d", C.cblack[c]);
}
if (C.linear_max[0] != 0)
{
fprintf(outfile, "\nHighlight linearity limits:");
for (int c = 0; c < 4; c++)
fprintf(outfile, " %ld", C.linear_max[c]);
}
if (P1.colors > 1)
{
fprintf(outfile, "\nMakernotes WB data: coeffs EVs");
if ((C.cam_mul[0] > 0) && (C.cam_mul[1] > 0))
{
fprintf(outfile, "\n %-23s %g %g %g %g %5.2f %5.2f %5.2f %5.2f", "As shot", C.cam_mul[0], C.cam_mul[1],
C.cam_mul[2], C.cam_mul[3], roundf(_log2(C.cam_mul[0] / C.cam_mul[1]) * 100.0f) / 100.0f, 0.0f,
roundf(_log2(C.cam_mul[2] / C.cam_mul[1]) * 100.0f) / 100.0f,
C.cam_mul[3] ? roundf(_log2(C.cam_mul[3] / C.cam_mul[1]) * 100.0f) / 100.0f : 0.0f);
}
for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++)
{
WBi = WBToStr[cnt].NumId;
if ((C.WB_Coeffs[WBi][0] > 0) && (C.WB_Coeffs[WBi][1] > 0))
{
denom = (float)C.WB_Coeffs[WBi][1];
fprintf(outfile, "\n %-23s %4d %4d %4d %4d %5.2f %5.2f %5.2f %5.2f", WBToStr[cnt].hrStrId,
C.WB_Coeffs[WBi][0], C.WB_Coeffs[WBi][1], C.WB_Coeffs[WBi][2], C.WB_Coeffs[WBi][3],
roundf(_log2((float)C.WB_Coeffs[WBi][0] / denom) * 100.0f) / 100.0f, 0.0f,
roundf(_log2((float)C.WB_Coeffs[WBi][2] / denom) * 100.0f) / 100.0f,
C.WB_Coeffs[3] ? roundf(_log2((float)C.WB_Coeffs[WBi][3] / denom) * 100.0f) / 100.0f : 0.0f);
}
}
if (C.rgb_cam[0][0] > 0.0001)
{
fprintf(outfile, "\n\nCamera2RGB matrix (mode: %d):\n", MyCoolRawProcessor.imgdata.params.use_camera_matrix);
PRINTMATRIX3x4(outfile, C.rgb_cam, P1.colors);
}
fprintf(outfile, "\nXYZ->CamRGB matrix:\n");
PRINTMATRIX4x3(outfile, C.cam_xyz, P1.colors);
for (int cnt = 0; cnt < 2; cnt++)
{
if (fabsf(C.P1_color[cnt].romm_cam[0]) > 0)
{
fprintf(outfile, "\nPhaseOne Matrix %d:\n", cnt + 1);
for (int i = 0; i < 3; i++)
fprintf(outfile, "%6.4f\t%6.4f\t%6.4f\n", C.P1_color[cnt].romm_cam[i * 3],
C.P1_color[cnt].romm_cam[i * 3 + 1], C.P1_color[cnt].romm_cam[i * 3 + 2]);
}
}
if (fabsf(C.cmatrix[0][0]) > 0)
{
fprintf(outfile, "\ncamRGB -> sRGB Matrix:\n");
PRINTMATRIX3x4(outfile, C.cmatrix, P1.colors);
}
if (fabsf(C.ccm[0][0]) > 0)
{
fprintf(outfile, "\nColor Correction Matrix:\n");
PRINTMATRIX3x4(outfile, C.ccm, P1.colors);
}
for (int cnt = 0; cnt < 2; cnt++)
{
if (C.dng_color[cnt].illuminant != LIBRAW_WBI_None)
{
if (C.dng_color[cnt].illuminant <= LIBRAW_WBI_StudioTungsten)
{
fprintf(outfile, "\nDNG Illuminant %d: %s", cnt + 1, WB_idx2hrstr(C.dng_color[cnt].illuminant));
}
else if (C.dng_color[cnt].illuminant == LIBRAW_WBI_Other)
{
fprintf(outfile, "\nDNG Illuminant %d: Other", cnt + 1);
}
else
{
fprintf(outfile,
"\nDNG Illuminant %d is out of EXIF LightSources range "
"[0:24, 255]: %d",
cnt + 1, C.dng_color[cnt].illuminant);
}
}
}
for (int n = 0; n < 2; n++)
{
if (fabsf(C.dng_color[n].colormatrix[0][0]) > 0)
{
fprintf(outfile, "\nDNG color matrix %d:\n", n + 1);
PRINTMATRIX4x3(outfile, C.dng_color[n].colormatrix, P1.colors);
}
}
for (int n = 0; n < 2; n++)
{
if (fabsf(C.dng_color[n].calibration[0][0]) > 0)
{
fprintf(outfile, "\nDNG calibration matrix %d:\n", n + 1);
for (int i = 0; i < P1.colors && i < 4; i++)
{
for (int j = 0; j < P1.colors && j < 4; j++)
fprintf(outfile, "%6.4f\t", C.dng_color[n].calibration[j][i]);
fprintf(outfile, "\n");
}
}
}
for (int n = 0; n < 2; n++)
{
if (fabsf(C.dng_color[n].forwardmatrix[0][0]) > 0)
{
fprintf(outfile, "\nDNG forward matrix %d:\n", n + 1);
PRINTMATRIX3x4(outfile, C.dng_color[n].forwardmatrix, P1.colors);
}
}
fprintf(outfile, "\nDerived D65 multipliers:");
for (int c = 0; c < P1.colors; c++)
fprintf(outfile, " %f", C.pre_mul[c]);
fprintf(outfile, "\n");
}
}
void print_wbfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn)
{
int WBi;
float denom;
fprintf(outfile, "// %s %s\n", P1.make, P1.model);
for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++)
{
WBi = WBToStr[cnt].NumId;
if (C.WB_Coeffs[WBi][0] && C.WB_Coeffs[WBi][1] && !WBToStr[cnt].aux_setting)
{
denom = (float)C.WB_Coeffs[WBi][1];
fprintf(outfile, "{\"%s\", \"%s\", %s, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model,
WBToStr[cnt].StrId, C.WB_Coeffs[WBi][0] / denom, C.WB_Coeffs[WBi][2] / denom);
if (C.WB_Coeffs[WBi][1] == C.WB_Coeffs[WBi][3])
fprintf(outfile, "1.0f}},\n");
else
fprintf(outfile, "%6.5ff}},\n", C.WB_Coeffs[WBi][3] / denom);
}
}
for (int cnt = 0; cnt < 64; cnt++)
if (C.WBCT_Coeffs[cnt][0])
{
fprintf(outfile, "{\"%s\", \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model,
(int)C.WBCT_Coeffs[cnt][0], C.WBCT_Coeffs[cnt][1] / C.WBCT_Coeffs[cnt][2],
C.WBCT_Coeffs[cnt][3] / C.WBCT_Coeffs[cnt][2]);
if (C.WBCT_Coeffs[cnt][2] == C.WBCT_Coeffs[cnt][4])
fprintf(outfile, "1.0f}},\n");
else
fprintf(outfile, "%6.5ff}},\n", C.WBCT_Coeffs[cnt][4] / C.WBCT_Coeffs[cnt][2]);
}
else
break;
fprintf(outfile, "\n");
}
void print_szfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn)
{
fprintf(outfile, "%s\t%s\t%s\t%d\t%d\n", fn.c_str(), P1.make, P1.model, S.width, S.height);
}
void print_unpackfun(FILE *outfile, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn)
{
char frame[48] = "";
if (print_frame)
{
ushort right_margin = S.raw_width - S.width - S.left_margin;
ushort bottom_margin = S.raw_height - S.height - S.top_margin;
snprintf(frame, 48, "F=%dx%dx%dx%d RS=%dx%d", S.left_margin, S.top_margin, right_margin, bottom_margin, S.raw_width,
S.raw_height);
}
fprintf(outfile, "%s\t%s\t%s\t%s/%s\n", fn.c_str(), MyCoolRawProcessor.unpack_function_name(), frame, P1.make,
P1.model);
}

144
samples/rawtextdump.cpp Normal file
View File

@@ -0,0 +1,144 @@
/* -*- C++ -*-
* File: raw2text.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sun Sept 01, 2020
*
* LibRaw sample
* Dumps (small) selection of RAW data to text file
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef WIN32
#include <netinet/in.h>
#else
#include <winsock2.h>
#endif
#include "libraw/libraw.h"
void usage(const char *av)
{
printf(
"Dump (small) selection of RAW file as tab-separated text file\n"
"Usage: %s inputfile COL ROW [CHANNEL] [width] [height]\n"
" COL - start column\n"
" ROW - start row\n"
" CHANNEL - raw channel to dump, default is 0 (red for rggb)\n"
" width - area width to dump, default is 16\n"
" height - area height to dump, default is 4\n"
, av);
}
unsigned subtract_bl(unsigned int val, int bl)
{
return val > (unsigned)bl ? val - (unsigned)bl : 0;
}
class LibRaw_bl : public LibRaw
{
public:
void adjust_blacklevel() { LibRaw::adjust_bl(); }
};
int main(int ac, char *av[])
{
if (ac < 4)
{
usage(av[0]);
exit(1);
}
int colstart = atoi(av[2]);
int rowstart = atoi(av[3]);
int channel = 0;
if (ac > 4) channel = atoi(av[4]);
int width = 16;
if (ac > 5) width = atoi(av[5]);
int height = 4;
if (ac > 6) height = atoi(av[6]);
if (width <1 || height<1)
{
usage(av[0]);
exit(1);
}
LibRaw_bl lr;
if (lr.open_file(av[1]) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Unable to open file %s\n", av[1]);
exit(1);
}
if ((lr.imgdata.idata.colors == 1 && channel>0) || (channel >3))
{
fprintf(stderr, "Incorrect CHANNEL specified: %d\n", channel);
exit(1);
}
if (lr.unpack() != LIBRAW_SUCCESS)
{
fprintf(stderr, "Unable to unpack raw data from %s\n", av[1]);
exit(1);
}
lr.adjust_blacklevel();
printf("%s\t%d-%d-%dx%d\tchannel: %d\n", av[1], colstart, rowstart, width, height, channel);
printf("%6s", "R\\C");
for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
printf("%6u", col);
printf("\n");
if (lr.imgdata.rawdata.raw_image)
{
for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
{
unsigned rcolors[48];
if (lr.imgdata.idata.colors > 1)
for (int c = 0; c < 48; c++)
rcolors[c] = lr.COLOR(row, c);
else
memset(rcolors, 0, sizeof(rcolors));
unsigned short *rowdata = &lr.imgdata.rawdata.raw_image[row * lr.imgdata.sizes.raw_pitch / 2];
printf("%6u", row);
for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
if (rcolors[col % 48] == (unsigned)channel) printf("%6u", subtract_bl(rowdata[col],lr.imgdata.color.cblack[channel]));
else printf(" -");
printf("\n");
}
}
else if (lr.imgdata.rawdata.color4_image && channel < 4)
{
for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
{
unsigned short(*rowdata)[4] = &lr.imgdata.rawdata.color4_image[row * lr.imgdata.sizes.raw_pitch / 8];
printf("%6u", row);
for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel]));
printf("\n");
}
}
else if (lr.imgdata.rawdata.color3_image && channel < 3)
{
for (int row = rowstart; row < rowstart + height && row < lr.imgdata.sizes.raw_height; row++)
{
unsigned short(*rowdata)[3] = &lr.imgdata.rawdata.color3_image[row * lr.imgdata.sizes.raw_pitch / 6];
printf("%6u", row);
for (int col = colstart; col < colstart + width && col < lr.imgdata.sizes.raw_width; col++)
printf("%6u", subtract_bl(rowdata[col][channel],lr.imgdata.color.cblack[channel]));
printf("\n");
}
}
else
printf("Unsupported file data (e.g. floating point format), or incorrect channel specified\n");
}

217
samples/simple_dcraw.cpp Normal file
View File

@@ -0,0 +1,217 @@
/* -*- C++ -*-
* File: simple_dcraw.cpp
* Copyright 2008-2021 LibRaw LLC (info@libraw.org)
* Created: Sat Mar 8, 2008
*
* LibRaw simple C++ API: emulates call to "dcraw [-D] [-T] [-v] [-e] [-4]"
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#endif
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif
int my_progress_callback(void *unused_data, enum LibRaw_progress state,
int iter, int expected)
{
if (iter == 0)
printf("CB: state=%x, expected %d iterations\n", state, expected);
return 0;
}
char *customCameras[] = {
(char *)"43704960,4080,5356, 0, 0, 0, 0,0,148,0,0, Dalsa, FTF4052C Full,0",
(char *)"42837504,4008,5344, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 3:4",
(char *)"32128128,4008,4008, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 1:1",
(char *)"24096096,4008,3006, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 4:3",
(char *)"18068064,4008,2254, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF4052C 16:9",
(char *)"67686894,5049,6703, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C Full",
(char *)"66573312,4992,6668, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 3:4",
(char *)"49840128,4992,4992, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 1:1",
(char *)"37400064,4992,3746, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 4:3",
(char *)"28035072,4992,2808, 0, 0, 0, 0,0,148,0,0,Dalsa, FTF5066C 16:9",
NULL};
int main(int ac, char *av[])
{
int i, ret, verbose = 0, output_thumbs = 0, output_all_thumbs = 0;
// don't use fixed size buffers in real apps!
char outfn[1024], thumbfn[1024];
LibRaw* RawProcessor = new LibRaw;
RawProcessor->imgdata.rawparams.custom_camera_strings = customCameras;
if (ac < 2)
{
printf("simple_dcraw - LibRaw %s sample. Emulates dcraw [-D] [-T] [-v] "
"[-e] [-E]\n"
" %d cameras supported\n"
"Usage: %s [-D] [-T] [-v] [-e] raw-files....\n"
"\t-4 - 16-bit mode\n"
"\t-L - list supported cameras and exit\n"
"\t-v - verbose output\n"
"\t-T - output TIFF files instead of .pgm/ppm\n"
"\t-e - extract thumbnails (same as dcraw -e in separate run)\n"
"\t-E - extract all thumbnails\n",
LibRaw::version(), LibRaw::cameraCount(), av[0]);
delete RawProcessor;
return 0;
}
putenv((char *)"TZ=UTC"); // dcraw compatibility, affects TIFF datestamp field
#define P1 RawProcessor->imgdata.idata
#define S RawProcessor->imgdata.sizes
#define C RawProcessor->imgdata.color
#define T RawProcessor->imgdata.thumbnail
#define P2 RawProcessor->imgdata.other
#define OUT RawProcessor->imgdata.params
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == 'T' && av[i][2] == 0)
OUT.output_tiff = 1;
if (av[i][1] == 'v' && av[i][2] == 0)
verbose++;
if (av[i][1] == 'e' && av[i][2] == 0)
output_thumbs++;
if (av[i][1] == 'E' && av[i][2] == 0)
{
output_thumbs++;
output_all_thumbs++;
}
if (av[i][1] == '4' && av[i][2] == 0)
OUT.output_bps = 16;
if (av[i][1] == 'C' && av[i][2] == 0)
RawProcessor->set_progress_handler(my_progress_callback, NULL);
if (av[i][1] == 'L' && av[i][2] == 0)
{
const char **clist = LibRaw::cameraList();
const char **cc = clist;
while (*cc)
{
printf("%s\n", *cc);
cc++;
}
delete RawProcessor;
exit(0);
}
continue;
}
if (verbose)
printf("Processing file %s\n", av[i]);
if ((ret = RawProcessor->open_file(av[i])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open_file %s: %s\n", av[i], libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if (!output_thumbs) // No unpack for thumb extraction
if ((ret = RawProcessor->unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
continue;
}
// thumbnail unpacking and output in the middle of main
// image processing - for test purposes!
if(output_all_thumbs)
{
if (verbose)
printf("Extracting %d thumbnails\n", RawProcessor->imgdata.thumbs_list.thumbcount);
for (int t = 0; t < RawProcessor->imgdata.thumbs_list.thumbcount; t++)
{
if ((ret = RawProcessor->unpack_thumb_ex(t)) != LIBRAW_SUCCESS)
fprintf(stderr, "Cannot unpack_thumb #%d from %s: %s\n", t, av[i], libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
break; // skip to next file
snprintf(thumbfn, sizeof(thumbfn), "%s.thumb.%d.%s", av[i], t,
T.tformat == LIBRAW_THUMBNAIL_JPEG ? "jpg" : "ppm");
if (verbose)
printf("Writing thumbnail file %s\n", thumbfn);
if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn)))
{
fprintf(stderr, "Cannot write %s: %s\n", thumbfn, libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
break;
}
}
continue;
}
else if (output_thumbs)
{
if ((ret = RawProcessor->unpack_thumb()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack_thumb %s: %s\n", av[i],
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue; // skip to next file
}
else
{
snprintf(thumbfn, sizeof(thumbfn), "%s.%s", av[i],
T.tformat == LIBRAW_THUMBNAIL_JPEG ? "thumb.jpg"
: (T.tcolors == 1? "thumb.pgm" : "thumb.ppm"));
if (verbose)
printf("Writing thumbnail file %s\n", thumbfn);
if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_thumb_writer(thumbfn)))
{
fprintf(stderr, "Cannot write %s: %s\n", thumbfn,
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue;
}
}
continue;
}
ret = RawProcessor->dcraw_process();
if (LIBRAW_SUCCESS != ret)
{
fprintf(stderr, "Cannot do postprocessing on %s: %s\n", av[i],
libraw_strerror(ret));
if (LIBRAW_FATAL_ERROR(ret))
continue;
}
snprintf(outfn, sizeof(outfn), "%s.%s", av[i],
OUT.output_tiff ? "tiff" : (P1.colors > 1 ? "ppm" : "pgm"));
if (verbose)
printf("Writing file %s\n", outfn);
if (LIBRAW_SUCCESS != (ret = RawProcessor->dcraw_ppm_tiff_writer(outfn)))
fprintf(stderr, "Cannot write %s: %s\n", outfn, libraw_strerror(ret));
RawProcessor->recycle(); // just for show this call
}
delete RawProcessor;
return 0;
}

319
samples/unprocessed_raw.cpp Normal file
View File

@@ -0,0 +1,319 @@
/* -*- C++ -*-
* File: unprocessed_raw.cpp
* Copyright 2009-2021 LibRaw LLC (info@libraw.org)
* Created: Fri Jan 02, 2009
*
* LibRaw sample
* Generates unprocessed raw image: with masked pixels and without black
subtraction
*
LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of two licenses as you choose:
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
(See file LICENSE.LGPL provided in LibRaw distribution archive for details).
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
(See file LICENSE.CDDL provided in LibRaw distribution archive for details).
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include "libraw/libraw.h"
#ifndef LIBRAW_WIN32_CALLS
#include <netinet/in.h>
#else
#include <sys/utime.h>
#include <winsock2.h>
#endif
#ifdef LIBRAW_WIN32_CALLS
#define snprintf _snprintf
#endif
#if !(LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0, 14))
#error This code is for LibRaw 0.14+ only
#endif
void gamma_curve(unsigned short curve[]);
void write_ppm(unsigned width, unsigned height, unsigned short *bitmap,
const char *basename);
void write_tiff(int width, int height, unsigned short *bitmap,
const char *basename);
int main(int ac, char *av[])
{
int i, ret;
int verbose = 1, autoscale = 0, use_gamma = 0, out_tiff = 0;
char outfn[1024];
LibRaw RawProcessor;
if (ac < 2)
{
usage:
printf("unprocessed_raw - LibRaw %s sample. %d cameras supported\n"
"Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n"
"\t-q - be quiet\n"
"\t-s N - select Nth image in file (default=0)\n"
"\t-g - use gamma correction with gamma 2.2 (not precise,use for "
"visual inspection only)\n"
"\t-A - autoscaling (by integer factor)\n"
"\t-T - write tiff instead of pgm\n",
LibRaw::version(), LibRaw::cameraCount(), av[0]);
return 0;
}
#define S RawProcessor.imgdata.sizes
#define OUT RawProcessor.imgdata.params
#define OUTR RawProcessor.imgdata.rawparams
for (i = 1; i < ac; i++)
{
if (av[i][0] == '-')
{
if (av[i][1] == 'q' && av[i][2] == 0)
verbose = 0;
else if (av[i][1] == 'A' && av[i][2] == 0)
autoscale = 1;
else if (av[i][1] == 'g' && av[i][2] == 0)
use_gamma = 1;
else if (av[i][1] == 'T' && av[i][2] == 0)
out_tiff = 1;
else if (av[i][1] == 's' && av[i][2] == 0)
{
i++;
OUTR.shot_select = av[i] ? atoi(av[i]) : 0;
}
else
goto usage;
continue;
}
if (verbose)
printf("Processing file %s\n", av[i]);
if ((ret = RawProcessor.open_file(av[i])) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot open %s: %s\n", av[i], libraw_strerror(ret));
continue; // no recycle b/c open file will recycle itself
}
if (verbose)
{
printf("Image size: %dx%d\nRaw size: %dx%d\n", S.width, S.height,
S.raw_width, S.raw_height);
printf("Margins: top=%d, left=%d\n", S.top_margin, S.left_margin);
}
if ((ret = RawProcessor.unpack()) != LIBRAW_SUCCESS)
{
fprintf(stderr, "Cannot unpack %s: %s\n", av[i], libraw_strerror(ret));
continue;
}
if (verbose)
printf("Unpacked....\n");
if (!(RawProcessor.imgdata.idata.filters ||
RawProcessor.imgdata.idata.colors == 1))
{
printf("Only Bayer-pattern RAW files supported, sorry....\n");
continue;
}
if (autoscale)
{
unsigned max = 0, scale;
for (int j = 0; j < S.raw_height * S.raw_width; j++)
if (max < RawProcessor.imgdata.rawdata.raw_image[j])
max = RawProcessor.imgdata.rawdata.raw_image[j];
if (max > 0 && max < 1 << 15)
{
scale = (1 << 16) / max;
if (verbose)
printf("Scaling with multiplier=%d (max=%d)\n", scale, max);
for (int j = 0; j < S.raw_height * S.raw_width; j++)
RawProcessor.imgdata.rawdata.raw_image[j] *= scale;
}
}
if (use_gamma)
{
unsigned short curve[0x10000];
gamma_curve(curve);
for (int j = 0; j < S.raw_height * S.raw_width; j++)
RawProcessor.imgdata.rawdata.raw_image[j] =
curve[RawProcessor.imgdata.rawdata.raw_image[j]];
if (verbose)
printf("Gamma-corrected....\n");
}
if (OUTR.shot_select)
snprintf(outfn, sizeof(outfn), "%s-%d.%s", av[i], OUTR.shot_select,
out_tiff ? "tiff" : "pgm");
else
snprintf(outfn, sizeof(outfn), "%s.%s", av[i], out_tiff ? "tiff" : "pgm");
if (out_tiff)
write_tiff(S.raw_width, S.raw_height,
RawProcessor.imgdata.rawdata.raw_image, outfn);
else
write_ppm(S.raw_width, S.raw_height,
RawProcessor.imgdata.rawdata.raw_image, outfn);
if (verbose)
printf("Stored to file %s\n", outfn);
}
return 0;
}
void write_ppm(unsigned width, unsigned height, unsigned short *bitmap,
const char *fname)
{
if (!bitmap)
return;
FILE *f = fopen(fname, "wb");
if (!f)
return;
int bits = 16;
fprintf(f, "P5\n%d %d\n%d\n", width, height, (1 << bits) - 1);
unsigned char *data = (unsigned char *)bitmap;
unsigned data_size = width * height * 2;
#define SWAP(a, b) \
{ \
a ^= b; \
a ^= (b ^= a); \
}
for (unsigned i = 0; i < data_size; i += 2)
SWAP(data[i], data[i + 1]);
#undef SWAP
fwrite(data, data_size, 1, f);
fclose(f);
}
/* == gamma curve and tiff writer - simplified cut'n'paste from dcraw.c */
#define SQR(x) ((x) * (x))
void gamma_curve(unsigned short *curve)
{
double pwr = 1.0 / 2.2;
double ts = 0.0;
int imax = 0xffff;
int mode = 2;
int i;
double g[6], bnd[2] = {0, 0}, r;
g[0] = pwr;
g[1] = ts;
g[2] = g[3] = g[4] = 0;
bnd[g[1] >= 1] = 1;
if (g[1] && (g[1] - 1) * (g[0] - 1) <= 0)
{
for (i = 0; i < 48; i++)
{
g[2] = (bnd[0] + bnd[1]) / 2;
if (g[0])
bnd[(pow(g[2] / g[1], -g[0]) - 1) / g[0] - 1 / g[2] > -1] = g[2];
else
bnd[g[2] / exp(1 - 1 / g[2]) < g[1]] = g[2];
}
g[3] = g[2] / g[1];
if (g[0])
g[4] = g[2] * (1 / g[0] - 1);
}
if (g[0])
g[5] = 1 / (g[1] * SQR(g[3]) / 2 - g[4] * (1 - g[3]) +
(1 - pow(g[3], 1 + g[0])) * (1 + g[4]) / (1 + g[0])) -
1;
else
g[5] = 1 / (g[1] * SQR(g[3]) / 2 + 1 - g[2] - g[3] -
g[2] * g[3] * (log(g[3]) - 1)) -
1;
for (i = 0; i < 0x10000; i++)
{
curve[i] = 0xffff;
if ((r = (double)i / imax) < 1)
curve[i] =
0x10000 *
(mode ? (r < g[3] ? r * g[1]
: (g[0] ? pow(r, g[0]) * (1 + g[4]) - g[4]
: log(r) * g[2] + 1))
: (r < g[2] ? r / g[1]
: (g[0] ? pow((r + g[4]) / (1 + g[4]), 1 / g[0])
: exp((r - 1) / g[2]))));
}
}
void tiff_set(ushort *ntag, ushort tag, ushort type, int count, int val)
{
struct libraw_tiff_tag *tt;
int c;
tt = (struct libraw_tiff_tag *)(ntag + 1) + (*ntag)++;
tt->tag = tag;
tt->type = type;
tt->count = count;
if ((type < LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 4))
for (c = 0; c < 4; c++)
tt->val.c[c] = val >> (c << 3);
else if (tagtypeIs(LIBRAW_EXIFTAG_TYPE_SHORT) && (count <= 2))
for (c = 0; c < 2; c++)
tt->val.s[c] = val >> (c << 4);
else
tt->val.i = val;
}
#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)
void tiff_head(int width, int height, struct tiff_hdr *th)
{
int c;
time_t timestamp = time(NULL);
struct tm *t;
memset(th, 0, sizeof *th);
th->t_order = htonl(0x4d4d4949) >> 16;
th->magic = 42;
th->ifd = 10;
tiff_set(&th->ntag, 254, 4, 1, 0);
tiff_set(&th->ntag, 256, 4, 1, width);
tiff_set(&th->ntag, 257, 4, 1, height);
tiff_set(&th->ntag, 258, 3, 1, 16);
for (c = 0; c < 4; c++)
th->bps[c] = 16;
tiff_set(&th->ntag, 259, 3, 1, 1);
tiff_set(&th->ntag, 262, 3, 1, 1);
tiff_set(&th->ntag, 273, 4, 1, sizeof *th);
tiff_set(&th->ntag, 277, 3, 1, 1);
tiff_set(&th->ntag, 278, 4, 1, height);
tiff_set(&th->ntag, 279, 4, 1, height * width * 2);
tiff_set(&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
tiff_set(&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
tiff_set(&th->ntag, 284, 3, 1, 1);
tiff_set(&th->ntag, 296, 3, 1, 2);
tiff_set(&th->ntag, 306, 2, 20, TOFF(th->date));
th->rat[0] = th->rat[2] = 300;
th->rat[1] = th->rat[3] = 1;
t = localtime(&timestamp);
if (t)
sprintf(th->date, "%04d:%02d:%02d %02d:%02d:%02d", t->tm_year + 1900,
t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
}
void write_tiff(int width, int height, unsigned short *bitmap, const char *fn)
{
struct tiff_hdr th;
FILE *ofp = fopen(fn, "wb");
if (!ofp)
return;
tiff_head(width, height, &th);
fwrite(&th, sizeof th, 1, ofp);
fwrite(bitmap, 2, width * height, ofp);
fclose(ofp);
}