C++ template memo
template うろおぼえだなぁ。動くかなとおもった次の物が動いた。int も class T で受けられる物なのか。
/* output: sizeof(4)=4 sizeof(2)=2 */ #include <iostream> using namespace std; template <class T> void afunc(T a) { cout << "sizeof(" << a << ")=" << sizeof(a) << endl; } int main(int argc, char *argv[]) { afunc<int>((int)4); afunc<short>((short)2); return 0; }
Scala の練習
Base64 encoder, decoder を wiki のアルゴリズム解説をもとに書いてみる。Decoder から始めた。いろんな試行錯誤のうちに collection 周りの復習ができたし、できない事も分かってきた。REPL で試しながら書けるのはやはり便利。
object Base64Decoder { def main(args: Array[String]) { import scala.io.Source val source = Source.fromFile(args(0)) for (line <- source.getLines) System.out.write(Base64Decoder.decode(line)) } def decode(str: String) = { val s1 = str.replace("\r\n","").replace("\n","").replace("\r","") val c4seq = for (i <- 0 until(s1.length, 4)) yield s1.substring(i, i+4) val t4vec = c4seq.map(for (c <- _) yield if (c=='=') 0 else c2vmap(c) ) val i3sec = for (v <- t4vec) yield v.reduceLeft((a,b) => a << 6 | b) val a = i3sec.flatMap(x=>List(x>>16,(x>>8)&0xff,x&0xff)).toList.toArray a.map(_.asInstanceOf[Byte]).filter(_ != 0) } def ctable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" def c2vmap = Map() ++ (for (i <- 0 until ctable.length) yield ctable(i) -> i) }
Encoder はなかなか上手く書けない。試行錯誤の後で、全体を見直せてないので、まだうまくまとめる余地はあると思うけど...
object Base64Encoder { def main(args: Array[String]) { import java.io.{File,FileInputStream} val f = new File(args(0)) val length = f.length.asInstanceOf[Int] println("file len " + length) val ba = new Array[Byte](length) val fis = new FileInputStream(f) val r = fis.read(ba) println("read return " + r) fis.close() val s = Base64Encoder.encode(ba) println(s) } def ctable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" def encode(indata: Array[Byte]) = { import scala.collection.mutable.ListBuffer // convert byte to nibbles 00000000 -> 0000 0000 val b4at = for (v <- indata) yield List(v>>4, v&0xf) val b4ltmp = b4at.reduceLeft((a,b) => a:::b) val n6bm = roundup(b4ltmp.length, 6) val b4l = b4ltmp val b4a = b4l.toArray val lb = ListBuffer() ++ b4a for (i <- 0 until n6bm - b4ltmp.length) lb += 0 val bl = lb.toList val ivv = for (i <- 0 until(b4ltmp.length,3)) yield List(0x3f& (bl(i)<<2 | bl(i+1)>>2), 0x3f&(bl(i+1)<<4 | bl(i+2))) val ia = ivv.reduceLeft((a,b) => a:::b) val ca = ia.map(ctable(_)) val neqpad = roundup(ca.length, 4) - ca.length val lb2 = ListBuffer() ++ ca for (i <- 0 until neqpad) lb2 += '=' val s1 = new String(lb2.toList.toArray) val sa = for (i <- 0 to s1.length / 64) yield s1.substring(i*64, Math.min(s1.length, roundup(i*64+1, 64))) sa.mkString("\n") } def roundup(v: Int, base: Int) = ((v + base - 1)/base)*base }
__NSAutoreleaseNoPool(): Object 0... of class NSCFString autorel
久々に Objective-C. 細かな所は完全に抜けてたけど、うろ覚えで書くとエラーが...
__NSAutoreleaseNoPool(): Object 0x1001102e0 of class NSCFString autoreleased with no pool in place - just leaking ...
#include <Foundation/Foundation.h> void arrEx() { NSArray *arr = [[NSArray alloc] initWithObjects:@"a,",@"b",@"c",nil]; NSLog(@"arr: %@", [arr description]); [arr release]; } int main(int argc, char *argv[]) { NSLog(@"Hello !"); arrEx(); return 0; }
メッセージの数、出方から arr の要素に関連しているのは間違いないだろう。NSAutoRelasePool を使えば解決なんだけど、参照カウンティングのやり方もきっちり押さえとかないとと少し粘ってみたが、なかなか消えてくれない物だ。もう一度、本読み直そうか。
#include <Foundation/Foundation.h> void arrEx() { //NSArray *arr = [[NSArray alloc] initWithObjects:@"a,",@"b",@"c",nil]; //NSArray *arr = [[NSArray alloc] initWithObjects:@"a,",nil]; NSArray *arr = [[NSArray alloc] initWithObjects:nil]; NSLog(@"arr: %@", [arr description]); int i; for (i = 0; i < [arr count]; i++) { [[arr objectAtIndex:i] release]; } #if 0 NSEnumerator *e = [arr objectEnumerator]; id object; while (object = [e nextObject]) { [object release]; } #endif [arr release]; } int main(int argc, char *argv[]) { NSLog(@"Hello !"); arrEx(); return 0; }
OpejJDK for Mac OS X
OS X 向けの OpenJDK が利用できるようになっていたので、ビルドしてみた。
http://mail.openjdk.java.net/pipermail/macosx-port-dev/2011-January/000007.html
http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port
Mercurial forest extension を使ってコードを持ってきて、環境変数をセットして make. XCode が必要。binary plug は Snow Leopard に入っている JDK を使うので、別途落とす必要はない。
引っかかったのは2点:
IDL 関連のコンパイルエラー
/private/tmp/macosx-port/build/macosx-universal/corba/gensrc/ org/omg/CORBA/ParameterModeHolder.java:5: ?????????????? ascii ?????????? * IDL-to-Java ?R???p?C?? (?|?[?^?u??), ?o?[?W???? "3.1" ?????? ^
LANG, LC_ALL を unset したり、C に設定したりしても駄目。Apple の Java は LANG を拾ってくれないので仕方ない。環境変数 _JAVA_OPTIONS=-Dfile.encoding=ASCII を使っても駄目だ。結局エラーになってるファイルが UTF-8 でできている事を確認して、native2ascii で ASCII のファイルに変換して通るようになった。
$ find build/macosx-universal/corba/gensrc/org/ \ -name '*.java' | while read p; do native2ascii \ -encoding UTF-8 $p > tmpj; mv tmpj $p; done
StubDebuggerLocal.c (SAPROC) のエラー
jni.h が見つからないと言っている。
Making SA debugger back-end... /Developer/usr/bin/llvm-gcc-4.2 -Di486 -D_GNU_SOURCE \ -m32 -march=i586 -mstackrealign -Wl,-install_name,@rpath/libsaproc.dylib -dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 -fPIC -fPIC \ -I/private/tmp/macosx-port/hotspot/agent/src/os/bsd \ -I../generated \ -I/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/include -I/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/include/darwin -I/System/Library/Frameworks/JavaVM.framework/Headers \ /private/tmp/macosx-port/hotspot/agent/src/os/bsd/StubDebuggerLocal.c \ \ \ -o libsaproc.dylib \ /private/tmp/macosx-port/hotspot/agent/src/os/bsd/StubDebuggerLocal.c:26:17: error: jni.h: No such file or directory
hotspot/make/bsd/makefiles/saproc.make が makefile.
コンパイラにはいくつも -I オプションを渡していて、その中には jni.h を持つ物もある。でもエラーになっている。
$ ls /System/Library/Frameworks/JavaVM.framework/Headers/jni.h /System/Library/Frameworks/JavaVM.framework/Headers/jni.h
一見、ファイルはあるように見える。
$ head /System/Library/Frameworks/JavaVM.framework/Headers/jni.h head: /System/Library/Frameworks/JavaVM.framework/Headers/jni.h: No such file or directory
でも、中身は見えない。
$ ls -l /System/Library/Frameworks/JavaVM.framework/Headers/jni.h lrwxr-xr-x 1 root wheel 30 10 17 17:23 /System/Library/Frameworks/JavaVM.framework/Headers/jni.h -> ../../CurrentJDK/Headers/jni.h
シンボリックリンクだけど、リンク先が存在しない。
/Developer の下には jni.h が見つかったので、強引にそのディレクトリを -I に続けて指定する。
... ifeq ($(OS_VENDOR), Darwin) BOOT_JAVA_INCLUDES = -I/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers -I$(BOOT_JAVA_HOME)/include \ ...
これで make が通るようになった。
$ build/macosx-universal/bin/java -version openjdk version "1.7.0-internal" OpenJDK Runtime Environment (build 1.7.0-internal-foo_2011_01_12_22_32-b00) OpenJDK 64-Bit Server VM (build 20.0-b03, mixed mode)
OpenJDK Java7 起動成功!
SwingSet2.jar を実行して気づいたけど、この版はまだ X11 を使っている。otool -L の出力では Cocoa もリンクされていて分かりにくいが、lsof で見ると Apple Java では出てこない X11 関連のパス(フォントが目立つが)がたくさん出てくる。今までの Apple Java というよりは BSD port に近い。早く Cocoa 対応した物を見てみたい。
Quartz Composer Programming
Quartz Composer、入門書をざっと読んで試してそれっきりだったけど、複雑なデータをビジュアライズするにはこれかなって思っていた所もあり、ふと見つけたページで少し遊んでみる。
Introduction to Quartz Composer Programming Guide
始めの辺りしか読んでないけど、Quartz Composer composition .qtz を QCView に関連づけて、Cocoa Application にできる。手順の概要は次のようになる。
- XCode から New Project, Cocoa Application を選ぶ。
- プロジェクト -> プロジェクトに追加で /System/Library/Frameworks/Quartz.framework を追加。Add to Target のシートが出てくるがデフォルトのままで次に進む。
- Resources フォルダの MainMenu.xib をダブルクリック。Interface Builder が起動する。
- Library が表示されていなければ Tools -> Library で表示。だいぶ下の方に Quartz Composer があるはず。なければ Interface Builder の Preference を開き、Plug-ins のタブで Developer > Extras > Pallets から QuartzComoser.ibplugin を追加する。
- Library の Quartz Composer は QCView という Quartz Composer 用の View を表しているので、Interface Builder の main window にドラッグしてサイズを調整。
- main window の QCView を選択した状態で Attribute inspector の Load ボタンから .qtz ふぁいるを選ぶ。/Developer/Library/Quartz Composer/Examples/Graphic Animations/Rings.qtz にしてみた。この例では使わないが、イベントを使う場合には Forward All Events にチェックを入れる。
- Interface Builder, File > Simulate Interface で概要チェック。
- XCode に戻り Build & Restart で実行可能。
Scala for expression with Java Collection
1行の import を加えるだけで Scala の for expression で Java の collection を iterate できる。
http://www.scala-lang.org/docu/files/collections-api/collections_46.html
例は、Hashtable のサブクラスである Properties を Scala の for expression で iterate。
Properties の初期化部分は、いちいち props.setProperty を繰り返し書きたくなかったので、trait などの anonymous subclass の説明で出てきたような書き方を行うと、期待した動作になった。つまり、いちいち props. の部分を指定しなくてすむ。実際には Properties を親に持つ anonymous class が作られ、コンストラクタで、これらの setProperties が呼ばれるバイトコードになる。
import java.util._ import collection.JavaConversions._ object Prop { def main(args: Array[String]) { val props = new Properties() { setProperty("US", "DC") setProperty("UK", "London") setProperty("JP", "Tokyo") } for ((k,v) <- props) { println(k + ": " + v) } println(props.getClass.toString) } }
Exif データ
iPhoto で写真->詳細写真情報とすると写真に関する様々な情報が表示される。写真のサイズや、撮影時間、カメラのメーカー、機種、撮影条件などが別のウィンドウに表示される。
写真の作例などを見ると、シャッタースピードや、絞り、ISO 値などが書かれている事が多いが、いちいちメモしている訳ではなく、この情報をもとにしているのだろう。
露出のセクションには、D90 の場合、シャッター速度、絞り、最大絞り、露出バイアス、露出、露出指数、焦点距離、距離、センサー方式、光源、フラッシュ、測光方式、明度、ISO 感度といった情報が含まれる。カメラが変わると表示される情報の種類も変わるようだし、中には値の入っていないものもある。天気や、場所といった外部の情報は無理だが、これもコメントを手動で入れる事は不可能ではない。
シャッター速度、絞り、焦点距離、フラッシュの情報から、およそ、どのようなカメラの条件で撮影したものかがわかる。ほとんどが AUTO の撮影で撮ったものなので、カメラがそれぞれの状況で、どのようにこれらのパラメータを調整したかという情報とも言える。
風景や、建築物、室内など、様々な条件はあるが、シャッタースピードに関しては昼間であれば数百分の1秒から、60分の1秒の範囲を変動している。これが夜間になると20分の1より長くなり、0.6、時には1秒を超えるようになっている事がわかる。また、暗くなるにつれ、ISO 値は大きめに撮る場合も出てくるし、絞りは解放気味にして、シャッタースピードを稼ぐように働いている事が見て取れる。
最大絞りというのは、ある焦点距離での絞り解放時のF値。18-105mm f/3.5-5.6 であれば、焦点距離 18mm で 3.5, 105mm で 5.6 となる。これに、意味があるのかは分からないが、いろいろな焦点距離で、最大絞りをプロットすると、焦点距離に対するレンズの F値の特性がわかる。簡単にやってみると、リニアという訳ではなく、徐々になだらかな変化になる。70mm 位で、F5.5 になり、そこからは少しなだらかになる。
ここで、ほかのカメラで撮った映像が気になり、何枚か確認してみる。
Panasonic DMC-FX30:
2304x3072
シャッター:可変 1/250, 1/30 など
絞り: 可変 f/3.7, f/5.0 など
最大絞り: f/2.8
焦点距離: 可変 4.6mm 7.9mm 16.4mm など
ISO感度: 可変 100, 250, 640 など
iPhone 3G:
製造元、機種、ソフトウェア: Apple, iPhone, 3.1 など
1600x1200
絞り: f/2.8
iPhone で撮ったものでも情報がないものが見られたが、これはアプリで撮った場合かも。
iPhone 3GS:
製造元、機種、ソフトウェア: Apple, iPhone 3GS, 3.1 など
2048x1536
シャッター: 可変 1/15, 1/1903 など
絞り: f/2.8
焦点距離: 3.85mm
ISO感度: 可変 70, 482, 505, 843, 1016 など
iPhone 4:
製造元、機種、ソフトウェア: Apple, iPhone, 4.0 4.0.1 4.1
2592x1936 pixel
シャッター: 可変 1/15, 1/17, 1/241, 1/2514, 1/2742 など
絞り: f/2.4 f/2.8(iOS 4.1)
焦点距離: 3.85mm
測光方式: スポット 平均
ISO感度: 可変 80, 125, 250, 320, 640, 1000 など
iPhone4 ではレンズが f/2.4 になって、少し明るくなったという事だったが、iOS 4.1 にしてから なぜかf/2.8 になっている。小さいカメラの場合には、焦点距離はそのままの数値はレンズの物理的サイズに依存するらしいが、35mm 換算でやく32mm に相当するらしく、少し広角という事らしい。光学ズームはないので、当然固定。
これらの情報に加えて、GPS の位置情報も入ってくる事がある。
この種の情報は Exif という規格によるもので、現在 2.2, 2.2.1 あたりのバージョン。Mac OS X 付属の Preview でも Exif の情報は表示でき、表記やカテゴライズが iPhoto とは異なるが、ツール -> インスペクタ、または Mac ではおなじみの Command + I で表示できる。
Exif 関連の情報を探していると、とあるツールにたどり着いた。exiftool という、コマンドラインで実行するもの。Perl で書かれているので、いろいろな環境で実行できる。
http://www.sno.phy.queensu.ca/~phil/exiftool/
覚えたての、AppleScript で iPhoto から、Exif 情報を拾って来れるのではと試してみたが、画像サイズや、時間など、ごく基本的なものしか取得できないようで、残念。多くの写真に関して、パラメータ情報などを一括して取得して、まとめられないかという事を考えていたのだけれど、exiftool を使えばできるだろう。GUI ツールで見ていてもわかったが、焦点距離に関しては圧倒的に広角側、望遠側の端っこを使っている事が多く、これらの間を有効に使えていない事に少し幻滅。
シャッタースピードや絞りの調整で、特定の効果が出せる事はわかってきたが、これは絵が明るい場合にはいろいろ試せるのだが、周囲に光が少ないと、シャッタースピードをいかに確保するかという問題が出てくる。
一般的に「1/焦点距離」のシャッタースピードならば手ぶれをしない数値と言う目安があるようで、
18mm = 1/18
105mm = 1/105
200mm = 1/200
DXフォーマット(APS-C)の場合、焦点距離がx1.5の計算になり
18mm = 1/27
105mm = 1/157.5
200mm = 1/300
APS-C は昔からの 35mm よりコンパクトで扱いやすい APS のフィルムの規格をベースにした、少しフィルムの小さい規格に従ったデジタルカメラの規格で、システムの小型化ができるため、現在 DSLR では主流。35mm 互換もない事はないらしい(D3 ?)が、これは 35mm の銀塩との互換が必要な場合に限られ、システムも大きく、重くなる傾向がある。
iPhone なら限界のシャッタースピードは 1/32 といった所か。確かに、夜や、暗い室内では 1/15 まで落ちているので、そのような条件の写真は残念なものが多い。無料のアプリで Exif & IPTC Metadata Browser というものがあり、これでカメラロールの写真(インポートしたものも含む)の Exif 情報が表示できる。シャッタースピードは Exif/ExposureTime にある。残念なのは普通の浮動小数点表記なので、何分の1というのがわかりづらい所。1/32 は 0.03125 なので、この数字は覚えておくと良いかも。最初の起動時に位置情報へのアクセスを確認してくる。これを許可しないと、なぜかカメラロールにアクセスできないけど、そういうものなのか?
三脚についても少し調べてみた。軽く、扱いやすいという所で SLIK Pro 200 といったものの周辺がお手頃のようだった。素材は A.M.T. (アルミ、マグネシウム、チタン)ということだが、評判は今ひとつよくなく、少し価格帯はあがるが、カーボン製の SLIKカーボンマスター 723 PRO といったあたりにしておくのがいいかもしれない。少々軽いものでもかさばる事には変わりなく、すこし軽く、安くなっても、安定性が損なわれるのであれば、しっかりしたものにしておいた方が良さそうだ。