原文:http://www.cnblogs.com/oloroso/p/5777959.html

FreeImage编译及遇到问题解决

1、下载freeImage源码包

wget http://downloads.sourceforge.net/freeimage/FreeImage3170.zip
#解压
unzip FreeImage3170.zip -d freeImage

2、Linux下编译

cd freeImage

sudo make

2.1、类型转换错误

这个问题出现在dcraw_common.cpp这个文件中的45224543行之间。
报错信息如下

Source/LibRawLite/./internal/dcraw_common.cpp: 在成员函数‘void LibRaw::vng_interpolate()’中:
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘128’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]};^
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘136’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘128’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘136’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘128’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]
Source/LibRawLite/./internal/dcraw_common.cpp:4546:3: 错误:在 {} 内将‘136’从‘int’转换为较窄的类型‘signed char’ [-Wnarrowing]

我们把有问题的这段代码摘出来,可以看到{}中以十六进制表示的数字,有的是超过127的,因为字面整数默认是int类型,所以这里会出现这个错误。

void CLASS vng_interpolate()
{static const signed char *cp, terms[] = {-2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,-2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,-2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,-2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,-2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,-1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,-1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,-1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,-1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,-1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,-1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,-1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,-1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,+0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,+0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,+0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,+0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,+0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,+0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,+0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,+1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,+1,+0,+2,+1,0,0x10}, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };

将上面的代码改为下面的形式即可

void CLASS vng_interpolate()
{static const signed char *cp, terms[] = {-2,-2,+0,-1,0,(char)0x01, -2,-2,+0,+0,1,(char)0x01, -2,-1,-1,+0,0,(char)0x01,-2,-1,+0,-1,0,(char)0x02, -2,-1,+0,+0,0,(char)0x03, -2,-1,+0,+1,1,(char)0x01,-2,+0,+0,-1,0,(char)0x06, -2,+0,+0,+0,1,(char)0x02, -2,+0,+0,+1,0,(char)0x03,-2,+1,-1,+0,0,(char)0x04, -2,+1,+0,-1,1,(char)0x04, -2,+1,+0,+0,0,(char)0x06,-2,+1,+0,+1,0,(char)0x02, -2,+2,+0,+0,1,(char)0x04, -2,+2,+0,+1,0,(char)0x04,-1,-2,-1,+0,0,(char)0x80, -1,-2,+0,-1,0,(char)0x01, -1,-2,+1,-1,0,(char)0x01,-1,-2,+1,+0,1,(char)0x01, -1,-1,-1,+1,0,(char)0x88, -1,-1,+1,-2,0,(char)0x40,-1,-1,+1,-1,0,(char)0x22, -1,-1,+1,+0,0,(char)0x33, -1,-1,+1,+1,1,(char)0x11,-1,+0,-1,+2,0,(char)0x08, -1,+0,+0,-1,0,(char)0x44, -1,+0,+0,+1,0,(char)0x11,-1,+0,+1,-2,1,(char)0x40, -1,+0,+1,-1,0,(char)0x66, -1,+0,+1,+0,1,(char)0x22,-1,+0,+1,+1,0,(char)0x33, -1,+0,+1,+2,1,(char)0x10, -1,+1,+1,-1,1,(char)0x44,-1,+1,+1,+0,0,(char)0x66, -1,+1,+1,+1,0,(char)0x22, -1,+1,+1,+2,0,(char)0x10,-1,+2,+0,+1,0,(char)0x04, -1,+2,+1,+0,1,(char)0x04, -1,+2,+1,+1,0,(char)0x04,+0,-2,+0,+0,1,(char)0x80, +0,-1,+0,+1,1,(char)0x88, +0,-1,+1,-2,0,(char)0x40,+0,-1,+1,+0,0,(char)0x11, +0,-1,+2,-2,0,(char)0x40, +0,-1,+2,-1,0,(char)0x20,+0,-1,+2,+0,0,(char)0x30, +0,-1,+2,+1,1,(char)0x10, +0,+0,+0,+2,1,(char)0x08,+0,+0,+2,-2,1,(char)0x40, +0,+0,+2,-1,0,(char)0x60, +0,+0,+2,+0,1,(char)0x20,+0,+0,+2,+1,0,(char)0x30, +0,+0,+2,+2,1,(char)0x10, +0,+1,+1,+0,0,(char)0x44,+0,+1,+1,+2,0,(char)0x10, +0,+1,+2,-1,1,(char)0x40, +0,+1,+2,+0,0,(char)0x60,+0,+1,+2,+1,0,(char)0x20, +0,+1,+2,+2,0,(char)0x10, +1,-2,+1,+0,0,(char)0x80,+1,-1,+1,+1,0,(char)0x88, +1,+0,+1,+2,0,(char)0x08, +1,+0,+2,-1,0,(char)0x40,+1,+0,+2,+1,0,(char)0x10}, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };

