AS問題解決系列3—iCCP: Not recognizing known sRGB profile



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/

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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章