转:http://my.oschina.net/1pei/blog/479162

PNG格式:每个PNG文件是由一个PNG标识(signature),后面跟一些数据块(chunk),每个chunk由

一个chunk类型来标识其功能。

摘要 本文解决了Android Studio 1.2.2下编译期间出现的libpng warning: iCCP: Not recognizing known sRGB profile that has been edited警告问题。

1. 问题描述

在Android Studio 1.2.2下编译期间,出现了下面警告信息:

...\res\drawable-hdpi\add_green.png: libpng warning: iCCP: Not recognizing known sRGB profile that has been edited

baidu和google,有一些网友是非png格式的图片(例如jpg格式等)而错误地采用了png为后缀,也会出现上述告警信息,可参见[7],本文不考虑这些情况。

其他网友的回答基本上都是:原因是新版本的libpng对关于iCCP采用了更严苛的约束。但是是从哪个libpng版本开始严格检查,主要是检查哪些内容导致的告警信息呢?基本上没有看到答案。

本文先学习下PNG文件格式,然后了解下libpng, 再来分析和解决这个警告信息。

2. PNG文件格式

[2]是WWW PNG的规范,[3]是通过例子来介绍PNG文件格式中文编写,下面材料主要来自于这两份文档。

每个PNG文件是由一个PNG标识(signature),后面跟一些数据块(chunk)组成,每个chunk由一个chunk类型来标识其功能。

2.1 PNG标识(signature)

每个PNG文件的前8个字节总是包含以下值:

十进制   137 80 78 71 13 10 26 10
十六进制  89 50 4E 47 0D 0A 1A 0A

第一个字节0x89超出了ASCII字符的范围,这是为了避免某些软件将PNG文件当做文本文件来处理。

2.2 数据块(chunk)

在png规范[2]中总计定义了18种chunk,其中4类chunk是关键数据块(critical chunk),每个PNG文件都必须包含它们,其余14类为辅助数据块(ancillary chunks),这是可选的数据块。

2.2.1 4类关键chunk

IHDR: image header, 在PNG文件中位置为第一块chunk.

PLTE: 调色板(palette table), 位于IDAT块之前.

IDAT: 图像数据块, 可以有多个连续的IDAT块.

IEND: image trailer, 在PNG文件中位置为最后一块chunk.

2.2.2 14类辅助chunk

14类辅助chunk可以归类为以下几种:

a. Transparency information(透明信息)

tRNS(Transparency-透明)

b. Colour space information(颜色空间信息)

cHRM(Primary chromaticities and white point:基色与白色点)

gAMA(Image gamma:图像gamma)

iCCP(Embedded ICC profile:内嵌ICC profile)

sBIT(Significant bits:样本有效位)

sRGB(Standard RGB colour space:标准RGB颜色空间)

c. Textual information(文本信息)

iTXt(International textual data: 国际化文本数据)

tEXt(Textual data:文本数据)

zTXt(Compressed textual data: 压缩文本数据)

d. Miscellaneous information(其他信息)

bKGD(Background colour:背景颜色)

hIST(Image histogram:图像直方图)

pHYs(Physical pixel dimensions:物理像素尺寸)

sPLT(Suggested palette:建议调色)

e. Time information(时间信息)

tIME(Image last-modification time: 图像最后修改时间)

2.2.3 chunk格式

每一块chunk由3个或4个字段组成。

Length (长度)                       4字节    指定Chunk Data字段的长度,可以为0, 不超过(2^31-1)字节

Chunk Type(数据块类型)      4字节    数据块类型由ASCII字母(A-Z和a-z)组成,

每个字节的bit 5表示chunk属性, 可参见[2]中5.4 Chunk naming conventions

Chunk Data (数据块数据)     可变长度  存储按照Chunk Type指定的数据

CRC (循环冗余检测)               4字节     存储用来检测是否有错误的循环冗余码

[2]中5.6 Chunk ordering描述了每一类chunk在PNG文件中的顺序。

IEND chunk中没有data字段,因此Length字段为0, IEND chunk为以下12个字节(十六进制):

00 00 00 00 49 45 4E 44 AE 42 60 82