2.2 C++11的原始字符串与宏定义R产生的错误

这个错误是因为gcc 5.4这里支持的是C++ 11的标准,C++11中引入了原始字符串的新特性,使用R""方式来定义一个不进行转义的字符串。而在FreeImage的一些代码中,使用了R作为一些宏函数的参数,导致一些场合会将其当做是一个原始字符串。

先来看一下报错信息

Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:37:34: 错误:原始字符串分隔符中有无效字符‘ ’"shll_s.w         %["#R"],      %["#R"],        9              \n\t"     \^
Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:37:48: 错误:原始字符串分隔符中有无效字符‘ ’"shll_s.w         %["#R"],      %["#R"],        9              \n\t"     \^
Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:40:34: 错误:原始字符串分隔符中有无效字符‘ ’"precrqu_s.qb.ph  %["#R"],      %["#R"],        $zero          \n\t"     \^
Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:40:48: 错误:原始字符串分隔符中有无效字符‘ ’"precrqu_s.qb.ph  %["#R"],      %["#R"],        $zero          \n\t"     \^
Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:43:34: 错误:原始字符串分隔符中有无效字符‘ ’"srl              %["#R"],      %["#R"],        24             \n\t"     \^
Source/LibWebP/./src/dsp/dsp.upsampling_mips_dsp_r2.c:43:48: 错误:原始字符串分隔符中有无效字符‘ ’"srl              %["#R"],      %["#R"],        24             \n\t"     \

报错的文件是dsp.upsampling_mips_dsp_r2.c。这是一个.c的文件,使用gcc编译也会出现这个错误。

报错的代码如下(dsp.upsampling_mips_dsp_r2.c 22-49)

#if !defined(WEBP_YUV_USE_TABLE)#define YUV_TO_RGB(Y, U, V, R, G, B) do {                                      \
    const int t1 = kYScale * Y;                                                \
    const int t2 = kVToG * V;                                                  \
    R = kVToR * V;                                                             \
    G = kUToG * U;                                                             \
    B = kUToB * U;                                                             \
    R = t1 + R;                                                                \
    G = t1 - G;                                                                \
    B = t1 + B;                                                                \
    R = R + kRCst;                                                             \
    G = G - t2 + kGCst;                                                        \
    B = B + kBCst;                                                             \
    __asm__ volatile (                                                         \
      "shll_s.w         %["#R"],      %["#R"],        9              \n\t"     \
      "shll_s.w         %["#G"],      %["#G"],        9              \n\t"     \
      "shll_s.w         %["#B"],      %["#B"],        9              \n\t"     \
      "precrqu_s.qb.ph  %["#R"],      %["#R"],        $zero          \n\t"     \
      "precrqu_s.qb.ph  %["#G"],      %["#G"],        $zero          \n\t"     \
      "precrqu_s.qb.ph  %["#B"],      %["#B"],        $zero          \n\t"     \
      "srl              %["#R"],      %["#R"],        24             \n\t"     \
      "srl              %["#G"],      %["#G"],        24             \n\t"     \
      "srl              %["#B"],      %["#B"],        24             \n\t"     \
      : [R]"+r"(R), [G]"+r"(G), [B]"+r"(B)                                     \
      :                                                                        \
    );                                                                         \
  } while (0)

上面代码中的第16行起,有多处是R"],的形式。这里编译器会将其当做一个原始字符串,从而导致错误。
做如下修改,将所有的R都使用Red替代。

