ImageMagick-6.9.10-13差分

ImageMagick-6.9.10-12差分 - yoyaのメモの続き

The latest release of ImageMagick is version 6.9.10-13

まとめ

気になる事
  • MagickWand API で list オプションを使った時に結果ステータスが True/False逆転してたのを修正。
  • compare コマンドの PSNR の計算式が変わってる。
    • "20.0*Log10(1.0/ sqrt(disto))" => "10.0*Log10(1.0)-10.0*Log10(disto)"
  • SVGDensityGeometryが "72.0x72.0" から "90.0x90.0" に変更
  • PS2,PS3,TIFF の圧縮タイプ ZSTD と WEBP 対応を作りかけてる
  • JPEG encode で jpeg_progress_mgr を使って input_scan_number が MaxJPEGScans:1024 以上だと longjump でエラー終了するようになった。
  • exif プロパティが大量に追記されてる。もしかして exiftool 的な機能が入るかも?

差分

以下、あちこち URL のドメイン名を www.imagemagick.org から imagemagick.org にする差分は省略。

  • Magick++/lib/Magick++/Include.h
    • 2つ using 追加と並び順のコード整理。
>   using MagickCore::WebPCompression;
>   using MagickCore::ZstdCompression;
  • coders/dcm.c
    • EOF が来た時に、それを負の値のまま足し算する不具合の修正。
2884c2884
<                 if (info->signed_data)
---
>                 if (info->signed_data != 0)
2894,2895c2894,2899
<                   pixel_value=(ReadDCMByte(stream_info,image) << 8) |
<                     byte;
---
>                   {
>                     pixel_value=byte;
>                     byte=ReadDCMByte(stream_info,image);
>                     if (byte >= 0)
>                       pixel_value|=(byte << 8);
>                   }
  • coders/jpeg.c
    • jpeg_progress_mgr を使い始めた。 compress で input_scan_number が MaxJPEGScans:1024) を超えたら longjmp(error_manager->error_recovery,1); する
105a106
> #define MaxJPEGScans  1024
308a310,312
>   ExceptionInfo
>     *exception;
>
314a319
>   exception=(&image->exception);
320,321c325,326
<     (void) ThrowMagickException(&image->exception,GetMagickModule(),
<       CorruptImageWarning,(char *) message,"`%s'",image->filename);
---
>     (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageWarning,
>       (char *) message,"`%s'",image->filename);
323,324c328,352
<     (void) ThrowMagickException(&image->exception,GetMagickModule(),
<       CorruptImageError,(char *) message,"`%s'",image->filename);
---
>     (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
>       (char *) message,"`%s'",image->filename);
>   longjmp(error_manager->error_recovery,1);
> }
>
> static void JPEGProgressHandler(j_common_ptr jpeg_info)
> {
>   ErrorManager
>     *error_manager;
>
>   ExceptionInfo
>     *exception;
>
>   Image
>     *image;
>
>   error_manager=(ErrorManager *) jpeg_info->client_data;
>   image=error_manager->image;
>   exception=(&image->exception);
>   if (jpeg_info->is_decompressor == 0)
>     return;
>   if (((j_decompress_ptr) jpeg_info)->input_scan_number < MaxJPEGScans)
>     return;
>   (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
>     "too many scans","`%s'",image->filename);
1042a1071,1073
>   struct jpeg_progress_mgr
>     jpeg_progress;
>
1081a1113
>   (void) memset(&jpeg_progress,0,sizeof(jpeg_progress));
1102a1135,1136
>   jpeg_progress.progress_monitor=(void (*)(j_common_ptr)) JPEGProgressHandler;
>   jpeg_info.progress=(&jpeg_progress);
2495c2529
<   if (colorspace == jpeg_info.in_color_space)
---
>   if ((J_COLOR_SPACE) colorspace == jpeg_info.in_color_space)
  • coders/meta.c
    • convertHTMLcodes の第二引数を削除。(結局、strlen(s) してるので渡す意味無し)
196c196
< static size_t convertHTMLcodes(char *s, const size_t len)
---
> static size_t convertHTMLcodes(char *s)
201c201,214
<   if ((len == 0) || (s == (char*) NULL) || (*s=='\0'))
<略>
<   return(ProcessMSLScript(image_info,&msl_image,&image->exception));
---
>   status=ProcessMSLScript(image_info,&msl_image,&image->exception);
>   msl_image=DestroyImageList(msl_image);
>   return(status);
  • coders/pcx.c
-- PCX のメモリリーク修正
>|c|
986a987,989
>       {
>         if (page_table != (MagickOffsetType *) NULL)
>           page_table=(MagickOffsetType *) RelinquishMagickMemory(page_table);
987a991
>       }
888a889
>       if (runlength != (unsigned char *) NULL)
889a891,894
>       if (buffer != (unsigned char *) NULL)
>         buffer=(unsigned char *) RelinquishMagickMemory(buffer);
>       if (scanline != (unsigned char *) NULL)
>         scanline=(unsigned char *) RelinquishMagickMemory(scanline);
448c448
<     row_bytes=(size_t) ((4*image->columns) | 0x8000);
---
>     row_bytes=(size_t) (4*(image->columns | 0x8000));
1798c1798
<    (row_bytes+MaxCount),sizeof(*packed_scanline));
---
>    (row_bytes+2*MaxCount),sizeof(*packed_scanline));
1814c1814,1815
<   (void) memset(packed_scanline,0,(size_t) (row_bytes+MaxCount));
---
>   (void) memset(packed_scanline,0,(size_t) (row_bytes+2*MaxCount)*
>     sizeof(*packed_scanline));
  • coders/png.c
    • リファクタ。正しいキャスト、優先順を明示する括弧
    • depth の設定漏れの修正。(自分が issue 送った件かな?)