前4个字节为00 00 00 00,Type总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82,每个PNG文件最后12字节都是相同的。

3. libpng

[4]是libpng官方首页,从介绍中可知道它是用ANSI C (C89)编写,需要zlib 1.0.4/1.2.5及更高版本。当前最新版本是1.6.17(2015-07-16),从1.6源码 http://sourceforge.net/p/libpng/code/ci/libpng16/tree/CHANGES 可看出1.6.18正式版本正即将发布。

在该官网首页有以下漏洞警告信息:

libpng versions 1.6.9 through 1.6.15 (and some subset of versions up through 1.5.20) have an integer-overflow vulnerability in png_combine_row() when decoding very wide interlaced images, which can allow an attacker to overwrite an arbitrary amount of memory with arbitrary (attacker-controlled) data. This vulnerability has been assigned ID CVE-2014-9495 and is fixed in versions 1.6.16 and 1.5.21, released on 21 December 2014.

因此推荐尽可能使用最新版本的linpng。

4. 问题分析与解决

前面简要分析了PNG文件格式中的chunk, 以及libpng后,下面就开始分析和解决前面遇到的警告问题:

...\res\drawable-hdpi\add_green.png: libpng warning: iCCP: Not recognizing known sRGB profile that has been edited

4.1 iCCP chunk分析

还是需要先分析下iCCP chunk, 其chunk type为十六进制的69 43 43 50(iCCP)。参考[2]中11.3.3.3 iCCP Embedded ICC profile, 可以看出,iCCP chunk包含的data字段为:

Profile name       1-79 bytes (character string)

Null separator    1 byte (null character)

Compression method   1 byte

Compressed profile      n bytes

其中,profile name是大小写敏感的,只能包含可打印拉丁字符与空格(即范围为十进制字符 32-126 与161-255 ), 不允许在前面与后面存在空格,不允许中间有多个连续空格。压缩方法只能取值为0,0表示对zlib数据流采用deflate压缩,接下来是压缩的profile.

每个PNG文件中最多只能包含一个内嵌profile, 可通过在iCCP chunk中显式指定或在sRGB chunk中隐含指定。

4.2 出问题PNG图片iCCP chunk分析

下面是出问题add_green.png文件中包含的iCCP chunk截图:

iCCP数据块各字段的含义:

十六进制值 描    述 
00 00 0A 4F iCCP数据块的长度,00 00 0A 4F =十进制2639
69 43 43 50 数据块类型标志,69 43 43 50的ASCII值等于iCCP

50 68

6F 74 6F 73 68 6F 70 20 49 43 43 20 70 72 6F 66

69 6C 65 00

Profile名称,长度1~79字节,

以0作为终止符的字符串,

ASCII值等于Photoshop ICC profile

00 压缩方法,0表示使用deflate压缩
78 DA 9D 53~03 98 F3 FC 压缩的profile,解码时使用
63 33 2D DB CRC

因此,这里的iCCP chunk的data字段从0x3D开始,由于长度为0A 4F, 因此data字段范围为0x00 3D~ 0A 8C。

4.3 libpng代码分析

从 http://sourceforge.net/p/libpng/code/ci/libpng16/tree/  下载代码,可看到告警信息是在int png_compare_ICC_profile_with_sRGB( )函数中出现的:

通过检查http://sourceforge.net/p/libpng/code/ci/d630301d996b152de09028bb6803c4c136a0e85f/log/?path=%2Fpng.c, 可看到png.c中这个函数是在2012.03.29由 John Bowler新增的,修改注释信息为:

[libpng16] Recognize known sRGB ICC profiles while reading; prefer writing the iCCP profile over writing the sRGB chunk, controlled by the PNG_sRGB_PROFILE_CHECKS option.

代码中利用PNG_ICC_CHECKSUM宏来定义数组png_sRGB_checks[]中的一项,每一项的结构字段包括adler crc, length, MD5[4], have_md5, is_broken, intent, 见下图:

PNG_ICC_CHECKSUM宏里后三个参数date, length, file-name只是用于标记。

