ドナドナされるプログラマのメモ

Windows用アプリのプログラミングメモ

mozjpegをつかった画像変換ソフトの開発 その9 MozJPEG2.3.1->4.1.1

MozJPEGがいつのまにか3.3.1から4.1.1に進化しており、GitHubにて対応要望が出ていた。そこで、開発を再開し4.1.1を適用しようとおもう。できたらいいな。

環境立ち上げ

先日Ryzen7800X3Dにした際にWindowsクリーンインストールしたため開発環境がまっさらな状態になってしまっている。そのため、まずは環境立ち上げから始めなければならない。

MozJPEG用に導入するものもあり、ちょっと大変。以下環境メモ。

 

■一般

VisualStudio: Visual Studio 2022 Community

Source Tree: 3.4.13

■MozJPEG用

CMake: 3.26.4

VCPkg: 2023.04.15

 

CMakeはWindows用バイナリを導入するだけなので楽。

VCPkgはbootstrap-vcpkg.batを使って適切なバイナリをダウンロードする。

あとはBUILDING.mdに書かれた手順通りにパッケージのインストールを進める。

vcpkg install mozjpeg

MozJPEGの変更点確認

さあ、一番面倒な部分だ。v3.3.1からv4.1.1でインターフェースやグローバル変数がどう変わったのかを確認する。

MozJPEGは残念ながらシングルスレッドを想定しているようで、グローバル変数が多用されている。また、関数がクラスとしてまとまっていない。そのためMozJpegGuiは、これらグローバル変数や関数をクラスとしてカプセル化している。すなわち、MozJPEGのコードに手を加えているのだ。その結果、MozJPEGのバージョンアップに対応するにはコードの書き換えが必要となる。

とはいえ、すべてのコードを書き換える必要はない(はず)。手を加えているのは以下のファイルのみ。

  • cdjpeg.cpp
  • cjpeg.cpp
  • rdbmp.cpp
  • rdgif.cpp
  • rdjpeg.cpp
  • rdpng.cpp
  • rdppm.cpp
  • rdswitch.cpp
  • rdtarga.cpp
  • cjpeg.h

ということは、これらに関する変更をまずはチェックすればOKということだ。

  • cdjpeg.cpp
    progress_monitor()の変更内容は危険だが、使わないのでヨシ
    • progress_monitor(j_common_ptr cinfo)が常時含まれるようになった。
    • progress_monitor(j_common_ptr cinfo)においてスキャン数が最大値を超えたらexit(EXIT_FAILURE)、つまり強制終了するようになった。
  • cdjpeg.h
    進捗状態をstd_errに出力するreportフラグは上記の通りアプリを強制終了させる恐れがあるので、false絶対。絶対false。
    あと、rleがサポート外になった模様。
    • #pragma onceがなくなった。
    • JDIMENSION max_scans; boolean report;が追加された。
    • jinit_write_gif()にboolean is_lzw引数が追加された。
    • jinit_read_rle(), jinit_write_rle()が消えた。
    • READ_BINARYが"rbS"から"rb"になった。"S"ってなんじゃろ?と確認したら、シーケンシャルアクセス最適化オプションだった。外しちゃったんだ?
  • cjpeg.c
    • #define _CRT_SECURE_NO_DEPRECATEが定義された。
    • CJPEG_FUZZERが定義されている場合、JPEG_INTERNALSも定義するようになった。
    • RLEサポートの終了。
    • reportスイッチのサポート。ONにするとstd_errに変換進捗を表示するが表示エラー即強制終了する罠がある。デフォルトはFALSE。
    • strictスイッチのサポート。ONにするとすべての警告をエラーとして扱う。デフォルトはFALSE。
    • CJPEG_FUZZER固有実装の追加(使わない予定なので省略)
    • 以下の説明文変更
      • -dct int:
        accurate(高精度)との説明追加
      • -dct fast
        legacy(遺産)との説明追加
      • -dct float
        legacy(遺産)との説明追加
      • -quant-table 2
        Kodak image setとの説明追加
      • -quant-table 3
        default値との説明追加
      • -quant-table 4
        Kodak image setとの説明追加
      • -quant-table 6,7,8:
        新規追加
    • FILE *input_fileをNULLで初期化。
    • main()がexitではなくreturnで終わるようになった。
  • rdbmp.c
    • unsigned charの利用可否チェックが消えた。
    • jinclude.hに定義したJFREAD()のかわりにfread()を使用する。
    • 32bit bmpのサポート。
    • JCS_RGBが1であってもカラーマップ判定に失敗したらグレースケールとみなすようになった。
    • GETJSAMPLE()のかわりに直接ポインタを参照するようになった。
    • 独自MEMCOPY()のかわりにmemcpy()を使うようになった。
    • bfOffBits, headerSize, biClrUsedがunsigned intからintになった。
    • ヘッダサイズチェックの失敗条件に(headerSize + 14) > bfOffBitsが加わった。
    • 24ビット処理からトレースメッセージ削除、32ビット処理に追加。
    • 画像の幅チェックを追加。幅が過大ならERREXIT()。
    • 暗黙的な型変換を排除
           - (JDIMENSION)(biWidth * cinfo->input_components), (JDIMENSION)1);
           + (JDIMENSION)biWidth * (JDIMENSION)cinfo->input_components, (JDIMENSION)1);
  • rdgif.c
    LZWに関する悪名高いUnisys社特許を迂回する必要がなくなったためか、大幅に書き換わっている。
    • ”GIF input is unsupported for legal reasons.  Sorry.”(法的な理由によりGIF入力は非対応です。ごめん。)という一文のかわりに、大量のコードが追加されている。
  • rdjpeg.c, rdpng.c
    差分をうまく取れず。または差分無し。
  • rdppm.c
    • unsigned charの利用可否チェックが消えた。
    • jinclude.hに定義したJFREAD()のかわりにfread()を使用する。
    • 最大値チェックを追加。過大ならERREXIT()。
    • read_pbm_integer()の返り値を(JSAMPLE)型に明示的変換。
    • read_pbm_integer()の最後の引数を省略ではなく空集合{}を明示するようにした。
    • get_word_rgb_row()をRGBAにも対応させたぽい。
    • グレースケールへの変換判定条件が更新されている。
    • メモリ確保時に使用するmaxvalの最大値が255になった。また、メモリを0クリアするようになった。処理が遅くなる方向の変更は珍しいが、memset専用CPU命令が現れ始めたからか?
  • rdswitch.c
    • #define _CRT_SECURE_NO_DEPRECATEが定義された。
    • 独自MEMCOPY()のかわりにmemcpy()を使うようになった。
  • rdtarga.c
    • unsigned charの利用可否チェックが消えた。
    • jinclude.hに定義したJFREAD()のかわりにfread()を使用する。
    • 構造体_tga_source_structに以下を追加。
      • int cmap_length;              /* colormap length */
    • map長(cmap_length)チェックを追加。過大ならERREXIT()。
    • map長(cmap_lengh)の更新処理を追加。

これで全部かな。コードレビューしている気分だw

今日はここまで。