1889c1889
<       for (; i<chunk->size; i++)
---
>       for (; i < (ssize_t) chunk->size; i++)
2320,2321c2320,2321
<       png_set_chunk_malloc_max(ping,(png_alloc_size_t) MagickMin(PNG_SIZE_MAX,
<         StringToLong(option)));
---
>       png_set_chunk_malloc_max(ping,(png_alloc_size_t) MagickMin((ssize_t)
>         PNG_SIZE_MAX,StringToLong(option)));
4462,4464c4462,4464
<         if (jng_width > 65535 || jng_height > 65535 ||
<              (long) jng_width > GetMagickResourceLimit(WidthResource) ||
<              (long) jng_height > GetMagickResourceLimit(HeightResource))
---
>         if ((jng_width > 65535) || (jng_height > 65535) ||
>             (MagickSizeType) jng_width > GetMagickResourceLimit(WidthResource) ||
>             (MagickSizeType) jng_height > GetMagickResourceLimit(HeightResource))
6038c6038
<                     if (loop_iters > GetMagickResourceLimit(ListLengthResource))
---
>                     if ((MagickSizeType) loop_iters > GetMagickResourceLimit(ListLengthResource))
8706c8706,8707
<   image->depth=GetImageDepth(image,&image->exception);
---
>   if (image->depth != GetImageDepth(image,&image->exception))
>     (void) SetImageDepth(image,image->depth);
  • coders/pnm.c
    • 正しいキャストで比較。 (unsigned long long) が (signed long long) に。/8 してるので悪影響なさそう。
442c442
<     if ((MagickOffsetType) (image->columns*image->rows/8) > GetBlobSize(image))
---
>     if ((MagickSizeType) (image->columns*image->rows/8) > GetBlobSize(image))
diff -rwb ImageMagick-6.9.10-12/coders/preview.c ImageMagick-6.9.10-13/coders/preview.c
  • coders/sgi.c
    • 正しいキャストで比較。
378c378
<     if ((MagickOffsetType) (image->columns*image->rows/255) > GetBlobSize(image))
---
>     if ((MagickSizeType) (image->columns*image->rows/255) > GetBlobSize(image))
424c424
<             if (count != (bytes_per_pixel*iris_info.columns))
---
>             if (count != (ssize_t) (bytes_per_pixel*iris_info.columns))
526c526
<                 if (count != runlength[y+z*iris_info.rows])
---
>                 if (count != (ssize_t) runlength[y+z*iris_info.rows])
566c566
<                 if (count != runlength[y+z*iris_info.rows])
---
>                 if (count != (ssize_t) runlength[y+z*iris_info.rows])
  • coders/tiff.c
    • 圧縮タイプに WEBP, ZSTD を追加。(また作りかけ)
    • TIFFTAG_EXTRASAMPLES の修正。以前はこの alpha 値の処理を誤っていた模様
