2015年08月30日
JPEG 法
明日で八月も終わり。九月になると朝晩の通勤がまた混雑するんでしょうね。
昔、「アルゴリズムのコーナー」で紹介した「JPEG 法」のサンプル・プログラムを見直しています。10 年くらい前にまとめたもので、当時は C 言語で構築していたので C++ で書き直し、並行してドキュメントもリニューアルする予定です。
JPEG は 90 年代に規格化された後、急速に広まった画像フォーマットでした。当時は JPEG と GIF が一般的な画像形式だったと記憶してます。離散コサイン変換 (DCT) を使い、見た目はほとんど変わることなく非可逆的に圧縮するというのはそれまでなかっただけに新鮮に思いました。本格的に内容を理解しようとしたのは 10 年前くらいから。そのころは JPEG2000 という新しいフォーマットも誕生して、これは「ウェーブレット変換」を使っているという情報だけでいろいろと調べたり悩んだりしていました。JPEG2000、今は全く使われないですね。結局今でも JPEG が残っているといいのはある意味すごいことだと思います。
ところで GIF と同様に JPEG も特許関係で訴えられたことがありました。有名なのが Forgent Networks (現在は Asure Software )。なんだか怪しげな会社です(会社と言っていいんでしょうか)。
昔、「アルゴリズムのコーナー」で紹介した「JPEG 法」のサンプル・プログラムを見直しています。10 年くらい前にまとめたもので、当時は C 言語で構築していたので C++ で書き直し、並行してドキュメントもリニューアルする予定です。
JPEG は 90 年代に規格化された後、急速に広まった画像フォーマットでした。当時は JPEG と GIF が一般的な画像形式だったと記憶してます。離散コサイン変換 (DCT) を使い、見た目はほとんど変わることなく非可逆的に圧縮するというのはそれまでなかっただけに新鮮に思いました。本格的に内容を理解しようとしたのは 10 年前くらいから。そのころは JPEG2000 という新しいフォーマットも誕生して、これは「ウェーブレット変換」を使っているという情報だけでいろいろと調べたり悩んだりしていました。JPEG2000、今は全く使われないですね。結局今でも JPEG が残っているといいのはある意味すごいことだと思います。
ところで GIF と同様に JPEG も特許関係で訴えられたことがありました。有名なのが Forgent Networks (現在は Asure Software )。なんだか怪しげな会社です(会社と言っていいんでしょうか)。
2015年08月30日
暑さが思考を鈍らせる
大雨の日が続きますね。しかし、おかげで涼しくなってきました。
最近になって思うのは、温度より湿度のほうが「暑苦しい」という感覚に影響しているということです。30 度を超えていても湿度の低い日は案外エアコンなしで大丈夫だったりしました。逆に 30 度以下でも湿度が高いときは耐えられないですね。だいたい 60% くらいがリミットでしょうか。
暑いと思考回路も鈍くなるということで、今日はどうでもいいようなところで悩んでいました。
例えば、下のようなクラスを作ります。
使うときはこんな感じになります。
意図した通り、これで 1 が出力されます。しかし、
とすると下のようなエラーが出力されます。
error: no matching function for call to ‘Test::Test(int*)’
いろいろ試行錯誤してみると
のようにポインタを定数とすればちゃんとコンパイルできました。実際はもう少し複雑なクラスの中で発生した問題だったので、最初はなぜこのような動作になるのか全くわからず、コンパイラのバグじゃないのと疑う始末。で、上に書いたようなクラスを使って検証した結果、
とすれば正常にコンパイルすることができて、&data[0] として渡した場合、定数ではないポインタへの参照としては扱われないということを理解しました。先週はこれにずっと頭を悩ませていたわけで、理由がわかって何かスッキリしました。というより、もっと早く気付けと過去の自分に言いたい
最近になって思うのは、温度より湿度のほうが「暑苦しい」という感覚に影響しているということです。30 度を超えていても湿度の低い日は案外エアコンなしで大丈夫だったりしました。逆に 30 度以下でも湿度が高いときは耐えられないですね。だいたい 60% くらいがリミットでしょうか。
暑いと思考回路も鈍くなるということで、今日はどうでもいいようなところで悩んでいました。
例えば、下のようなクラスを作ります。
template< class T >
class Test
{
T* t_;
public:
Test( T& t ) : t_( &t ) {}
void print( size_t i )
{ std::cout << (*t_)[i] << std::endl; }
};
使うときはこんな感じになります。
int data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
std::vector<int> vec( &data[0], &data[sizeof(data) / sizeof(data[0])] );
Test< std::vector<int> > test1( vec );
test1.print( 1 );
意図した通り、これで 1 が出力されます。しかし、
Test< int* > test2( &data[0] );
test2.print( 1 );
とすると下のようなエラーが出力されます。
error: no matching function for call to ‘Test
いろいろ試行錯誤してみると
Test< int*const > test2( &data[0] );
のようにポインタを定数とすればちゃんとコンパイルできました。実際はもう少し複雑なクラスの中で発生した問題だったので、最初はなぜこのような動作になるのか全くわからず、コンパイラのバグじゃないのと疑う始末。で、上に書いたようなクラスを使って検証した結果、
int* p = &data[0];
Test< int* > test2( p );
とすれば正常にコンパイルすることができて、&data[0] として渡した場合、定数ではないポインタへの参照としては扱われないということを理解しました。先週はこれにずっと頭を悩ませていたわけで、理由がわかって何かスッキリしました。というより、もっと早く気付けと過去の自分に言いたい