注意書き

このページに書かれている内容については一切の保証はありませんし、私を含めて誰もなんにも責任を負いません。その点よろしくです。
master@kani.com / 青木 康雄

DC-1/1S/2/2L Frequently Asked Questions の伊藤いとぢゅん純一郎さん、がんばってください。
'96.07.13 '96.07.11

RICOH DC-1/2 の画像・音声ファイルについて

RICOH DC-1/2 の画像・音声ファイルは、JEIDA で標準化されているデジタルスチルカメラに関するファイルフォーマットの規格(G16-1993 ディジタルスチルカメラ用68ピンICメモリカードガイドライン)に準拠(則った?)したフォーマットであり、情報は開示されております。

ここでは、DSC 68 ピン規格の解説をすることは目的でありませんので、以下、RICOH DC-1/2 に限定した話をします。なお、DSC 68 ピン規格自体に興味のある方は、 JEIDAへ直接お問い合わせください。私自身も、標準化規格関係は全くの素人で、今回 DC-1 の画像を展開するためだけに調査したのであります。

RICOH DC-1/2 画像ファイル(J6I)の構造

RICOH DC-1/2 から、シリアル / カードリーダー経由でコンピュータに持ち込まれた画像ファイルのデータについて説明します。

RICOH DC-1/2 については、画像データの実体は、768 X 480 Pixel の JFIF 準拠 JPEG データになっておりまして、頭に 172 バイトの DSC ヘッダがついております。

簡単なデコード方法

単にファイルの先頭を 172 バイト飛ばして、JPEG のデコーダーに入力すれば、画像展開が可能です。但しこの場合、画像アスペクトが4:3に対して、画像サイズが 768 X 480 になってます。縦に潰れた画像になっちゃってますので、768 X 576、あるいは、640 X 480 にリサイズすると正しい画像アスペクトになります。
画面の左右側面に、4 Pixel ほど画像のない部分(ゴミ領域)が発生します。純正ソフトではここのところを白く塗って目立たなくしてますが、拙作 Macintosh 版のデコーダー ( ComeBackImage に内蔵 )では、JPEG データを QuickTime でデコードしたあと、768 Pixel の左右 4 Pixel を除いた 760 Pixel の範囲を、768 Pixel にバイリニア伸長するという方法で、 768 X 576 全体を画像にしております。なんかこのほうが、気持ちいいですね。厳密に言えば、純正ソフトで画像展開するよりもやや横長画像になってしまいますが、DC-1/2 の画像自体、若干縦方向に長い傾向がありますので、むしろ自然な方向への変化です。
余談ですが、オリンパスのデルティスも、この J6I ファイルなんですけど、画像サイズは 768 X 480 で同じなんですが、画像へのゴミの入り方が DC-1/2 と違います。

DSC ヘッダを活かす方法

DSC 68 ピン規格で定める画像フォーマットは、VIDEO 1 規格といいます。この、VIDEO 1 規格にはいくつかのバリエーションがありまして、例えば、垂直画素数は、フィールド記録で 240、フレーム記録で 480 の2種類があり、画像データの実体として、JPEG と非圧縮が選べます。JPEG 量子化テーブルも3個以下となっております。
DC-1/2 に限って言えば、垂直画素数は 480、画像の実体は JPEG となっております。
DSC ヘッダ部には、撮影日時やガンマなどの情報も入ってまして、これを活用しない手はありません。172 バイトの DSC ヘッダの内容は以下のようになってます。

  [ FileOffset ]     Data     意味
  --------------------------------------------------------------------------
         0x00        0x80     お決まり。必ず DSC J6I の頭はこれ。
         0x01        0x3E     次の情報ブロック(JEIDA 規格書ではタプルと呼ぶ)
                              へのオフセット。(次のタプル - 2)値が入るのだが、
                              DC-1/2 では常に 0x3E。
         0x02        0x44     "D"
         0x03        0x53     "S"
         0x04        0x43     "C"
         0x05        0x53     "I"
         0x06        0x44     "M"
         0x07        0x00
         0x08                 DSC ファイル規格のバージョン整数部
         0x09                 DSC ファイル規格のバージョン小数部
      0x0A - 0x0F    0x00     -
      0x10 - 0x2D             規格名称。DC-1/2 では、VIDEO1 と入っている。
                              あまりの領域は、0x00。
         0x30                 ビットフラグで画像属性を示す。
                              8 - 5 bit : 予約( 0 )。
                                  4     : 0 で color、1 でモノクロ。
                                  3     : DC-1/2 では 0。
                                  2     : DC-1/2 では 0。
                                  1     : DC-1/2 では 0。
         0x31        0x00     ガンマ値を示す。DC-1/2 では 0.45 固定(0x00)。
         0x32        0x00     データ格納順。big endian か little endian か
                              の識別。0x00 で上位バイト先、0x0f で下位バイ
                              トが先。
         0x33        0x00     -
      0x34 - 0x37             -
      0x38 - 0x3B             データ領域開始アドレス。DC-1/2 の場合、ヘッダ
                              が 0x00AC 固定なので、ここは、0x000000AC となっ
                              ている。
      0x3C - 0x3F             データ領域終了アドレス。
         0x40        0x81     以下のデータが、記録日時であることを示す ID。
         0x41        0x08     次のタプルへのオフセット。(次のタプル - 2)
         0x42        0x09     GMT に対する時差。DC-1/2 の場合は、0x09 で9
                              時間と定義されている。2 の補数形式で表現。
         0x43        0x00     -
      0x44 - 0x49             記録日時を BCD で記録。YY/MM/DD/HH/MM/SS。
         0x4A        0xFF     これでおしまいの意。
         0x4B        0x00     pad byte。
      0x4C - 0xAB    0x00     ごみ埋め?
        
      0xAC -                  JPEG の画像データ。



