3

最近、グラフィックを圧縮形式 (JPEG および PNG) で保存するようにゲームを更新しようとしていました。

最終的に別のライブラリに落ち着きましたが、最初の試みはijgを組み込んで JPEG 解凍を行うことでした。ただし、最も単純なコンソール アプリケーションでさえも動作させることができませんでした。誰かがその理由を解明できるのではないかと考えています。

ijg パッケージの一部であるjpeg.libにリンクされている私のコードは次のとおりです。

#include "stdafx.h"
#include <stdio.h>
#include <assert.h>
#include <jpeglib.h>

int _tmain(int argc, _TCHAR* argv[])
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPARRAY buffer;
    int row_stride;

    //initialize error handling
    cinfo.err = jpeg_std_error(&jerr);

    //initialize the decompression
    jpeg_create_decompress(&cinfo);

    FILE* infile;
    errno_t err = fopen_s(&infile, "..\\Sample.jpg", "rb");
    assert(err == 0);

    //specify the input
    jpeg_stdio_src(&cinfo, infile);

    //read headers
    (void) jpeg_read_header(&cinfo, TRUE);

    return 0;
}

問題は、への呼び出しがjpeg_read_header()アクセス違反で失敗することです。

JPEGTest.exe の 0x7c91b1fa (ntdll.dll) で未処理の例外: 0xC0000005: アクセス違反書き込み場所 0x00000010。

私が間違っているかもしれないことを誰かが知っていますか?

4

7 に答える 7

7

同じ問題が発生しました(画像をエンコードしようとしていましたが)。どうやら、FILE *はDLL間で移植できないため、FILE*をパラメーターとして受け取るlibjpegAPIを使用することはできません。

いくつかの解決策がありますが、それらはすべて、ライブラリを再構築する必要があります。

  • ライブラリを静的ライブラリとしてビルドし、アプリケーションにリンクします。これは私がしたことであり、それは私の問題を解決しました。
  • ソース/宛先ハンドラーをlibjpegからアプリケーションに移動します。次に、libjpegを静的libまたはDLLのいずれか適切なものとしてビルドできます。これが機能するかどうかはわかりませんが、ソースコードとともに配布されている「install.doc」ファイルで推奨される解決策です。
于 2009-03-05T03:28:57.527 に答える
4

私はエルナンに同意します。これは良いインターフェイスではありません (内部コード自体はおそらく良いと思います)。ただし、本当に低レベルで作業する必要がある場合を除きます (そして、そうでない場合もあるかもしれません)。おそらくImageMagickの方が優れていると思います。彼らは、より多くのフォーマットをサポートすることは言うまでもなく、より高レベルの「MagickWand」C インターフェイスを持っています。

しかし、私は libjpeg のインターフェイスに興味があったので、あなたのサンプル プログラムとlibjpeg.docIJG example、および USING THE IJG JPEG LIBRARYに基づいて、満足のいくように動作するテスト プログラムを取得しました。とにかく、ここにコードがあります。寸法と、各行の最初のピクセルの RGB を出力するだけです。

私のコードでエラーが発生することに非常に驚いています。私にとっては問題なく動作し、警告なしでコンパイルされます。他の誰かがそれをテストできますか?

#include <stdio.h>
#include <assert.h>
#include <jpeglib.h>

int main(int argc, char* argv[])
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPARRAY buffer;
    int row_stride;

    //initialize error handling
    cinfo.err = jpeg_std_error(&jerr);

    FILE* infile;
    infile = fopen("Sample.jpg", "rb");
    assert(infile != NULL);

    //initialize the decompression
    jpeg_create_decompress(&cinfo);

    //specify the input
    jpeg_stdio_src(&cinfo, infile);

    //read headers
    (void) jpeg_read_header(&cinfo, TRUE);

    jpeg_start_decompress(&cinfo);

    printf("width: %d, height: %d\n", cinfo.output_width, cinfo.output_height);

    row_stride = cinfo.output_width * cinfo.output_components;

    buffer = (*cinfo.mem->alloc_sarray)
        ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

    JSAMPLE firstRed, firstGreen, firstBlue; // first pixel of each row, recycled
    while (cinfo.output_scanline < cinfo.output_height)
    {
    (void)jpeg_read_scanlines(&cinfo, buffer, 1);
    firstRed = buffer[0][0];
    firstBlue = buffer[0][1];
    firstGreen = buffer[0][2];
    printf("R: %d, G: %d, B: %d\n", firstRed, firstBlue, firstGreen);
    }

    jpeg_finish_decompress(&cinfo);

    return 0;
}
于 2008-12-25T10:33:10.150 に答える
2

