ImageMagick-6.9.8-4差分

ImageMagick-6.9.8-3差分 - yoyaのメモの続き

The latest release of ImageMagick is version 6.9.8-4

まとめ

  • OpenCL 性能改善
  • PCD 書き出し不具合修正
  • ICC ベース PDF 対応
  • PerlMagick の quantum で Property セットのついでに Artifacts セットも行う改造
  • copyright や参照 URL スキームを http から https
  • -Wno-suggest-attribute=format のない環境でもビルドできるようにした
  • JPEG2000 の読み込みで、YCbCr, YUV 色空間の判断処理が変わったので注意。
  • PCX (IBMペイントブラシ形式) の読み込みで planes==0 の時に弾く処理が入っている。(0のまま処理続くと相当まずい。。)
  • SVG 周りにかなり手が入っている
    • SVGDensityGeometry 相当の値が 90.0x90.0 と 96.0x96.0 で揺れていたので後者に統一。
    • イプシロン比較前に abs を入れたり。(負の側で値がはみ出ても イプシロン内と判定されてた)
  • RGBTransformImage で YCCColorspace 変換テーブルを作成する時の係数を修正。
  • security policy の virtual memory mapping 周りの対応を追加。
  • FormatMagickSize の実数(%g)精度に GetMagickPrecision を使う。
    • + があったら終端にさせる。

差分

