コグノスケ


2024年11月2日

Python - まとめリンク

目次: Python

一覧が欲しくなったので作りました。

編集者:すずき(2024/11/15 23:25)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月6日

Ubuntu 24.04 LTS on ThinkPad X1 Carbon Gen 12

目次: Linux

会社ではThinkPad X1 Carbon 12th GenにUbuntu 24.04 LTSをインストールして使っています。Lenovoが公式サポートしている(Lenovoのサイトへのリンク、正確にはUbuntu 22.04を正式サポート)だけあり、大体は問題なく動作しますが、使って数日にして既に困った点が2つほど出てきました。

困った点その1はWi-Fiです。会社のWi-Fiと相性が悪いのか接続がブチブチ途切れます。全く仕事にならないので、諦めてUSB接続の有線Ethernetアダプタを使っています。有線接続バンザイ。

困った点その2は感圧式タッチパッドです。Gen 12からクリック用のボタンを廃し、タッチパッドは単なる板になりました。板を押した圧力を検知してゴツンと押し返すことでクリック感を表現するデバイスです。個人的には手が疲れるので嫌いです。

感圧式タッチパッドのドライバがおかしいのか、たまに感圧機能がバカになりクリックにめちゃくちゃ力が必要になってしまいます。この症状が発生すると設定ウインドウにタッチパッドの項目が出なくなります。もしこの症状になったときは、

Ubuntu 24.04 LTSタッチパッド復活の呪文
$ sudo rmmod i2c_hid_acpi && sudo modprobe i2c_hid_acpi

これで直りました。この直し方見つけた人すごいですね。どうやって見つけたんだろうね……?

編集者:すずき(2024/11/15 23:47)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月11日

Pythonのテストフレームワーク

目次: Python

最近Pythonを触ることが増えたのでテストについて調べようと思い立ちました。超有名テストフレームワークpytestがありますので、無から使い始めるまでを試します。

環境はDebian Testingで、ツールのバージョンはpython 3.12.6, pytest 8.2.2です。

設定ファイルは新し目のpyproject.tomlにします。その他の選択肢についてはpytestのドキュメントを参照ください。設定ファイルではpytest実行時のオプション、テスト用のスクリプトが置いてあるディレクトリを指定します。

pytestの設定

# pyproject.toml

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = [
    "tests",
]

サンプルにあるオプションの説明をしておくと、

  • -ra: パスしなかった結果だけレポートする
  • -q: バージョン情報などのメッセージを抑制する

となります。これらの効果を打ち消したければ、

  • -rA: 全ての結果をレポートする
  • -vまたは-vv: メッセージ全て(-vvだとより大量に)表示する

オプションを使うと良いみたいです。

テスト対象を作成する

全体構造はこんな感じです。