// 以下4个ICC sRGB profiles是来自于 www.color.org, 每个都有MD5校验码

下面3个profiles没有明确的MD5校验码,如果匹配空的MD5则用其他字段来尝试匹配并给出警告。下面这些profiles中前两个有一个'cprt' tag, 表示它们是由HP(Hewlett Packard)创建的。

根据png_compare_ICC_profile_with_sRGB( )函数中的逻辑,遍历png_sRGB_checks[]数组,当.md5[4]与profile中的md5值相同,length, intent, adler也相同,但重新计算的crc不等时,就将提示“Not recognizing known sRGB profile that has been edited”警告信息。

在scripts/pnglibconf.dfa文件中说明了本次修改的意图以及缺省检查级别为2的理由:

setting sRGB_PROFILE_CHECKS default 2

详细可参见[5]。

4.4 警告信息分析

结合libpng中png.c文件 png_compare_ICC_profile_with_sRGB( )函数可以看出,当profile的许多字段都相同时,如果crc不等则提示“Not recognizing known sRGB profile that has been edited”警告信息。

前面对出问题add_green.png文件分析可得出iCCP chunk中压缩的profile的最后四个字节是03 98 F3 FC, 对应的就是png_sRGB_checks[]数组中最后一个profile的adler字段:

PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,

PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,

"1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")

因此,这张图的iCCP profile file name就是"HP-Microsoft sRGB v2 media-relative"。

https://github.com/madler/zlib/blob/master/zlib.h 中struct z_stream可以看出:

uLong   adler;      /* adler32 value of the uncompressed data */

字段adler就是未压缩数据的adler值。那么这个adler字段是做什么用的呢?根据[6], Adler-32校验和在zlib中作为CRC32几乎是可靠的,但是计算起来更快,将iCCP profile data压缩后就追加在data后面。adler其实就是创始人Mark Adler的名字。

4.5 回答第一章节中提出的问题

综上,通过对PNG文件格式中iCCP chunk中profile的分析,libpng中png.c文件的分析,www.color.org中ICC sRGB profiles的说明,以及对zlib.h中adler32的分析,可以得出以下结论:

当PNG图片中iCCP chunk中压缩的profile在处理时,当md5, length, intent, adler32等字段相同,但重新计算的crc不等时则提示“Not recognizing known sRGB profile that has been edited”警告信息。

上述警告信息在2012.03.29由 John Bowler新增的png_compare_ICC_profile_with_sRGB( )函数在检查时给出,即libpng 1.6.0正式版本中引入这个检查函数。

4.6 问题解决

明确了linpng严格检查的版本以及检查的内容后,那么如何来解决该问题呢。

4.6.1 解决方案1: 删除png图片内嵌的iCCP profile sRGB

[13, 16, 17]中有一些答案建议通过Image Magick/mogrify/GIMP/exiftool等工具来"convert"或"mogrify"图片,删除png图片中内嵌的iCCP profile sRGB:

Image Magick使用举例:

删除单个png文件内的profile:  % convert -strip <input filename> <output filename>

批量删除所有png文件内的profile sRGB:

set fn=E:\Program Files\ImageMagick-6.9.0-Q16\convert.exe

for /f "tokens=*" %%i in ('dir/s/b *.png') do "%fn%" "%%i" -strip "%%i"

mogrify使用举例:

删除单个png文件内的profile sRGB:  mogrify +profile sRGB <png file>

批量删除所有png文件内的profile sRGB:

find <path to res folder> -name *.png -exec mogrify +profile sRGB {}  \;

GIMP使用举例:

删除内嵌profile, 可先进入Image > Mode > Assign Color Profile并设置为RGB workspace(sRGB built-in), 然后File > Overwrite add_green.png覆盖原来的png文件。

修改内嵌profile, 可进入Image > Mode > Convert to Color Profile, 可选择一种profile。

在[17]也还提到:libpng 1.6+更严格的检查会对original HP/MS sRGB profile报警。老的profile使用D50 whitepoint, 而D65才是标准。这种profile由Adobe Photoshop使用, 虽然缺省在png图片中并不嵌入该profile。最简单的方法是从图片中删除内嵌的profile,但这会导致颜色有稍许偏差(当有颜色校正系统时)。但如果不希望颜色有偏差(例如用于打印输出), 可以嵌入另一种不同的颜色profile。