ライブラリを再構築する必要のない回避策は次のとおりです。André Caron が述べたように、置換 I/O 関数を作成しますが、標準の stdio 関数以外には何もありません。

過去に作成した以下のコードが役立つかもしれません。これは libpng 用に書かれていますが、libjpeg でも同じことが簡単にできると思います。

これをコードに追加しました:

    png_set_write_fn (png_ptr,file,replwrite,replflush);

次に、置換関数を作成しました。

void replwrite (png_structp png_ptr, png_bytep data, png_size_t length)
{
    fwrite (data,1,length,(FILE*) png_get_io_ptr(png_ptr));
}

void replflush (png_structp png_ptr)
{
    fflush ((FILE*) png_get_io_ptr(png_ptr));
}

それはいつも私のために働きます。私が実際に行っているのは、libpng に、「.dll が指す MSVCR の書き込み関数を使用しないでください。プログラムで使用している MSVCR の fwrite と fflush から来るこれらの関数を使用してください」と言うことです。基本的に互換性の問題であることがわかります。

これまたはこのようなものが問題を解決することを願っています。

于 2012-10-03T13:59:52.743 に答える
1

提供されたコード サンプルからアクセス違反の原因を確認することは困難です。問題の特定に役立つスタック トレース (シンボル付き) を含めることができる場合。確認すべきことの 1 つは、.LIB および .EXE プロジェクトのアライメント設定が一貫していることです。構造体/クラス メンバーがコンパイラーが期待する場所にないため、しばしば厄介な問題が発生します。

于 2008-12-26T05:12:06.600 に答える
0

複数の形式の画像を扱うには、ライブラリhttp://openil.sourceforge.net/として DevIL をお勧めします。何度も使用して優れた結果が得られたので、これは優れた選択です。構文が OpenGL に似ていることに注意してください。

機能のリスト:

以下の読み込みをサポート:

  • .bmp
  • 。切る
  • .dcx
  • .dds
  • .exr
  • .ico
  • .icns
  • .gif
  • .jpg
  • .jp2
  • .lbm
  • .lif
  • .mdl
  • .pcd
  • .pcx
  • .pic
  • .png
  • .pnm
  • .psd
  • .psp
  • 。生
  • .sgi
  • .tga
  • .tif
  • .wal
  • 。行為
  • .pal
  • .hdr
  • ドゥームのグラフィック

以下の保存をサポート:

  • .bmp
  • .dds
  • .jpg
  • .pcx
  • .png
  • .pnm
  • 。生
  • .sgi
  • .tga
  • .tif
  • .pal

ライブラリの機能

  • ポータブルで、Windows、Mac OS X、および *nix をサポートします。
  • OpenGL スタイルの構文。
  • 醜いポインターの代わりに画像名を使用します。
  • ファイル、ファイル ストリーム、またはメモリの「塊」からの読み込み。
  • ilGetData() および ilSetData() によるデータへの直接アクセス。
  • 輝度、rgb(a)、bgr(a)、カラー インデックス付きイメージのサポート。
  • チャネルごとに 3 つの異なるビット数をサポート。
  • すべての形式とデータ型 (パレットを含む) 間の変換。
  • 画像の読み込み時に、必要に応じてユーザー定義の自動変換。
  • 必要に応じて画像を保存する際の自動変換。
  • 必要に応じて、カラー インデックス付き画像をトゥルーカラー画像に自動変換します。
  • 保存時の制御可能な圧縮。
  • プッシュおよびポップできる状態スタックを維持します。
  • 3d テクスチャ ボリューム (3d イメージ) の完全サポート。
  • 画像の検証。
  • レイヤーのサポート。
  • ミップマップのサポート。
  • アニメーションのサポート。
  • ユーザー指定のクリアカラー。
  • 読み込みに失敗した場合、デフォルトの画像を読み込むことができます。
  • ユーザー指定のヒント。
  • キーカラーの使用。
  • 画像を別の画像の上に重ねる機能のサポート。
  • ユーザーが独自の読み込みおよび保存コールバックを指定できるようにし、デフォルトのものをオーバーライドすることもできます。
  • ユーザー指定の読み取りおよび書き込み機能のサポート。
  • デルファイのサポート。
  • Visual Basic のサポート。
  • Linux のサポート。
  • 小さい dll を作成するために使用する機能を選択できます。
  • Intel Jpeg ライブラリまたは libjpeg のどちらを使用するかを選択します。
  • エンボス加工やエッジ検出など、画像に適用する多数のエフェクトとフィルター。
  • 画像のサイズを変更したり、より大きな背景 (キャンバスを拡大) に配置したりすることもできます。
  • OpenGL、Allegro、Windows GDI、および DirectX API のサポート。
于 2008-12-25T06:48:53.223 に答える