ディレクトリとファイル構造
.
|-- pyproject.toml
|-- sample
|   `-- main.py
`-- tests
    |-- __init__.py    ★★空っぽでOK★★
    `-- test_main.py

テストするにはテスト対象のコードが必要です。とりあえず成功と失敗を見たいので、合っている関数と間違っている関数の2つを作りました。アホみたいなコードですけど気にしないでください。

テスト対象のコード

# sample/main.py

def my_add(a, b):
    print('my_add!!!!')
    return a + b

def my_wrong_add(a, b):
    print('my_wrong_add!!!!')
    return a + b + 1

テストするためのコードは下記のとおりです。クラスを作ってその下にメソッドを足していくのが基本的な使い方です。

テストのコード

# tests/test_main.py

import pytest
from sample.main import my_add, my_wrong_add

class TestAdd:
    def test_add(self):
        assert my_add(1, 2) == 3

    def test_wrong_add(self):
        assert my_wrong_add(1, 2) == 3

クラスに分ける理由が良くわからなかったのですが、世の中のテスト達を見ているとどうもクラスごとにmarkを付けて、Linuxだったら実行する、Macだったら実行するなどの条件を追加する単位として使うようです。

テストの実行

実行は簡単でpytestコマンドを実行するだけです。

成功と失敗が発生する実行結果
$ pytest
.F                                                                       [100%]
=================================== FAILURES ===================================
____________________________ TestAdd.test_wrong_add ____________________________
 
self = <tests.test_main.TestAdd object at 0x7f617eab4650>
 
    def test_wrong_add(self):
>       assert my_wrong_add(1, 2) == 3
E       assert 4 == 3
E        +  where 4 = my_wrong_add(1, 2)
 
tests/test_main.py:9: AssertionError
----------------------------- Captured stdout call -----------------------------
my_wrong_add!!!!
=========================== short test summary info ============================
FAILED tests/test_main.py::TestAdd::test_wrong_add - assert 4 == 3
1 failed, 1 passed in 0.03s

関数my_add()のテストは成功し、my_wrong_add()のテストは失敗します。意図通りですね。my_wrong_add()を修正すればテスト成功する様子も簡単に確認できるはずです。

全て成功する実行結果
$ pytest
..                                                                       [100%]
2 passed in 0.00s

テストはスクリプト、テストクラス、関数を指定して部分的に実行できます。

部分的にテストを実行する方法
#### スクリプトを指定

$ pytest tests/test_main.py
..                                                                       [100%]
2 passed in 0.00s


#### クラスを指定

$ pytest tests/test_main.py::TestAdd
..                                                                       [100%]
2 passed in 0.00s


#### 関数を指定

$ pytest tests/test_main.py::TestAdd::test_add
.                                                                        [100%]
1 passed in 0.00s

失敗するテストだけ何度も再実行するときに便利ですね。

テストが出力した結果はどこへ?

どちらの関数もprint()しますが、失敗したテストの標準出力のみが表示され、成功したテストの標準出力は無視されます。もし成功したテストも見たければ-rAを指定してください。

成功するテストの標準出力も表示する
$ pytest -rA
..                                                                       [100%]
==================================== PASSES ====================================
_______________________________ TestAdd.test_add _______________________________
----------------------------- Captured stdout call -----------------------------
my_add!!!!
____________________________ TestAdd.test_wrong_add ____________________________
----------------------------- Captured stdout call -----------------------------
my_wrong_add!!!!
=========================== short test summary info ============================
PASSED tests/test_main.py::TestAdd::test_add
PASSED tests/test_main.py::TestAdd::test_wrong_add
2 passed in 0.00s

とりあえず基本的な使い方はこんなもんかなと思います。また気が向いたら書きます。

編集者:すずき(2024/11/15 23:26)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月17日

JTSA Limited大会参加2024

目次: 射的

JTSA Limitedの大会に参加しました。去年はベレッタが壊れましたが、今年は大丈夫でした。記録は絶好調というほどではありませんでしたが、自己ベストに近い71.65秒のタイムが出ました(総合79位/115人、LM 16位/26人)。さすがに3年目ともなると大会本番のまぐれ当たり&自己ベスト、なんて嬉しいアクシデントは発生しませんでした。


JTSA Limited練習会の記録

大会の記録だけ見ると、2022年85秒、2023年76秒、2024年71秒と順調に記録は伸びています。良きかな良きかな。来年はどうなるかな?

編集者:すずき(2024/11/26 15:40)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月18日

nvJPEGとNVJPGとJetson APIその1 - nvJPEG decoupled API

目次: Linux

半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。NVIDIA GPUとCUDAを使ってJPEGが扱えるそうで、API名はnvJPEGだそうです(nvJPEGのAPIドキュメント)。それと別にJPEGのHWコーデックもあり、名前はNVJPG(Eがない)です。nvJPEGと紛らわしくて仕方ありません。

nvJPEG decoupled decoding

NVIDIAがnvJPEGのサンプルを公開しています(nvJPEGデコードサンプルコード)。ありがたいですね。でもなぜかサンプルはデコーダーしかありません。一応Resizeサンプルでエンコーダーを扱っていますが、なぜこんなサンプルの構造にしたのでしょう。

エンコード方法は公式ドキュメント(nvJPEGのドキュメント)の3.1.5 JPEG Encoding Exampleがシンプルで見やすいかもしれません。こちらはなぜかデコーダーのサンプルがありません。変なの。

困ったことにデコーダーのサンプルはRGBからYUVに変更すると動きません。試行錯誤したところストライドが間違っているようです。あとYUV420P(UとVプレーンの幅と高さはYプレーンの半分)なのに、YとUVが同じ高さじゃないとお気に召さないようでした。すなわち、

  • ストライドを256バイトの倍数にする
  • YUVの3プレーン全ての高さを同じにする

このようにするとデコードできました。ドキュメントに何も書いていないので、バグか合っているか全くわかりません。上記を考慮しつつDecoupled decodingする場合のAPI呼び出し順を載せておきます。

CUDA関連の謎APIについては、CUDA Stream Management(cudaStream_tなどのドキュメント)と、CUDA Memory Management(cudaMalloc()などのドキュメント)をご参照ください。

nvJPEG decoupled decodingのAPI呼び出し順

	cudaStream_t stream = nullptr;
	nvjpegHandle_t nvj_handle = nullptr;
	nvjpegJpegState_t nvj_dcstate = nullptr;
	nvjpegBufferPinned_t pinned_buffers[2] = {nullptr};
	nvjpegBufferDevice_t device_buffer = nullptr;
	nvjpegJpegStream_t jpeg_streams[2] = {nullptr};
	nvjpegDecodeParams_t nvj_decparams = nullptr;
	nvjpegJpegDecoder_t nvj_dec = nullptr;
	nvjpegImage_t outbuf = {0};
	uint8_t *img_buf[4] = {nullptr};
	int img_stride[4] = {0};
	int img_sz[4] = {0};
	int r;

	// Create
	cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);

	nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, nullptr, nullptr, NVJPEG_FLAGS_DEFAULT, &nvj_handle);
	nvjpegDecoderCreate(nvj_handle, NVJPEG_BACKEND_DEFAULT, &nvj_dec);
	nvjpegDecoderStateCreate(nvj_handle, nvj_dec, &nvj_dcstate);

	nvjpegBufferPinnedCreate(nvj_handle, nullptr, &pinned_buffers[0]);
	nvjpegBufferPinnedCreate(nvj_handle, nullptr, &pinned_buffers[1]);
	nvjpegBufferDeviceCreate(nvj_handle, nullptr, &device_buffer);

	nvjpegJpegStreamCreate(nvj_handle, &jpeg_streams[0]);
	nvjpegJpegStreamCreate(nvj_handle, &jpeg_streams[1]);

	nvjpegDecodeParamsCreate(nvj_handle, &nvj_decparams);

	//2のべき乗境界に切り上げる
#define ALIGN_2N(a, b)    (((a) + (b) - 1) & ~((b) - 1))

	outbuf.pitch[0] = ALIGN_2N(width, 256);
	outbuf.pitch[1] = ALIGN_2N(width, 256);
	outbuf.pitch[2] = ALIGN_2N(width, 256);
	cudaMalloc(&outbuf.channel[0], outbuf.pitch[0] * height);
	cudaMalloc(&outbuf.channel[1], outbuf.pitch[1] * height);
	cudaMalloc(&outbuf.channel[2], outbuf.pitch[2] * height);

	img_stride[0] = width;
	img_stride[1] = width / 2;
	img_stride[2] = width / 2;
	img_sz[0] = img_stride[0] * height;
	img_sz[1] = img_stride[1] * height / 2;
	img_sz[2] = img_stride[2] * height / 2;
	img_buf[0] = (uint8_t *)malloc(img_sz[0]);
	img_buf[1] = (uint8_t *)malloc(img_sz[1]);
	img_buf[2] = (uint8_t *)malloc(img_sz[2]);

	//Decoupled phase decoding
	nvjpegStateAttachDeviceBuffer(nvj_dcstate, device_buffer);

	nvjpegOutputFormat_t fmt = NVJPEG_OUTPUT_YUV;
	nvjpegDecodeParamsSetOutputFormat(nvj_decparams, fmt);

	int index = 0;
	nvjpegJpegStreamParse(nvj_handle, jpegbuf, jpegsize, 0, 0, jpeg_streams[index]);
	nvjpegStateAttachPinnedBuffer(nvj_dcstate, pinned_buffers[index]);
	nvjpegDecodeJpegHost(nvj_handle, nvj_dec, nvj_dcstate, nvj_decparams, jpeg_streams[index]);

	nvjpegDecodeJpegTransferToDevice(nvj_handle, nvj_dec, nvj_dcstate, jpeg_streams[index], stream);
	nvjpegDecodeJpegDevice(nvj_handle, nvj_dec, nvj_dcstate, &outbuf, stream);

	cudaStreamSynchronize(stream);

	for (int i = 0; i < 3; i++) {
		cudaMemcpy2D(img_buf[i], img_stride[i], outbuf.channel[i], outbuf.pitch[i],
			(i == 0) ? width : width / 2,
			(i == 0) ? height : height / 2,
			cudaMemcpyDeviceToHost);
	}


	// Destroy
	free(img_buf[0]);
	free(img_buf[1]);
	free(img_buf[2]);

	cudaFree(outbuf.channel[0]);
	cudaFree(outbuf.channel[1]);
	cudaFree(outbuf.channel[2]);

	nvjpegDecodeParamsDestroy(nvj_decparams);

	nvjpegJpegStreamDestroy(jpeg_streams[0]);
	nvjpegJpegStreamDestroy(jpeg_streams[1]);

	nvjpegBufferPinnedDestroy(pinned_buffers[0]);
	nvjpegBufferPinnedDestroy(pinned_buffers[1]);
	nvjpegBufferDeviceDestroy(device_buffer);

	nvjpegJpegStateDestroy(nvj_dcstate);
	nvjpegDecoderDestroy(nvj_dec);
	nvjpegDestroy(nvj_handle);

	cudaStreamDestroy(stream);

今回紹介したdecoupled decodingは速度が稼げるみたいですが、複雑です。もっと簡単なsimple decodingもあるので次回にご紹介しようと思います。

実行

ソースコードも置いておきます。

使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.jpgのJPEGファイルを読み込んで、ファイル名decoupled_420.yuvのRawvideoファイルを書き出します。

コンパイル、結果確認
$ g++ -g -O2 -Wall 20241118_nvjpeg_decoupled.cpp -lnvjpeg -lcudart
$ ./a.out

$ ffplay -f rawvideo -video_size 1920x1440 -pixel_format yuv420p -i decoupled_420.yuv

Rawvideoを確認するときはffplayを使うと便利です。FFMPEGは本当にありがたい。

編集者:すずき(2024/12/08 23:40)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月20日

nvJPEGとNVJPGとJetson APIその2 - nvJPEG simple decode API

目次: Linux

半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。NVIDIA GPUとCUDAを使ってJPEGが扱えるそうで、API名はnvJPEGだそうです(nvJPEGのAPIドキュメント)。

nvJPEG simple decoding

前回ご紹介したdecoupled decodingは呼び出すべきAPI数が多くて、ウワァ……と引いてしまう見た目でした。今回のsimple decodingはその名の通りシンプルです。ちなみにエンコード側もあります。なぜかsimpleに該当するAPIしかなく、decoupled相当のエンコード用APIは存在しないようです。変なの。

Simple decodingはこんな感じでした。Decoupledと比べるとかなりAPIが少なく済みます。

nvJPEG simple decodingのAPI呼び出し順

	cudaStream_t stream = nullptr;
	nvjpegHandle_t nvj_handle = nullptr;
	nvjpegJpegState_t nvj_state = nullptr;
	nvjpegImage_t outbuf = {0};
	uint8_t *img_buf[4] = {nullptr};
	int img_stride[4] = {0};
	int img_sz[4] = {0};
	int r;

	// Create
	cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);

	nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, nullptr, nullptr, NVJPEG_FLAGS_DEFAULT, &nvj_handle);
	nvjpegJpegStateCreate(nvj_handle, &nvj_state);

	//2のべき乗境界に切り上げる
#define ALIGN_2N(a, b)    (((a) + (b) - 1) & ~((b) - 1))

	outbuf.pitch[0] = ALIGN_2N(width, 256);
	outbuf.pitch[1] = ALIGN_2N(width, 256);
	outbuf.pitch[2] = ALIGN_2N(width, 256);
	cudaMalloc(&outbuf.channel[0], outbuf.pitch[0] * height);
	cudaMalloc(&outbuf.channel[1], outbuf.pitch[1] * height);
	cudaMalloc(&outbuf.channel[2], outbuf.pitch[2] * height);

	img_stride[0] = ALIGN_2N(width, 256);
	img_stride[1] = ALIGN_2N(width, 256);
	img_stride[2] = ALIGN_2N(width, 256);
	img_buf[0] = (uint8_t *)malloc(img_stride[0] * height);
	img_buf[1] = (uint8_t *)malloc(img_stride[1] * height);
	img_buf[2] = (uint8_t *)malloc(img_stride[2] * height);

	//Decoupled phase decoding
	nvjpegGetImageInfo(nvj_handle, jpegbuf, jpegsize, &jpegcomps, &jpegsamp, jpegwidths, jpegheights);
	nvjpegDecode(nvj_handle, nvj_state, jpegbuf, jpegsize, NVJPEG_OUTPUT_YUV, &outbuf, stream);

	cudaStreamSynchronize(stream);

	for (int i = 0; i < 3; i++) {
		cudaMemcpy2D(img_buf[i], img_stride[i], outbuf.channel[i], outbuf.pitch[i],
			width, height, cudaMemcpyDeviceToHost);
	}


	// Destroy
	free(img_buf[0]);
	free(img_buf[1]);
	free(img_buf[2]);

	cudaFree(outbuf.channel[0]);
	cudaFree(outbuf.channel[1]);
	cudaFree(outbuf.channel[2]);

	nvjpegJpegStateDestroy(nvj_state);
	nvjpegDestroy(nvj_handle);

	cudaStreamDestroy(stream);

1枚だけJPEGをデコードするならこちらの方が断然楽ですね。

実行

前回同様にソースコードを置いておきます。

使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.jpgのJPEGファイルを読み込んで、ファイル名simple_420.yuvのRawvideoファイルを書き出します。

コンパイル、結果確認
$ g++ -g -O2 -Wall 20241120_nvjpeg_simple_dec.cpp -lnvjpeg -lcudart
$ ./a.out

$ ffplay -f rawvideo -video_size 1920x1440 -pixel_format yuv420p -i simple_420.yuv

デコード結果のRawvideoを確認するときはffplayを使うと便利です。

編集者:すずき(2024/12/06 23:34)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月22日

nvJPEGとNVJPGとJetson APIその3 - nvJPEG encode API

目次: Linux

半年経ったら完全に忘れるのでメモします。最近JPEGのデコードエンコードが必要になって色々調べていました。NVIDIA GPUとCUDAを使ってJPEGが扱えるそうで、API名はnvJPEGだそうです(nvJPEGのAPIドキュメント)。

nvJPEG encoding

前回まではデコード処理でした。今回はエンコードのAPIをご紹介します。decoupled decodingのような複雑なAPIは存在しないようです。

Raw YUV420の画素データを置くメモリを確保する際はcudaMalloc()ではなく、cudaMallocHost()を使う点がデコードと異なります。エンコードはこんな感じでした。

nvJPEG encodingのAPI呼び出し順

	cudaStream_t stream = nullptr;
	nvjpegHandle_t nvj_handle = nullptr;
	nvjpegEncoderState_t nvj_state = nullptr;
	nvjpegEncoderParams_t nvj_param = nullptr;
	nvjpegImage_t inbuf = {0};
	uint8_t *jpegbuf = nullptr;
	size_t bufsize = 0;
	int r;

	// Create
	cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);

	nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, nullptr, nullptr, NVJPEG_FLAGS_DEFAULT, &nvj_handle);
	nvjpegEncoderStateCreate(nvj_handle, &nvj_state, stream);
	nvjpegEncoderParamsCreate(nvj_handle, &nvj_param, stream);

	// Set JPEG parameters
	nvjpegEncoderParamsSetQuality(nvj_param, 80, stream);
	nvjpegEncoderParamsSetSamplingFactors(nvj_param, NVJPEG_CSS_420, stream);


	// 2のべき乗境界に切り上げる
#define ALIGN_2N(a, b)    (((a) + (b) - 1) & ~((b) - 1))

	inbuf.pitch[0] = ALIGN_2N(width, 256);
	inbuf.pitch[1] = ALIGN_2N(width, 256);
	inbuf.pitch[2] = ALIGN_2N(width, 256);
	cudaMallocHost((void **)&inbuf.channel[0], inbuf.pitch[0] * height);
	cudaMallocHost((void **)&inbuf.channel[1], inbuf.pitch[1] * height);
	cudaMallocHost((void **)&inbuf.channel[2], inbuf.pitch[2] * height);

	bufsize = width * height * 3 / 2;
	jpegbuf = (uint8_t *)malloc(bufsize);

	// YUVデータをinbufにロードする
	// 詳細はソースコードを参照

	// Encoding
	nvjpegChromaSubsampling_t jpegsamp = NVJPEG_CSS_420;
	size_t jpegsize = bufsize;

	nvjpegEncodeYUV(nvj_handle, nvj_state, nvj_param, &inbuf, jpegsamp, width, height, stream);
	nvjpegEncodeRetrieveBitstream(nvj_handle, nvj_state, jpegbuf, &jpegsize, stream);

	cudaStreamSynchronize(stream);

	// Destroy
	free(jpegbuf);

	cudaFree(inbuf.channel[0]);
	cudaFree(inbuf.channel[1]);
	cudaFree(inbuf.channel[2]);

	nvjpegEncoderParamsDestroy(nvj_param);
	nvjpegEncoderStateDestroy(nvj_state);
	nvjpegDestroy(nvj_handle);

	cudaStreamDestroy(stream);

YUV420Pのロード部分は本質と関係ないことと、若干長いので省略しました。nvJPEG APIの数は少なくてシンプルです。nvJPEGやNVJPGは機械学習用データ(JPEGファイルのことが多いらしい)を高速に入力するため?らしく、デコード命なのでしょう。エンコードもできるけど主眼ではないから、APIもシンプルなものしかないのかな?

実行

前回同様にソースコードを置いておきます。

使い方はコードの先頭にコメントで書いている通りですが、ここでも説明しておきます。引数はありません。ファイル名test_420.yuvのRaw YUV420ファイルを読み込んで、ファイル名simple_420.jpgのJPEGファイルを書き出します。

コンパイル、結果確認
$ g++ -g -O2 -Wall 20241120_nvjpeg_simple_enc.cpp -lnvjpeg -lcudart
$ ./a.out

$ ffplay -i simple_420.jpg

エンコード結果はJPEGです。ffplayでも普段お使いの画像ビューアでも、何を使って確認しても構いません。

編集者:すずき(2024/12/08 15:24)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月25日

libjpeg-turboのライブラリは2つある

目次: Linux

高速なJPEGデコード/エンコードライブラリで有名なlibjpeg-turboですが、ライブラリというかAPIが2系統あります(公式ドキュメントへのリンクlibjpeg-turboのソースコード)。系統その1はlibjpeg(IJG: Independent JPEG Groupのライブラリ)互換のAPIで、系統その2は独自のTurboJPEG APIです。パッケージの名前もややこしくて、しばらくしたら忘れてしまいそうなのでメモしておきます。

libjpeg系
ライブラリlibjpeg.so、ヘッダjpeglib.h、パッケージlibjpeg-turbo8、API名はjpeg_から始まります。
TurboJPEG系
ライブラリlibturbojpeg.so、ヘッダturbojpeg.h、パッケージlibturbojpeg、API名はtj(バージョン2.x系)もしくはtj3(バージョン3.x系)から始まります。

各パッケージに含まれるファイルも示しておきます。

Ubuntu 22.04 AArch64向け各パッケージのファイル一覧
libjpeg-turbo8

/usr/lib/aarch64-linux-gnu/libjpeg.so.8
/usr/lib/aarch64-linux-gnu/libjpeg.so.8.2.2

libjpeg-turbo8-dev

/usr/include/aarch64-linux-gnu/jconfig.h
/usr/include/jerror.h
/usr/include/jmorecfg.h
/usr/include/jpegint.h
/usr/include/jpeglib.h
/usr/lib/aarch64-linux-gnu/libjpeg.a
/usr/lib/aarch64-linux-gnu/libjpeg.so
/usr/lib/aarch64-linux-gnu/pkgconfig/libjpeg.pc


libturbojpeg

/usr/lib/aarch64-linux-gnu/libturbojpeg.so.0
/usr/lib/aarch64-linux-gnu/libturbojpeg.so.0.2.0

libturbojpeg0-dev

/usr/include/turbojpeg.h
/usr/lib/aarch64-linux-gnu/libturbojpeg.a
/usr/lib/aarch64-linux-gnu/libturbojpeg.so
/usr/lib/aarch64-linux-gnu/pkgconfig/libturbojpeg.pc

例としてUbuntu 22.04 AArch64向けのものを示しましたが、他のアーキテクチャやバージョンでも構造は同じです。

編集者:すずき(2024/12/09 00:30)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年11月28日

BIOS/UEFI画面に入る方法

PCは起動時にあるキーを押すとBIOS/UEFIの設定画面に遷移します。良く見るパターンはF1, F2, DELキー辺りですが、メーカーごとに完全にバラバラで統一感なしです。私の場合、初めて見るPCのBIOS/UEFI画面を拝みたいときはEsc, F1, F2, F12, DEL辺りを乱打しながら起動します。これでもたまに普通に起動してしまうPCがあってイライラします。

Twitterでこの話に言及したら、いくつか知らないパターンを教えてもらいましたのでそれも紹介します。

こんなものに独自性を出して誰が幸せになるんでしょうか?実に不毛です。PCメーカーとBIOSメーカーはさっさとキーを統一してください……。

編集者:すずき(2024/12/01 00:53)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報