#if !defined(WEBP_YUV_USE_TABLE)#define YUV_TO_RGB(Y, U, V, Red, G, B) do {                                      \
    const int t1 = kYScale * Y;                                                \
    const int t2 = kVToG * V;                                                  \
    Red = kVToR * V;                                                             \
    G = kUToG * U;                                                             \
    B = kUToB * U;                                                             \
    Red = t1 + Red;                                                                \
    G = t1 - G;                                                                \
    B = t1 + B;                                                                \
    Red = Red + kRCst;                                                             \
    G = G - t2 + kGCst;                                                        \
    B = B + kBCst;                                                             \
    __asm__ volatile (                                                         \
      "shll_s.w         %["#Red"],      %["#Red"],      9              \n\t"     \
      "shll_s.w         %["#G"],        %["#G"],        9              \n\t"     \
      "shll_s.w         %["#B"],        %["#B"],        9              \n\t"     \
      "precrqu_s.qb.ph  %["#Red"],      %["#Red"],      $zero          \n\t"     \
      "precrqu_s.qb.ph  %["#G"],        %["#G"],        $zero          \n\t"     \
      "precrqu_s.qb.ph  %["#B"],        %["#B"],        $zero          \n\t"     \
      "srl              %["#Red"],      %["#Red"],      24             \n\t"     \
      "srl              %["#G"],        %["#G"],        24             \n\t"     \
      "srl              %["#B"],        %["#B"],        24             \n\t"     \
      : [R]"+r"(R), [G]"+r"(G), [B]"+r"(B)                                     \
      :                                                                        \
    );                                                                         \
  } while (0)

这个错误还会出现在Source/LibWebP/./src/dsp/dsp.yuv_mips_dsp_r2.c文件中,修改的方式是一样的。

2.3 tmpnam与mkstemp的选择

这并不是一个错误,只是一个警告。

Source/LibJXR/./image/encode/strenc.o:在函数‘StrIOEncInit’中:
strenc.c:(.text+0x17cc): 警告: the use of `tmpnam' is dangerous, better use `mkstemp'

tmpnam函数是危险的,建议使用mkstemp。原因是mkstemp调用完成后,就已经生成并打开了一个临时文件,而tmpnam只是生成了一个临时文件的文件名,并没有创建文件,不能保证其一定不存在!!!
这里就不做修改了。

2.4 安装到指定目录

sudo make install 默认在usr/lib目录下面。

我们可以使用如下命令指定安装目录。

> sudo make DESTDIR=/home/o/code/freeimage install
[sudo] o 的密码:
make -f Makefile.gnu install
make[1]: Entering directory '/media/o/work/development_library/FreeImage'
install -d /home/o/code/freeimage/usr/include /home/o/code/freeimage/usr/lib
install -m 644 -o root -g root Source/FreeImage.h /home/o/code/freeimage/usr/include
install -m 644 -o root -g root libfreeimage.a /home/o/code/freeimage/usr/lib
install -m 755 -o root -g root libfreeimage-3.17.0.so /home/o/code/freeimage/usr/lib
ln -sf libfreeimage-3.17.0.so /home/o/code/freeimage/usr/lib/libfreeimage.so.3
ln -sf libfreeimage.so.3 /home/o/code/freeimage/usr/lib/libfreeimage.so
make[1]: Leaving directory '/media/o/work/development_library/FreeImage'

到安装目录下查看一下

/home/o/code/freeimage/usr [o@o-pc] [12:05]
> tree
.
├── include
│   └── FreeImage.h
└── lib├── libfreeimage-3.17.0.so├── libfreeimage.a├── libfreeimage.so -> libfreeimage.so.3└── libfreeimage.so.3 -> libfreeimage-3.17.0.so2 directories, 5 files

3、VS2015进行编译

我当前下载的版本,里面没有带VS2015的工程文件。但是有VS2005/2008/2013的。

直接使用VS2015打开源码目录下的FreeImage.2013.sln文件,然后升级 VC++ 编译器和库

3.1 源码的修改

1、将文件tif_config.h中的

#ifdef _WIN32
#define snprintf _snprintf  // 将此行注释掉
#define lfind _lfind
#endif // _WIN32

修改为

#ifdef _WIN32
//#define snprintf _snprintf
#define lfind _lfind
#endif // _WIN32

早期的VC自带的C标准库中确实没有snprintf这个函数,只有_snprintf。但是VS2015下是有的,所以这里不注释掉会有重定义的问题。
也可以修改为

#ifdef _WIN32
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define lfind _lfind
#endif // _WIN32

3.2 编译和生成

直接构建解决方案即可。编译完成后可以到源码目录下的 Dist目录拷贝 FreeImage.h和库文件。