1083,1084c1083,1084
<       *q++='\0';
<       return(q-utf16);
---
>       *q++=(wchar_t) '\0';
>       return((size_t) (q-utf16));
1113c1113
<   return(p-utf8);
---
>   return((size_t) (p-utf8));
1243a1244
>     *device,
1246a1248,1250
>   const StringInfo
>     *profile;
>
1294a1299
>     channels,
1349a1355,1357
>   profile=GetImageProfile(image,"icc");
>   if (profile != (StringInfo *) NULL)
>     version=(size_t) MagickMax(version,7);
2177c2185
<     (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g 0 obj\n",(double)
---
>     (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g 0 obj\n",(double)
2179a2188,2189
>     device="DeviceRGB";
>     channels=0;
2181c2191,2194
<       (void) CopyMagickString(buffer,"/DeviceCMYK\n",MaxTextExtent);
---
>       {
>         device="DeviceCMYK";
>         channels=4;
>       }
2187c2200,2203
<           (void) CopyMagickString(buffer,"/DeviceGray\n",MaxTextExtent);
---
>         {
>           device="DeviceGray";
>           channels=1;
>         }
2189,2190c2205,2206
<         if ((image->storage_class == DirectClass) || (image->colors > 256) ||
<             (compression == JPEGCompression) ||
---
>         if ((image->storage_class == DirectClass) ||
>             (image->colors > 256) || (compression == JPEGCompression) ||
2192c2208,2216
<           (void) CopyMagickString(buffer,"/DeviceRGB\n",MaxTextExtent);
---
>           {
>             device="DeviceRGB";
>             channels=3;
>           }
>     profile=GetImageProfile(image,"icc");
>     if ((profile == (StringInfo *) NULL) || (channels == 0))
>       {
>         if (channels != 0)
>           (void) FormatLocaleString(buffer,MagickPathExtent,"/%s\n",device);
2194,2195c2218,2219
<           (void) FormatLocaleString(buffer,MaxTextExtent,
<             "[ /Indexed /DeviceRGB %.20g %.20g 0 R ]\n",(double) image->colors-
---
>           (void) FormatLocaleString(buffer,MagickPathExtent,
>             "[ /Indexed /%s %.20g %.20g 0 R ]\n",device,(double) image->colors-
2197c2221,2262
<     (void) WriteBlobString(image,buffer);
---
>         (void) WriteBlobString(image,buffer);
>       }
>     else
>       {
>         const unsigned char
>           *p;
>
>         /*
>           Write ICC profile.
>         */
>         (void) FormatLocaleString(buffer,MagickPathExtent,
>           "[/ICCBased %.20g 0 R]\n",(double) object+1);
>         (void) WriteBlobString(image,buffer);
>         (void) WriteBlobString(image,"endobj\n");
>         xref[object++]=TellBlob(image);
>         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g 0 obj\n",
>           (double) object);
>         (void) WriteBlobString(image,buffer);
>         (void) FormatLocaleString(buffer,MagickPathExtent,"<<\n/N %.20g\n"
>           "/Filter /ASCII85Decode\n/Length %.20g 0 R\n/Alternate /%s\n>>\n"
>           "stream\n",(double) channels,(double) object+1,device);
>         (void) WriteBlobString(image,buffer);
>         offset=TellBlob(image);
>         Ascii85Initialize(image);
>         p=GetStringInfoDatum(profile);
>         for (i=0; i < (ssize_t) GetStringInfoLength(profile); i++)
>           Ascii85Encode(image,(unsigned char) *p++);
>         Ascii85Flush(image);
>         offset=TellBlob(image)-offset;
>         (void) WriteBlobString(image,"endstream\n");
>         (void) WriteBlobString(image,"endobj\n");
>         /*
>           Write Length object.
>         */
>         xref[object++]=TellBlob(image);
>         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g 0 obj\n",
>           (double) object);
>         (void) WriteBlobString(image,buffer);
>         (void) FormatLocaleString(buffer,MagickPathExtent,"%.20g\n",(double)
>           offset);
>         (void) WriteBlobString(image,buffer);
>       }
2831c2896
<         WriteBlobMSBShort(image,(unsigned short) utf16[i]);
---
>         (void) WriteBlobMSBShort(image,(unsigned short) utf16[i]);
ChangeLogにない差分
  • Magick++/lib/Drawable.cpp
    • 引数名を正しくする。(動作は変わらないはず)
<   DrawRoundRectangle( context_, _centerX,_centerY, _width,_hight,
<                       _cornerWidth, _cornerHeight);
---
>   DrawRoundRectangle(context_,_upperLeftX,_upperLeftY,_lowerRightX,
>     _lowerRightY,_cornerWidth, _cornerHeight);
  • Magick++/lib/Magick++/Drawable.h
1437,1438c1437,1438
<   DrawableRoundRectangle ( double centerX_, double centerY_,
<                            double width_, double hight_,
---
>   DrawableRoundRectangle ( double upperLeftX_, double upperLeftY_,
>                            double lowerRightX_, double lowerRightY_,
1440,1443c1440,1443
<     : _centerX(centerX_),
<       _centerY(centerY_),
<       _width(width_),
<       _hight(hight_),
---
>     : _upperLeftX(upperLeftX_),
>       _upperLeftY(upperLeftY_),
>       _lowerRightX(lowerRightX_),
>       _lowerRightY(lowerRightY_),
<以下、変数名の追随>
  • PerlMagick/quantum/quantum.xs
    • Property 設定と同時に Artifact も。
1185c1185,1188
<         SetImageProperty(image,attribute,SvPV(sval,na));
---
>       {
>         (void) SetImageProperty(image,attribute,SvPV(sval,na));
>         (void) SetImageArtifact(image,attribute,SvPV(sval,na));
>       }
<以下同様>
  • clocal.m4
    • GNU サイトの URL を http から https に変更
    • -Wno-suggest-attribute=format をセットする前に、対応しているかチェックする。
23,25c23,25
< # ===========================================================================
< #  http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
< # ===========================================================================
---
> # ============================================================================
> #  https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
> # ============================================================================
66c66
< #   with this program. If not, see <http://www.gnu.org/licenses/>.
---
> #   with this program. If not, see <https://www.gnu.org/licenses/>.
<以下同様>
|427c427
<     m4_define(ax_warn_cflags_variable,
---
>     m4_define([ax_warn_cflags_variable],
442a443,449
>     # Check that -Wno-suggest-attribute=format is supported
>     AX_CHECK_COMPILE_FLAG([-Wno-suggest-attribute=format],[
>         ax_compiler_no_suggest_attribute_flags="-Wno-suggest-attribute=format"
>     ],[
>         ax_compiler_no_suggest_attribute_flags=""
>     ])
>
501c508
<             -Wno-suggest-attribute=format dnl

<以下同様>
26c26
< %    http://www.imagemagick.org/script/license.php                            %
---
> %    https://www.imagemagick.org/script/license.php                           %
<以下、色んな codec で同じく>
  • coders/icon.c
    • ファイル内の画像で一番大きなサイズより、画像バイナリが小さい時は途中で切れてるのでエラーにする。
256a257,259
>   MagickSizeType
>     extent;
>
303a307
>   extent=0;
316a321
+    extent=MagickMax(extent,icon_file.directory[i].size);
+  }
-  if (EOFBlob(image) != MagickFalse)
-  if ((EOFBlob(image) != MagickFalse) || (extent > GetBlobSize(image)))
-    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
  • coder/inline.c
    • ファイル名に data:〜 が指定された時は、その後ろをインライン画像として扱う。以前は inline:data:,〜 で指定。
<   if (LocaleCompare(image_info->magick,"DATA") == 0)
---
>   if (LocaleNCompare(image_info->filename,"data:",5) == 0)
  • coders/jp2.c
    • ReadJP2Image で色空間判断の処理が変わってる。
      • 以前 numcomps(色コンポーネント数)が 2以下の時に YCbcr にしてたのを color_space == 2 を条件にした
      • dx > 1, dx > 1 なのでサブクロマサンプリングの時は YUVColorscape に。(いいのだろうか?)
411c411
<   if (jp2_image->numcomps <= 2)
---
>   if (jp2_image->color_space == 2)
416a417,419
>   else
>     if (jp2_image->color_space == 3)
>       SetImageColorspace(image,Rec601YCbCrColorspace);
419,421d421
<   for (i=0; i < (ssize_t) jp2_image->numcomps; i++)
<     if ((jp2_image->comps[i].dx > 1) || (jp2_image->comps[i].dy > 1))
<       SetImageColorspace(image,YUVColorspace);
  • coders/pcx.c (IBMペイントブラシ形式)
    • planes(ピクセルを配置する単位?)が0の時にエラーで弾く。(0 のまま処理続くとひどい事になりそう)
359a358,359
>     if (pcx_info.planes == 0)
>       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  • coder/rle.c
    • HDRI サポート外の時に 0〜255 にクランプ処理を入れた。
277c277,278
<             *p++=(unsigned char) ScaleShortToQuantum(ReadBlobLSBShort(image));
---
>             *p++=(unsigned char) ScaleQuantumToChar(ScaleShortToQuantum(
>               ReadBlobLSBShort(image)));
  • coders/sgi.c
    • AcquireVirtualMemory に失敗した時に、すでにとった分のメモリ解放処理(Relinquish系)が色々なかったので、沢山追加。
406c406,409
<           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
---
>           {
>             pixel_info=RelinquishVirtualMemory(pixel_info);
>             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
>           }
463,467c466,468
<             if (offsets == (ssize_t *) NULL)
<               offsets=(ssize_t *) RelinquishMagickMemory(offsets);
 <以下略>
  • coders/svg.c
    • SVGDensityGeometry 相当の値が 90.0x90.0 と 96.0x96.0 で揺れていたので後者に統一。
    • イプシロン比較前に abs を入れたり。(負の側で値がはみ出ても イプシロン内と判定されてた)
 <略>
2787c2787
<   SVGDensityGeometry[] = "90.0x90.0";
---
>   SVGDensityGeometry[] = "96.0x96.0";
2837,2838c2837,2838
<   if ((image->x_resolution < MagickEpsilon) ||
<       (image->y_resolution < MagickEpsilon))
---
>   if ((fabs(image->x_resolution) < MagickEpsilon) ||
>       (fabs(image->y_resolution) < MagickEpsilon))
2984c2984,2985
<         if ((image->x_resolution > 0.0) && (image->y_resolution > 0.0))
---
>         if ((fabs(image->x_resolution) > MagickEpsilon) &&
>             (fabs(image->y_resolution) > MagickEpsilon))
2999a3001
>         apply_density=MagickTrue;
3025,3027c3027,3029
<                 image->x_resolution=90.0*image->columns/dimension_info.width;
<                 image->y_resolution=90.0*image->rows/dimension_info.height;
<                 if (image->x_resolution == 0)
---
>                 image->x_resolution=96.0*image->columns/dimension_info.width;
>                 image->y_resolution=96.0*image->rows/dimension_info.height;
>                 if (fabs(image->x_resolution) < MagickEpsilon)
<略>
  • magick/colorspace.c
    • RGBTransformImage で YCCColorspace 変換テーブルを作成する時の係数を修正。
931,939c931,939
<         x_map[i].x=0.003962014134275617*i;
<         y_map[i].x=0.007778268551236748*i;
<         z_map[i].x=0.001510600706713781*i;
<         x_map[i].y=(-0.002426619775463276)*i;
<         y_map[i].y=(-0.004763965913702149)*i;
<         z_map[i].y=0.007190585689165425*i;
<         x_map[i].z=0.006927257754597858*i;
<         y_map[i].z=(-0.005800713697502058)*i;
<         z_map[i].z=(-0.0011265440570958)*i;
---
>         x_map[i].x=0.005382*i;
>         y_map[i].x=0.010566*i;
>         z_map[i].x=0.002052*i;
>         x_map[i].y=(-0.003296)*i;
>         y_map[i].y=(-0.006471)*i;
>         z_map[i].y=0.009768*i;
>         x_map[i].z=0.009410*i;
>         y_map[i].z=(-0.007880)*i;
>         z_map[i].z=(-0.001530)*i;
943,951c943,951
<         x_map[i].x=0.2201118963486454*(1.099*i-0.099);
<         y_map[i].x=0.4321260306242638*(1.099*i-0.099);
<         z_map[i].x=0.08392226148409894*(1.099*i-0.099);
<         x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
<         y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
<         z_map[i].y=0.3994769827314126*(1.099*i-0.099);
<         x_map[i].z=0.3848476530332144*(1.099*i-0.099);
<         y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
<         z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
---
>         x_map[i].x=0.298839*(1.099*i-0.099);
>         y_map[i].x=0.586811*(1.099*i-0.099);
>         z_map[i].x=0.114350*(1.099*i-0.099);
>         x_map[i].y=(-0.298839)*(1.099*i-0.099);
>         y_map[i].y=(-0.586811)*(1.099*i-0.099);
>         z_map[i].y=0.88600*(1.099*i-0.099);
>         x_map[i].z=0.70100*(1.099*i-0.099);
>         y_map[i].z=(-0.586811)*(1.099*i-0.099);
>         z_map[i].z=(-0.114350)*(1.099*i-0.099);
  • magick/composite.c
    • composite パラメータを Artifact に設定するの間違えて、変換前画像にしてた。
1845c1845
<       value=GetImageArtifact(source_image,"compose:args");
---
>       value=GetImageArtifact(image,"compose:args");
  • magick/decorate.c
    • FrameImage の Set frame interior pixels の処理をごっそり削除 (いいの?)
455a456
>     for (x=0; x < (ssize_t) image->columns; x++)
457,478c458,460
<       register const IndexPacket
<         *indexes;
<
<       register const PixelPacket
<         *p;
<
<       p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
<       if (p == (const PixelPacket *) NULL)
<         {
<           status=MagickFalse;
<           continue;
<         }
<       indexes=GetCacheViewVirtualIndexQueue(image_view);
<       (void) CopyMagickMemory(q,p,image->columns*sizeof(*p));
<       if ((image->colorspace == CMYKColorspace) &&
<           (frame_image->colorspace == CMYKColorspace))
<         {
<           (void) CopyMagickMemory(frame_indexes,indexes,image->columns*
<             sizeof(*indexes));
<           frame_indexes+=image->columns;
<         }
<       q+=image->columns;
---
>       SetPixelPacket(frame_image,&border,q,frame_indexes);
>       q++;
>       frame_indexes++;
  • magick/draw.c
    • ハードコーディングの 96.0 を DefaultResolution に変更。72.0 を 96.0 に修正(こっちはハードコーディングで)
1287,1288c1287,1288
<   resolution.x=DefaultResolution;
<   resolution.y=DefaultResolution;
---
>   resolution.x=96.0;;
>   resolution.y=96.0;;
1303c1303
<   mid=(resolution.x/72.0)*ExpandAffine(&clone_info->affine)*
---
>   mid=(resolution.x/96.0)*ExpandAffine(&clone_info->affine)*
  • magick/memory.c
    • AcquireAlignedMemory から anonymous mapping("system:memory-map")の処理を追加。
62a63
> #include "magick/policy.h"
66c67
< #include "magick/utility-private.h"
---
> #include "magick/utility.h"
224c225
< %  bytes whose address is a multiple of 16*sizeof(void *).
---
> %  bytes whose address is aligned on a cache line or page boundary.
253d253
<   alignment=CACHE_LINE_SIZE;
255,256c255,259
<   extent=AlignedExtent(size,alignment);
<   if ((size == 0) || (alignment < sizeof(void *)) || (extent < size))
---
>   alignment=CACHE_LINE_SIZE;
>   if (size > (GetMagickPageSize() >> 1))
>     alignment=GetMagickPageSize();
>   extent=AlignedExtent(size,CACHE_LINE_SIZE);
>   if ((size == 0) || (extent < size))
570a574,576
>   static ssize_t
>     virtual_anonymous_memory = (-1);
>
580a587,606
>   if (virtual_anonymous_memory < 0)
>     {
>       char
>         *value;
>
>       /*
>         Does the security policy require anonymous mapping for pixel cache?
>       */
>       virtual_anonymous_memory=0;
>       value=GetPolicyValue("system:memory-map");
>       if (LocaleCompare(value,"anonymous") == 0)
>         {
> #if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
>           virtual_anonymous_memory=1;
> #endif
>         }
>       value=DestroyString(value);
>     }
>   if (virtual_anonymous_memory <= 0)
>     {
590a617,619
>     }
>   else
>     {
594c623
<         Heap memory failed, try anonymous memory mapping.
---
>             Acquire anonymous memory map.
  • magick/module.c
    • MagickReadDirectory インライン関数を追加。
383,395d383
<
< static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
<   struct dirent **result)
< {
< #if defined(MAGICKCORE_HAVE_READDIR_R)
<   return(readdir_r(directory,entry,result));
< #else
<   (void) entry;
<   errno=0;
<   *result=readdir(directory);
<   return(errno);
< #endif
< }
  • magick/nt-base-private.h
    • NTGetPageSize 関数追加
136a137
>   NTGetPageSize(void),
144,145c145
<   NTReportEvent(const char *,const MagickBooleanType),
<   NTReportException(const char *,const MagickBooleanType);
---
>   NTReportEvent(const char *,const MagickBooleanType);
  • magick/nt-base.c
    • NTGetPageSize 関数追加
> MagickPrivate ssize_t NTGetPageSize(void)
> {
>   SYSTEM_INFO
>     system_info;
>
>    GetSystemInfo(&system_info);
>    return((ssize_t) system_info.dwPageSize);
> }
2711a2739
>   magick_unreferenced(info);
  • magick/semaphore.c
    • alignment を定数の CACHE_LINE_SIZE に変更
53a54
> #include "magick/utility.h"
149,150c150,151
<   extent=AlignedExtent(size,alignment);
<   if ((size == 0) || (alignment < sizeof(void *)) || (extent < size))
---
>   extent=AlignedExtent(size,CACHE_LINE_SIZE);
>   if ((size == 0) || (extent < size))
  • magick/stream.c
    • AcquireStreamPixels で security policy の anonymous mapping for pixel cache 対応。
56a57
> #include "magick/policy.h"
129a131,136
>   Global declarations.
> */
> static ssize_t
>   cache_anonymous_memory = (-1);
> ^L
> /*
649a657,683
>   if (cache_anonymous_memory < 0)
>     {
>       char
>         *value;
>
>       /*
>         Does the security policy require anonymous mapping for pixel cache?
>       */
>       cache_anonymous_memory=0;
>       value=GetPolicyValue("pixel-cache-memory");
>       if (value == (char *) NULL)
>         value=GetPolicyValue("cache:memory-map");
>       if (LocaleCompare(value,"anonymous") == 0)
>         {
> #if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
>           cache_anonymous_memory=1;
> #else
>           (void) ThrowMagickException(exception,GetMagickModule(),
>             MissingDelegateError,"DelegateLibrarySupportNotBuiltIn",
>             "'%s' (policy requires anonymous memory mapping)",
>             cache_info->filename);
> #endif
>         }
>       value=DestroyString(value);
>     }
>    if (cache_anonymous_memory <= 0)
>      {
651,653c685,688
<   cache_info->pixels=(PixelPacket *) MagickAssumeAligned(AcquireAlignedMemory(1,
<     (size_t) cache_info->length));
<   if (cache_info->pixels == (PixelPacket *) NULL)
---
>        cache_info->pixels=(PixelPacket *) MagickAssumeAligned(
>          AcquireAlignedMemory(1,(size_t) cache_info->length));
>      }
>    else
  • magick/string.c
    • FormatMagickSize の実数(%g)精度に GetMagickPrecision を使う。
    • + があったら終端にさせる。
1071a1072,1075
>   char
>     p[MaxTextExtent],
>     q[MaxTextExtent];
>
1080,1081c1084
<     i,
<     j;
---
>     i;
1108,1111c1111,1114
<   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
<     length/=bytes;
<   count=0;
<   for (j=2; j < 12; j++)
---
>   (void) FormatLocaleString(p,MaxTextExtent,"%.*g",GetMagickPrecision(),
>     length);
>   (void) FormatLocaleString(q,MaxTextExtent,"%.20g",length);
>   if (strtod(p,(char **) NULL) == strtod(q,(char **) NULL))
1113,1116c1116,1117
<     count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
<       units[i]);
<     if (strchr(format,'+') == (char *) NULL)
<       break;
---
>       count=FormatLocaleString(format,MaxTextExtent,"%.20g%sB",length,units[0]);
>       return(count);
1117a1119,1122
>   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
>     length/=bytes;
>   count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",GetMagickPrecision(),
>     length,units[i]);
  • magick/utility-private.h
    • MagickReadDirectory インライン関数追加
30a31,43
>
> static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
>   struct dirent **result)
> {
> #if defined(MAGICKCORE_HAVE_READDIR_R)
>   return(readdir_r(directory,entry,result));
> #else
>   (void) entry;
>   errno=0;
>   *result=readdir(directory);
>   return(errno);
> #endif
> }
  • magick/utility.c
    • GetMagickPageSize のデフォルトを 16384 から 4096 に。Windows の場合は NTGetPageSize で取得
    • MagickReadDirectory インライン関数を削除してヘッダに移動。
> #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
>   page_size=NTGetPageSize();
1119c1119
<     page_size=16384;
---
>     page_size=4096;
1547,1557d1546
<
< static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
<   struct dirent **result)
< {
<   errno=0;
<   entry=readdir(directory);
<   *result=entry;
<   if ((entry == (struct dirent *) NULL) && (errno != 0))
<     return(-1);
<   return(0);
< }

ChangeLog

2017-04-24  6.9.8-4 Cristy  <quetzlzacatenango@image...>
  * Release ImageMagick version 6.9.8-4, GIT revision 11521:d7433aa:20170424.

2017-03-26  6.9.8-4 Cristy  <quetzlzacatenango@image...>
  * Minimize buffer copies to improve OpenCL performance.
  * Patch a PCD writer problem, dark pixels (reference
    https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=3164).
  * Support ICC based PDF's (reference
    https://github.com/ImageMagick/ImageMagick/issues/417).