105a106,108
> # if defined(COMPRESSION_ZSTD) && defined(MAGICKCORE_ZSTD_DELEGATE)
> #   include <zstd.h>
> # endif
1454a1458,1463
> #if defined(COMPRESSION_WEBP)
>       case COMPRESSION_WEBP: image->compression=WebPCompression; break;
> #endif
> #if defined(COMPRESSION_ZSTD)
>       case COMPRESSION_ZSTD: image->compression=ZstdCompression; break;
> #endif
1585c1594
<                 SetQuantumAlphaType(quantum_info,DisassociatedQuantumAlpha);
---
>                 SetQuantumAlphaType(quantum_info,AssociatedQuantumAlpha);
1589a1599,1600
>                 {
>                   SetQuantumAlphaType(quantum_info,DisassociatedQuantumAlpha);
1592a1604
>       }
<略>
  • coders/xpm.c
    • 正しいキャストで比較
392c392
<     if (CopyXPMColor(key,p,length) != length)
---
>     if (CopyXPMColor(key,p,length) != (ssize_t) length)
  • configure.ac
    • 利用ライブラリに ZSTD 追加。
>   ZSTD              --with-zstd=$with_zstd            $have_zstd
  • filters/analyze.c
    • OpenMP の複数スレッド対応を削除。
< #if defined(MAGICKCORE_OPENMP_SUPPORT)
<     #pragma omp parallel for schedule(static) shared(status) \
<       magick_number_threads(image,image,image->rows,1)
< #endif
>     FT_Outline
>       outline;
>
1528,1529c1531,1532
<     ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
<       &bounds);
---
>     outline=((FT_OutlineGlyph) glyph.image)->outline;
>     ft_status=FT_Outline_Get_BBox(&outline,&bounds);
1553,1554c1556,1558
<         (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->outline,
<           &OutlineMethods,annotate_info);
---
>         if ((outline.n_contours > 0) && (outline.n_points > 0))
>           ft_status=FT_Outline_Decompose(&outline,&OutlineMethods,
>             annotate_info);
  • magick/blob.c
    • リファクタ? gzeof の返り値をbool化。gzeof も 1 or 0 なので変わらないはず。
921c921,922
<       blob_info->eof=gzeof(blob_info->file_info.gzfile);
---
>       blob_info->eof=gzeof(blob_info->file_info.gzfile) != 0 ? MagickTrue :
>         MagickFalse;
  • magick/cache.c
    • event_status が CL_COMPLETE 以外でも、それより値が大きいのは成功扱い
214c214
<     if ((status == CL_SUCCESS) && (event_status != CL_COMPLETE))
---
>     if ((status == CL_SUCCESS) && (event_status > CL_COMPLETE))
  • magick/compare.c
    • GetPeakSignalToNoiseRatio (PSNR 計算)の高速化?: 20.0*Log10(1.0/ sqrt(disto)) => 10.0*Log10(1.0)-10.0*Log10(disto);
1400,1401c1400,1401
<         distortion[RedChannel]=20.0*MagickLog10(1.0/
<           sqrt(distortion[RedChannel]));
---
>         distortion[RedChannel]=10.0*MagickLog10(1.0)-10.0*
>           MagickLog10(distortion[RedChannel]);
1408,1409c1408,1409
<         distortion[GreenChannel]=20.0*MagickLog10(1.0/
<           sqrt(distortion[GreenChannel]));
---
>         distortion[GreenChannel]=10.0*MagickLog10(1.0)-10.0*
>           MagickLog10(distortion[GreenChannel]);
1416,1417c1416,1417
<         distortion[BlueChannel]=20.0*MagickLog10(1.0/
<           sqrt(distortion[BlueChannel]));
---
>         distortion[BlueChannel]=10.0*MagickLog10(1.0)-10.0*
>           MagickLog10(distortion[BlueChannel]);
1424,1425c1424,1425
<         distortion[OpacityChannel]=20.0*MagickLog10(1.0/
<           sqrt(distortion[OpacityChannel]));
---
>         distortion[OpacityChannel]=10.0*MagickLog10(1.0)-10.0*
>           MagickLog10(distortion[OpacityChannel]);
1432,1433c1432,1433
<         distortion[BlackChannel]=20.0*MagickLog10(1.0/
<           sqrt(distortion[BlackChannel]));
---
>         distortion[BlackChannel]=10.0*MagickLog10(1.0)-10.0*
>           MagickLog10(distortion[BlackChannel]);
1435,1436d1434
<   if (fabs(distortion[CompositeChannels]) >= MagickEpsilon)
<     {
1440,1442c1438,1439
<         distortion[CompositeChannels]=20.0*MagickLog10(1.0/
<           sqrt(distortion[CompositeChannels]));
<     }
---
>     distortion[CompositeChannels]=10.0*MagickLog10(1.0)-10.0*
>       MagickLog10(distortion[CompositeChannels]);
1631,1632c1628
<   (void) memset(channel_distortion,0,length*
<     sizeof(*channel_distortion));
---
>   (void) memset(channel_distortion,0,length*sizeof(*channel_distortion));
  • magick/compress.h
    • 圧縮方式に Zstd と WebP を追加。
