Squashed 'rtengine/libraw/' content from commit cccb97647
git-subtree-dir: rtengine/libraw git-subtree-split: cccb97647fcee56801fa68231fa8a38aa8b52ef7
This commit is contained in:
251
RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp
Normal file
251
RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
#include "rawspeed3_capi.h"
|
||||
#include "RawSpeed-API.h"
|
||||
#define HAVE_PUGIXML
|
||||
#include <../pugixml/pugixml.hpp> // for xml_document, xml_pars...
|
||||
|
||||
extern const char* _rawspeed3_data_xml;
|
||||
|
||||
class rawspeed3_handle_data
|
||||
{
|
||||
public:
|
||||
rawspeed3_handle_data(const char* cameradefs, bool is_file);
|
||||
void release();
|
||||
int decodefile(rawspeed3_ret_t* resultp, const void *data, size_t datasize, bool allowunknown);
|
||||
~rawspeed3_handle_data();
|
||||
private:
|
||||
std::unique_ptr <rawspeed::CameraMetaData> cameraMeta;
|
||||
std::unique_ptr<rawspeed::RawParser> rawParser;
|
||||
std::unique_ptr<rawspeed::RawDecoder> rawDecoder;
|
||||
};
|
||||
|
||||
|
||||
/* API calls */
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
/*
|
||||
void rawspeed3_clearresult(rawspeed3_ret_t* r)
|
||||
|
||||
Clears (inits) results structure
|
||||
*/
|
||||
DllDef void rawspeed3_clearresult(rawspeed3_ret_t* r)
|
||||
{
|
||||
if(!r) return;
|
||||
r->width = r->height = r->bpp = r->cpp = 0;
|
||||
r->status = rawspeed_inited;
|
||||
r->pitch = r->filters = 0;
|
||||
r->pixeldata = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
rawspeed3_init()
|
||||
Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success
|
||||
Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true)
|
||||
*/
|
||||
|
||||
DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file)
|
||||
{
|
||||
/* Create rawspeed3_handle_data and return it as void document */
|
||||
if(!cameradefs) return nullptr;
|
||||
try
|
||||
{
|
||||
/* code */
|
||||
auto *handle = new rawspeed3_handle_data(cameradefs, is_file);
|
||||
return (void*)handle;
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
rawspeed3_initdefault()
|
||||
Init rawspeed3 Cameradefs with built-in cameras.xml (converted to _rawspeed3_data_xml),
|
||||
returns: 0 on failure, pointer to data block on success
|
||||
*/
|
||||
|
||||
DllDef rawspeed3_handle_t rawspeed3_initdefault()
|
||||
{
|
||||
return rawspeed3_init(_rawspeed3_data_xml,false);
|
||||
}
|
||||
|
||||
/*
|
||||
rawspeed3_decodefile(..)
|
||||
parse/decode RAW file passed via memory
|
||||
Parameters:
|
||||
handle - rawspeed3_handle_t => handle created by rawspeed3_init()
|
||||
resultp -> pointer to rawspeed3_ret_t to be filled with
|
||||
data -> data buffer with raw file
|
||||
datasize -> size of this buffer
|
||||
allowunknown -> allow to process unknown cameras (not listed in cameras.xml)
|
||||
Return values:
|
||||
0 -> OK
|
||||
>=1 -> decode error
|
||||
-1 -> Incorrect parameters passed (handle, or data, or datasize)
|
||||
*/
|
||||
|
||||
DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp,
|
||||
const void *data, size_t datasize, bool allowunknown)
|
||||
{
|
||||
if(!handle || !resultp || !data || datasize > 2UL * 1024UL * 1024UL * 1024UL)
|
||||
{
|
||||
if(resultp)
|
||||
resultp->status = rawspeed3_param_error;
|
||||
return -1;
|
||||
}
|
||||
rawspeed3_clearresult(resultp);
|
||||
auto *p = static_cast<rawspeed3_handle_data*>(handle);
|
||||
return p->decodefile(resultp,data,datasize,allowunknown);
|
||||
}
|
||||
|
||||
/*
|
||||
void rawspeed3_release(rawspeed3_handle_t handle)
|
||||
|
||||
release internal raw data buffer and error code;
|
||||
*/
|
||||
|
||||
/* release internal raw data buffer and errmessage (if any) */
|
||||
DllDef void rawspeed3_release(rawspeed3_handle_t handle)
|
||||
{
|
||||
if(!handle) return;
|
||||
auto *p = static_cast<rawspeed3_handle_data*>(handle);
|
||||
p->release();
|
||||
}
|
||||
|
||||
/* close handle: release all internal data */
|
||||
DllDef void rawspeed3_close(rawspeed3_handle_t handle)
|
||||
{
|
||||
if(!handle) return;
|
||||
auto *p = static_cast<rawspeed3_handle_data*>(handle);
|
||||
delete p;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
// == Implementation
|
||||
|
||||
int rawspeed3_handle_data::decodefile(rawspeed3_ret_t* resultp,
|
||||
const void *data, size_t datasize, bool allowunknown)
|
||||
{
|
||||
if(!cameraMeta)
|
||||
{
|
||||
resultp->status = rawspeed3_not_inited;
|
||||
return rawspeed3_not_inited;
|
||||
}
|
||||
try
|
||||
{
|
||||
rawspeed::Buffer buffer( static_cast<const uint8_t*>(data),datasize);
|
||||
release();
|
||||
rawParser = std::make_unique<rawspeed::RawParser>(buffer);
|
||||
auto d(rawParser->getDecoder(cameraMeta.get()));
|
||||
if(!d)
|
||||
{
|
||||
resultp->status = rawspeed3_no_decoder;
|
||||
return rawspeed3_no_decoder;
|
||||
}
|
||||
|
||||
d->applyCrop = false;
|
||||
d->failOnUnknown = !allowunknown;
|
||||
d->interpolateBadPixels = false;
|
||||
d->applyStage1DngOpcodes = false;
|
||||
d->fujiRotate = false;
|
||||
d->applyCrop = false;
|
||||
|
||||
try {
|
||||
d->checkSupport(cameraMeta.get());
|
||||
} catch (...) {
|
||||
release();
|
||||
resultp->status = rawspeed3_not_supported;
|
||||
return resultp->status;
|
||||
}
|
||||
|
||||
rawspeed::RawImage r = d->mRaw;
|
||||
d->decodeMetaData(cameraMeta.get());
|
||||
|
||||
d->checkSupport(cameraMeta.get());
|
||||
d->decodeRaw();
|
||||
d->decodeMetaData(cameraMeta.get());
|
||||
r = d->mRaw;
|
||||
|
||||
rawDecoder = std::move(d);
|
||||
// we're here w/o exceptions: success
|
||||
const rawspeed::iPoint2D dimUncropped = r->getUncroppedDim();
|
||||
resultp->width = dimUncropped.x;
|
||||
resultp->height = dimUncropped.y;
|
||||
resultp->filters = r->cfa.getDcrawFilter();
|
||||
resultp->cpp = r->getCpp();
|
||||
resultp->bpp = r->getBpp();
|
||||
resultp->pitch = r->pitch;
|
||||
resultp->pixeldata = r->getDataUncropped(0,0);
|
||||
const auto errors = r->getErrors();
|
||||
resultp->status = errors.empty()? rawspeed3_ok : rawspeed3_ok_warnings;
|
||||
return resultp->status;
|
||||
/* code */
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
resultp->status = rawspeed3_processing_error;
|
||||
return rawspeed3_processing_error;
|
||||
}
|
||||
}
|
||||
|
||||
namespace rawspeed
|
||||
{
|
||||
class CameraMetaDataFromMem : public CameraMetaData
|
||||
{
|
||||
public:
|
||||
explicit CameraMetaDataFromMem(const char* xmlstring);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
rawspeed3_handle_data::rawspeed3_handle_data(const char* cameradefs, bool is_file)
|
||||
: rawParser(nullptr)
|
||||
{
|
||||
cameraMeta = is_file ? std::make_unique<rawspeed::CameraMetaData>(cameradefs)
|
||||
: std::make_unique <rawspeed::CameraMetaDataFromMem>(cameradefs);
|
||||
}
|
||||
rawspeed3_handle_data::~rawspeed3_handle_data()
|
||||
{
|
||||
release();
|
||||
cameraMeta.reset();
|
||||
}
|
||||
|
||||
void rawspeed3_handle_data::release()
|
||||
{
|
||||
if(rawDecoder)
|
||||
rawDecoder.reset();
|
||||
if (rawParser)
|
||||
rawParser.reset();
|
||||
}
|
||||
|
||||
// Camera metadata from mem
|
||||
namespace rawspeed
|
||||
{
|
||||
CameraMetaDataFromMem::CameraMetaDataFromMem(const char* document)
|
||||
{
|
||||
using pugi::xml_node;
|
||||
using pugi::xml_document;
|
||||
using pugi::xml_parse_result;
|
||||
|
||||
xml_document doc;
|
||||
xml_parse_result result = doc.load_string(document);
|
||||
|
||||
if (!result)
|
||||
throw "Camera definitions parse error";
|
||||
|
||||
for (xml_node camera : doc.child("Cameras").children("Camera"))
|
||||
{
|
||||
const auto* cam = addCamera(std::make_unique<Camera>(camera));
|
||||
|
||||
if (cam == nullptr)
|
||||
continue;
|
||||
|
||||
// Create cameras for aliases.
|
||||
for (auto i = 0UL; i < cam->aliases.size(); i++)
|
||||
addCamera(std::make_unique<Camera>(cam, i));
|
||||
}
|
||||
}
|
||||
} // namespace rawspeed
|
83
RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h
Normal file
83
RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef RAWSPEED_BUILDLIB
|
||||
#define DllDef __declspec(dllexport)
|
||||
#else
|
||||
#define DllDef __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define DllDef
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
enum rawspeed3_error_codes
|
||||
{
|
||||
rawspeed_inited = -2,
|
||||
rawspeed3_param_error = -1,
|
||||
rawspeed3_ok = 0,
|
||||
rawspeed3_ok_warnings = 1,
|
||||
rawspeed3_not_inited = 2,
|
||||
rawspeed3_processing_error = 3,
|
||||
rawspeed3_no_decoder = 4,
|
||||
rawspeed3_not_supported = 5,
|
||||
};
|
||||
|
||||
typedef void *rawspeed3_handle_t;
|
||||
|
||||
/* RAW file parsing results */
|
||||
typedef struct
|
||||
{
|
||||
int status; /* -1: param error, 0 => OK, >=1 error code */
|
||||
uint16_t width, height, bpp, cpp;
|
||||
unsigned pitch, filters;
|
||||
const void *pixeldata;
|
||||
}rawspeed3_ret_t;
|
||||
|
||||
/* API calls */
|
||||
DllDef void rawspeed3_clearresult(rawspeed3_ret_t*);
|
||||
/*
|
||||
rawspeed3_init()
|
||||
Init rawspeed3 Camera, returns: 0 on failure, pointer to data block on success
|
||||
Cameradefs: cameras.xml in string (is_file == false) or file (is_file == true)
|
||||
*/
|
||||
DllDef rawspeed3_handle_t rawspeed3_init(const char* cameradefs, bool is_file);
|
||||
|
||||
/* init with built-in cameras.xml */
|
||||
DllDef rawspeed3_handle_t rawspeed3_initdefault();
|
||||
|
||||
/*
|
||||
rawspeed3_decodefile(..)
|
||||
parse/decode RAW file passed via memory
|
||||
Parameters:
|
||||
handle - rawspeed3_handle_t => handle created by rawspeed3_init()
|
||||
resultp -> pointer to rawspeed3_ret_t to be filled with
|
||||
data -> data buffer with raw file
|
||||
datasize -> size of this buffer
|
||||
allowunknown -> allow to process unknown cameras (not listed in cameras.xml)
|
||||
Return values:
|
||||
0 -> OK
|
||||
1 -> decode warnings (not fatal)
|
||||
>1 -> error code
|
||||
-1 -> Incorrect parameters passed (handle, or data, or datasize)
|
||||
*/
|
||||
DllDef int rawspeed3_decodefile(rawspeed3_handle_t handle, rawspeed3_ret_t* resultp,
|
||||
const void *data, size_t datasize, bool allowunknown);
|
||||
|
||||
/* release internal raw data buffer */
|
||||
DllDef void rawspeed3_release(rawspeed3_handle_t handle);
|
||||
|
||||
/* close handle: release all internal data */
|
||||
DllDef void rawspeed3_close(rawspeed3_handle_t handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* Extern C */
|
||||
#endif
|
71
RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp
Normal file
71
RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "rawspeed3_capi.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
std::vector<uint8_t> readfile(char *fn)
|
||||
{
|
||||
std::ifstream is(fn,std::ifstream::binary);
|
||||
if(is)
|
||||
{
|
||||
is.seekg(0, is.end);
|
||||
size_t length = is.tellg();
|
||||
is.seekg(0, is.beg);
|
||||
std::vector<uint8_t> ret;
|
||||
ret.resize(length+1);
|
||||
is.read ((char*)ret.data(),length);
|
||||
is.close();
|
||||
ret[length] = 0; // zero terminated
|
||||
std::cout << "File: " << fn << " size:" << ret.size() << std::endl;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return std::vector<uint8_t>();
|
||||
}
|
||||
|
||||
|
||||
int main(int ac, char *av[])
|
||||
{
|
||||
if(ac < 2)
|
||||
{
|
||||
std::cout << "Usage: " << av[0] << " rawfile rawfile2 ...." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
rawspeed3_handle_t handle = rawspeed3_initdefault();
|
||||
if(!handle)
|
||||
{
|
||||
std::cerr << "Unable to init rs3" << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
for(int i = 1; i < ac; i++)
|
||||
{
|
||||
std::vector<uint8_t> rawdata = readfile(av[i]);
|
||||
if (rawdata.size() < 100) {
|
||||
std::cerr << "Input file " << av[i] << " too small or nonexistent" << std::endl;
|
||||
continue;
|
||||
}
|
||||
rawspeed3_ret_t result;
|
||||
int q = rawspeed3_decodefile(handle, &result, rawdata.data(),
|
||||
rawdata.size(), true);
|
||||
if (q >= rawspeed3_ok && q <= rawspeed3_ok_warnings) {
|
||||
std::cout << "File decoded code=" << result.status <<" width=" << result.width
|
||||
<< " height=" << result.height
|
||||
<< " pitch=" << result.pitch
|
||||
<< " filters=" << std::hex << result.filters << std::dec
|
||||
<< " channels=" << result.cpp
|
||||
<< " bpp=" << result.bpp
|
||||
<< std::endl;
|
||||
} else
|
||||
std::cout << "RawSpeed wrapper error code:" << result.status
|
||||
<< std::endl;
|
||||
|
||||
rawspeed3_release(handle);
|
||||
}
|
||||
|
||||
rawspeed3_close(handle);
|
||||
|
||||
}
|
5
RawSpeed3/rawspeed3_c_api/rsxml2c.sh
Normal file
5
RawSpeed3/rawspeed3_c_api/rsxml2c.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "const char *_rawspeed3_data_xml="
|
||||
cat $1 | tr -d '\015' | sed -e 's/\\/\\\\/g;s/"/\\"/g;s/ /\\t/g;s/^/"/;s/$/\\n"/'
|
||||
echo "\"\\0\";"
|
Reference in New Issue
Block a user