J6I を JPEG 化の時には、必要な情報を取得して FFFE 以降に入れてしまうのがいいと思います。あ、もちろん自分で作ったデコーダなりなんなりでなければ活かせませんが。

RICOH DC-1/2 音声ファイル(J6S)の構造

RICOH DC-1/2 から、シリアル / カードリーダー経由でコンピュータに持ち込まれた音声ファイルのデータについて説明します。

RICOH DC-1/2 については、音声データの実体は、CCITT 勧告 G.726(旧 G.721)準拠 ADPCM 32 kbps / 8 KHz sample / 8 bit / u-law(μ則)/ mono であり、頭に 256 バイトの DSC ヘッダがついております。

簡単なデコード方法

単にファイルの先頭を 256 バイト飛ばして、ADPCM のデコーダーに入力すれば、音声のデコードが可能です。と、言っても ADPCM のデコーダーなんて JPEG ほどメジャーじゃないですし、「ハテ?」となります。
私は初め、G.726(721) の勧告書でアルゴリズムを見て、自力で作ろうかと思ったのですがなんと、G.726(721) の部分は和訳されていない上に、実際のものを見てみると、なんかやたら難しいじゃないですか:)。で、IJG の JFIF ソースみたいのがないかな〜って探したらありました。Sun Micosystems,Inc. がリリースしているものですが、Public-domain の ANCI C SourceCode です。いろんな音声形式のコンバートをサポートしているのですが、今回は取りあえず、DC-1/2 の ADPCM を PCM 8 にすることを目的としてこのソースを使いました。
ソースはあちこちにあるようですが、海の向こうのサイトなので、私のところにも持ってきてあります(このページ下のほうを見てくださいね)。ソースをゲットするだけでしたら私のところからどーぞ。取りあえず一カ所、オリジナルの在りかをご紹介します。

ftp://svr-ftp.eng.cam.ac.uk/pub/comp.speech/coding/

G711_G721_G723.tar.gz ってのが目的のアーカイブです。で、他にいくつかのパッチがありますが、今回の DC-1/2 ADPCM -> PCM については関係なさそうなので、私は特になんにもしてません。
私がこのサイトを発見するに至ったのは、以下のページ