[13]中也有网友指出:这样删除png图片中的iCCP profile sRGB, 将丢失如何来render图片等信息,png中的色彩可能被改变。

4.6.2 解决方案2:  将aRGB转换为sRGB

[14]中有网友提到:这个图片是sRGB的改成ARGB(Adobe RGB)的就可以啦,在Android  Studio中的右上角会显示24位而ARGB的图片显示是32位,但我本地报这种警告的png图片除了有32位以外还有24位的,因此这个方案不太可行。

综合上面的意见,[17]中给出的结论比较令人信服,利用GIMP工具删除内嵌的profile后问题解决。

5. 参考资料

[1] Libpng 1.6.17 - March 26, 2015, http://www.libpng.org/pub/png/src/libpng-1.6.17-README.txt

[2] Portable Network Graphics (PNG) Specification (Second Edition), http://www.w3.org/TR/2003/PR-PNG-20030520/

[3] PNG文件结构分析, http://wenku.baidu.com/view/b87e978583d049649b66586a.html?re=view

[4] libpng官方, http://libmng.com/pub/png/libpng.html

[5] [libpng16] Recognize known sRGB ICC profiles while reading, http://sourceforge.net/p/libpng/code/ci/921648a997e733eb63e18e835a9b98a5507da197/

[6] zlib库剖析(1):实现概览, http://blog.csdn.net/zhoudaxia/article/details/8034606

[7] 图片资源添加出现问题: No resource found that matches the given name 安卓 maven编译, http://1985wanggang.blog.163.com/blog/static/77638332015011114647601/

[8] zlib Technical Details, http://www.zlib.net/zlib_tech.html

[9] 漫谈显示器色彩管理(一), http://zhuanlan.zhihu.com/hardware/19648994

[10] 漫谈显示器色彩管理(二), http://zhuanlan.zhihu.com/hardware/19649559

[11] 漫谈显示器色彩管理(三), http://zhuanlan.zhihu.com/hardware/19649897

[12] 漫谈显示器色彩管理(四), http://zhuanlan.zhihu.com/hardware/19651812

[13] Issue 77704: Built tools 21.0.1: multiple libpng warnings, https://code.google.com/p/android/issues/detail?id=77704

[14] AndroidStudio中\com.android.support错误如何解决, http://ask.csdn.net/questions/161424

[15] sRGB与aRGB的颜色设置转换, http://blog.sina.com.cn/s/blog_6cf45fc10102v81s.html