48c48,50
<   JBIG2Compression            /* ISO/IEC std 14492 / ITU-T rec T.88 */
---
>   JBIG2Compression,           /* ISO/IEC std 14492 / ITU-T rec T.88 */
>   ZstdCompression,
>   WebPCompression
  • magick/draw.c
    • fill.opacity が TransparentOpacity の処理を追加。
2840,2842c2840,2844
<             if (graphic_context[n]->fill_opacity != OpaqueOpacity)
<               graphic_context[n]->fill.opacity=ClampToQuantum(
<                 graphic_context[n]->fill_opacity);
---
>             if (graphic_context[n]->fill.opacity != TransparentOpacity)
>               graphic_context[n]->fill.opacity=graphic_context[n]->fill_opacity;
>             else
>               graphic_context[n]->fill.opacity=ClampToQuantum(QuantumRange*
>                 (1.0-opacity));
3617,3619c3619,3624
<             if (graphic_context[n]->stroke_opacity != OpaqueOpacity)
<               graphic_context[n]->stroke.opacity=ClampToQuantum(
<                 graphic_context[n]->stroke_opacity);
---
>             if (graphic_context[n]->stroke.opacity != TransparentOpacity)
>               graphic_context[n]->stroke.opacity=
>                 graphic_context[n]->stroke_opacity;
>             else
>               graphic_context[n]->stroke.opacity=ClampToQuantum(QuantumRange*
>                 (1.0-opacity));
  • magick/list.c
    • キャストを付けた
<     first=MagickMin(MagickMax(first,0),length);
<     last=MagickMin(MagickMax(last,0),length);
---
>     first=MagickMin(MagickMax(first,0),(ssize_t) length);
>     last=MagickMin(MagickMax(last,0),(ssize_t) length);
  • magick/magick.c
    • GetRootValueFromSplayTree が NULL を返した時に name (="")をつけてもう一度呼ぶが、意味がない(メモリがギリギリの時くらい?)ので、即 return する。
    if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
<     magick_info=(const MagickInfo *) GetRootValueFromSplayTree(magick_list);
>     return((const MagickInfo *) GetRootValueFromSplayTree(magick_list));
    if (magick_info == (const MagickInfo *) NULL)
      magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,name);
    return(magick_info);
2758,2759c2758,2760
<       debug|=_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF |
<         _CRTDBG_LEAK_CHECK_DF;
---
>       //debug |= _CRTDBG_CHECK_ALWAYS_DF;
>       debug |= _CRTDBG_DELAY_FREE_MEM_DF;
>       debug |= _CRTDBG_LEAK_CHECK_DF;
2761c2762,2765
<       _ASSERTE(_CrtCheckMemory());
---
>
>       //_ASSERTE(_CrtCheckMemory());
>
>       //_CrtSetBreakAlloc(42);
  • magick/option.c
    • WebP, Zstd のオプション定義を地下。
972a972
>     { "WebP", WebPCompression, UndefinedOptionFlag, MagickFalse },
<略>
>     { "Zstd", ZstdCompression, UndefinedOptionFlag, MagickFalse },
  • magick/property.c
    • exif のプロパティを大量に追加。タグの定義。