linux FreeImage安装编译相关推荐

  1. Linux Ubuntu 安装编译Opencv 3.4.3 C++开发环境

    在安装Autoware之前,需要先安装Opencv,之前在Windows下安装了Opencv,挺复杂的.不过,在Ubuntu 16.04环境中配置安装Opencv相对来说,比较简单. Linux Ub ...

  2. FFmpeg学习之路:Linux下安装编译

    FFmpeg学习之路:Linux下安装编译 文章目录 FFmpeg学习之路:Linux下安装编译 前言 一.下载FFmpeg 二.准备工作 1.安装yasm的汇编编译器 2.安装SDL2 三.编译安装 ...

  3. linux 服务器 安装网卡驱动,linux下安装编译网卡驱动的方法

    安装linux操作系统后发现没有网卡驱动,表现为 system → Administration → Network下Hardware列表为空. 以下为安装编译网卡驱动的过程,本人是菜鸟,以下是我从网 ...

  4. linux下安装编译网卡驱动

    安装linux操作系统后发现没有网卡驱动,表现为 system → Administration → Network下Hardware列表为空. 以下为安装编译网卡驱动的过程,本人是菜鸟,以下是我从网 ...

  5. linux内核安装编译

    Linux内核下载及编译 下载Linux内核 可以从官网下载linux内核,也可以通过第三方网站进行下载. 官网网址:https://www.kernel.org/. 由于官网可能存在被墙的原因,所以 ...

  6. linux下运行htk,Linux下安装编译并且测试HTK语音识别库

    决定写一个linux下的HTK的安装和测试,如果有人想看windows下的,可以看我之前的那篇文章 http://www.linuxidc.com/Linux/2013-03/80801.htm. 首 ...

  7. linux 编译hadoop,linux centos 安装编译hadoop2.7.1

    因为Apache hadoop 只提供了32位的包,所以需要自己编译64位的包,下面是编译步骤 所需要的包 6:java 1.7+ 下面是具体安装: 1:Java安装 安装之前请卸载系统自带的jdk, ...

  8. linux删除编译中间件,关于linux 里安装编译环境和中间件

    这里只是在参考其他博主的操作上,提出一些自己操作时出现的问题,仅供参考. 1. 安装jdk 链接:https://blog.csdn.net/pang_ping/article/details/805 ...

  9. opencv4.0.1配合contrib在linux下面安装编译全过程

    环境: opencv:4.0.1 opencv_contrib:4.0.1 使用git checkout获得上述两个版本即可,不要重复去下载压缩包 ubuntu18.10 需要下载的东西: ippic ...

最新文章

  1. Faster-RCNN 自己的数据训练
  2. 数据库范式1NF 2NF 3NF BCNF
  3. 【转】mac os、linux及unix之间的关系
  4. PHP不同域名cookie共享(单点登录实现原理)
  5. 为什么c语言要定义变量,C语言为什么要规定对所用到的变量要“先定义,后使用”...
  6. Kubernetes系列之Helm介绍篇
  7. 手指甲上的月牙辨健康,月牙会“丢”也能“长回来”
  8. Gitter - 高颜值GitHub小程序客户端诞生记
  9. 随想录(thread类的编写)
  10. 2万亿市值公司的网络运营技术解密
  11. vim 配置文件 (未完待续)
  12. DL实战(2):SiamFC - TensorFlow配置
  13. layui中table表格的操作列(删除,编辑)等按钮的操作
  14. 打开计算机不显示百度云管家,百度云管家怎么打不开电脑上的百度云管家打不开的解决方法...
  15. SoC设计与验证——大型IP——PCIE控制器
  16. 机器学习与神经网络绪论
  17. GD32F303调试小记(零)之工程创建与编译
  18. 从狗屁不通文章生成器,到机器写作之路
  19. 高考改革后计算机老师,高考改革“漏洞”多?2020新高考选科数据曝光!这是选科最佳组合...
  20. idea中创建scala的worksheet第五章

热门文章

  1. openstack(Queens版) 安装FWaaS
  2. gearman php 进程守护,用 Gearman 分发 PHP 应用程序的工作负载
  3. ubuntu mysql5.6 编译安装_Ubuntu14.04编译安装mysql5.6.26
  4. java 共享锁 独占锁_Java并发编程锁之独占公平锁与非公平锁比较
  5. 小学计算机课计划,小学信息技术教学工作计划
  6. c中写汇编语言,将汇编程序写在一个文件里,能否直接在C中调用
  7. python中remove函数是什么意思,python中pop函数和remove函数有什么区别
  8. 今日运势 酷q_一言及每日运势API开源
  9. 仍然报错_详解oracle经典报错:ORA-04030排错思路和解决方法
  10. 分库分表 vs NewSQL数据库