JV: Difference between revisions

From MultimediaWiki
Jump to navigation Jump to search
m (cat)
(rewrite)
Line 3: Line 3:
* Samples: TBD
* Samples: TBD


JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game [http://www.mobygames.com/game/dos/z Z]. No other games are known to use this format.
JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game [http://www.mobygames.com/game/dos/z Z]. No other games are known to use this format. Carries palettized video using [[BTC]] encoding and [[PCM]] audio.


==File Structure==
== File Format ==
Files consist of a fixed-length header, followed by an index table, and the


    0x0000  70 bytes  ASCIIZ "JV00 Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."
Files consist of a fixed-length header, followed by an index table, and then frame chunks. All numbers are little-endian.
    0x0050  le_u16    frame width (pixels)
    0x0052  le_u16    frame height (pixels)
    0x0054  le_u16    total frame count
    0x0056  le_u16    always 0x50
    0x0058  le_u16    always 0x01
    0x005a  le_u16    always 0x02
    0x005c  le_u16    audio samples per second (22050 observed)
    0x0060  7 bytes  always zero
    0x0067  u8        always non-zero


The frame index table begins at offset 0x68, and contains an index record for each frame. The size of the table can be calculated using the total frame count field.
File header (0x68 bytes):


    le_u32 - total frame length (octets)
  u8  sig[2]            -- File signature, "JV"
    le_u32 - audio chunk length (octets)
  u8  palmode1          -- Initial palette mode. 'W' - all White, '0' (or any
    le_u32 - video chunk length (octets)
                            other value) - Black. (Un)used for fade-in effect
    le_u16 - unknown
  u8  palmode2          -- Final palette mode. Same as above, but fade-out
    le_u16 - unknown
  u8  copyright[0x4C];  -- "Compression by John M Phillips"... bla-bla
  s16 width;            -- Frame width
  s16 height;            -- Frame height
  s16 frames;            -- Number of frames
  s16 rate;              -- Frame rate. Delay between successive frames in ms
  s32 maxchunk;          -- Maximal size of a single frame chunk
  s32 freq;              -- Audio frequency
  u8  flags0:1;          -- ?
  u8  volume:7;          -- Default sound volume (0 - max)
  u8  unused[6];
  u8  flags1:3;          -- Number of fade-in frames?
  u8  flags2:3;          -- ?
  u8  flags3:1;          -- ?
  u8  flags4:1;          -- ?


Frame data is stored immediately follows the header, where each frame corresonds to an entry in the index table. Each frame comprises an audio chunk followed immediately by a video chunk. The length of the audio and video data corresponds to the value indicated in the index record. Video chunks may sometimes be zero length. Frames sometimes contain additional unknown data (suspected to be padding), therefore the "total frame length" field must considered when parsing each frame.
File header is followed by frame index table, one entry per frame.


==Audio Chunk==
Table entry format (0x10 bytes):


Each audio chunk contains mono unsigned 8-bit PCM audio samples.
  s32 chunk_size;        -- Size of the chunk data
  s32 audio_size;        -- Size of the audio portion of the frame
  s32 video_size;        -- Size of the video portion of the frame
  s8  has_palette;      -- New palette is present
  s8  audio_type;        -- Audio format. Always 0 - mono, 8-bit [[PCM]]
  s8  video_type;        -- Video compression method (see below)
  s8  unused;


==Video Chunk==
Finally, frame chunks follows.


The compression algorithm is unknown.
Frama chunk format:
 
  s8  audio[audio_size]; -- Audio data
  RGB palette[256];      -- New palette (present only if has_palette flag is set)
  s8  video[video_size]; -- Video data
  s8  padding[];        -- sizeof(audio + palette + video + padding) == chunk_size
 
== Video compression ==
 
Depending on video_type value, frame can be encoded using the following way:
 
=== Type 0: Raw frame ===
Paint frame using the video data and continue with Type 1 decoding.
Apparently, someone forgot to put the "break" keyword here because additional decoding of the raw data seems redundant. Or perhaps it was originally planned to (losely) compress this block data somehow.
 
=== Type 1: BTC frame ===
Initialize a bit-reader using video data. Fill it with 8-bit values, fetch bits starting from the highest. Multi-byte values are read as byte0 = GetByte(), byte1 = GetByte(), etc.
 
Frame is encoded as a series of 8x8 blocks. To decode single block:
  Read 2-bit block type:
  0: End. End of (sub)block decoding.
  1: Fill. Read 8 bits and use them to fill the (sub)block.
  2: BTC. Read color0 and color1, 8 bits each. Read mask. For each pixel of
    (sub)block, if mask bit is set - paint it using color1. Use color0 if bit
    is clear. Complete mask read first (4/16/64 bits) and processed from
    its highest bit to lowest.
  3: Subblock. Split the block on 4 equal subblocks and process each one
    separately using the same scheme recursively. If the subblock size is
    already 2x2, paint it using the next 2 * 2 * 8 bits.
 
=== Type 2: Solid frame ===
Read 8-bit pixel value from video data and use it to fill the whole frame.


[[Category:Game Formats]]
[[Category:Game Formats]]
[[Category:Undiscovered_Video_Codecs]]
[[Category:Undiscovered_Video_Codecs]]

Revision as of 07:30, 6 March 2011

JV is a multimedia format developed by the Bitmap Brothers and is used in the DOS game Z. No other games are known to use this format. Carries palettized video using BTC encoding and PCM audio.

File Format

Files consist of a fixed-length header, followed by an index table, and then frame chunks. All numbers are little-endian.

File header (0x68 bytes):

 u8  sig[2]             -- File signature, "JV"
 u8  palmode1           -- Initial palette mode. 'W' - all White, '0' (or any
                           other value) - Black. (Un)used for fade-in effect
 u8  palmode2           -- Final palette mode. Same as above, but fade-out
 u8  copyright[0x4C];   -- "Compression by John M Phillips"... bla-bla
 s16 width;             -- Frame width
 s16 height;            -- Frame height
 s16 frames;            -- Number of frames
 s16 rate;              -- Frame rate. Delay between successive frames in ms
 s32 maxchunk;          -- Maximal size of a single frame chunk
 s32 freq;              -- Audio frequency
 u8  flags0:1;          -- ?
 u8  volume:7;          -- Default sound volume (0 - max)
 u8  unused[6];
 u8  flags1:3;          -- Number of fade-in frames?
 u8  flags2:3;          -- ?
 u8  flags3:1;          -- ?
 u8  flags4:1;          -- ?

File header is followed by frame index table, one entry per frame.

Table entry format (0x10 bytes):

 s32 chunk_size;        -- Size of the chunk data
 s32 audio_size;        -- Size of the audio portion of the frame
 s32 video_size;        -- Size of the video portion of the frame
 s8  has_palette;       -- New palette is present
 s8  audio_type;        -- Audio format. Always 0 - mono, 8-bit PCM
 s8  video_type;        -- Video compression method (see below)
 s8  unused;

Finally, frame chunks follows.

Frama chunk format:

 s8  audio[audio_size]; -- Audio data
 RGB palette[256];      -- New palette (present only if has_palette flag is set)
 s8  video[video_size]; -- Video data
 s8  padding[];         -- sizeof(audio + palette + video + padding) == chunk_size 

Video compression

Depending on video_type value, frame can be encoded using the following way:

Type 0: Raw frame

Paint frame using the video data and continue with Type 1 decoding. Apparently, someone forgot to put the "break" keyword here because additional decoding of the raw data seems redundant. Or perhaps it was originally planned to (losely) compress this block data somehow.

Type 1: BTC frame

Initialize a bit-reader using video data. Fill it with 8-bit values, fetch bits starting from the highest. Multi-byte values are read as byte0 = GetByte(), byte1 = GetByte(), etc.

Frame is encoded as a series of 8x8 blocks. To decode single block:

 Read 2-bit block type:
 0: End. End of (sub)block decoding.
 1: Fill. Read 8 bits and use them to fill the (sub)block.
 2: BTC. Read color0 and color1, 8 bits each. Read mask. For each pixel of
    (sub)block, if mask bit is set - paint it using color1. Use color0 if bit
    is clear. Complete mask read first (4/16/64 bits) and processed from
    its highest bit to lowest.
 3: Subblock. Split the block on 4 equal subblocks and process each one
    separately using the same scheme recursively. If the subblock size is
    already 2x2, paint it using the next 2 * 2 * 8 bits.

Type 2: Solid frame

Read 8-bit pixel value from video data and use it to fill the whole frame.