Signal Processing (http://tjev.tel.etf.hr/josip/DSP/)

でして、これは OpenText で見つけました。

オリジナルのソースアーカイブ一式を以下においておきますので興味あるかたはもっていってくださいね。 G711_G721_G723.tar.gz オリジナルと、tar.gz を解凍して出来たソースファイルを lha して binhex したものとを用意しました。

G711_G721_G723.tar.gz( 12,731 bytes)
G711_G721_G723.lha.hqx( 27,483 bytes)

使い方は、README に詳しく書いてありますので、そちらをお読みくださいね。

しかしこのソースのままじゃ、ちゃんと J6S の ADPCM をデコードできないのだ。

このソースのまま、J6S の ADPCM を入れちゃうと、「なんかヘン」な音になります。どのようにヘンな音なのかと言いますと、「なんとなくわかるんだけど、なんかヘン」と言った感じで、一応鳴ることはなります。ADPCM のビット格納順の問題かな? なのですが、 ADPCM デコードの時だけ、 decode.c の中にある、unpack_input 関数の中で、ファイルから 1 バイト読んだデータの上位 4 bit と下位 4 bit を入れ換えないと、正しい音にならないのです。私は以下のように修正しました。
int
unpack_input_adpcm(
    unsigned char *code,
    int bits)
{
    static unsigned int   in_buffer = 0;
    static int            in_bits = 0;
    unsigned char         in_byte;

    if (in_bits < bits) {
        if (fread(&in_byte, sizeof (char), 1, stdin) != 1) {
            *code = 0;
            return (-1);
        }
        /*
        以下、私が追加したビット入れ換え部
        */
        {
            unsigned char        swap_byte;

            swap_byte = in_byte >> 4;
            swap_byte |= in_byte << 4;
            in_byte = swap_byte;
        }        
        /*
        以上、私が追加したビット入れ換え部
        */
        in_buffer |= (in_byte << in_bits);
        in_bits += 8;
    }
    *code = in_buffer & ((1 << bits) - 1);
    in_buffer >>= bits;
    in_bits -= bits;
    return (in_bits > 0);
}
私は Macintosh な人です。もし、他のプラットフォーム上でこのコードを使われた場合で、音が「なんかヘン」みたいな場合は、上の「ビット入れ換え部」を削除してみてください。

私はこのあと、このデータに AIFF ヘッダを付けて AIFF ファイル化してます。そうすれば、あとは QuickTime でそのまま鳴らせますし、サウンドコマンドにしてサウンドマネージャーに投げれば、リアルタイム再生処理(デコードしながら鳴らす)も出来ますね。

ここに、ANSI-C で書いた(つもり)、DC-1/2 の J6S 音声ファイルデコーダーのサンプルソースファイルをおいておきます。

DSC ヘッダを活かす法

画像ファイルにおんなじで、DSC ヘッダ部には、撮影日時や音声エンコード方法などの情報も入ってまして、これを活用しない手はありません。DC-1/2 の 256 バイトの DSC SOUND1 ヘッダの内容は以下のようになってます。なお、初めにあるフォーマットタプルというのは、JEIDA DSC 68 ピン IC 規格では、「フォーマットタプルは必須であり、必ずファイル先頭にないとダメ」と決まっているので、DC-1/2 に限らず JEIDA DSC 68 ピン IC 規格音声ファイルは、0x00 〜 0x3F までは同じであるハズです。0x38 以降のフィールドでデータの在りかを取得するようにデコーダーを組んでおけば、JEIDA DSC 68 ピン IC 規格音声ファイルならなんでもデコード出来るような汎用のものが作れるぞ。
  [ FileOffset ]     Data     意味
  --------------------------------------------------------------------------
         0x00        0x80     お決まり。必ず DSC J6S の頭はこれ。
         0x01        0x3E     次のタプルへのオフセット。(次のタプル - 2)
                              の値が入るのだが、DC-1/2 では常に 0x3E。
         0x02        0x44     "D"
         0x03        0x53     "S"
         0x04        0x43     "C"
         0x05        0x53     "S"(画像の時は、"I")
         0x06        0x44     "D"(画像の時は、"M")
         0x07        0x00
         0x08                 DSC ファイル規格のバージョン整数部
         0x09                 DSC ファイル規格のバージョン小数部
      0x0A - 0x0F             -
      0x10 - 0x2D             規格名称。DC-1/2 では、SOUND1 と入っている。
                              あまりの領域は、0x00。
      0x30, 0x31              -
         0x32                 データ格納順。big endian か little endian か
                              の識別。0x00 で上位バイト先、0x0f で下位バイ
                              トが先。
         0x33        0x00     -
      0x34 - 0x37             -
      0x38 - 0x3B             データ領域開始アドレス。DC-1/2 の場合、ヘッダ
                              が 0x0100 固定なので、ここは、0x00000100 となっ
                              ている。
      0x3C - 0x3F             データ領域終了アドレス。
         0x40        0x81     以下のデータが、記録日時であることを示す ID。
         0x41        0x08     次のタプルへのオフセット。(次のタプル - 2)
         0x42        0x09     GMT に対する時差。DC-1/2 の場合は、0x09 で9
                              時間と定義されている。
         0x43        0x00     -
      0x44 - 0x49             記録日時を BCD で記録。YY/MM/DD/HH/MM/SS。
         0x4A        0xFF     これでおしまいの意。
         0x4B        0x00     pad byte。
      0x4C - 0xFF    0x00     ごみ埋め?
        
      0x100 -                 ADPCM の音声データ。

− 以後、次回に続く −

かにこむ扉頁へ