关于API的一般说明
内容
- LibRaw版本
- 错误代码约定和错误处理
- 非标准情况并非错误
- 输入层抽象
- 线程安全
- 使用C ++
- LibRaw :: imgdata.params结构的参数影响open_file / unpack / unpack_thumb的行为
- 内存使用情况
- 与dcraw不兼容
LibRaw版本
从版本0.9开始,只有一个LibRaw变体。旧版本有三个单独的版本(普通版,-Lite版和商业版)。
错误代码约定和错误处理
以下约定涉及返回的错误:
- 所有可以返回错误代码的函数都有整数类型的返回数据。
- 如果没有错误,则返回值为0(LIBRAW_SUCCESS)。
- 如果系统调用中发生错误,则返回值为errno(正数),可以使用strerror()或类似方法进行分析。
- 所有LibRaw自己的错误代码都是否定的; 每个错误都属于以下两种类型之一:
- 非致命错误
- 非致命错误不禁止在处理连续中执行其他函数(例如, unpack_thumb() 可以轻松返回对应于“预览不存在”的代码,但这不会阻止进一步调用 unpack() 。
- 致命错误
-
在致命错误(内存不足,输入数据错误,数据解包失败)的情况下,终止当前处理阶段并释放所有分配的资源。
如果尝试继续处理,则所有后续API调用都将返回LIBRAW_OUT_OF_ORDER_CALL错误。
同时,发生致命错误的LibRaw实例可以通常的方式处理下一个RAW文件(通过调用 open_file() (或其他输入方法),然后 解压缩() 等)。
- 宏LIBRAW_FATAL_ERROR(错误代码)检查错误是否致命。
- 此处列出并解密错误代码。
非标准情况并非错误
如果程序遇到不阻止从文件中检索某些数据的非标准情况,它会通过设置imgdata.process_warnings中的相应位来发送信号。这里列出并破译了可能的警告类型。
输入层抽象
LibRaw使用从LibRaw_abstract_datastream派生的对象进行数据输入。这些对象的语义类似于“具有任意搜索的文件”对象:使用读取和查找操作。
某些RAW格式需要临时切换到在内存缓冲区顶部创建的另一个数据流,以便读取元数据。这样做的方法是通过内部数据字段子流在基类LibRaw_abstract_datastream中实现的。有关详细信息,请查看libraw / libraw_datastream.h文件中LibRaw_file_datastream类的源代码。在实现自己的数据流类时,需要考虑子流并将控制权传递给该字段的方法(如果它是活动的(非NULL))。
如果datastream implementationaton知道输入文件的名称,它应该提供fname()调用。此名称将用于错误回调和猜测带有元数据的JPEG文件的名称(对于具有外部元数据的RAW文件)。
对于外部元数据支持,输入类应实现subfile_open()/ subfile_close()方法。возврашаюткодошибки。
可以在LibRaw_file_datastream类中找到这些方法实现的示例(有关详细信息,请查看libraw / libraw_datastream.h文件)。
线程安全
如果在一个线程内创建并使用LibRaw对象,则可确保线程安全。同时,线程数(每个线程都有自己的LibRaw对象)不受任何限制(除了内存要求)。
如果在一个执行线程中创建LibRaw对象并在另一个执行线程中使用,则需要进行外部同步。
Unix环境下有两个库(Linux / FreeBSD / MacOS):libraw_r.a(线程安全)和libraw.a(单线程,稍快)。
线程安全库版本将中间解包器数据存储到LibRaw类数据中。因此,可以并行工作的几个LibRaw副本。
非线程安全库使用全局变量用于中间数据存储,该存储更快但不重新进行。这个非线程安全的库仍然可以在多线程应用程序中使用,但前提是程序中只存在一个LibRaw类副本。
Windows版本类似于多线程Unix版本。
使用C ++
使用C ++异常机制处理LibRaw中的异常情况。所有异常都在库函数中捕获,不应渗透到外部。
使用函数malloc(calloc)/ free而不是new / delete来分配/释放内存。
如果使用C API,则仍然保留对C ++调用new / delete的引用,因此需要使用libstdc ++(Unix)/ ....(Windows)进行链接。
LibRaw :: imgdata.params结构的参数影响open_file / unpack / unpack_thumb的行为
结构LibRaw :: imgdata.params的大多数数据字段仅影响数据后处理,但是有一些例外,它们已经被来自/ dcraw源文本的当前版本的LibRaw继承(这些依赖将逐渐被删除)。
- imgdata.params.use_camera_matrix和imgdata.params.use_camera_wb
-
这些字段会影响带有颜色矩阵的摄像机的RAW数据加载。
注意! 如果用户未设置参数 imgdata.params.use_camera_matrix ,则在文件打开阶段从 imgdata.params.use_camera_wb 复制它。 - imgdata.params.user_flip
-
如果此参数大于或等于零,
imgdata.sizes.flip = imgdata.params.user_flip
则在 open_file() 阶段执行赋值。 - imgdata.params.shot_select
- 该参数使得可以选择用于数据格式的提取图像的数量,其中可以在一个数据文件中存储多个RAW图像。
- imgdata.params.half_size
- 影响第一阶段和Sinar后备的RAW数据加载。此外,设置此参数,然后在每个维度中图像位图将减少一半。在后一种情况下,位图的所有4个组件将在数据提取阶段填充。
- imgdata.params.threshold,imgdata.params.aber
- 如果使用这些参数,那么半尺寸位图将用于数据解包。请参阅上文了解详情。
- imgdata.params.use_camera_wb
- 影响叶背的白平衡矩阵的加载。
内存使用情况
堆栈使用
LibRaw类的一个实例有自己的大小约100 Kb ; 如果LibRaw imageProcessor;
使用了类似的结构,则此内存是堆栈分配的。
类LibRaw(和C API调用)的方法可以在工作期间在堆栈上分配多达130-140 Kb的数据(以放置自动变量)。
因此,一个LibRaw实例的工作可能需要大约250 Kb的堆栈内存。对于大多数当代架构而言,这不是问题。但是,在多线程环境中工作时,不应忘记为线程堆栈分配足够的内存量。
在动态分配(LibRaw *iProcessor = new LibRaw;
)的情况下,堆栈内存的要求将减少100 Kb,这是类实例的大小)。如果使用C API,则动态分配LibRaw实例。
动态内存管理
LibRaw记录所有分配的动态内存块; 在特殊情况(致命错误)的情况下,他们都被释放。用于保存该记录的代码是相当原始的并且不是为了考虑分配许多块而设计的(在正常情况下,在文件处理期间分配发生2到6次); 尝试向LibRaw添加新方法的开发人员应该考虑这个事实。
动态内存使用
LibRaw使用动态内存
- 对于解码图像;
- 对于解码的缩略图;
- 对于后处理图像;
- 从RAW文件中检索的ICC配置文件(如果可用);
- 用于RAW文件解包阶段的临时数据;
- 用于后处理和结果输出阶段的临时数据;
- 用于读取RAW源文件(仅在Win32下)。
RAW图像的内存缓冲区
存储解码的RAW数据:
- “拜耳”图像的每像素一个16位值。屏蔽像素(黑色或暗色或遮蔽帧)与图像数据一起存储。
- 全彩色图像的四个16位值(Foveon,Linear DNG,Canon sRAW等)。
RAW数据的缓冲区由unpack()调用分配,并在调用recycle()时释放。
后处理图像的内存
在后处理阶段,每个像素包含四个16位值,每个可能的颜色通道一个(一些传感器实际上是4色)。
在调用raw2image()或dcraw_process()时分配解码图像的缓冲区
调用recycle()或free_image()调用时释放缓冲区。
解码缩略图的内存
调用unpack_thumb()时会分配thumbmail的内存,并在调用recycle()时释放。分配的缓冲区的大小精确调整为缩略图大小,即最多几Mb。
解码ICC配置文件的内存
ICC配置文件的内存在调用unpack_profile()时分配,并在调用recycle()时释放。分配的缓冲区的大小精确调整到ICC配置文件大小,即高达几百Kb。
RAW解包的内存
RAW数据解包期间所需的临时缓冲区的内存可以在unpack()工作期间分配,并在完成此功能之前释放。分配的缓冲区的大小很小,高达数十Kb。
用于后处理的内存
在图像后处理期间(从dcraw继承),分配直方图(128 Kb)的内存。该内存在调用dcraw_process()时分配,并在调用recycle()时释放。
另外,在dcraw_process()的工作期间以及在使用某些可用的可能性时,例如
- 从FUJI相机旋转图像;
- 校正色差;
- 图像尺寸变化(包括非方形像素的校正);
- 突出恢复;
将分配大小等于所得图像的大小的临时缓冲区(对于各种处理阶段,每像素6-8个字节)。一旦处理的中间子阶段完成,将释放具有先前图像副本的缓冲器。
如果未使用后处理,则不会分配临时缓冲区。
文件写作的记忆
在调用dcraw_ppm_tiff_writer()时,将分配输出图像的单行内存。在此调用结束之前释放已分配的内存。
解压缩到内存缓冲区
Functons dcraw_make_mem_image()和dcraw_make_mem_thumb()(以及C-API中的互补调用)为整个输出数据集分配内存(分别为完整的RGB位图和缩略图)。调用函数应该释放()这个内存本身。
与dcraw不兼容
自动最大搜索/亮度调整
许多相机格式确实使用较少的数据范围,而不是格式性质(位数)。如果数据最大估计不正确(太低),这可能会导致彩色高光('粉红色云'),因为数据切割错误。
为了防止这种情况,如果此最大值大于格式最大值乘以imdata.params.adjust_maximum_thr值(默认值为0.75),则LibRaw将使用当前文件中的实际数据最大值。
要关闭此功能(并重复dcraw.c粉红色云),请将imdata.params.adjust_maximum_thr设置为0.0
从柯达相机处理缩略图
在某些柯达相机中,预览(缩略图)以未校正图像的形式存储。在使用dcraw -e进行提取时,白平衡,颜色转换和其他设置与用于提取主RAW数据的设置相同(包括缺陷消除和暗帧减法,这是错误的,因为图像大小不同)。
在LibRaw :: unpack_thumb()调用中,使用从摄像机获取的白平衡(“正在拍摄”),并且不考虑imgdata.params的设置。
对于所有其他相机,缩略图“按原样”提取,无需任何颜色转换,无论是在dcraw还是在LibRaw中。