[[16] libpng warning: iCCP: Not recognizing known sRGB profile that has been edited, https://groups.google.com/forum/#!msg/adt-dev/rjTQ_STR3OE/-UcNQRISTKsJ

[17] libpng errors, https://wiki.archlinux.org/index.php/Libpng_errors

[18] GIMP, http://www.gimp.org/

android studio问题-ICCP:Not recognizing known sRGB profile的更多相关文章

  1. Android Studio:libpng warning: iCCP: Not recognizing known sRGB profile that has been edited解决办法

    把以前的eclipse的项目导入Android Studio中,Build项目的时候,出现了一堆错误. 如下: AAPT err(Facade for 1944774242): ERROR: 9-pa ...

  2. 【Xamarin报错】libpng warning : iCCP: Not recognizing known sRGB profile that has been edited

    报错: Xamarin Android 编译时发生以下错误: libpng warning : iCCP: Not recognizing known sRGB profile that has be ...

  3. AS问题解决系列3—iCCP: Not recognizing known sRGB profile

    http://my.oschina.net/1pei/blog/479162 摘要 本文解决了Android Studio 1.2.2下编译期间出现的libpng warning: iCCP: Not ...

  4. libpng warning:iCCP:known incorrect sRGB profile

    原因是新版的libpng增强了检查,发出警告.此警告可以忽略.若要消除此警告则要使用v4的色彩配置.GIMP sRGB v4 色彩配置,修改当前图片的色彩配置,设为默认. sRGB profilesO ...

  5. 如何将ADT项目导入Android studio及常見問題

    ADT导出Android studio项目 右键-->ExportAndroid/Generate Gradle build files--> Android studio导入项目 Fil ...

  6. Android Studio添加PNG图片报错原因

    今天在网上看到一个关于Splash Activity的Android帖子,博主在一通讲解之后也给出了代码.于是果断下载下来了看看怎么实现的.一步步照着流程把这个功能实现了一遍.一切都没有大问题,但是在 ...

  7. 团队项目-BUG排查-ADT工程 To Android Studio 一整天的排查日记

    4-22 10:44至4-23 0:45 ①打开Eclipse从Github上Clone MathsApp到本机,报错'Unable to resolve target'android-19' ②尝试 ...

  8. Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记

    以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...

  9. Android Studio 多个编译环境配置 多渠道打包 APK输出配置

    看完这篇你学到什么: 熟悉gradle的构建配置 熟悉代码构建环境的目录结构,你知道的不仅仅是只有src/main 开发.生成环境等等环境可以任意切换打包 多渠道打包 APK输出文件配置 需求 一般我 ...

随机推荐

  1. 17Mybatis_动态sql-sql片段

    这篇文章讲一下sql片段. 讲一下sql片段的的需求: 将上边实现的动态sql判断代码块抽取出来,组成一个sql片段.其它的statement中就可以引用sql片段. 方便程序员进行开发. 第一步我们 ...

  2. 【C#】ContextMenuStrip 右键菜单颜色设置

    有些时候自己想要修改ContexMenuStrip右键菜单的一些背景色之类的,该如何实现呢? 首先: ContextMenuStrip _context = new ContextMenuStrip( ...

  3. AVR/Arduino定时/计数器、中断入门

    在Arduino中,可以使用AnalogWrite来使用硬件产生490Hz/980Hz的pwm波,并可根据参数来设定占空比.不了解这个的同学可以去AnalogWrite学习下,SecretsOfArd ...

  4. 墙国内新建Rails应用的要点(windows 7环境, Rails 4.2.0)

    1. 使用rails new 命令创建完的应用在自动执行bundle install不会成功,根据出错提示,判断原因有可能是被墙与https的证书的安全性问题. 作为开发环境,选用绕开的办法,在目录  ...

  5. [转]2006 MySQL server has gone away错误,最大值溢出解决办法 mysql max_allowed_packet 查询和修改

    From : http://www.cnblogs.com/huangcong/archive/2013/03/26/2981790.html 1.应用程序(比如PHP)长时间的执行批量的MYSQL语 ...

  6. 多个相同jar存在时的引用顺序

    起因:今天一个aar包在测试环境中正常运行,使用soapui测试正常返回,在本地环境中运行则老是报数据库连接异常,经检查,是因为在运行时环境中缺少ojdbc相关的jar包引起的. 重新打了一个aar包 ...

  7. 淘宝SKU组合查询算法实现

    淘宝SKU组合查询算法实现 2015-11-14 16:18 1140人阅读 评论(0) 收藏 举报  分类: JavaScript(14)    目录(?)[+]   前端有多少事情可以做,能做到多 ...

  8. 实现可以滑动的GrildView,类似美团网首页的GrildView功能菜单

    首先上实现效果图,不会做动态图,就先凑合着看吧 使用了网上的一个开源控件viewpagerindicator,可以自定义切换时候显示的标记,圆点,或者下划线. GrildView显示的是手机上的全部a ...

  9. 用postgreSQL做基于地理位置的app(zz)

    前言:项目中用到了postgreSQL中的earthdistance()函数功能计算地球上两点之间的距离,中文的资料太少了,我找到了一篇英文的.讲的很好的文章,特此翻译,希望能够帮助到以后用到eart ...

  10. Hash中的一些概率计算

    Hash是把锋利的刀子,处理海量数据时经常用到,大家可能经常用hash,但hash的有些特点你是否想过.理解过.我们可以利用我们掌握的概率和期望的知识,来分析Hash中一些有趣的问题,比如: 平均每个 ...