1077c1077
<       {  0x8769, "exif:ExifOffset" },
---
>       {  0x8769, "exif:ExifOffset" },  /* specs as "Exif IFD Pointer"? */
1081,1082c1081,1082
<       {  0x8825, "exif:GPSInfo" },
<       {  0x8827, "exif:ISOSpeedRatings" },
---
>       {  0x8825, "exif:GPSInfo" }, /* specs as "GPSInfo IFD Pointer"? */
>       {  0x8827, "exif:PhotographicSensitivity" },
1086a1087,1092
>       {  0x8830, "exif:SensitivityType" },
>       {  0x8831, "exif:StandardOutputSensitivity" },
>       {  0x8832, "exif:RecommendedExposureIndex" },
>       {  0x8833, "exif:ISOSpeed" },
>       {  0x8834, "exif:ISOSpeedLatitudeyyy" },
>       {  0x8835, "exif:ISOSpeedLatitudezzz" },
1089a1096,1098
>       {  0x9010, "exif:OffsetTime" },
>       {  0x9011, "exif:OffsetTimeOriginal" },
>       {  0x9012, "exif:OffsetTimeDigitized" },
1104a1114,1117
>       {  0x9214, "exif:SubjectArea" },
>       {  0x9290, "exif:SubSecTime" },
>       {  0x9291, "exif:SubSecTimeOriginal" },
>       {  0x9292, "exif:SubSecTimeDigitized" },
1111a1125,1134
>       {  0x9286, "exif:UserComment" },
>       {  0x9290, "exif:SubSecTime" },
>       {  0x9291, "exif:SubSecTimeOriginal" },
>       {  0x9292, "exif:SubSecTimeDigitized" },
>       {  0x9400, "exif:Temperature" },
>       {  0x9401, "exif:Humidity" },
>       {  0x9402, "exif:Pressure" },
>       {  0x9403, "exif:WaterDepth" },
>       {  0x9404, "exif:Acceleration" },
>       {  0x9405, "exif:CameraElevationAngle" },
1117,1120d1139
<       {  0x9286, "exif:UserComment" },
<       {  0x9290, "exif:SubSecTime" },
<       {  0x9291, "exif:SubSecTimeOriginal" },
<       {  0x9292, "exif:SubSecTimeDigitized" },
1123,1124c1142,1143
<       {  0xa002, "exif:ExifImageWidth" },
<       {  0xa003, "exif:ExifImageLength" },
---
>       {  0xa002, "exif:PixelXDimension" },
>       {  0xa003, "exif:PixelYDimension" },
1152a1172,1177
>       {  0xa430, "exif:CameraOwnerName" },
>       {  0xa431, "exif:BodySerialNumber" },
>       {  0xa432, "exif:LensSpecification" },
>       {  0xa433, "exif:LensMake" },
>       {  0xa434, "exif:LensModel" },
>       {  0xa435, "exif:LensSerialNumber" },
1186a1212
>       { 0x1001f, "exif:GPSHPositioningError" },
1188c1214
<     };
---
>     };  /* http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf */
  • magick/token.c
    • url(#〜) の # を必須に。
177a178,180
>   register char
>     *q;
>
304c307,308
<   if ((LocaleNCompare(token,"url(",4) == 0) && (strlen(token) > 5))
---
>   q=strrchr(token,')');
>   if ((LocaleNCompare(token,"url(#",5) == 0) && (q != (char *) NULL))
306,317c310,311
<       ssize_t
<         offset;
<
<       offset=4;
<       if (token[offset] == '#')
<         offset++;
<       i=(ssize_t) strlen(token);
<       if (i > offset)
<         {
<           (void) CopyMagickString(token,token+offset,MaxTextExtent);
<           token[i-offset-1]='\0';
<         }
---
>       *q='\0';
>       (void) memmove(token,token+5,(size_t) (q-token-4));
  • wand/MagickWand.h
    • C++11 から register 非推奨なので、その対応。ちなみに C++17 から register 廃止されてます。
50,52d49
< #if __cplusplus > 199711L
< #define register
< #endif
  • wand/animate.c, compare.c, composite.c, convert.c, display.c, identify.c, import.c, mogrify.c, montage.c, stream.c
    • list オプションに応じて Mogrify 処理したステータスを逆に見てたのを修正。全コマンドに対応する MagickWand は多分コピペで、同じ間違いをしてた。
1020c1020
<             return(status == 0 ? MagickTrue : MagickFalse);
---
>             return(status == 0 ? MagickFalse : MagickTrue);

ChangeLog

2018-10-21  6.9.10-13 Cristy  <quetzlzacatenango@image...>
  * Release ImageMagick version 6.9.10-13, GIT revision 13936:2379b24b8:20181021